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

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

一、实验目标(内容)

  • 掌握缓冲区溢出的基本原理。
  • 理解栈的工作方式和返回地址覆盖。
  • 学会编写和注入Shellcode,并在Linux下调试。
  • 熟悉gdb、objdump等调试与分析工具。

二、实验知识点回顾(本周学习的内容)

1.Linux操作

  • 文件与目录操作(cd、ls 、cp等)。
  • 权限控制与命令提升(chmod、sudo)。
  • 输入输出重定向与管道使用。

2.缓冲区溢出

  • 核心原理:栈从高地址向低地址生长,数组越界会覆盖栈上的内容,
  • 返回地址覆盖:用输入数据覆盖EIP,实现跳转到目标函数或Shellcode。
  • 栈帧理解:函数调用时压栈、局部变量布局、返回地址存储。

3.汇编基础与工具

  • call、mov等常见指令。
  • EIP指令指针作用与修改方法。
  • objdump反汇编查看程序逻辑。
  • gdb调试:断点设置、寄存器查看、栈内存分析。

4.Shellcode相关

  • 编写/获取Shellcode。
  • 堆栈可执行设置(execstack还有patchelf)。
    -地址随机化关闭(ASLR),保证地址可预测。

三、实验步骤与心得

任务一:修改可执行文件直接跳转函数

  1. 下载pwn1,传到Kali虚拟机。

  2. 修改主机名sudo hostnamectl set-hostname liujiacheng再重启sudo reboot
    image

  3. 反汇编文件objdump -d pwn20232426 | more,找出call指令跳转地址。
    93ccdab6b470004ef9ebde8068999bc4

在main函数中,第四行的机器码"e8 d7ffffff"对应汇编指令"call 8048491",表示调用foo函数(8048491为其首地址)。
其中"e8"是操作码,作用于EIP(指令指针寄存器),后续的"d7ffffff"是偏移量。
执行原理:

1. 执行call指令时,EIP已指向下一行地址80484ba
2. 先将该EIP值压栈(用于foo执行完后恢复程序流程)
3. 计算目标地址:EIP(80484ba) + 偏移量(补码运算),得到foo函数地址

若要改为调用getShell(地址804847d),需重新计算偏移量:
804847d - 80484ba = 补码c3ffffff
因此,将机器码"e8 d7ffffff"改为"e8 c3ffffff",即可实现调用getShell函数。
4. 备份文件并修改:

  • 用vi切换16进制模式::%!xxd
    0a9b3a61e038516bf0fabb0433bd3717

  • 找到call指令的机器码,修改为目标偏移
    63ae7e1bad2aacf23e7bc1e2ce91ddc0

  • 转回原格式保存::%!xxd -r
    image

  1. 运行pwn20232426ljc./pwn20232426ljc:
    4f70a3a1f2589224cb0189fb11b6ba0e

成功看到Shell提示符,任务完成。

任务二:利用BOF漏洞覆盖返回地址

  1. 反汇编foo函数,确认缓冲区大小(56字节)。
  2. 确定哪些输入字符会覆盖RET:
  • 用gdb测试1111111122222222333333334444444455555555
    b742af29fc27b5f3f9e66293bf9ff552
  • EIP显示覆盖字符,确认覆盖位置。
    71a0f513e32a3f5e520058c540c8fe28
  1. 小端存储顺序验证:
  • 输入11111111222222223333333344444444\x7d\x84\x04\x08,观察EIP → 倒序覆盖返回地址。
    7590e539353a0cd4d05b0a672afcf013
  1. 构造攻击输入文件8*1 8*2 8*3 8*4 \x7d\x84\x04\x08 ... \x0a
    (含回车\x0a)并执行:
    23ff5ca40216e6baaedbca7becfa2780

成功弹出Shell,任务完成。

任务三:注入Shellcode

  1. 设置堆栈可执行:
    d7195ed0fb04dd44e4bd524f1000b478
  2. 准备一段Shellcode Payload,注入运行。
    image
    这是一个典型的 Linux x86 Shellcode,用于执行 /bin/sh:\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80
    这是豆包告诉我的:

31 c0 清空 eax 寄存器
50 压入 NULL
68 2f2f7368 压入字符串“//sh”
68 2f62696e 压入字符串“/bin”
89 e3 把栈顶地址放到 ebx
50 53 89 e1 设置参数
99 b0 0b cd 80 执行系统调用 execve("/bin/sh")

这段 Shellcode 总长度为 25 字节左右。

  1. 查看进程号,在另一个终端中输入:ps -ef | grep pwn20232426ljc4
    输出结果中可以看到目标程序的 PID:
    image

  2. 附加到进程调试,设置断点,查看注入的内存
    image

  3. 确认 RET 覆盖跳转
    在继续运行前,修改栈中返回地址为 Shellcode 的地址,然后输入 continue 或 c 继续执行。
    image

  4. Shellcode 执行结果
    程序返回后,控制流跳转至注入的 Shellcode 区域;
    Shellcode 执行成功,命令行中会出现 新的 Shell 提示符;
    image

Shellcode 注入成功,程序已成功执行恶意 Payload,并在目标进程中获得命令行控制。

四、实验中遇到的问题与解决方法

问题 解决方法
有些操作必须 sudo(例如写 /proc、安装包、修改系统设置),直接使用 sudo echo ... > file 会因重定向权限导致失败。 使用能提升整个命令行权限的方式,例如:sudo sh -c 'echo 0 > /proc/sys/kernel/randomize_va_space';安装包使用 sudo dpkg -i <file.deb>;或用管道+tee:`echo "..."
不熟悉在 vi 中进行十六进制编辑与基本操作(模式切换、搜索、保存等),导致在二进制文件内难以定位与修改字节。 vi 中编辑二进制的推荐流程:打开文件 vi pwn1 → 按 Esc:%!xxd(切到 hex 视图)→ /e8 d7 搜索 → i 进入插入修改 → Esc:%!xxd -r(恢复二进制)→ :wq 保存退出。修改前请 cp pwn1 pwn1.bak 备份。
在十六进制视图中查找机器码失败(如直接搜索 e8d7 无结果),因为字节之间有空格或格式差异。 在十六进制视图按字节格式搜索:在 vi 十六进制模式用 /e8 d7;或在 shell 用 `xxd pwn1
execstack 无法获取或安装(导致无法方便设置可执行栈),已尝试用 patchelf 替代但不确定正确性。 先检查 ELF GNU_STACK 标志:`readelf -l pwn1
无法 gdb attach 到目标进程:运行 payload 后进程立即退出,找不到长期存在的 PID。 让目标进程保持等待以便 attach:`(cat input_shellcode; cat)

五、学习体会

隔了挺久终于重新上手Linux,这次实验对我来说,既是对Linux各类操作的全面回顾,也把数据结构和网络攻防的知识串联整合到了一起。
我挺喜欢这种实验模式——能把不同领域的内容打通,还能在查询过程中get到很多细碎的新知识。对我这种体系化知识掌握得不够全面的人来说,这种方式特别友好:从零散的知识点产生兴趣,再慢慢把新旧知识串联成网,整个过程特别有成就感,真的很棒。

posted @ 2025-10-12 22:54  20232426刘嘉成  阅读(9)  评论(0)    收藏  举报