SEC660/GXPN In Review

TL;DR: Awesome course if you're ready to move past using other people's exploits. Pretty difficult but well worth it. Spend as much time as you can doing labs.

A few months ago I had the opportunity to take SANS's SEC660: Advanced Penetration Testing, Exploit Writing, and Ethical Hacking course. I had taken SEC560 in late 2014 with Ed Skoudis and figured this would be the follow-on course that builds on when was discussed (boy was I wrong!).

This class is really intense. I'd definitely recommend it to seasoned testers, anyone who is interested in vulnerability/exploit research and bug hunting, or general offsec masochists. SEC660 is NOT a prep course for the GXPN, but rather the intro to the material. You work through the books and exercises with the instructor(s) (Stephen Sims and Jim Shewmaker in my case) in class, but afterwards you'll be rereading the books, reading the additional resources, practicing writing exploits, and banging your head against the keyboard.

Course Structure

Day 1 - Intro & Network Attacks

The first day of the course kicked off with a very short intro and then dove right into the material. A few of the key things discussed are bypassing NACs, manipulating routing protocols (especially Cisco stuff), and some stuff to do once you've got your MitM. This day is also deceptively easy. Make sure to do the labs for days 1 and 2 as much as possible because they will not be available unless you bought an OnDemand package.

Day 2 - Crypto, PXE Attacks, & Escaping Restricted Environments

Day 2 starts picking up the difficulty. Topics covered are attacking crypto implementations (hash length extension, oracle padding, IV reuse, etc.), network booting attacks, and escaping restricted environments (SRPs and GPO restrictions). There was also a small section on PowerShell, but it wasn't really in-depth and didn't play a large part in the exam.

Day 3 - Python, Scapy, and Fuzzing

The third day starts off just going over the basics of Python syntax. If you've worked with Python for any amount of time, this should be super easy. It is then followed up with some Scapy info. Again, nothing too difficult but a good refresher. The rest of the day is filled with fuzzing, most of which was focused on using Sulley. I really enjoyed this day and thought it fed into the final 2 days very well.

Day 4 - Exploiting Linux

Here's where things start to get fun. 9AM rolls around and we're immediately dumped into the guts of Linux memory and x86 assembly. Once we were done with that part (and got a much needed break), it was back to it with stack overflows and ret2libc. Stephen did an awesome jobs of breaking everything down and keeping us engaged so we didn't get lost. We worked through different difficulties starting from very basic to modern Linux protections. Thankfully there were plenty of exercises to go along with the lectures. If you're not paying 100% attention it is really easy to miss something important and the labs make sure you fully grasp the attack.

Day 5 - Exploiting Windows

Day 5 is by far the most difficult. It is very similar in structure to day 4, starting with understanding the OS's controls and history, but the exploitation techniques are pretty different. Stack overflows and SEH overwrites were the focus for the first half of the day, followed with ROP and writing Windows shellcode. By the end the room looked like a horde of zombies.

Day 6 - CTF

We all staggered back into the classroom for the final day. The class was broken up into team of 4-5, briefed on rules for the game, and then we were set off. The CTF was Jeopardy style, similar to CSAW or Pico, and well put together. There were a group of ninjas in the course who teamed up and smoked the rest of us, but it was a good learning experience and I got to work with some really smart people. As soon as we were done, I packed up, headed home, and slept for like 18 hours.


After the course wrapped up, there was a 2-week block for the exam to become available. Once it is available, there was 3 months to take it. I took nearly that whole block to prep for the test, going back and reading the material, doing the labs, and rewriting old exploits from exploit-db.

I took the first practice test 1 month out with no books, and the second once 2 months out using the books and my index. I passed both of them, but used the questions that I missed to make flash cards and improve my index. By test day I was as ready as I could be.

And important tactic for me during the test was to slow down. They give you 3 hours for 75 questions so you can spend 2:24 on each one. That gave me enough time to go back and read more on answers I wasn't totally sure about. I also used the "Skip Question" button on the hardest 5 questions for me and answered them at the end where I could use pretty much as much time as I wanted.

Overall, the exam was very difficult. There are no trick questions, but you really have to know the material inside and out. Most of the questions are not answers you can find in the books, but rather rely on experience with the material itself.

