1.实验内容
1.1本周学习内容
①Linux基础知识
基本的shell命令(例如:ls、cd、cp、touch、cat、su等等)
在Linux中熟练使用编译器gcc、调试器gdb,尤其是gdb调试指令(例如:设置断点break/clear、 启用/禁用断点enable/disable、运行程序run、继续运行continue、单步代码跟入函数step、查看各类信息info、显示调用栈backtrack等)
②汇编语言
可以阅读基础的汇编指令(例如:PUSH、POP、JMP、CALL、LEAVE、RET)
熟知esp、ebp、eip等寄存器中信息的作用
③掌握反汇编和十六进制编辑
④Linux的进程内存管理
32位机器内存4GB,用户态0-3GB,内核态3-4GB
env、argv、argc的含义
.bss、.data、.text的含义
熟知堆、栈的概念
⑤缓冲区、缓冲区溢出漏洞的相关概念
定义概念
形成原因
了解堆溢出、栈溢出的逻辑
1.2实验任务
1.手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
2.利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
3.注入一个自己制作的shellcode并运行这段shellcode。
2.实验内容
任务一 直接修改程序机器指令,改变程序执行流程
下载目标文件pwn1,将其上传至kali,重命名为pwn20222306txm,使用命令objdump -d pwn20222306txm | more对文件pwn20222306txm进行反汇编。
找到getShell、foo、main的部分。
main函数运行到这里,call语句将调用foo函数。如果按正常流程,EIP存的是下条指令的地址。
此时机器指令为e8 d7 ff ff ff,e8就是跳转,指令意思就是跳转到EIP+d7ffffff位置。
要想让main函数调用getshell,只需要让跳转到的位置是getshell的地址就可以了,即EIP+×××××××× = &getshell。EIP为下一条指令的地址,也就是80484ba。
根据反汇编的结果,getshell的地址为804847d,那么根据计算,××××××××也就是804847d-80484ba,即c3ffffff(补码)。
据上述分析,我们只需要将main函数的call指令的目标地址更换为c3ffffff即可跳转至getshell。
使用vi指令,并使用 :%!xxd 切换至十六进制视图;
用/e8 d7(注意查询时中间需要打个空格)查询到所在位置;
把d7修改为c3,然后使用 :%!xxd -r 转换为原格式,最后保存即可。
再反汇编看一下,call指令是否正确调用getShell。
这次call指令可以正确调用getShell了。
尝试运行代码,发现确实有了命令行。
任务二 通过构造输入参数,造成BOF攻击,改变程序执行流
foo函数只预留了56字节的缓冲区,有Buffer overflow漏洞,超出部分会造成溢出,我们的目标是覆盖返回地址,触发getShell函数。
使用gdb对pwn20222306txm程序进行调试时,输入字符串1111111122222222333333334444444412345678,然后使用命令info r查看寄存器eip的值,发现输入的1234(即十六进制的0x34333231)被覆盖到了堆栈上的返回地址。因此,我们只需将这四个字符替换为getShell的内存地址,就可以让程序执行getShell函数。
根据之前的反汇编结果,getShell函数的内存地址为0x0804847d。将该地址替换为原来的返回地址位置,并将其输入给pwn20222306txm,即可成功运行getShell函数。
通过反汇编,我们已经得到了getshell的内存地址是0804847d,那么我们就要将上述位置覆盖成\x7d\x84\x04\x08。
使用xxd指令查看并确认input文件内容。
最后通过管道符“|”,将input输入作为了pwn20222306txm的输入。
成功获取了shell,任务二结束!
任务三 注入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\。这段shellcode是启动一个新的/bin/sh shell的机器码,用于后续的攻击操作。
做准备工作,设置堆栈可执行,关闭地址随机化,并进行确认。
这里需要开两个终端。
第一个终端先注入一段攻击buf:
第二个终端使用gdb进行调试,先查询pwn20222306txm的进程号,是8642,然后使用attach 8642进行调试,并设置断点。
断点设在了0x080484ae处,此时注入的东西都在堆栈上,ret完成后就可以调到覆盖的retaddr处。
此时查看寄存器的值:
将栈顶指针地址再加4字节,就是shellcode应该处于的地址,即0xffffd3bc+4=0xffffd3c0。根据机器存储的方式,可以知道应当将“\x1\x2\x3\x4”更换为“\xc0\xd3\xff\xff”,将分析得到的shellcode保存至文件input_shellcode_2。
将input_shellcode_2作为pwn的输入,成功注入shellcode,获取到了shell。
如上图所示,shell获取成功。
任务三结束!
3.问题及解决方案
问题1:在任务一中,使用/e8d7查找要修改的内容失败。
问题1解决方案:在/e8d7中间加上空格,使用/e8 d7来进行查找即可或者采用d7ff查找也是可以的。
问题2:在实验过程中发现许多软件没有下载,比如gdb、execstack。
问题2解决方案:gdb我重新装了虚拟机和kali,之后就自带了,而execstack在输入类似命令后报错“Unable tolocate package execstack”,于是采用另一种安装方式,先从http://ftp.de.debian.org/debian/pool/main/p/prelink/execstack_0.0.20131005-1+b10_amd64.deb 位置下载安装包,再使用“sudo dpkg -i execstack_0.0.20131005-1+b10_amd64.deb”命令进行解压与安装,但网络用校园网是不行的,需要自己的流量。
问题3:任务三进程号只有1个。
问题3解决方案:在原来的终端中'ps -ef | grep pwn20222306txm'后,只按一次enter,多按的话就相当于把进程停掉了。
4.学习感悟、思考等
本次实验是网络与系统攻防技术的第一次实验。在我看来本次实验难度并不小,不只是指按照参考资料完整做出来;而是真正搞懂每个指令、每个操作的原理,并转化为自己的理解;还包括针对自己的机器的特殊报错的原因排查、解决方案寻找和测试等。我几乎每一步都会碰到一个很难解决的问题,无论是最开始的虚拟机选择,还是中间的各种权限修改、指令安装,我觉得我可能把所有能踩的坑都踩了一遍。好不容易做到注入攻击buf这一步,结果就因为一个小失误,导致始终成功不了,耗费了大量的时间。后来在自己的琢磨和同学们的帮助下,也是完成了本次实验。同时,在撰写博客的过程中,我也对Markdown格式有了基本的了解,也算是收获颇多。感谢老师的指导和同学们的帮助,之后的实验,我将沉住气,继续锻炼自己钻研的能力。
标签:getShell,函数,2024,2025,地址,指令,pwn20222306txm,20222306,shellcode From: https://www.cnblogs.com/ming-20222306/p/18455632