Writeups

UTCTF2021: Web: Cutest Cookie Clicker Rip-Off (100)

This is from the UTCTF2021 CTF

Challenge Author: Aya Abdelgawad

For this challenge we are given a little hint and a URL:

It is a game with an automatic timer that count’s down. You click the cookie to earn points. The high score is 1,000,000:

Given the name and theme of this game, I look to see what cookies it uses:

Neat, it stores my high score in a cookie. Let’s bake in a better score and refresh the page:

It applied my new highest score and is counting down:

When the clock runs out, it pops up with an alert containing the flag:

DaVinciCTF: Crypto: Substitution (25)

This is for the DaVinciCTF.

For this challenge, we are given the following ciphertext:

Rm xibkgltizksb, z hfyhgrgfgrlm xrksvi rh z nvgslw lu vmxibkgrmt rm dsrxs fmrgh lu kozrmgvcg ziv ivkozxvw drgs xrksvigvcg, zxxliwrmt gl z urcvw hbhgvn; gsv "fmrgh" nzb yv hrmtov ovggvih (gsv nlhg xlnnlm), kzrih lu ovggvih, girkovgh lu ovggvih, nrcgfivh lu gsv zylev, zmw hl uligs. Gsv ivxvrevi wvxrksvih gsv gvcg yb kviulinrmt gsv rmevihv hfyhgrgfgrlm.

Hfyhgrgfgrlm xrksvih xzm yv xlnkzivw drgs gizmhklhrgrlm xrksvih. Rm z gizmhklhrgrlm xrksvi, gsv fmrgh lu gsv kozrmgvcg ziv ivziizmtvw rm z wruuvivmg zmw fhfzoob jfrgv xlnkovc liwvi, yfg gsv fmrgh gsvnhvoevh ziv ovug fmxszmtvw. Yb xlmgizhg, rm z hfyhgrgfgrlm xrksvi, gsv fmrgh lu gsv kozrmgvcg ziv ivgzrmvw rm gsv hznv hvjfvmxv rm gsv xrksvigvcg, yfg gsv fmrgh gsvnhvoevh ziv zogvivw.

Gsviv ziv z mfnyvi lu wruuvivmg gbkvh lu hfyhgrgfgrlm xrksvi. Ru gsv xrksvi lkvizgvh lm hrmtov ovggvih, rg rh gvinvw z hrnkov hfyhgrgfgrlm xrksvi; z xrksvi gszg lkvizgvh lm ozitvi tilfkh lu ovggvih rh gvinvw klobtizksrx. Z nlmlzokszyvgrx xrksvi fhvh urcvw hfyhgrgfgrlm levi gsv vmgriv nvhhztv, dsvivzh z klobzokszyvgrx xrksvi fhvh z mfnyvi lu hfyhgrgfgrlmh zg wruuvivmg klhrgrlmh rm gsv nvhhztv, dsviv z fmrg uiln gsv kozrmgvcg rh nzkkvw gl lmv lu hvevizo klhhryrorgrvh rm gsv xrksvigvcg zmw erxv evihz.
weXGU{xi1kg3w_x1ks3i}

Given the challenge title, I head over to dcode.fr’s Mono-alphabetic Substitution cipher decoder:

Due to the amount of ciphertext, it took a few seconds to crank through it, but it did solve it:

And now I have the flag!

dvCTF{cr1pt3d_c1ph3r}

Vishwa CTF: Web: Redeeem (440)

This is from the 2021 Vishwa CTF

For this challenge, we are given a URL:

Going to the page, we get this:

Entering a coupon code does not appear to do anything. If we click the “BUY” button, we get this:

Inspecting the source, we see a hidden element named “current” with a value of “0”. This appears to be how my current balance is tracked.

I modify that element’s value to “7000” and then click the “BUY” button:

That gives us the flag!

UTCTF2021: Web: Source it!! (100)

This is from the UTCTF2021 CTF