The Index

As with all GIAC exams, they are open book but you have to write your own index if you want to efficiently reference them. I did mine in the same format as with the GPEN, but this one was much longer.

Term Book Page Notes
ZwSetInformationProcess() 5 136 Used in disabling DEP


SEC660 and the GXPN were definitely worth the stress. I learned a ton of stuff, met some great people, and found a few areas of research I'd like to dig deeper into.

Next up for me is the OSCP, but I may wait and do it with some junior testers to help them along the way.

Thanks to SANS, Stephen Sims, Jim Shewmaker, and Josh Wright for an awesome course.

penteesy - A USB HID for Penetration Testing

A few weeks ago, I was working on planning a test that would (hopefully) give me physical access to a target facility. While inside, I wanted to get access to a few specific users' systems but didn't have a quick and reliable way to do so. I figured I only had a minute or two to get access when the users leave their desk and forget to lock their screen.

After doing a little bit of digging, it looked like a Teensy acting as a HID/keyboard was my best bet. Thankfully, a decent amount of research had already been done in this area (see links at the bottom) so all I had to do was modify it to fit my needs.

While there is some good information out there, I still wanted to share how I made mine to hopefully fill in any gaps.

I've published the code on my Github at


I started off by grabbing a Teensy 3.2 from PJRC and a few 8-pin DIP switches from Amazon. The only issue I ran into here was that the switch needs pins 9-12 and a shared ground, so I had to bend the pins and solder them together. I'm no soldering genius, but here's what I ended up with.

Soldered DIP switch

Everything else was fairly straight forward - just solder the switch on and we're up and running.

Completed penteensy with switch attached


There were only a few steps to push the sketch to the Teensy. First, I had to install the Teensy Loader from PJRC. Then came the Arduino IDE followed by Teensyduino.

Once all 3 were installed, the process becomes pretty simple - open the sketch, verify it, then upload it to the Teensy.

Steps to verify and upload sketch to the Teensy

The Code

Now came the interesting part. Offsec, Kautilya, and Sift Security had awesome examples of what was possible, but I found that some parts of them were a little lengthy or didn't totally fit my needs. Rather than reinventing the wheel, I ended up using bits and pieces of each of them to build what I needed.


This section contains some variables that need to be changed by the user before pushing the sketch to the Teensy, followed by a few lines of setup code. The variables that need to be changed include:

  • remote_ip - IP for netcat shells to call back to
  • remote_nc_port - TCP port netcat should call out on
  • remote_url - URL used to deliver files to the system from (not in use yet)
  • msf_web_delivery - URL provided by MSF (exploit/multi/script/web_delivery) for the Powershell shell
  • msf_python_handler - String generated by MSF (payload/python/meterpreter/reverse_tcp) using "generate -t raw). I plan on finding a better way to do this, by using the necessary while loop in a one liner isn't working.

Common Functions

These are just a few functions used regardless of operating system. Things like controlling the LED blink rate and clearing keys live here.

OS-Specific Functions

This section is broken down into *nix and Windows functions. They needed to be split up due to different key mappings, shortcuts, files, and commands. The functions here do most of the heavy lifting and act as the individual actions in the larger function assigned to each switch.


In here are the "main" functions - the netcat, Powershell, and Python commands as well as the functionality test.

  • Netcat - Minimizes all open windows, opens Spotlight followed by Terminal, opens a new Terminal window just in case another was already open and running something, changes directories to /tmp/, then types out the command to open a named pipe using a file named "f."
  • Powershell - Minimizes all open windows, opens the Start menu, runs cmd.exe, types out the string used by exploit/multi/script/web_delivery to connect back to Metasploit and get a shell, then restores all previously minimized windows.
  • Python - Operates very similar to the Netcat function, but instead of a named pipe it types out a Python one-liner with a base64-encoded string to call back to the MSF handler.
  • Test - I kept this in here just for checking that the device still works. It is likely to take a beating and just needed a simple way to make sure it's still alive. This can easily be ported to Windows/Linux, but I use a Mac 90% of the time.

In the field

So far I've had good luck with this method of gaining access. Often times I find people walking away for "just a minute" and not locking their computers which gives me a great opportunity to plug in and get away before they're back.

