‹ Back to blog

CTF Writeup | Numbers

This is a writeup for the Numbers CTF challenge from n00bzCTF. I participated in this competition with the bER4bb1t$ CTF team which was a lot of fun.


Numbers Challenge Description

This challenge basically just needed coding skills. First we need a function to calculate the appearence of a first_number in all numbers to a second_number.

def count_occurrences(first_number, second_number):
    num_string = ','.join(str(i) for i in range(second_number))
    count = num_string.count(str(first_number))
    print(num_string)
    if first_number == 0:
        count = count - 1
    return count

At first my script was failing because the count was off by one when the first_number was a zero. I fixed that though by decreasing the count by one if the first_number was equal to zero.


Next we need a way to connect to the server mentioned in the challenge description. For that I’m using the pwntools library.

from pwn import *
import re

host = 'challs.n00bzunit3d.xyz'
port = 13541
conn = remote(host, port)

We are also importing the python regex library to extract the numbers from the server’s response. We start an endless loop and receive one line “clean it up” and store the first two numbers in the match variable.

print(conn.recvline())
    round_info = conn.recvline().decode().strip()
    print(round_info)
    match = re.search(r'(\d+).*?(\d+)\?', round_info)

Now we hand the matched numbers to the count_occurrences function and send the result to the server.

if match:
        first_number = int(match.group(1))
        target_number = int(match.group(2))
    else:
        print("Failed to extract numbers")
        print(conn.recvline())
        print(conn.recvline())
        print(conn.recvline())
    # Count occurrences
    occurrences = count_occurrences(first_number, target_number)
    # Send string to server
    print(str(occurrences))
    conn.sendline(str(occurrences))
    # Receive and print the response
    response = conn.recvline().decode().strip()
    print(response)

If the there is no match in the response we assume we cleared all levels and and should receive the flag. While my solution may be inefficient it works. The full script looks like the following:

from pwn import *
import re

host = 'challs.n00bzunit3d.xyz'
port = 13541
conn = remote(host, port)

def count_occurrences(first_number, second_number):
    num_string = ','.join(str(i) for i in range(second_number))
    count = num_string.count(str(first_number))
    print(num_string)
    if first_number == 0:
        count = count - 1
    return count

while True:
    print(conn.recvline())
    round_info = conn.recvline().decode().strip()
    print(round_info)
    match = re.search(r'(\d+).*?(\d+)\?', round_info)
    if match:
        first_number = int(match.group(1))
        target_number = int(match.group(2))
    else:
        print("Failed to extract numbers")
        print(conn.recvline())
        print(conn.recvline())
        print(conn.recvline())
    # Count occurrences
    occurrences = count_occurrences(first_number, target_number)
    # Send string to server
    print(str(occurrences))
    conn.sendline(str(occurrences))
    # Receive and print the response
    response = conn.recvline().decode().strip()
    print(response)

Flag:

n00bz{4n_345y_pr0gr4mm1ng_ch4ll}

Thank you for reading.