ENGINEERCTF 2022 writeup

I participated Enginner CTF 2022. The 0003 article.

f:id:Berrys:20220307193304p:plain



I can do this all day.

f:id:Berrys:20220307193902p:plain

We can get "icandothisallday.zip" first and unzip it.

  • icandothisallday.zip

You can see lots of files in your current directory. Like this.

f:id:Berrys:20220307195942p:plain

We can guess that the flag is in those files. Therefore, we type this and run it.
from glob import glob

directory = "<your current directory absolute path>"
for file in glob(directory + '/*.txt'):
    data = open(file, "r").read()
    if ("CTF" in data):
        print(data)
Now, we can get this flag.
CTF{d3cry47ing_nu3l34r_c0d35}


Save Our Souls!

f:id:Berrys:20220307200121p:plain

We can get a file below.

  • Message.wav

Open with audacity. Then, display spectrogram and set the sampling frequency to 22050 Hz. Now, we can see this image.

f:id:Berrys:20220307230327p:plain

I thought the message was "we need infoce me", however this was incrrect. This was unnatural, but also read as natural. I took some mistakes for submitting flag. Finally, I understand what message below is.
FLAG : CTF{WE-NEED-INFORCEMENTS}


Time

f:id:Berrys:20220307201936p:plain

A text file contained the search parameters below was given.
[https://www.google.com/search?q=ectf+nitk&sxsrf=APq-WBucQC97ty5WJujCZdH3xgNKkG4DcA%3A1646337798523&source=hp&ei=Bh8hYqykHc64mAXkkoTgCg&iflsig=AHkkrS4AAAAAYiEtFvYpL6BEakDJQ-fOP-eWa7kvFyAO&ved=0ahUKEwisv6Kd3qr2AhVOHKYKHWQJAawQ4dUDCAg&uact=5&oq=ectf+nitk&gs_lcp=Cgdnd3Mtd2l6EAMyBAgjECcyBAgjECc6BAgAEEM6CwguEMcBEK8BEJECOgoILhDHARCvARBDOgUIABCRAjoLCAAQgAQQsQMQgwE6CAgAEIAEELEDOgcIABCxAxBDOhAIABCABBCHAhCxAxCDARAUOgUIABCABDoGCAAQFhAeOggIABAWEAoQHlAAWMMKYPUNaABwAHgAgAHcAYgBqgySAQUwLjcuMpgBAKABAQ&sclient=gws-wiz]
According to this article below, the ei parameter is the suspect.

www.reddit.com

We can get UNIX time by decoding the ei parameter using the program at the site below.

deedpolloffice.com

I had to convert UNIX time and submit it, but I forgot that it was Mbabane time and made a mistake 7 times.
FLAG : CTF{2022-03-03-22}
Looking at Discord, it looks like someone else made a same mistake.

f:id:Berrys:20220307230404p:plain

Not really random

f:id:Berrys:20220307203715p:plain

A python file was given.
import random 
import time 
import hashlib

seed = round(time.time())
random.seed(seed, version=2)

while True:
    rand = random.random()
    has = hashlib.sha256(str(rand).encode()).hexdigest()
    flag = f"CTF{{{has}}}"
    if "7a2" in has:
        with open("./flag", "w") as f:
            f.write(flag)
            break
    else:
        print(f"Bad random value: {rand}")
Bad random value: 0.33567959567961436
Bad random value: 0.8913897703358419
Bad random value: 0.3032054069265432
Bad random value: 0.6860829464688437
Bad random value: 0.2658087107328536
Bad random value: 0.8903005048882441
Bad random value: 0.914630909612433
Bad random value: 0.9688578899818961
Bad random value: 0.7925090397955323
Bad random value: 0.10136501216336935
Bad random value: 0.568451491382639
Bad random value: 0.16898065821921437
Bad random value: 0.5541712073794856
Bad random value: 0.029926361216790154
Bad random value: 0.18218590474521223
Bad random value: 0.49713845657579536
Bad random value: 0.7631162105077507
Bad random value: 0.7386939443532723
Bad random value: 0.5815609491717452
Bad random value: 0.5905894610211082
Bad random value: 0.09018146469820387
Flag created 
"rand.py" is a program that uses UNIX time as a seed value to obtain a pseudorandom number. We can see "flag created" in log.txt at 22 lines, so we need to calculate the UNIX time which has "7a2" in line22. I obtained by the use of brute-force.
import random
import time
import hashlib

now = 1646547850   # current time

tmp = [0.33567959567961436, 0.8913897703358419, 0.3032054069265432, 0.6860829464688437, 0.2658087107328536, 0.8903005048882441, 0.914630909612433, 0.9688578899818961, 0.7925090397955323, 0.10136501216336935, 0.568451491382639, 0.16898065821921437, 0.5541712073794856, 0.029926361216790154, 0.18218590474521223, 0.49713845657579536, 0.7631162105077507, 0.7386939443532723, 0.5815609491717452, 0.5905894610211082, 0.09018146469820387]

while (now > 0):
    random.seed(now, version=2)
    for cnt in range(21):
        rand = random.random()
        if (rand != tmp[cnt]):
            break
    else:
        print(now)
        exit()
    
    now -= 1
Then, run "rand.py" using UNIX time which obtained earlier. Finally, we can get FLAG.
FLAG : CTF{82eafc43f229ea3ffe489444c973a8bbbfbbbac54095ba207a222e9918290fdc}


Hecker Beluga

f:id:Berrys:20220307205711p:plain

A python file below was given.
def ValidatePassword(password):
    valid = False
    print("Attempting to validate password...")

    if(len(password[::-2]) != 8):
        print("Nah, you're not even close!!")
        return False

    pwlen = len(password)
    chunk1 = 'key'.join([chr(0x98 - ord(password[c])) for c in range(0, int(pwlen / 2))])
   
    if "".join([c for c in chunk1[::4]]) != '&e"3&Ew*':
        print("Seems you're a terrible reverse engineer, come back after gaining some skills!")
        return False

    chunk2 = [ord(c) - 0x1F if ord(c) > 0x60 else (ord(c) + 0x1F if ord(c) > 0x40 else ord(c)) for c in password[int(pwlen / 2) : int(2 * pwlen / 2)]]
    
    rand = [54, -45, 9, 25, -42, -25, 31, -79]
    for i in range(0, len(chunk2)):
        if(0 if i == len(chunk2) - 1 else chunk2[i + 1]) != chunk2[i] + rand[i]:
            print("You're not a real hecker, try again! " + str(i))
            return False
        
    print("Password accepted!")
    return True

print("\n************** Password Validator ***************")
print("Please enter password")

while True:
    if  ValidatePassword(input()):
        exit()
    else:
        print("Try again!")
This is a program that judges whether input is correct or not. In line 5, it determines if the input has 16 charactors. In line 11, it determines if difference from "0x98" for each characters in the input is equal to "&e"3&Ew*". So, we need to find characters which does not match the condition in line 19. It's easy to find them from back.
I solved with a paper and pen. Finally, got a FLAG below.
FLAG : CTF{r3verS!ng_pyTh0n}


Lost Password

f:id:Berrys:20220307213659p:plain

A file below was given.

  • main

We can get first half of the FLAG using strings and grep commands.

f:id:Berrys:20220307215554p:plain

Open with Ghidra for the next step, you can see that it compares a string "mingw.exe" and outputs something. Run it and input "mingw.exe", then you will get the FLAG.

f:id:Berrys:20220307214509p:plain

FLAG : CTF{HaCK3R_MaN}


Lights off

f:id:Berrys:20220307214537p:plain

The C lang file below was given.
int magic(char arr[], int a)
{
    int i;
    int k = strlen(arr);
    int flag = 0;
    a = 25;
    for (int i = 0; i < k / 2; i++)
    {
        if ((i % 2 ? arr[i] + a : arr[i] - a) != ((k - 1) % 2 ? arr[k - i - 1] + a : arr[k - i - 1] - a))
        {
            return 0;
        }
    }
    if (k % 2 == 1 && a < 24 && k == 4)
    {
        return 0;
    }
    return 1;
}
It seems to be judging whether the letters in the index from the front are the same for the index from the back. An odd number of string length is convenient, input "AAA" to get FLAG.
FLAG : CTF{L1Ghts=O}