둘둘리둘둘리둘둘리둘둘리둘둘리둘

[ Fedora Core 3 ] dark_stone -> Clear !! 본문

War game/해커 스쿨 FC3

[ Fedora Core 3 ] dark_stone -> Clear !!

dool2ly 2015. 8. 23. 22:57

#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+264, 4);


        // 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(0xf6ffe000, 0, 0xf7000000-0xf6ffe000);


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

}



evil_wizard(http://dool2ly.tistory.com/33) 문제와 거의 같다.


다른점이라면 setreuid를 제공해주는 대신 프로그램을 슈퍼데몬이 돌려 마찬가지로 system함수만 호출하면 되는것밖에 없어보이지만, 이전방법 처럼 주변을 지저분하게하며 printf@got를 바로 덮어써버리면 쉘을 띄울 수 없다.



-- 실패한 공격 ( printf@got overwrite) --



그 이유는 아래와 같다

[evil_wizard@Fedora_1stFloor ~]$ objdump ./dark_ston1 -d | grep plt

Disassembly of section .plt:

080483b8 <fflush@plt-0x10>:

080483c8 <fflush@plt>:

080483d8 <fgets@plt>:

080483e8 <strlen@plt>:

080483f8 <__libc_start_main@plt>:

08048408 <printf@plt>:

08048418 <memcpy@plt>:

08048428 <memset@plt>:

08048438 <strcpy@plt>:


(gdb) x/3i 0x08048408

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

0x804840e <_init+110>:  push   $0x20

0x8048413 <_init+115>:  jmp    0x80483b8 <_init+24>

[evil_wizard@Fedora_1stFloor ~]$ readelf -S ./dark_ston1 | grep -A 10 .got
  [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  


printf@got의 주소는 0x0804984c이고 바로 0x10byte 떨어진곳에 data영역이 있다.

우리가 덮어쓸 printf@got와 .data영역의 차이가 0x10byte밖에 안되서 strcpy수행중에 .data영역을 건드려서 그렇다는데, 아직 검증은 안해봤지만 맞는말인것같다 ..


그래서 .bss영역에서 system함수의 주소를 조립한 뒤 다시 printf@got에 깔끔하게 복사한 후 printf@plt를 실행해야 한다.

(bss영역을 쓰는이유 > .data와 .bss영역의 차이점 : http://shinluckyarchive.tistory.com/159 )


그렇다면 아래와 같은 페이로드를 구성할 수 있다.


| buffer 268 | +

 strcpy@plt | PPR | bss+0 | system[0] | +

 strcpy@plt | PPR | bss+1 | system[1] | +

 strcpy@plt | PPR | bss+2 | system[2] | +

 strcpy@plt | PPR | bss+3 | system[3] | +

 strcpy@plt | PPR | printf@got | bss | +

 printf@plt | dummy 4 | &/bin/sh |



필요한 주소들은 evil_wizard(http://dool2ly.tistory.com/33) 문제에서와 같은 방법으로 얻을 수 있다.



//혹시나 해서 .bss영역 주소 주섬주섬..

[evil_wizard@Fedora_1stFloor ~]$ readelf -S ./dark_ston1 | grep .bss

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




--풀이--


Comments