I want to first start out by thanking the organizers for this great CTF. I had a lot of fun playing with my team cyb3r_w1z4rd5
.
Bites was a reversing challenge in RTL CTF worth 50 points.
We are given two files (I put them at the end of this section if you want to see them): dc9_bites.txt
and flag.txt
.
The first file is the one we need to reverse and what it does is the following:
key
cipher
in a list called a
-> we do not know what cipher contains but we can guess that it’s the ascii code of the flag’s characters.key
(119) in a variable named key_1
.key
(77) in a variable named key_2
key_1
and key_2
in a list called keyes
.Executes a for loop that does that basically following:
index
is even: it saves the xor of key_2
and a[index]
in cipher
index
is odd: it saves the xor of key_1
and a[index]
in cipher
cipher
in the file flag.txtSo we can now write the following script to get the flag:
file = open("flag.txt", "r")
#get all 15 numbers in an array
for line in file:
elements = line.split(' ')
keyes = [119, 77]
chars = []
for i in range(len(elements)):
if i % 2 == 0:
chars.append(chr(int(elements[i])^keyes[1]))
else:
chars.append(chr(int(elements[i])^keyes[0]))
flag = ''.join(chars)
print(flag)
We get the following flag: RTL{H4x_ByT3$$}
.
31 35 1 12 5 67 53 40 15 14 25 68 105 83 48
dc9_bites.txt:
2 0 LOAD_CONST 1 ('w')
3 STORE_FAST 1 (key)
3 6 LOAD_FAST 0 (cipher)
9 LOAD_ATTR 0 (split)
12 LOAD_CONST 2 (' ')
15 CALL_FUNCTION 1
18 STORE_FAST 2 (a)
4 21 LOAD_GLOBAL 1 (ord)
24 LOAD_FAST 1 (key)
27 CALL_FUNCTION 1
30 STORE_FAST 3 (key_1)
5 33 LOAD_GLOBAL 2 (int)
36 LOAD_FAST 1 (key)
39 LOAD_ATTR 3 (encode)
42 LOAD_CONST 3 ('hex')
45 CALL_FUNCTION 1
48 CALL_FUNCTION 1
51 STORE_FAST 4 (key_2)
6 54 LOAD_FAST 3 (key_1)
57 LOAD_FAST 4 (key_2)
60 BUILD_LIST 2
63 STORE_FAST 5 (keyes)
7 66 LOAD_CONST 4 ('')
69 STORE_FAST 0 (cipher)
8 72 SETUP_LOOP 135 (to 210)
75 LOAD_GLOBAL 4 (range)
78 LOAD_CONST 5 (0)
81 LOAD_GLOBAL 5 (len)
84 LOAD_FAST 2 (a)
87 CALL_FUNCTION 1
90 CALL_FUNCTION 2
93 GET_ITER
>> 94 FOR_ITER 112 (to 209)
97 STORE_FAST 6 (x)
9 100 LOAD_FAST 6 (x)
103 LOAD_CONST 6 (2)
106 BINARY_MODULO
107 LOAD_CONST 7 (1)
110 COMPARE_OP 2 (==)
113 POP_JUMP_IF_FALSE 153
10 116 LOAD_FAST 0 (cipher)
119 LOAD_GLOBAL 6 (chr)
122 LOAD_GLOBAL 2 (int)
125 LOAD_FAST 2 (a)
128 LOAD_FAST 6 (x)
131 BINARY_SUBSCR
132 CALL_FUNCTION 1
135 LOAD_FAST 5 (keyes)
138 LOAD_CONST 5 (0)
141 BINARY_SUBSCR
142 BINARY_XOR
143 CALL_FUNCTION 1
146 INPLACE_ADD
147 STORE_FAST 0 (cipher)
150 JUMP_ABSOLUTE 94
11 >> 153 LOAD_FAST 6 (x)
156 LOAD_CONST 6 (2)
159 BINARY_MODULO
160 LOAD_CONST 5 (0)
163 COMPARE_OP 2 (==)
166 POP_JUMP_IF_FALSE 94
12 169 LOAD_FAST 0 (cipher)
172 LOAD_GLOBAL 6 (chr)
175 LOAD_GLOBAL 2 (int)
178 LOAD_FAST 2 (a)
181 LOAD_FAST 6 (x)
184 BINARY_SUBSCR
185 CALL_FUNCTION 1
188 LOAD_FAST 5 (keyes)
191 LOAD_CONST 7 (1)
194 BINARY_SUBSCR
195 BINARY_XOR
196 CALL_FUNCTION 1
199 INPLACE_ADD
200 STORE_FAST 0 (cipher)
203 JUMP_ABSOLUTE 94
206 JUMP_ABSOLUTE 94
>> 209 POP_BLOCK
13 >> 210 LOAD_FAST 0 (cipher)
213 PRINT_ITEM
214 PRINT_NEWLINE
215 LOAD_CONST 0 (None)
218 RETURN_VALUE
This challenge was part of the Crypto section of this CTF and was worth 10 points.
We are given the following: 133f29027034094a33253126395b3704
and are told that it was encrypted with a 4 byte key, meaning 4 characters.
I basically just bruteforced this challenge, so that I could work on other challenges in the meantime, with the following script:
import string
def hex_xor(hex_a, hex_b):
return hex(int(hex_a, 16) ^ int(hex_b, 16))[2:]
def xor_solver(string, string_key):
new_key = ''
decryption = ''
# Repeat key in new_key for as long as hex_string is
for i in range(0, round(len(hex_string)/2), 1):
new_key += hex(ord(string_key[i % len(string_key)]))[2:]
# Perform xor on both hex
xor_result = hex_xor(hex_string, new_key)
# Convert the hex to char
for j in range(0, len(xor_result)-1, 2):
decryption += chr(int(xor_result[j]+xor_result[j+1], 16))
return decryption
value = '133f29027034094a33253126395b3704'
flags = []
for i in string.printable:
for j in string.printable:
for k in string.printable:
for l in string.printable:
print(f"Trying: {i}{j}{k}{l}")
result = xor_solver(value, f"{i}{j}{k}{l}")
if "RTL{" in result:
print(f"\n{result} is a possible flag!!!!\n")
flags.append(result)
print(flags)
I got the following flag: RTL{1_l3rNT_x0R}
.
This challenge was part of the Crypto section of this CTF and was worth 50 points.
We were given values for n
,e
and c
, meaning that it was a RSA challenge.
The first thing I did is run n
in http://factordb.com/ and there I learned that n
was equal to a certain number p
(this number figures in my script I’m not putting it here because it would be too long) power 3. So n=p^3
.
This changes the way we need to calculate phi
, I found this article, https://en.wikipedia.org/wiki/Euler%27s_totient_function#Value_of_phi_for_a_prime_power_argument, that tells us that phi
is now equal to p^2*(p-1)
.
We can now put it in our script and solve it like a basic RSA. Note: if you are unfamiliar with basic RSA ctf challenges, the following video by John Hammond is a good introduction on how to solve these challenges: https://www.youtube.com/watch?v=INOjNotyLjA.
This is the final script:
from Crypto.Util.number import inverse
import codecs
n=654922591808399471401115531725039933804976416275178080902192760929946158327379913921397815675866572368514471928883646492843129515545704650288455484139194674085479767043433916059634120332033088959269854607488937394748966549930683612344765680930825877346853207413052755531377359101713133223003902598963694672505995923904179391456221568627581198379796103905853274401142025181753922563551760475421349438387207814101835728396617249777551918738205026251791041540304166035801169367444769632368098508148321283516990672280903943844076578831127878464804361185261171218008337510295988058766597378522306523707845029512326086281153969312238517561678149326216382068770238520736531273600941471546492734984885174688640769745572963612242607879009754765129567334064867941063826839593018197528692242502124648098963061951119350954396467735643056862091298259178844956622094028547135110211632557488448742742990287309014601421331198088078262672918791473250793328827598271675543610977104049017695062380578362377174224228163980223055437425220689053314587171763084816067718392663203432596767350691383811865855862699762433397509373202656517
e=65537
ct=100710438795162977079348743974088808865381156915931230652674830564884952723797964737417330704790990449847640350694313826907540645947517771309102468382620491151431303509245971254205327928401285858105844273322941744709730235138404791133855224230464330311543377527034287444040442497607564368033381652353025668428244301303066924437016815162803737278638329823899949834679835580778760115487417517224721370787073698165030607724383674378473550370840265887300696291636301457816942477342875386648871368111343762416276747522564143279926396047848536514023846050160848670498687478441942327283357707903465054287238235065476035197766241316080918681581228125031794197267118491412751434265211623073108630476746894061360362486334754179185179035203622586839918393560491482900365894224904151749064929247038688878617389856012413316816710758669316380134350637155478806193340543320655839127039864941782215970914222744836875559787971645305231571859542782671984468965485858145740868483956306860449187868403601170785547890022967337275595188765793071937500328605240827441496747925821120273130333043107613757070639870802278814019421139964349
p=86842034747506493609419721799469420931995622862762177911235982167541270872531314416635530661571139759415845637249847122973461307626071732001202620839724983790638777821431490624281206999841752934471207639839705304729136564852048258975833304653350042975893538110232832319190920640420813884920174219068423676798778919245766035367660194191901644604977395931936301500921652573
#n = p**3
phi = p**2*(p-1)
d = inverse(e,phi)
m = pow(ct,d,n)
print(codecs.decode(hex(m)[2:],'hex').decode())
The flag is the following: RTL{1_c0uld_pr0b4bly_m4k3_th15_al0t_h4rd3r_next_t1m3!!!-e82fac7a780f72579c47b6ce0d5b7fd82eb6192ed65949ca485309b5}
This challenge was part of the Crypto section of this CTF and was worth 100 points.
It was a MITM (Man in the middle) attack. We were listening in on Bob and Alice exchanging their keys, following the Diffie-Hellman key exchange protocol, and Bob finally sends the flag encrypted using this shared key. If we send in 0
disguising ourselves as Alice, Bob’s sends the flag in an unencrypted format and we get the following: RTL{4c7d928f563796fbe0d5f1d094c348b5}
.
Red was an OSINT challenge released later in the CTF worth 40 points. We are told that Railan Jareth is the sysadmin of a company and we need to find out which company it is, the version of their current windows server and the name of their server.
The first thing I did is look up this man on Linkedin and there I found his profile: https://ro.linkedin.com/in/railan-jareth-10a800218. This told me that he worked at HackArmour
and also linked me to his twitter: https://twitter.com/5C3P73R5PH1NX/.
There was nothing interesting on his twitter so I decided to run sherlock
on his twitter handle, 5C3P73R5PH1NX
and I found his reddit https://www.reddit.com/user/5C3P73R5PH1NX.
On his reddit, I found out their Windows Server version was 2016
and that their server was DL360
.
The final flag was: RTL{HackArmour_2016_DL360}
Thanks for playing was an OSINT challenge released towards the end of the CTF worth 5 points. We are told that the CTF organisers left a note on twitter with the following hashtag: #RTLxHA
.
The first thing I did was looking up this hashtag on twitter and I found the following tweet: https://twitter.com/d4rckh/status/1421816732860157956.
This tweet lead me to the rtl-ctf.hackarmour.tech/secret where lied the flag: RTL{TH4NK2_F0R_PL4Y1NG}
Where is this? was an OSINT challenge released later in the ctf worth 40 points. We are given an image and need to find its coordinates rounded to 3 decimal places.
The image is the following:
If we zoom in on the left, we can kind of make out the words “Zum Padd”, I started typing it out on my search bar and was automatically recommended Zum Paddenwirt. I checked it out on Google Maps and found there its coordinates.
The flag was: RTL{52.517_13.409}
.
Expic was a forensics challenge worth 15 points. We are given an image and need to find the flag hidden in it.
The first thing to is run exiftool
on this image (Syntax: exiftool photo
) and we find something that looks really interesting: a number -> 68747470733a2f2f706173746562696e2e636f6d2f514632557a6a56590a
.
It looks like hex so let’s run it in CyberChef, we get back the following: https://pastebin.com/QF2UzjVY.
If we go to this link, we find this T0tLIApSVEx7MTBiYmE5YTUyNDE3MDk1ZGU1MWRiOTQ1NjM2MWQ3NDR9Cg==
which is base64, let’s run it again in CyberChef and we get the flag: RTL{10bba9a52417095de51db9456361d744}
If you have any questions or remarks don’t hesitate to reach out on discord to therokdaba#9872.
Go back to the homepage of this website.