Skip to content
Open
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
3 changes: 2 additions & 1 deletion downunderctf2022/babypywn/babypywn
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

from ctypes import CDLL, c_buffer
libc = CDLL('/usr/lib/x86_64-linux-gnu/libc.so.6')
prime = [c_buffer(512) for _ in range(10)]
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new prime allocation list is never referenced, so it reads as unused/accidental. If this is intentional heap grooming, consider renaming it to something descriptive (e.g., heap_groom/groom_allocs) and add a short comment explaining why this allocation count/size is needed to keep the buffers alive and influence layout.

Suggested change
prime = [c_buffer(512) for _ in range(10)]
# Heap grooming: keep these allocations alive to influence buffer layout.
heap_groom = [c_buffer(512) for _ in range(10)]

Copilot uses AI. Check for mistakes.
buf1 = c_buffer(512)
buf2 = c_buffer(512)
libc.gets(buf1)
Comment on lines 3 to 8
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of libc.gets(buf1) with a fixed-size c_buffer(512) is inherently unsafe, because gets does not enforce any length limit and allows an attacker to overflow buf1 and corrupt adjacent memory (including buf2). In this context an attacker can input more than 512 bytes to control buf2 and satisfy the if b'pwn.college' in bytes(buf2) check to read /flag, and depending on layout may also achieve arbitrary memory corruption or code execution. Replace gets with a bounded input API (e.g., one that takes the buffer size and enforces it) and ensure that any low-level reads via ctypes are strictly length-checked.

Suggested change
from ctypes import CDLL, c_buffer
libc = CDLL('/usr/lib/x86_64-linux-gnu/libc.so.6')
prime = [c_buffer(512) for _ in range(10)]
buf1 = c_buffer(512)
buf2 = c_buffer(512)
libc.gets(buf1)
from ctypes import c_buffer
prime = [c_buffer(512) for _ in range(10)]
buf1 = c_buffer(512)
buf2 = c_buffer(512)
# Safely read at most 511 bytes of user input into buf1, leaving room for a null terminator.
user_input = input()
data = user_input.encode('utf-8', errors='ignore')[:511]
buf1.value = data

Copilot uses AI. Check for mistakes.
if b'pwn.college' in bytes(buf2):
print(open('/flag', 'r').read())
print(open('/flag', 'r').read())
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

open('/flag', 'r').read() leaves the file descriptor open until GC; use a context manager (with open(...) as f:) to ensure the file is closed deterministically.

Suggested change
print(open('/flag', 'r').read())
with open('/flag', 'r') as f:
print(f.read())

Copilot uses AI. Check for mistakes.