Challenge Author: Rob H

For this challenge, we are given a little hint and a URL:

Here is the site:

I take a look at the source and find that it is doing client-side authentication in JavaScript:

I see that the password’s MD5 hash is “1bea3a3d4bc3be1149a75b33fb8d82bc”

A quick google search for that hash and I see that is has already been cracks and is “sherlock“.

I try logging in as admin with password sherlock and I’m in:

WinjaCTF2021: Find The Secret Person (550)

This is from the WinjaCTF2021.

For this challenge, we are given the following hint:

Going to the link give this page:

Looking at the source of the page, I see the images are named in sequential numbers:

Based on the hint “you are suppose to find the old person out them” on the page, I assume the image names (numbers) correspond to the order they were created. I look to see if there is a 0000.jpg file and there is!

I paste the name “Marie Collinsworth” into the text box and hit the enter key and get the flag as a response:

FLAG{Find_the_Secret_Agent_Y0u_F0uNd_Th3_R1gHt_P3rs0N}

WinjaCTF2021: JUSTWINTHIS (300)

This is from the WinjaCTF2021.

For this challenge, we are given he following hint:

Going to the link provided, we get this simple page:

After a bit of poking, I register an account:

When I log in with my new credentials, I am given this message:

Remembering a cipher I once saw that uses emojis, I try and decipher it using emojicipher.com

I see it decodes to “ar3_t0kens_$$$}”, which looks a lot like the tail end of a flag!

After some more poking, I see there is a cookie set by this site.

I decode the cookie value (base64) and see it is a JASON Web Token. Knowing how they are formatted, I break up the encoded cookie value and just decode the header to get this:

{"typ":"JWT","alg":"HS256"}{"iss":"http:\/\/ctf.winja.site","aud":"http:\/\/ctf.winja.site","role":"user","iat":1615014948,"exp":1615016748}

Seeing the “role” element with a value of “user”, I try changing the value to “admin” and then re-encoding the header and adding the preserved tail end of the original cookie value:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9jdGYud2luamEuc2l0ZSIsImF1ZCI6Imh0dHA6XC9cL2N0Zi53aW5qYS5zaXRlIiwicm9sZSI6ImFkbWluIiwiaWF0IjoxNjE1MDE0OTQ4LCJleHAiOjE2MTUwMTY3NDh9.Zsn6FXTUcHnRQ98d6PuYsJpLBuv7_FLOzx_8y8lu13c

I paste that cookie value into my browser and refresh the page to get this new message:

I just got the first half of the flag.

Combining the two I get the full flag value:

flag{justwinthis_all_i_w4nt_ar3_t0kens_$$$}

0x41414141 CTF: Misc: optimizer (400)

This is from the 0x41414141 CTF by pop_eax.

For this challenge, we are just given details for two server instances; one for US and one for EU.

Connecting via netcat, we are told that we will be given a number of problems and we have to solve them. It mentions that level 1 is tower of hanoi. A quick google search and I find more information about it. After some trial and error using different possibilities for the number of pegs.

This presentation was especially helpful in determining the formula (moves = 2n – 1) to get the number of moves: http://www.cs.uvm.edu/~rsnapp/teaching/cs32/lectures/hanoi.pdf

A manual check confirms the formula is correct, but the server responds with another problem.

There are four disks listed, so n=4. 24 – 1 = 15

We will need to automate this 🙂

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('45.134.3.200', 9660))

print('Server:', str(s.recv(1024)))
#print s.recv(1024)
while True:
    data = s.recv(1024).strip()
    if data:
	count = 0
        data = str(data)
        print(data)
        for i in data:
		if i == ',':
			count = count + 1
	count = count + 1
	n = pow(2, count) - 1
        if '[' in data:
		s.send(str(n))
        	print('Client: ', n)
s.close()

When I run this script, it iterates through quite a few problems, then the server reports that I’m in level 2: and have to give the number of inversions for the provided output.

