pwnable.kr(6) - random
## Problem
Points: 1 pt
1
2
3Daddy, teach me how to use random value in programming!
ssh [email protected] -p2222 (pw:guest)
Code
1 |
|
Thinking
L32產生一個亂數放入random
。
L37如果輸入的key
跟random
作互斥或(XOR)
運算後等於0xdeadbeef
,則獲得flag。
Prepare
C rand
1 |
|
1 | An integer value between 0 and RAND_MAX. |
rand()
所產生的,是使用Linear congruential generator(線性同餘法, LCG)
所產生的偽亂數。
Solution
本題只有使用rand()
取亂數,而rand()
在呼叫前會檢查是否呼叫過srand()
,
如果有的話,則把seed拿來取亂數。
否的話,則自動呼叫srand(1)
再取亂數。
所以按照L34來看,程式每次執行的random
變數都會是一樣,因為每次使用的seed
都是1
。
進入gdb
來看大略的程式: 1
2
3
4
5
6
7
8
9
10
11gdb-peda$ disass
Dump of assembler code for function main:
0x00000000004005f4 <+0>: push rbp
0x00000000004005f5 <+1>: mov rbp,rsp
0x00000000004005f8 <+4>: sub rsp,0x10
0x00000000004005fc <+8>: mov eax,0x0
0x0000000000400601 <+13>: call 0x400500 <rand@plt>
0x0000000000400606 <+18>: mov DWORD PTR [rbp-0x4],eax
0x0000000000400609 <+21>: mov DWORD PTR [rbp-0x8],0x0
0x0000000000400610 <+28>: mov eax,0x400760
0x0000000000400615 <+33>: lea rdx,[rbp-0x8]
可以看到在+13
的部份呼叫了rand
方法。
而下面的+18
,+21
則是在把值放進去,高位元0x8
放入了0x0
,低位元0x4
放入了EAX
的值。
這個時候我們只需要察看EAX
裏面是什麼,就可以知道rand
所產生的數是多少了。
1 | gdb-peda$ xinfo $eax |
所以0x6b8b4567
就是實際rand
出來的數值。
1 | 1 ^ 1 = 0 |
key ^ EAX = 0xdeadbeef
然後0xdeadbeef ^ EAX = key
於是套入0xdeadbeef ^ 0x6b8b4567 = 0xb526fb88
XOR
完的結果還需要轉換成十進位,因為key
的輸入是採十進位輸入。
最終結果是3039230856
直接開啟程式,輸入就可以獲得flag了。