Run times are consistently pretty quick, even with necessary delays.

  • Netcat - 7 seconds
  • Powershell - 31 seconds (waits for driver initialization)
  • Python - 10 seconds

I am working on getting these times down even further.

Fixing the problem

As I mentioned, people who think they are just stepping away for a second and don't lock their workstation are the easiest way to get this to work.

Whenever a user steps away from their computer, they should lock their screen. Also, once the screensaver starts (especially for Mac users using hot corners), the screen should lock automatically.

More Reading

Huge thanks to everyone who had done this before me and shared their notes. The following resources were particularly useful:

Fun With Teensy - Sift Security
Advanced Teensy Penetration Testing Payloads - Offensive Security
Kautilya - Nikhil Mittal
PHUKD: Using the Teensy as a pen testing device - Adrian Crenshaw

Fixing the Burp Suite "handshake alert: unrecognized_name" Error

During testing this past week, I ran into an error in Burp I hadn't seen before.

After some Googling, many people were saying that it appears to be an issue in the way that SSL is implemented in Java 7. I tried with the most recent Java 8 Update 51 on the most recent release of Burp Pro and the issue persists.

The only workaround I've found that works is the following:

java -Djsse.enableSNIExtension=false -jar burpsuite_pro_v1.X.jar

This will disable the Server Name Indication (SNI) extension and allow Java to ignore the "Unrecognized Name" error which is what's causing Burp issues.

More info on StackOverflow

Advanced Email Phishing Tactics, Revisited

Advanced Email Phishing Tactics, Revisited

I love phishing. It's so satisfying spending weeks planning a campaign, crafting emails, identifying targets, figuring out how to bypass roadblocks, and getting that first click to know it all worked.

But what happens when you have a really small amount of time and an even smaller budget?

This is the exact situation I ran into. Scrambling to come up with a way to phish users, measure responses, and identify unique clicks all with a budget of $0.00, I started Googling. Eventually I stumbled across this ruby script from Brandon McCann (@zeknox). He uses a GoDaddy-hosted address he controls to send email from. Each email has a link with the target's email address base64-encoded and appended to the end for them to click. He would then be able to simply read through the access logs on the site the link points to, decode the base64-encoded strings, and find out what user clicked even if they're behind NAT.

Sounds great, right? I thought so too. There was one issue though. As I mentioned, my budget was nonexistent. I didn't have the ability to buy a domain from GoDaddy and get their "free" email, so I turned to webmail providers. Each time I configured the script to use Gmail or, it would fail. After an hour of scratching my head as to why, it turns out that Ruby doesn't support STARTTLS, which both of the above providers need. Crap.

Rather than giving up, however, I figured that I could rewrite the script using Python's smtplib module which I knew supported STARTTLS. Long story short, I released a reworked version of sendmail.rb that supports using free webmail providers like Gmail, Yahoo, or You can find that tool here:

How it works

The concept is very similar to the sendmail.rb script, except that it takes in a HTML message template with a set variable for the unique link as an argument, builds out a properly formatted MIME message, and establishes a TLS connection with the webmail host.

There are 3 variables that need to be changed in the script before using:

  • host - The SMTP server for your mail host.
  • port - Port the mail host uses. If for some reason 587 doesn't work, try 465.
  • subject - The subject of the message to send.

The HTML-formatted message can contain whatever you'd like, but it must contain a string of $IDENTIFIER$ at the end of the URL so it knows where to put the base64-encoded email address. Here's an example for reference:

<b>This message is from your Email Administrator.</b> Your email has exceeded \  
storage limit and it is slowing down the web server.  
At this moment you cannot receive further email. For more space activate your \  
account by <a href=$IDENTIFIER$>Clicking Here</a> and \  
complete information requested. Activation for more space will commence immediately. \  
Failure to follow the above instructions will render your account inactive.  
Mail Help Desk.  

Using the script is pretty straightforward to run. Use the -t arg to specify the file containing the addresses to send to and -m for the message template file.

[email protected]:/tools# cat emails.txt  
[email protected]  
[email protected]  
[email protected]:/tools# ./  
Usage: -m <message file> -t <recipient file>

  -h, --help            show this help message and exit
                        File with the body of the message you want to send.
                        File with a list of emails you want to send the
                        message to.
