서브웨이

pwnable.kr uaf 풀이 본문

Pwnable/pwnable.kr

pwnable.kr uaf 풀이

샌드위치메이커 2020. 8. 26. 18:00

UAF(Use After Free) 취약점에 관한 문제 입니다. 일단 uaf가 무엇인지 먼저 알아봅시다.

https://woosunbi.tistory.com/95

 

Use-After-Free 취약점

UAF(Use-After_free) 취약점이란 무엇인가? : UAF 취약점이란, 프로그래머가 Heap 영역을 잘못 다룰 때 발생하는 취약점으로, 가령 우리가 Heap 영역을 사용한 후 Free 하고 재사용(reallocation) 할 경우 일어

woosunbi.tistory.com

간단히 말해 A변수에 동적할당 후 해당 값을 사용한 뒤 해제를 하고 B라는 값에 동적할당을 해주면 A에서 사용한 값이 그대로 남아있는 취약점을 말합니다.

 

일단 접속해봅시다.

 

언제나처럼 소스코드를 먼저 봅시다. 이번 파일은 특이하게 C++파일이네요.

#include <fcntl.h>
#include <iostream> 
#include <cstring>
#include <cstdlib>
#include <unistd.h>
using namespace std;

class Human{
private:
	virtual void give_shell(){
		system("/bin/sh");
	}
protected:
	int age;
	string name;
public:
	virtual void introduce(){
		cout << "My name is " << name << endl;
		cout << "I am " << age << " years old" << endl;
	}
};

class Man: public Human{
public:
	Man(string name, int age){
		this->name = name;
		this->age = age;
        }
        virtual void introduce(){
		Human::introduce();
                cout << "I am a nice guy!" << endl;
        }
};

class Woman: public Human{
public:
        Woman(string name, int age){
                this->name = name;
                this->age = age;
        }
        virtual void introduce(){
                Human::introduce();
                cout << "I am a cute girl!" << endl;
        }
};

int main(int argc, char* argv[]){
	Human* m = new Man("Jack", 25);
	Human* w = new Woman("Jill", 21);

	size_t len;
	char* data;
	unsigned int op;
	while(1){
		cout << "1. use\n2. after\n3. free\n";
		cin >> op;

		switch(op){
			case 1:
				m->introduce();
				w->introduce();
				break;
			case 2:
				len = atoi(argv[1]);
				data = new char[len];
				read(open(argv[2], O_RDONLY), data, len);
				cout << "your data is allocated" << endl;
				break;
			case 3:
				delete m;
				delete w;
				break;
			default:
				break;
		}
	}

	return 0;	
}

자 소스코드를 대충 읽어보니 woman, man 이라는 클래스가 존재하는데 이는 각각 Human 클래스를 상속받아 해당 타입으로 생성된 객체는 give_shell이라는 함수를 가지게 됩니다.

우리의 목표는 uaf 취약점을 활용하여 객체를 해제하고 그곳에 특정 값을 할당한 뒤 give_shell 함수를 실행하도록 하는 것입니다.

 

아무래도 디버깅을 해가며 풀어야할 것 같네요. 디버깅을 합시다.

일단 gdb peda로 분석을 해봅시다.

메인을 디스어셈블해보면 위와 같은 부분이 나옵니다. 이 부분이 딱봐도 switch문임을 알 수 있죠?

 

잘 모르니 일단 분기마다 다 중단점을 걸어줍시다.(다 풀고나서 알았는데 필요한건 main+265 뿐입니다.)

그리고 일단 1을 use 부분을 실행해 봅시다.

이 부분이 되겠네요.

rdx 부분을 호출하는데 rdx는 결국 rax+8 이고 rax는 rbp-0x38값 입니다. 

+8을 해주기 전 rax값을 보면 rax는 처음부터 give_shell 함수를 가리킵니다.

+8을 해준 후에는 introduce 함수를 가리키네요.

그럼 rbp-0x38 주위에는 어떤 값들이 있을까요?

give_shell 함수의 주소인 0x401570이 보이는데.... 예.... 뭐 일단 참고해둡시다.

 

그리고 소스코드를 보면 동적할당할 길이와 동적할당시킬 내용을 가진 파일의 위치를 인자로 받아 after를 선택했을때 인자로 넘긴 파일의 내용을 불러와 동적할당 시켜줍니다. 그러므로 일단 어디에 뭐가 들어가는지 확인해야하므로 아무 파일이나 만들어서 인자로 넘겨봅시다.

그리고 free를 해준후 after를 두번 해 주고 확인해 봅시다.

딱봐도 아까 처음 use 했을때 401570 즉 give_shell의 주소가 있던 자리에 AAAA가 위치한 것을 알 수 있습니다.(파일을 만드느라 주소가 달라졌지만 맥락만 이해하시면 됩니다.) 

우리가 원하는 것은 use를 선택하고 rdx를 호출할때 give_shell을 호출하도록 하는 것입니다. 따라서 0x401570에서 8을 뺀 0x401568이라는 값을 해당 위치에 집어 넣어 free를 통해 기존 객체를 해제를 시켜주고 after를 통해 동적할당을 해준 후 use를 했을 때 우리가 조작한 0x401568이라는 값에 8을 더한 0x401570가 가리키는 위치의 함수, 즉 give_shell함수를 실행하여 uaf 취약점을 활용한 공격을 하게 됩니다.

 

그럼 0x401568이라는 값을 한번 넘겨봅시다.

흐엌.... 힘들었습니다.

아무리 생각해도 모르겠어서 구글링을 하여 다른 분들의 풀이를 조금 참고했습니다.

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

pwnable.kr memcpy 풀이  (0) 2020.09.22
pwnable.kr cmd2 풀이  (0) 2020.08.24
pwnable.kr cmd1 풀이  (0) 2020.08.24
pwnable.kr lotto 풀이  (0) 2020.08.21
pwnable.kr blackjack 풀이  (0) 2020.08.19
Comments