一、实验目标
本次实践的对象是一个名叫pwn1的linux可执行文件。
该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。
该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。我们将学习两种方法运行这个代码片段,然后学习如何注入运行任何Shellcode。
三个实践内容如下:
·手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
·利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,出发getShell函数。
·诸如一个自己制作的shellcode并运行这段shellcode。
这几种思路,基本代表显示情况中的攻击目标:
·运行原本不可访问的代码片段
·强行修改程序执行流
·注入运行任意代码
二、实验要求
1.掌握NOP、JNE、JE、JMP、CMP、汇编指令的机器码
汇编指令 | 机器码 | 作用 |
NOP | 0x90 | 不执行操作,但占一个程序步 |
JNE | 0x75 | 条件转移指令,不相等跳转 |
JE | 0x74 | 条件转移指令,相等跳转 |
JMP | 0xe9 | 无条件跳转,段内直接近转移 |
JMP | 0xeb | 无条件跳转,段内直接短转 |
JMP | 0xff | 无条件跳转,段内间接转移 |
JMP | 0xea | 段间直接远转移 |
CMP | 0x39 | 比较指令。对操作数之间进行比较 |
2.掌握反汇编与十六进制编辑器
(1)反汇编
指将机器语言转换为汇编语言,指令为:objdump 文件名 -d |more ,它是一个从低级转为高级的过程,通过将机器码反汇编,可以知道它的功能和工作方式。以下是一行反汇编后的代码,其中:第一部分是内存地址,第二部分是机器语言,第三部分是汲取语言对应的汇编语言。
(2)十六进制编辑器
vim编辑器可以调用外部十六进制文件,在终端输入vi 文件名,即可打开编辑器,输入命令xxd即可将二进制转换为十六进制,输入命令xxf -r可以转换回二进制,按i键可以转换成insert状态,就可以修改程序文件。
也可以调用图形化的十六进制编辑器,指令如下:
apt-get install wxhexeditor
wxHexEditor
3.几种改变程序执行流程的方法
(1)直接修改机器指令
即通过反汇编可执行文件,用十六进制编辑器打开文件,转为十六进制后,直接修改对应的返回地址,转而执行另一段代码。
(2)bof攻击
构造一段payload,导致栈溢出,指令寄存器EIP的值被覆盖为其他代码地址。
(3)注入shellcode
通过构造payload,执行代码,在另一个终端中查看程序的进程号,使用gdb调试,链接此进程设置断点,查看注入buf的内存地址,找到payload尾部数据的地址,shellcode就在其地址+0x00000004的位置,从而可以构造一段payload来改变覆盖地址,运行可执行文件,就可以执行shellcode。
三、实验步骤
(一)直接修改程序机器指令,改变程序执行流程
·进入pwn所在文件夹,如果没有权限则先sudo -s输入密码
cd /mnt/hgfs/qiuqiule
·下载pwn1文件,由于后面操作容易出错,可以用cp指令将原文件复制后再进行操作。
·计算指令跳转地址
可以看到call 8048491就是我们要修改的。
此指令作用是:调用位于地址8048491的foo函数。其对应的机器指令“e8d7ffffff”中,e8是call的机器码,即跳转,跳转的地址是“EIP+d7ffffff”。
要调用getShell,则修改“d7ffffff”为,“804847d-80484ba”对应的补码,即c3ffffff。
·修改可执行文件
使用vi指令打开可执行文件,转换为十六进制后,输入/d7查找,按esc键+i键进入insert模式修改d7为c3。
·验证是否修改成功
反汇编,看是否正确调用getShell
运行改后代码,得到shell提示符
(二)通过构造输入参数,造成BOF攻击,改变程序执行流
·确认输入字符串
我们知道堆栈结构是从从高地址到低地址一端增长的,从高到低依次存放着EIP、EBP和输入
字符串,其中为输入字符串预留的内存空间是28位,而EIP和EBP各占4位,为覆盖EIP,payload至少输入36位字符串,其中33-36位会覆盖EIP,只要把这四个字符替换成getShell的内存地址即可。
getShell地址是0804847d,要注意输入getShell的地址时需要反向输入,综上构造的字符串为:11111111222222223333333344444444\x7d\x84\x04\x08。
·构造输入字符串
先生成包含字符串的文件,并使用xxd查看input文件的内容,如下:
通过管道符 | 将字符串输入到文件中。
(三)注入shellcode并执行
·准备工作
设置堆栈可执行,并验证是否可执行,关闭地址随机化
execstack -s 4301c//设置堆栈可执行
execstack -q 4301c//验证是否可执行
more /proc/sys/kernel/randomize_va_space
echo "0" > /proc/sys/kernel/randomize_va_space
more /proc/sys/kernel/randomize_va_space//关闭地址随机化
·构造payload
使用一段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\
缓冲区足够存放shellcode,因此buf结构为nops+shellcode+retaddr,nop一是作为填充,填够36位,使33-36位正好是shellcode的地址,二是作为滑行区,程序的返回地址
落在nop上,就会自然的滑到shellcode上。
·确定payload最后四位
先将最后四位填充为\x4\x3\x2\x1,然后注入这段buf。
打开另外一个终端,用gdb调试进程。
查找文件的进程号,如下:
可知进程号为26842,启动gdb调试进程,设置断点,以查看注入buf的内存地址。
然后回到之前的终端按下回车键,gets程序完成,输入c执行。
查看esp寄存器的地址,如下:
可以看到\x4\x3\x2\x1所在的地址是0xffffd6dc,由于栈是从高地址到低地址存储,返回地址占4位,在低地址端,
那么距离0xffffd6dc增长4位处就是shellcode的位置,即0xffffd6dc+0x00000004=0xffffd6e0。
构造payload并注入执行文件。
四、实验总结
·思考题
什么是漏洞?
漏洞就是在软硬件系统中存在的一些弱点或缺陷,没有设置安全性的防控措施,如溢出问题,由于没有检测和约束输入位数,就可被攻击者利用以攻击系统,造成原有的执行的紊乱,为攻击者提供便利。
·问题与反思
本次实验,我遇到了不少问题,通过查询资料一一解决,如共享文件的设置,主要步骤是正确安装vmware-tool、设置共享文件、挂载共享文件、获取root权限、进入共享文件,步骤明了,实际执行却又许许多多不同的问题。
再如用vi打开可执行文件时,转到十六进制,关掉后再转会二进制会出错,必须修改完就转二进制,又如执行execstack指令时,需要先安装prelink,而安装没有成功,还需要先apt-get update,更新失败,原因是连接
不上kali.org……但是办法总比困难多,最后还是成功搞定了!