본문 바로가기

Pwnable.kr

Pwanble.kr [passcode]

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

void login(){
	int passcode1;
	int passcode2;

	printf("enter passcode1 : ");
	scanf("%d", passcode1);
	fflush(stdin);

	// ha! mommy told me that 32bit is vulnerable to bruteforcing :)
	printf("enter passcode2 : ");
        scanf("%d", passcode2);

	printf("checking...\n");
	if(passcode1==338150 && passcode2==13371337){
                printf("Login OK!\n");
                system("/bin/cat flag");
        }
        else{
                printf("Login Failed!\n");
		exit(0);
        }
}

void welcome(){
	char name[100];
	printf("enter you name : ");
	scanf("%100s", name);
	printf("Welcome %s!\n", name);
}

int main(){
	printf("Toddler's Secure Login System 1.0 beta.\n");

	welcome();
	login();

	// something after login...
	printf("Now I can safely trust you that you have credential :)\n");
	return 0;	
}

 

맨 처음에 welcome에서는 100칸짜리 배열을 %100s로 입력받고 있고,

심지어 디버거로 확인해보면 스택 카나리도 있어서 해당 부분은 안 건드리는 줄 알았다. 

 

그래서 login 부분만 팠는데, %d 입력을 받는데 입력 변수 앞에 &를 주지 않아 주소값의 내용 자체를 바꾸고 있다. 

초기화도 하지 않아 어차피 쓰레기 값인 주소값의 내용을 바꾼다고 해도 의미가 없다는 것이다. 

 

위의 사진은 welcome함수인데 우선 카나리값이 ebp-0xc에 들어가고, 우리의 입력 버퍼는 0x70부터 시작한다.

%100s로 100칸만 입력받는데 계산해보면 0x70부터 0xC 전까지 꽉 채워서 받는다.

 

그리고 메인함수에서 콜하는 부분을 보면 따로 스택 쓰는 것 없이 그냥 바로 함수 호출을 이어서 한다.

 

즉 welcome에서 덮은 버퍼 부분이 아직은 그대로 살아있다. 

 

위의 사진은 login 함수의 시작부분부터 첫 scanf까지인데, 보다시피 ebp-0x10에다가 값을 입력받으려고 하지만

초기화하는 부분도 없으니 이전 welcome 함수에서 덮어놓은 값이 그대로 있다는 것이 확실해졌다.

 

이렇게 되면 원하는 주소에 원하는 값을 넣는 것 까지 성립한다.

 

그래서 처음 welcome에서 입력한 부분 또는 stdin 임시버퍼를 가리키게 해서 exploit 시키는 방법을 생각했지만, 

passcode1의 변수가 해당 부분을 가리키게 해서 값을 바꿔도 (심지어 ASLR 때문에 약간의 brute forcing도 필요)

해당 부분으로 점프시키는 게 문제였다.

 

알고 있는 부분들을 잘 활용하는데 아직 문제가 많은 것 같다.

 

간단히 덮을 수 있고 항상 거쳐야하는 곳은 어딘가??

 

static linking이 아니라면 쓰기권한이 있을 수 밖에 없는 곳... GOT(Global Offset Table)이다...

 

사용가능한 GOT 인자들은

scanf("%d", passcode1); 이후부터 if문을 거쳐 종료 분기를 타기 전에 있는

 

fflush / printf / scanf가 사용 가능하다고 할 수 있다. 

 

다만 got 주소를 구해보면, 

 

printf에는 0x00(null)이, scanf에는 0x20(공백)이 들어있어

 

결국 fflush밖에 사용할 수 없다. 

 

96칸의 더미, 4칸의 GOT 주소, system("/bin/cat flag")를 호출할 수 있는 주소를 적어주면 exploit된다.

 

다만, %100s로 받기 때문에 100바이트가 문자열 구분 바이트로 끝날 필요 없이 꽉 채워서 쓰면 되고,

그 뒤에 바로 system 주소를 입력해야 한다. 

 

그리고 system 주소는 %d, passcode로 받고 있기 때문에 정수로 적어줘야 하고,

어디로 점프뛰어야 할지는 잘 보고 결정해야 한당

 

구구절절 적은 이유는 내가 다 했던 삽질이기 때문이다...

'Pwnable.kr' 카테고리의 다른 글

Pwnable.kr [input]  (0) 2019.04.30
Pwnable.kr [random]  (0) 2019.04.29
Pwnable.kr [bof]  (0) 2019.04.24
Pwnable.kr [collision]  (0) 2019.04.24
Pwnable.kr [fd]  (0) 2019.04.24