20155328 《网络攻防》 实验一:PC平台逆向破解(5)M
实践目标
-
实践对象:linux可执行文件pwn1.
-
正常执行时,main调用foo函数,foo函数会简单回显任何用户输入的字符串。
-
实践运行代码片段getShell,学习如何注入运行任何Shellcode。
实践内容:
1.手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
2.利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
3.注入一个自己制作的shellcode并运行这段shellcode。
这几种思路基本上代表了现实情况中的攻击目标:
-
运行原本不可访问的代码片段
-
强行修改程序执行流
-
注入运行任意代码
一些汇编指令
-
NOP:空指令,执行后不产生任何结果,但会占用一个指令的时间。机器码:90.
-
JNE:条件转移指令,当ZF=0,转至标号处执行。机器码:75.
-
JE:条件转移指令,当ZF=1,转至标号处执行。机器码:74.
-
JMP:无条件跳转指令,可跳转到内存中任何程序段。机器码:EA.
-
CMP:比较指令,两数相减以比较大小,而并不保存比较结果。机器码:39.
实验一:直接修改程序机器指令,改变程序执行流程
下载并解压pwn1,使用命令objdump -d
对其进行反汇编:
可看到三个框中的地址。main中使用call调用到foo,我们的目标就是要将调用的函数换成getShell,计算foo和getShell的地址差值可得,要将红色框中的d7修改为c3.
使用vi编辑pwn1文件,用:%! xxd
将文件转换为16进制查看。用/d7ff
搜索,找到了需要修改的地方。
修改后使用:%! xxd -r
把文件转回二进制,用:wq
保存并退出。可以查看main中调用函数部分已经由调用foo变成了调用getShell.
接下来运行下新的文件5328pwn1,可以看到已经变成了getShell中的功能。
实验二:通过构造输入参数造成BOF攻击,改变程序执行流
要先确认是哪几个字节覆盖了返回地址,于是在调试中运行,输入如下:
用info r
查看各寄存器的值,可以看到eip的值被“1234”部分覆盖了:
由此,只要把这四个字符替换为getShell的地址即可。反汇编可看到getShell的内存地址是0804847d。
实验三:注入Shellcode并执行
输入apt-get install execstack
下载软件包。
输入以下命令修改设置。(下图是我自己手抖在5328和pwn3之间打了个空格...)
输入命令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
,然后输入攻击命令(cat input_shellcode;cat) | ./5328pwn3
.
打开一个新终端,找到进程号4120.
在此终端下使用gdb对5328pwn3进行调试,通过设置断点,来查看注入buf的内存地址。
修改地址后再次攻击,就成功了。
实验后的问题回答
- 实验收获与感想
这次实验分别用三种方法循序渐进地对可执行文件进行了攻击,修改了程序的执行轨迹。实验过程犯了一些错误,比如用apt-get install execstack
下载软件包的时候提示无法定位软件包,问了几个人说没碰到这问题...心里一惊赶紧去百度找各种方案,最后发现是软件源配置的问题,就去增添配置了一个中科大的kali软件源,更新了下就好了。还有一些比较蠢的错误就按下不提了。
总之第一次实验学到的东西还是挺多的,做完的时候也蛮有成就感(?)。虽然只是个入门级的小实验吧。希望自己可以以后好好加油,不当废柴。
- 什么是漏洞?漏洞有什么危害?
编写程序时的疏忽或者是编程语言的局限性,都会带来漏洞。漏洞很可能会被恶意利用,来挂马、传播恶意软件等。