csictf-2020 Writeups

Aviral
5 min readJul 22, 2020

This was a beginner-intermediate level ctf. Many challs were easy, some were guessy and some were fun. My team ended up at no-49 with 12805 points.

1. little-RSA

This challenge had a file attached to it with these values:

c=32949
n=64741
e=42667

`n`was easily factorable: 641*101, which resulted in totient=64000. Second step is to find 'd' by d=inverse(e,phi). Using this value of d to find the message( pow(c,d,n)=18429 ). Resulted message was the key to the zip file and the flag was inside.

Flag: csictf{gr34t_m1nds_th1nk_4l1ke}

2. The Climb

Reading just the title of the challenge gave me a hint that it is a hill cipher and the key was given in the java script.(key=”gybnqkurp” We just needed to convert it into 3x3 matrix of indexes). Nevertheless, I took it as a challenge to write a reverse engineered python script and succeeded. Checkout the script given below:

def brute_multiply(key, matrix):
l=[]
for i in range(26):
for j in range(26):
for k in range(26):
x=(key[0][0]*i + key[0][1]*j + key[0][2]*k)%26
if(x==matrix[0]):
l.append([i, j, k])
for lis in l:
i, j, k = lis[0], lis[1], lis[2]
x=(key[1][0]*i + key[1][1]*j + key[1][2]*k)%26
y=(key[2][0]*i + key[2][1]*j + key[2][2]*k)%26
if(x==matrix[1] and y==matrix[2]):
print chr(97+i), chr(97+j), chr(97+k),
key = "gybnqkurp"
key=[key[i:i+3] for i in range(0,9,3)]
c = "lrzlhhombgichae"
for i in range(3):
key[i]=[ord(char)-97 for char in list(key[i])]
print "key =", key
rmatrix=[ord(char)-97 for char in list(c)]
print "rmatrix =", rmatrix
for i in range(0, len(rmatrix), 3):
brute_multiply(key, rmatrix[i:i+3])

Running that script will spit out:

key = [[6, 24, 1], [13, 16, 10], [20, 17, 15]]
rmatrix = [11, 17, 25, 11, 7, 7, 14, 12, 1, 6, 8, 2, 7, 0, 4]
h i l l s h a v e e y e s x x

Removing ‘xx’ and wrapping in csictf{}.

Flag: csictf{hills_have_eyes}

3. Riverst Shamir Aldman

Pretty Basic RSA challenge. Found totient using https://www.alpertron.com.ar/ECM.HTM . Checkout the script given below:

c = 226582271940094442087193050781730854272200420106419489092394544365159707306164351084355362938310978502945875712496307487367548451311593283589317511213656234433015906518135430048027246548193062845961541375898496150123721180020417232872212026782286711541777491477220762823620612241593367070405349675337889270277102235298455763273194540359004938828819546420083966793260159983751717798236019327334525608143172073795095665271013295322241504491351162010517033995871502259721412160906176911277416194406909

n = 408579146706567976063586763758203051093687666875502812646277701560732347095463873824829467529879836457478436098685606552992513164224712398195503564207485938278827523972139196070431397049700119503436522251010430918143933255323117421712000644324381094600257291929523792609421325002527067471808992410166917641057703562860663026873111322556414272297111644069436801401012920448661637616392792337964865050210799542881102709109912849797010633838067759525247734892916438373776477679080154595973530904808231

e = 65537
phi = 408579120322559108971841469124848503258474925184086139548833106688770638488565627633198182607013895445354251771442359038429937414167181589307913754359396477104727102263157011988136721549122783277478724262191709545597184123942240855574393608022907658836225632844247632699974069178210075740249216128470998584630713277740385076547512621785826119966545869523217190040845172547694126237683215971908137183971439798396759609787472175362989759637473718491321532313974929404180248280920189014452204246207232

d = inverse(e, phi)
m = pow(c,d,n)
print(bytes.fromhex(hex(m)[2:]))

