Pwnable.kr [Toddler's Bottle]의 8번째 문제인 leg입니다.

곰 일러스트네요

문제를 눌러보니 문제의 ssh 주소와 두개의 다운로드 링크가 있네요

 

#include <stdio.h>
#include <fcntl.h>
int key1(){
	asm("mov r3, pc\n");
}
int key2(){
	asm(
	"push	{r6}\n"
	"add	r6, pc, $1\n"
	"bx	r6\n"
	".code   16\n"
	"mov	r3, pc\n"
	"add	r3, $0x4\n"
	"push	{r3}\n"
	"pop	{pc}\n"
	".code	32\n"
	"pop	{r6}\n"
	);
}
int key3(){
	asm("mov r3, lr\n");
}
int main(){
	int key=0;
	printf("Daddy has very strong arm! : ");
	scanf("%d", &key);
	if( (key1()+key2()+key3()) == key ){
		printf("Congratz!\n");
		int fd = open("flag", O_RDONLY);
		char buf[100];
		int r = read(fd, buf, 100);
		write(0, buf, r);
	}
	else{
		printf("I have strong leg :P\n");
	}
	return 0;
}

http://pwnable.kr/bin/leg.c에는 위의 C코드가 적혀져 있었습니다.

 

http://pwnable.kr/bin/leg.asm에는 위와 같이 gdb로 분석한것이 적혀져 있었습니다.

 

 

ssh leg@pwnable.kr -p2222로 접속했을때의 화면입니다. 

 

 

ls -l 명령어를 이용하여 파일을 확인햇지만 볼만한 파일이 없는걸로 봐선 위의 c코드와 gdb를 보고 푸는 것 같습니다.

 

C코드를 보면 key1부터 key3까지의 함수들은 모두 ARM 어셈블리어로 작성한 것을 알 수 있습니다.

 

먼저 main함수를 보면 위 3개의 함수값의 총합을 구하면 Flag가 출력 되는 것 같습니다.

 

main 함수의 어셈코드입니다

 

함수를 통해 구한 r0값들을 모두 더해서 최종적으로 r2에 들어가는 것을 알 수 있습니다.

 

각각 함수들을 볼 필요가 있겠군요.

 

int key1(){
	asm("mov r3, pc\n");
}

 

key1의 어쎔코드와 c코드를 같이 보겠습니다.

 

일단 c코드를 보면 pc라는 값을 r3에 넣고 r3를 r0에 넣었습니다.

 

pc = key1

 

pc가 과연 무엇일까요?

 

일단 cpu의 명령어 처리과정부터 알아봐야합니다. 일단 cpu가 하나의 명령을 수행할때 fetch > decode > execute의

 

과정을 거칩니다.

 

하지만 pipe line이라는 방법이 있습니다.

 

pipe line은 처리과정을 병렬적으로 수행시켜 2개의 opcode를 실행할때 6번이 필요했던것을 4번으로 줄일수 있습니다.

 

그럼 key1 함수에서 pc의 값은 0x00008ce4가 됩니다.

 

int key2(){
	asm(
	"push	{r6}\n"
	"add	r6, pc, $1\n"
	"bx	r6\n"
	".code   16\n"
	"mov	r3, pc\n"
	"add	r3, $0x4\n"
	"push	{r3}\n"
	"pop	{pc}\n"
	".code	32\n"
	"pop	{r6}\n"
	);
}

r3에 pc값(0x00008d08) 대입하고, 4를 더해서 r0에 대입했네요.

 

key2의 값은 0x8d08 + 4 = 0x8d0c

 

key3를 봅시다.

 

int key3(){
	asm("mov r3, lr\n");
}

lr값을 r3에 대입하고 r3의 값을 r0에 대입하는군요.

 

그리고 lr값을 구해야 합니다.

 

lr은 함수 호출 전에 다시 되돌아가 실행할 주소를 담고 있습니다.

 

main함수를 보면

lr의 값은 0z00008d80이 되겠네요.

 

key 1 = 0x8ce4

key 2 = 0x8d0c

key 3 = 0x8d80

 

모두 더하면 0x1a770 이네욥!

 

0x1a770을 정수로 변환하면 108400 입력해줍시다!

 

Flag가 성공적으로 출력되었습니다!

FLAG: My daddy has a lot of ARMv5te muscle!

반응형
복사했습니다!