[email protected]:/tools# ./ -t emails.txt -m message.html  
Please provide the username: [email protected]  
Please provide the password for [email protected]:  
[+] Successfully sent email to [email protected]
[+] Successfully sent email to [email protected]
[email protected]:/tools#  

Make sure to check out Brandon's article and the rest of the PentestGeek site here.

Bypassing XSS Filters Using Data URIs

One of the web app testers on a team I work with shared a technique for bypassing XSS filters that I hadn’t used (although admittedly I don’t get much hands-on time with web apps anymore) – using data uniform resource identifiers (URIs). Data URIs are defined by RFC 2397 and can be used to embed file in an HTML document without referencing a file stored on the server.

The way this works is by allowing the data to be self-contained within the URI and if a valid MIME type is specified, the data will be rendered. If a MIME type is not specified, it will default to text/plain which would be okay for textualized data, however to embed binary data one would need to specify base64 in the string. The syntax is as follows:

<img src="data:[MIMEtype];base64,[DATA]">  

So to embed this PNG

using the method shown, the string would be

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADcAAAA3CAAAAACNsI2aAAAACXBIWXMAAAB5AAAAeQBPsriEAAAB6ElEQVR42rVWO46EMAzNadAcY3vaOQMXoXcXKZehS8NpqNxamw8JxDYra1Zjhgge9jhx/By7bYvtl4Y8Qn+tEjty6WxuQ0KkfOM5wJEeEkT1bsigU+xGQV+QfZ2ned0LAkLnyQ4XV2XB/k+jXdTs8Mc1+UlvQehEt5Fit7hLFsUfqfOk3d1lJ9VO+qN1sFvJm+IScB7s3uo8ZVzC8RrsXjIuqp2n0d+sxFNbHxCw9cF34yn2L5jyJWndIprzRfqLpvw0+6PCh1fjgxpP5NL4VzlYEa6zOYDgzyvk0cMbykMek6THipSXAD5/BKh8H/3JGZTxPgM9Px9WDL0CkM1ORJie48nsWAXQ8kW1YxlknKfIWJs/EBXgoZ6Jf2KMNMYz4FgBJjTGkxR/H67vm/H8eP9ShlyRqfli24c0svy0zLNXgOkNtQJEle/P/MPOv8T3TGZIZIbO7sL7BMON74nkuQqUj4XvnMvwiNCBjO+yev2NVDtZLeX5rvD9lu0zauxW+a6dBvJ8H5Gyfzz3wIBkO57rYECyHeeWF+xW+YcT47Jkdzi4TpT+lPNdIv9Z34fxNOxf0PhO91yw5MuMen56AxLPOtG7W9T63SCQ2k9Uol1so3bVnrog2JTyU57n1bb37n3s5s8Of5RfsaTdSlfuyUAAAAA8dEVYdGNvbW1lbnQAIEltYWdlIGdlbmVyYXRlZCBieSBHTlUgR2hvc3RzY3JpcHQgKGRldmljZT1wbm1yYXcpCvqLFvMAAABKdEVYdHNpZ25hdHVyZQA4NWUxYWU0YTJmYmE3OGVlZDRmZDhmMGFjZjIzNzYwOWU4NGY1NDk2Y2RlMjBiNWQ3NmM5Y2JjMjk4YzRhZWJjJecJ2gAAAABJRU5ErkJggg==">  

Taking advantage of this feature, an attacker can inject their XSS code into the page. In the case of a system that blocks specific strings like “script” or symbols like parentheses, this method can be used to disguise the payload and evade the protections. An example of this using the default <script>alert("XSS");</script> payload would be:

<object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgiWFNTIik7PC9zY3JpcHQ+Cg==">  

HTML tags that are able to carry these payloads are IFRAME, Object, Anchor, and Image.

There are some limitations to this technique though. Most modern browsers support the use of data URIs, however Internet Explorer <8 does not. IE8 now has support for URIs but only with CSS. Using CSS is not much more difficult than with HTML. Using the image provided above for example, a CSS version would be:

li {  
    left center;
  padding: 5px 0 5px 25px;