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

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

1.基础知识

1.1常用汇编指令

①NOP

机器码0x90,空操作。CPU 读到这条指令,什么都不干,直接执行下一条指令。就是实验里的NOP雪橇:一堆连续0x90,只要跳到这一大片NOP里任意位置,就会一路“滑过去”,直到碰到后面的 shellcode。

②JNE/JE 条件跳转

JE:Jump if Equal,相等则跳转。CMP 比较后,两个值相等就跳。
JNE:Jump if Not Equal,不相等则跳转。CMP 比较后,两个值不相等就跳。
常见在 if 判断、循环代码的汇编里。

③JMP 无条件跳转

直接修改EIP,跳到指定地址执行代码,不需要任何条件。

④CALL 函数调用

CALL执行两件事:把CALL的下一条指令地址压入栈(这个就是返回地址),然后跳转到目标函数去执行。
函数结束用ret指令:从栈取出这个保存的返回地址,放到EIP,程序回到call的下一行继续跑。
BOF攻击就是我们手动覆盖栈上这个返回地址,改掉EIP,让CPU去执行我们写的 shellcode,而不是原本的代码。

1.2栈与BOF

af53fdb9b7aa04d5746155246a27d352
函数调用时,栈里面存:局部变量、旧EBP、返回地址。
BOF 原理:foo()里面用gets()读取输入,gets()是极度危险函数,不检查输入长度,读到换行/EOF就停,不管缓冲区多大。所以当输入超过32字节时,超过部分覆盖旧EBP,继续往后写,直接覆盖返回地址,原本ret的时候,CPU会拿栈上返回地址放进EIP,回到main。所以攻击时我们把返回地址改成我们想要的地址,ret执行时EIP被篡改,CPU跳转到NOP雪橇,最终跑shellcode 拿到shell。

1.3Shellcode

一段原始机器码(二进制字节),执行/bin/sh,弹出交互式shell(终端),就可以执行ls、id命令。

2.实验内容

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

3.实验过程

3.1手工修改可执行文件

image
image
image
image
image
image
image
image
image
image
image

3.2利用 BOF 漏洞

image
image
image

3.3注入自定义shellcode

image
image
image
image
image
image

4.问题及解决方案

  • 问题1:vi十六进制编辑时光标无法移动。
  • 解决方案:一开始少敲了 %,执行的是 :!xxd(把 xxd 当外部命令只读展示输出)而不是 :%!xxd(把文件内容过滤转成可编辑的十六进制视图)。退回后重新执行 :%!xxd;编辑完必须 :%!xxd -r 转回二进制再保存,否则文件损坏(幸好事先 cp pwn1 pwn2 做了备份)
  • 问题2:payload构造好输入后程序直接段错误,而不是进入getShell。
  • 问题2解决方案:x86 是小端序(LSB),多字节数据低位在前。0804847d 在内存中必须存成 7d 84 04 08,按书写顺序填会跳到非法地址。用 perl -e 'print "A"x32 . "\x7d\x84\x04\x08"' 构造,先在 gdb 里用 \xde\xad\xbe\xef 验证崩溃时 EIP 恰好等于 0xdeadbeef,确认偏移 32 和字节序都正确后,再换真实地址。

5.学习感悟、思考等

做完三个任务,我最大的感受是攻击成功的关键在之前大量的"算"和"试",漏洞利用本质上是内存布局的精确计算。对栈帧、返回地址、EIP 这些概念也有了更形象的了解,这次亲手把它们覆盖掉,再看着程序跳进 Shell,直观的感受到什么是缓冲区溢出,也理解了缓冲区溢出为什么危险。现在再看到 read、strcpy 这类函数,会下意识去看它读进来的东西有没有边界。

posted @ 2026-10-12 22:58  sususususu20060424  阅读(5)  评论(0)    收藏  举报