n00bzCTF
Not last week but the week before that I participated in n00bzCTF! I solved 5 problems and had lots of fun working with teammates from Japan. When I woke up to check the problems to solve, they’d already done so many! Here are a few that I solved.
RSA
Crypto
The cryptography category is incomplete without RSA. So here is a simple RSA challenge. Have fun!
e = 3
n = 135112…
c = 130377…
Where n and c were about 100-200 digits long. I saw a problem like this when I was making my RSA presentation for the Directed Reading Program at university. So I went and found the writeup, installed the necessary packages, and we were cracking!
The shell commands used for installing the packages:
python3 -m venv n00bz-ctf
source n00bz-ctf/bin/activate
python3 -m pip install gmpy
The script run to find the flag:
import gmpy
mToE = c
mToE = gmpy.mpz(int(mToE))
m = int(mToE.root(e)[0])
print(bytes.fromhex(hex(m)[2:]))
This is explained in point three in this answer on Cryptography StackExchange where we do root extraction on c = m^e.
n00bz{crypt0_1s_1nc0mpl3t3_w1th0ut_rs4!!}
Vinegar 2
Crypto
Never limit yourself to only alphabets!
Given chall.py and enc.txt. I started by reading through chall.py and adding notes:
flag=''
key='5up3r_s3cr3t_k3y_f0r_1337h4x0rs_r1gh7?'
flag_arr = []
key_arr = []
decr_arr=[]
# Create an array of the indices of the matrices which start with the letters in the flag
for flag_letter in flag:
# go through every matrix of alphabet orders
for i in range(len(alphanumerical)):
# if the matrix starts with the letter in the flag, append it to flag_arr
if matrix[i][0][0]==flag_letter:
flag_arr.append(i)
# do the same for the key
for key_letter in '5up3r_s3cr3t_k3y_f0r_1337h4x0rs_r1gh7?':
for i in range(len(alphanumerical)):
if matrix[i][0][0]==key_letter:
key_arr.append(i)
# For each flag letter,
for i in range(len(flag)):
# Get the matrix which starts with that letter
# Append the letter at the index of the matrix which starts with the corresponding key letter
enc_arr.append(matrix[flag_arr[i]][0][key_arr[i]])
encrypted=''.join(enc_arr)
encrypted='*fa4Q(}$ryHGswGPYhOC{C{1)&_vOpHpc2r0({'
The matrix is the encryption/decription key and the scheme is Vigenere. So that’s why they called it Vinegar! I always look forward to the funny challenge names. After messing with the code, I got the solution:
alphanumerical = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*(){}_?'
matrix = []
for i in alphanumerical:
matrix.append([i])
idx=0
for i in alphanumerical:
matrix[idx][0] = (alphanumerical[idx:len(alphanumerical)]+alphanumerical[0:idx])
idx += 1
key='5up3r_s3cr3t_k3y_f0r_1337h4x0rs_r1gh7?'
key_arr = []
encrypted='*fa4Q(}$ryHGswGPYhOC{C{1)&_vOpHpc2r0({' # given in enc.txt
enc_arr= list(encrypted)
flag_arr = []
# Want to solve for
flag=''
decr_arr=[]
# Build the key array
for key_letter in key:
for i in range(len(alphanumerical)):
if matrix[i][0][0]==key_letter:
key_arr.append(i)
# Build the flag array
for enc_i in range(len(encrypted)):
for i in range(len(alphanumerical)):
# Find the matrix whose key_arr[i]-th character is enc_arr[i]
if matrix[i][0][key_arr[enc_i]]==encrypted[enc_i]:
flag_arr.append(i)
break
for i in flag_arr:
decr_arr.append(matrix[i][0][0])
flag=''.join(decr_arr)
print(flag)
n00bz{4lph4num3r1c4l_1s_n0t_4_pr0bl3m}
Numbers 2
Programming
The full challenge statement is here. The statement referenced n00bzCTF 2023, so I took a look at the old writeups and found this similar problem. I used the code in the solution as starter code for this problem.
Then I connected to the container to see the different formats of questions that could be asked. The possible formats were
- “Give me the least common multiple of {x} and {y}:”
- “Give me the greatest common divisor of {x} and {y}:”
- “Give me the greatest prime factor of {x}:”
So I started cracking! I took the list of prime numbers up to 621 or so from Wikipedia and hard-coded it into an array. Because of that, the script is quite large, so I put it in a separate file. You can download/view it here. After running, I got an EOF error. Can you guess what caused it?
Traceback (most recent call last):
File "/PATH/n00bz-ctf/num2.py", line 45, in <module>
round = io.readline() # Current round:
File "/PATH/python3.10/site-packages/pwnlib/tubes/tube.py", line 1489, in wrapper
return func(self, *a, **kw)
File "/PATH/python3.10/site-packages/pwnlib/tubes/tube.py", line 498, in recvline
return self.recvuntil(self.newline, drop = not keepends, timeout = timeout)
File "/PATH/python3.10/site-packages/pwnlib/tubes/tube.py", line 341, in recvuntil
res = self.recv(timeout=self.timeout)
File "/PATH/python3.10/site-packages/pwnlib/tubes/tube.py", line 106, in recv
return self._recv(numb, timeout) or b''
File "/PATH/python3.10/site-packages/pwnlib/tubes/tube.py", line 176, in _recv
if not self.buffer and not self._fillbuffer(timeout):
File "/PATH/python3.10/site-packages/pwnlib/tubes/tube.py", line 155, in _fillbuffer
data = self.recv_raw(self.buffer.get_fill_size())
File "/PATH/python3.10/site-packages/pwnlib/tubes/sock.py", line 56, in recv_raw
raise EOFError
EOFError
I didn’t have enough primes in my array! So I went back and added the whole table from Wikipedia (primes up to 1,000), ran the script again, and vwala!
n00bz{numb3r5_4r3_fun_7f3d4a}
Subtraction
Misc
My little brother is learning math, can you show him how to do some subtraction problems?
Given server.py.
I started by adding notes.
import random
n = 696969
a = []
# Fill the array with even integers from 0 to 696968
for i in range(n):
a.append(random.randint(0, n))
a[i] -= a[i] % 2
# print(' '.join(list(map(str, a))))
# print(max(a)//2)
for turns in range(20):
c = int(input())
# Replace with the absolute difference in each value
for i in range(n):
a[i] = abs(c - a[i])
print(set(a))
# Until they all become the same number
if len(set(a)) == 1:
print(set(a))
# print(open('/flag.txt', 'r').read())
break
And as you can see by the print comments in the middle that I added, I started by replying with the floor of half of the max value in the array. But that didn’t always work in less than 20 tries.1
So I was a bit stumped. What to do? Then I realized that if I want to get the elements to converge to a point, why not choose the median?
from statistics import median
strA = open('./subtract_server_response.txt').read()
a=[int(i) for i in strA.split()]
response = int(median(a))
print("median: " + str(response))
for i in range(20):
print(f"sending {response}")
for i in range(len(a)):
a[i] = abs(response - a[i])
setA = set(a)
a = list(setA)
response = int(median(a))
print(a)
With that, we got the flag!
n00bz{1_sh0uld_t34ch_my_br0th3r_logs}
For more challenges, check the official writeups here!
Notes
-
Turns out I was supposed to use the ceil, not the floor, according to the writeup. Oops. ↩