Write up (Wargame)/Pwnable

[pwnable.kr] passcode 풀이

그믐​ 2023. 9. 11. 21:44
반응형

ssh로 서버에 접속해서 문제를 풀어야 한다.

우선 접속해서 살펴본다.

 

analysis


서버가 좀 느리다.

flag를 읽어야하고 passcode 프로그램에는 set uid가 걸려있다.

 

C 코드를  분석하고 쉘을 따면 될 것 같다.

 

프로그램 실행 먼저 해보면 이렇게 뜬다.

 

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;	
}

 

조건에 나와있듯이, flag를 얻기 위해서 passcode1 이 338150이고, passcode2가 13371337인 조건을 만족해야한다.

이상한 점은 scanf를 받을 때, &를 빼먹었다는 것이다. 여기서는 scanf에서  &를 실수로 빼면 어떤 취약점이 발생할 수 있는지 보여주는 것 같다.

 

scanf는 본래 주소에 값을 입력하는 것이지만, 이렇게 되면 passcode1, passscode2가 가지는 값을 주소로 하여 거기에 입력할 것이다.

 

따라서 passcode1, 2에 원하는 주소를 넣을 수 있으면 좋다. 변수가 초기화되어있지 않기 때문에 그 전 함수에서 주소를 지정할 수 있다.

 

passcode1 변수는 ebp-0x10

passcode2는 ebp-0xc이다.

 

이전 함수에서 ebp-0x70부터 100만큼 덮으므로 0x64만큼 덮으니까. ebp-0x10은 덮는다. ebp-0xc~ebp-0x8은 못 덮으니까 passcode2는 이후 고려할 사항이 된다.

 

이걸로 일단 원하는 주소에 원하는 값을 덮을 수 있다.

 

그러면 여기엔 RELRO가 걸려있지 않으니 got overwrite를 통해 flag를 출력하는 주소로 바꿀 수 있을 것이다.

 

solution


그 전에 조건을 어떻게 맞춰보려고 했었는데 이건 불가능하다. python code 작성도 안되고.. 페이크로 주석을 붙여놓은 것 같다.. ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ

 

gdb를 잘 쓸 줄 모르니 plt 코드를 보고 got를 구해본다.

 

got 주소는 0x804a004이다.

여기에 

 

원래는 모든 분기를 통과해야 넘어갈 수 있는 0x080485d7를 넣어준다.

 

된다.

하. 주석때매 got overwrite 쉽게 생각하지 못한게 후회된다.

있는 그대로 문제를 봐야겠다.

반응형