A quick google search helps me figure out how to do this in python. https://www.geeksforgeeks.org/python-program-for-count-inversions-in-an-array-set-1-using-merge-sort/

I add some checks for the current level to help apply the appropriate process and then calculate the inversions:

import socket
import re

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('45.134.3.200', 9660))

def getInvCount(arr, n): 
  
    inv_count = 0
    for i in range(n): 
        for j in range(i + 1, n): 
            if (arr[i] > arr[j]): 
                inv_count += 1
  
    return inv_count 
level = 1
print('Server:', str(s.recv(1024)))
while True:
    data = s.recv(2048).strip()
    if data == '':
        break
    if data:
		if 'level 1' in data:
			level = 1
			print ('********************************** Level 1 **********************************')
		if 'level 2' in data:
			level = 2
			print ('********************************** Level 2 **********************************')

		if level == 1:
		
			count = 0
			data = str(data)
			print str(data)
			for i in data:
					if i == ',':
							count = count + 1
			count = count + 1
			n = pow(2, count) - 1
			if '[' in data:
				s.send(str(n))
				#print('Client: ', n)
	
		if level == 2:
			print str(data)
			
			if '[' in data:
			    sep = ']'
			    stripped = data.split(sep, 1)[0]
			    arr1 = stripped.split(', ')
			    arr1 = map(lambda each:each.strip("["), arr1)
			    arr = arr1
			    arr = [int(numeric_string) for numeric_string in arr1]
			    n = len(arr)
			    inversioncount = getInvCount(arr,n)
			    s.send(str(inversioncount))
s.close()

Here is a video of the script in action:

And the flag:

I really appreciate the challenge!

0x41414141 CTF: Register Secret PIN

This is from the 0x41414141 CTF.

When I went to register to compete in the 0x41414141 CTF I found that is was a little different from other CTFd based CTFs. Besides the normal registration information, it asks for a pin code (secret pin code for CTF registration).

Going back and looking through the site, I see on the About page that the secret pin code for CTF entry is hidden somewhere on the site:

After pouring through the source files for each page on the site, running curl POSTs, and looking at previous versions of the site on Archive.org, I considered the steganography approach.

Besides the normal social media link images, there are only two images on the site. One is the animated Offshift logo, which yielded no obvious results when running strings, binwalk, or other stego decoders:

The second image is a small Offshift logo that is used as the header logo:

After downloading this image, I ran strings on it to look for anything interesting:

Ahh! I see “secret: 100100100101” at the bottom of the results.

I convert the binary string to decimal:

echo "obase=10; ibase=2; 100100100101" | bc

Using the resulting decimal value as the pin, I am now able to register for the CTF.

0x41414141 CTF: Blockchain: sanity check (400)

This is from the 0x41414141 CTF.

This challenge is unique for a sanity check.

We are given a blockchain address for the Rinkeby network:

0x5CDd53b4dFe8AE92d73F40894C67c1a6da82032d

And a solidity script:

pragma solidity ^0.7.0;
//SPDX-License-Identifier: UNLICENSED

contract sanity_check {
    function welcome() public pure returns (string memory){
        return "flag{}";
    }
}

I googled the Rinkeby blockchain and found that I can look up addresses on the Etherscan.io site. Looking up the provided address gives me some information. Specifically under the “Contract” tab:

I see the handy “Decompile ByteCode” button, so I give it a shot:

This opens a new tab with more information about this tool and another button to execute it. This tool is based on the Panoramix decompiler and is designed to decompile smart contracts.

Running the tool gives me what I am looking for:

#
#  Panoramix v4 Oct 2019 
#  Decompiled source of rinkeby:0x5CDd53b4dFe8AE92d73F40894C67c1a6da82032d
# 
#  Let's make the world open source
#

const welcome = 'flag{1t_1s_jus7_th3_st@rt}'

#
#  Regular functions
#

def _fallback() payable: # default function
  revert

This was a very cool sanity check!