Daddy, teach me how to use random value in programming!
ssh [email protected] -p2222 (pw:guest)
#include <stdio.h> int main(){ unsigned int random; random = rand(); // random value! unsigned int key=0; scanf("%d", &key); if( (key ^ random) == 0xdeadbeef ){ printf("Good!\n"); system("/bin/cat flag"); return 0; } printf("Wrong, maybe you should try 2^32 cases.\n"); return 0; }
문제의 소스코드는 위와 같다.
rand() 함수로 받은 random 값과 사용자로부터 받은 key 값을 XOR 연산했을때 0xdeadbeef면, 플래그를 출력한다.
풀이
rand() 함수는 랜덤한 숫자를 반환하는데, 실제로는 프로그램을 매번 처음 실행시킬때마다 같은 값이 나온다.
따라서 디버거에서 rand 함수의 반환값을 처리하는 메모리주소에 브레이크포인트를 설정하고 값을 알아내면 된다.
gdb-peda$ disas main Dump of assembler code for function main: ... 0x0000000000400601 <+13>: call 0x400500 <rand@plt> 0x0000000000400606 <+18>: mov DWORD PTR [rbp-0x4],eax ... gdb-peda$ b *main+18 Breakpoint 1 at 0x400606 gdb-peda$ r ... Breakpoint 1, 0x0000000000400606 in main () gdb-peda$ i r $eax eax 0x6b8b4567 0x6b8b4567
rand()의 반환값은 0x6b8b4567였다.
XOR 연산은 (A ^ B) ^ B = A이기에
key ^ random = 0xdeadbeef
key ^ 0x6b8b4567 = 0xdeadbeef
key = 0xdeadbeef ^ 0x6b8b4567 = 0xb526fb88
scanf(“%d”, &key);에서 10진수로 값을 입력받기 때문에
0xb526fb88 = 3039230856
from pwn import * s = ssh('random', 'pwnable.kr', 2222, 'guest') p = s.process('./random') p.sendline(b"3039230856") data = p.recvall() print(data) p.close() s.close()
ubuntu@docker:~/CTF/pwnable.kr/random$ python3 random_solve.py [+] Connecting to pwnable.kr on port 2222: Done [*] [email protected]: Distro Ubuntu 16.04 OS: linux Arch: amd64 Version: 4.4.179 ASLR: Enabled [+] Starting remote process bytearray(b'./random') on pwnable.kr: pid 406828 [+] Receiving all data: Done (55B) [*] Stopped remote process 'random' on pwnable.kr (pid 406828) b'Good!\nMommy, I thought libc random is unpredictable...\n' [*] Closed connection to 'pwnable.kr'