Flag: csictf{sh0uld'v3_t4k3n_b1gg3r_pr1m3s}

4. Quick Math

Ben encrypted his message with same ‘e’ and three public modulli. Hmm, smell of Hastad attack.

n1 = 86812553978993
n2 = 81744303091421
n3 = 83695120256591
c1 = 8875674977048
c2 = 70744354709710
c3 = 29146719498409

I was too lazy to write a script for this. So, I got it from internet.

n1 = 86812553978993 
n2 = 81744303091421
n3 = 83695120256591
c1 = 8875674977048
c2 = 70744354709710
c3 = 29146719498409
def chinese_remainder(n, a):
sum = 0
prod = reduce(lambda a, b: a*b, n)
for n_i, a_i in zip(n, a):
p = prod / n_i
sum += a_i * mul_inv(p, n_i) * p
return sum % prod
def mul_inv(a, b):
b0 = b
x0, x1 = 0, 1
if b == 1: return 1
while a > 1:
q = a / b
a, b = b, a%b
x0, x1 = x1 - q * x0, x0
if x1 < 0: x1 += b0
return x1
def find_invpow(x,n):
high = 1
while high ** n < x:
high *= 2
low = high/2
while low < high:
mid = (low + high) // 2
if low < mid and mid**n < x:
low = mid
elif high > mid and mid**n > x:
high = mid
else:
return mid
return mid + 1
flag_cubed=chinese_remainder([n1,n2,n3],[c1,c2,c3])
print flag_cubed
flag=find_invpow(flag_cubed,5)
print "flag: ", flag

We got flag as 683435743464. But, long_to_bytes(m) gave garbage. I double checked my stolen script xD and then cursed admins for bad challs. After a while my teammate pointed out that they are just hexadecimal characters.

chr(0x68)=’h’, chr(0x34)=’4' etc.

Flag: csictf{h45t4d}

5. Mein Kampf

It was quite clear that it was enigma m4. The real difficulty was to bruteforce the rotors. We don’t like to do it by hand. Do we?

Fired up sublime and started writing script for it. After some hit and trial and help from teammates wrote this script:

import sys
from enigma.machine import EnigmaMachine
kis=['I','II','III','IV','V','VI','VII','VIII']ciphertext='ZKRTWVVVNRKULXHOYWOJ'
for a in kis:
for b in kis:
for c in kis:
machine = EnigmaMachine.from_key_sheet(
rotors='Gamma '+a+' '+b+' '+c,
reflector='B-Thin',
ring_settings="4 9 3 20",
plugboard_settings='FV CD HU IK ES OP YL WQ JM')

machine.set_display('BENE')
plaintext = machine.process_text(ciphertext)
if("CSICTF" in plaintext):
print(plaintext.lower())
print(a,b,c)

Flag: csictf{no_shit_sherlock}

6. Unseen

Given were two files namely morse.wav and nyc.png . Challenge hinted towards lsb stegnography but whatever the forensic challenge may be, my first choice is to use https://aperisolve.fr/ . This site gives us the result of zsteg, steghide, outguess, exiftool, binwalk, foremost and strings on the image. I quickly analysed the image and found this:

Now, we have the numerical key to the morse.wav file. Decoding that morse using an online tool gave us nothing. Since we had the key, so I used steghide(bcoz it uses a key).

steghide extarct -sf morse.wav

Recovered one file named flag.txt. Opened it in sublime. It got many tabs and spaces in it. It was whitespace stegnography. Used an online tool to decode it and got the flag.

Flag: csictf{7h47_15_h0w_y0u_c4n_83c0m3_1nv151813}

7. Panda

Easy challenge again. We were given a password protected zip file and the password was a pin. Considering the pin length to be of max. 7 digits, I made a wordlist.

f=open('wordlist', 'w')
for i in range(10000000):
f.write(str(i)+'\n')

Now, running this command

fcrackzip -D -u -p wordlist panda.zip

I got some pins in result but only 2611 worked out. In that zip files there were two images namely panda.jpg and panda1.jpg. I had seen this kind of challenge somewhere before . Aha, it was whats-the-difference from picoctf2019. I quickly copied the code, didn’t even change the variables xD and got the flag.

with open('panda.jpg', 'rb') as f:
kitters = f.read()
with open('panda1.jpg', 'rb') as f:
cattos = f.read()
flag = ''
for i in range(min(len(kitters), len(cattos))):
if kitters[i] != cattos[i]:
flag += cattos[i]
print flag

Flag: csictf{kung_fu_p4nd4}

8. Archenemy

Got a password-protected zip file. No problem fcrackzip and rockyou.txt are here for help.

fcrackzip -D -u -p rockyou.txt flag.zip

Got the password: kathmandu

Recovered meme.png from that zip file and it contained the flag.

Writing each character by seeing the image is a tedius task so kust use tesseract(a tool for ocr) to get text from images.

Flag: csictf{1_h0pe_y0u_don't_s33_m3_here}

If you want writeups for any other challenge, please comment the challenge name.

--

--