Golden Tickets and External SIDs – Spread the Compromise

Note: Be sure to check out Sean Metcalf’s (@Pyrotek3) post about this technique available here!  He talked about this at BlackHat USA 2015!

Benjamin Delpy (@gentilkiwi) recently tweeted about adding External SIDs into Mimikatz’s golden tickets which was quickly followed up by Skip Duckwall (@Passingthehash) also tweeting how devastating this addition can be to defenders.  Skip said it best by saying, “Pwning the child can (with default settings) compromise the parent”.  This capability has a fairly significant impact for both attackers and defenders.  If as an attacker I can just target the weakest child domain and leverage that access to compromise the parent domain, my attack path just potentially became significantly easier.  As a defender, I now know that if any child domain is compromised, then the integrity of the forest as a whole is now in jeopardy.

This was something that I really wanted to test myself, so I did just that.  I set up a parent (sonofflynnlab.com) and child (child.sonofflynnlab.com) domain in my home lab with workstations in each respective domain.  I used the default settings when creating the child domain within the parent domain.  There’s a total of four normal user accounts:

  • test1 and test2 – Members of the parent domain’s (SONOFFLYNNLAB) Domain Users group
  • testc1 and testc2 – Members of the child domain’s (CHILD.SONOFFLYNNLAB) Domain Users group

Once both domains were created and populated with user and computer accounts, I wanted to test the relationship between the two domains.  One of the easiest ways to do this is to use Veil-Powerview, which is part of the Veil-Framework’s Powertools and developed by Will Schroeder (@harmj0y).  I ran Invoke-MapDomainTrusts to view the relationship between the two domains and received the following output:

3 - domaintrustsAs you can see, there’s a bidirectional trust between the child and parent domain.  Now that it looks like I have everything setup the way I would like it to be, it’s time to test creating a golden ticket with an external SID.  To give some context to how I am testing this scenario, I will be running all commands from a workstation within the child domain and will be logged into the workstation in the context of a user within the child domain.

The first step I will perform is to download Mimikatz onto this workstation and purge all kerberos tickets.

1 - mimikatz krb purgeNow that all tickets have been purged, let’s verify that I cannot access either the child domain’s domain controller’s C$ share, or the parent domain’s domain controller’s C$ share.

2 - cantaccessNext, lets build the golden ticket with the external/parent SID information.  The golden ticket is built with all the same information as a normal golden ticket with the addition of the external SID via the /sids flag.  At this point, I’m going to assume that you have already obtained the krbtgt hash, and domain sid of the child domain.  If you need help finding this information, review this post.  However, the new piece of information that we will need to grab is the SID of the parent domain, and the RID of the group we want to “add” the user to.  One way to obtain this is to utilize PowerView.  I can use the Get-NetLocalGroup command to find the SID of the domain with the following command (since my machine can currently hit the parent domain’s DC):

parentsid

Once I’ve obtained all the information I need, it’s time to create the golden ticket.

pttchild In this case, you can see I am referencing the 519 group which is the Enterprise Admins group within the external SID.  If you are looking to change the group you wish to “add” yourself into, some default group values are available here. I’m also using /ptt to immediately submit the ticket.

Now that my ticket has been submitted, it’s time to open a command prompt with the submitted ticket applied to it.

4 - getshellLet’s test our access!

5 - accesstoprimarydcSweet!  My normal domain user account within the child domain now has access to not only the child domain’s domain controller’s C$ share, but I can also access the C$ share on the parent domain’s domain controller since I am essentially running in the context of an Enterprise Admin!

At this point, I can leverage any number of techniques to move into the parent domain.  Needless to say, this is something that I will look for on future assessments.

 

 

 

 

 

Egress-Assess in Action via Powershell

For a week or two now, rvrsh3ll (@424f424f) has been working on creating a powershell client for Egress-Assess that would allow Windows users to simply load the script in memory and use it to test egress filters.  As of yesterday evening, his script has been merged into Egress-Assess, and is now available in the Github repository.

@424f424f went one further and wanted to send some screenshots to demo any potential detections when sending data outside of his network.  But first, let’s demo the powershell script.

Loading up the powershell script is easy, and doesn’t require any file to be placed on disk.  To do this, the Windows machine will need to have internet access.  Start powershell on the Windows machine you want to run Egress-Assess from, and use the following command to load it into memory:

IEX (New-Object Net.Webclient).DownloadString(‘https://raw.githubusercontent.com/ChrisTruncer/Egress-Assess/master/Invoke-EgressAssess.ps1‘)

In-Memory Download EA

Now the powershell script is in memory and ready for use!  Usage is near identical with the python client.  To send data over http to another system running Egress-Assess you can use the following command:

Invoke-EgressAssess -client https -datatype cc -Verbose -ip 192.168.63.149

EA Powershell https

Server side, we can see that the data is received.

Server received powershell http

@424f424f has a Snorby instance in use and ran Egress-Assess through it.  The following were some of the alerts that were generated (you want to hope that similar results are generated for your clients!).

Snorby credit cards Snorby social security

If anyone has any questions on the usage, be sure to hit me up.  Otherwise, a big thanks again to Rvrsh3ll (@424f424f) for sending this awesome addition.

Egress-Assess – Testing your Egress Data Detection Capabilities

Github Link: https://github.com/ChrisTruncer/Egress-Assess

On a variety of occasions, our team will attempt to extract data from the network we are operating in and move it to another location for offline analysis.  Ideally, the customer that is being assessed will detect the data being extracted from their network and take preventive measures to stop further data loss.

When looking to copy data off of our target network, an attacker can do so over a variety of channels:

  • Download data through Cobalt Strike’s Beacon (over http or dns)
  • Download data through a Meterpreter Session
  • Manually moving data over FTP, SFTP, etc.

While we routinely inspect and analyze data from the customer environment in order to aid in lateral movement, we also provide customers data exfiltration testing as a service. Performing a data exfiltration exercise can be a valuable service to a customer who wants to validate if their egress detection capabilities can identify potentially sensitive data leaving their network.

I wanted to come up with an easy to use solution that would simulate the extraction of sensitive data from my machine to another.  While trying to plan out a tool, I targeted a few protocols commonly used by attackers:  FTP, HTTP, and HTTPS.  To ensure that I could generate “sensitive” data that would be discovered during defensive operations, I needed to identify what multiple organizations would highly value. Two different sensitive data types that would likely have signatures across organizations are social security numbers and credit card numbers and I decided to target those forms of data in my proof of concept.

After spending a couple days piecing bits of code together, I am happy to release Egress-Assess.

Updated EgressAssess Help Menu

Egress-Assess can act as both the client and the server for the protocol you wish to simulate.  It supports exfiltration testing over HTTP, HTTPS, and FTP.  I envision the tool being used on an internal client and an external server where data would be passed over network boundaries. Once cloned from the repository, the dummy data can be transferred from one machine to another. 

To extract data over FTP, you would first start Egress-Assess’s FTP server by placing it in server mode with the ftp and providing a username and password to use:

./Egress-Assess.py --server ftp --username testuser --password pass123

FTP Server Setup EA

Running that command should start something similar to the following:

FTP Server

This shows that the FTP server is up and running.  With this going, all we need to do now is configure the client to connect to the server!  This is simple, can can be done by telling Egress-Assess to act in client mode and use ftp, provide the username and password to use, the ip to connect to, and the datatype to transmit (in this case, social security numbers).  Your output should look similar to the following…

./Egress-Assess.py --client ftp --username test --password pass --datatype ssn --ip 192.168.63.149

ftpclientupdated

Within the same directory as Egress-Assess, a “data” directory will be created.  Within it is where all transmitted files will be stored.  At this point, the transfer is complete via FTP!

You can also do the same over HTTP or HTTPS.  Again, the first step will be starting one instance to act as the server in http mode.

./Egress-Assess.py --server http

HTTP Server Startup

This will now start a web server to listen on port 80.  The next step is to have your client generate new dummy data, and send it to the web server.  Only this time, we’ll change it up by specifying the approximate amount of data we want to generate.

By default, Egress-Assess will generate approximately 1 megabyte of data (either social security numbers or credit card numbers).  This amount can be changed using the “–data-size” flag.  If we want to send approximately 15 megabytes of credit card data to our web server over http, the command may look as follows…

./Egress-Assess.py --client http --data-size 15 --ip 192.168.63.149 --datatype cc

HTTP Client setup

http data sent

As you can see above, the file was transferred, and our web server received the file!

That about rounds out the current state of Egress-Assess.  Future revisions will include making a more modularized tool so users can easily add support for new protocols, and new data types for transfer.  If there are any other requests, I’d love to hear them!

EyeWitness Now in Ruby!

The best way that I learn languages, is to give myself a task, and force myself to write a script/program that carries out that task.  Well, in this case, I’ve been wanting to change some aspects of EyeWitness, and decided that porting EyeWitness to Ruby would be a great way to make those changes, and learn a new language.  After @harmjoy suggested that I look into learning Ruby, I decided to dive in and get it done.  Now, about two months of working on it, I’m happy to say the EyeWitness Ruby port is ready for its initial release.

To view and download EyeWitness, head to my Github account, or click here!

I will continue to keep the Python version of EyeWitness available, as there are a few differences between the two versions of EyeWitness.  These differences are:

  • Screenshot Library – By adding an additional library for capturing screenshots, the user can switch between the two in the event that one library encounters an issue when capturing select websites.
    • The Python version of EyeWitness uses Ghost to take screenshots of websites.  One of the benefits of this is that it can run headlessly.  However, I have seen an issue when given 3000+ websites, Ghost can freeze.  Also, Robin Wood (@digininja) pointed out that EyeWitness can completely crash while screenshotting websites.  This looks to be due to a potential file descriptor leak within Ghost.  Even though I rarely hit these issues, I still wanted a solution/alternative.  An alternative has been implemented in the Ruby version.
    • The Ruby version uses Selenium for capturing screenshots.  Specifically, Selenium-Webdriver will start up an instance of your web browser (default firefox),  and use the web browser to navigate and screenshot web pages.  For this first release, the ruby version is ONLY supporting Firefox (or a fork like Ice Weasel).  Future releases will support other browsers, such as Chrome.
  • User Agent Switching
    • The Ruby version of EyeWitness does not currently have the ability to dynamically switch user agents for every URL and perform the same comparison checks that the Python version can carry out.  This is because EyeWitness would have to instantiate a new selenium-webdriver object for every user agent, and that takes place in the form of a new web browser opening up.  I believe it would be more of a hassle/distraction to have a large number of web browsers open, so I have not implemented it in the Ruby version.  However, if this is needed, you can still use the user agent switching functionality within the Python version.
  • File Input
    • The Ruby version of Eyewitness requires you to specify the file type you are using as input.  If using Nmap XML output for EyeWitness, you will have to use the –nmap flag, for nessus, the –nessus flag.
  • Skip Sorting
    • The Ruby version has a –skip-sort flag.  This will tell EyeWitness not to group similar pages together, and just write out the report as it goes, vs. writing the report at the end after sorting all pages.

These seem to be the major differences within the two versions for the time being.  I personally believe the Ruby implementation of EyeWitness will be better to use for assessments.  If you encounter any issues, please be sure to report them to me!

Thanks!

EyeWitness Usage Guide

NOTE: This post is now out of date – check this for the latest info – https://www.christophertruncer.com/eyewitness-2-0-release-and-user-guide/

I originally released EyeWitness in February in what I thought was pretty functional state.  When released, EyeWitness came in at about 400 lines of code.  Since February, it has had multiple new features added to it (which I will go over in this post), and its code base has expanded to about 1600 lines of code. I’d like this post to act as a usage guide of all normal usage scenarios that I can think of.

I’ll start off by describing how I normally use EyeWitness.  I typically call EyeWitness, provide it a text file (with each URL on a new line), and let it run.  If I have a .nessus file or nmap.xml output, and it has more than 350 URLs, I’ll run EyeWitness with the –createtargets flag (explained below), and output all the targets to a single text file.  I typically then split that file up into roughly 300 URLs per text file, and then either script up EyeWitness to run one after another, or run scans simultaneously.  However, different situations might cause EyeWitness to need to be used in a different manner, so hopefully this EyeWitness usage guide can help explain all of its features.

Python:

The bare bones, and likely most common, use of EyeWitness is to provide a single URL, or multiple URLs within a file for EyeWitness to screenshot and generate a report.  To provide a single URL, just use the –single flag as follows:
Single URL Scan

EyeWitness also accepts files for providing the URLs.  The file can be provided in the following formats:

  • Single text file with a URL on each line
  • Nmap XML output
  • .Nessus file
  • amap file output
To perform a scan, using any of these filetypes, just provide the -f flag as follows:
File Input Scan

By default, EyeWitness will attempt to screenshot the website, and have a max timeout of 7 seconds.  If it takes longer than 7 seconds to render the website, EyeWitness will skip to the next URL.  If you wish to change the timeout of EyeWitness, use the -t flag and set it to the max number of seconds you want it to wait to render a website. Set Timeout

Once EyeWitness has finished navigating to all URLs, and has generated a report, EyeWitness outputs the report to the same directory EyeWitness is in, and names it based off of the date and time the scan ran.  If you want to change the directory name that EyeWitness outputs its report to, use the -d flag and provide the name.  When using the -d flag, you can provide just a name, and EyeWitness will create the report using the provided name within the same directory as EyeWitness.  You can also provide the full path to a directory, and EyeWitness will create the report folder at that location (just make sure you have the proper write permissions).

Directory name change Full Path report

Sorted reporting was a feature brought up to me by Jason Frank (@jasonjfrank) as something that would be helpful when reviewing the EyeWitness report.  If we had a way to make EyeWitness analyze the different web applications, and group similar web apps together, then it would be easy to quickly sort through/review the groups you want to target.  We envisioned similar printers, mirrored web pages, etc. all grouped together within the report.  Lucky for us, Rohan Vazarkar (@cptjesus) worked on adding this feature in.  His pull request was merged in on April 22nd, and EyeWitness will now attempt to sort all results based off of their title within each report generated.

The –localscan option was added based on a request from David McGuire (@davidpmcguire).  We wanted a way to perform some basic port scanning for web servers once a machine has been compromised. Currently, one way to do it is to drop Nmap on the compromised machine, but if we did that, we’d have to install winpcap on the machine, which requires admin rights.  Instead of this, you can drop the windows Eyewitness binary, and provide the –localscan option with a CIDR range to scan.  EyeWitness will then try to find any ip listening on 80, 443, 8080, and 8443 within the provided range.  All live hosts listening on any of those ports will be added to a file that can be fed back into EyeWitness.

Localscan Portscanning

The –createtargets option came about when I wanted to have EyeWitness just provide me a list of all web servers from the XML output of Nmap or Nessus.  All web servers that EyeWitness finds within Nmap’s xml output, or the nessus file will be added to a file containing the target servers.  Just provide the filename you want the your targets file to be called.

createtargets

The user agent definition and cycling came about from working with Micah Hoffman (@webbreacher), Robin Wood (@digininja), and Chris John Riley (@ChrisJohnRiley).  After a lot of discussion on how best to carry out user agent switching and comparison, the feature was added in.  First, you can simply provide the –useragent option, and it will use any string you provide as the user agent.

Single User Agent

You can also use the –cycle option along with either browser, mobile, crawler, scanner, misc, or all.  When using this option, EyeWitness makes a baseline request.  It will then make subsequent requests with user agents of the “type” you specified.  If the subsequent requests deviate “too much” from the baseline request, the subsequent request will be added in to the report letting you know it was different from the baseline.  The deviation is currently based on the length of the source code the web server provides to EyeWitness.  By default, the deviation that’s used to measure if the requests are different is set to 50.  To change this value, use the –difference flag and provide the new value to use.

Uacycle Cycling Set Difference Value

Finally, the –jitter option was one that was discussed about at a NovaHackers meeting, and also requested by @ruddawg26.  To use this option, provide all the scan parameters you would normally provide, but add on the –jitter parameter at the end, and provide the base number of seconds that it deviates from.  Now, EyeWitness will randomize the order of the URLs provided (via text or XML), and will also have a random delay between each request.

Jitter command Jitter scan

Finally, EyeWitness has a –open flag.  If you provide the –open flag, each URL passed into EyeWitness will also be opened up in a web browser.  Your command string might look similar to the following:

Open option

Ruby:

EyeWitnessRubyHelp

To generate a report for a single website, you need to use the -s or –single flag and provide the URL.

For file based input, you will need to specify the filetype that you are providing.  If giving just a normal text file with each URL on a new line, use the -f or –filename switch.  If using providing Nmap XML output, you’ll need to use the –nmap flag, and .nessus based input requires the –nessus flag.

The –skip-sort flag is used to tell EyeWitness to not auto-group similar web pages together in the report.  This can be helpful if you want to see report pages as they are available, instead of waiting until the very end.  However, if this flag is used, similar pages will not be grouped together.

The –no-dns flag is used when you want EyeWitness to find web servers via their IP address, not their DNS name, while parsing Nmap XML output.

This pretty much covers the features of EyeWitness.  If anyone has any questions, don’t hesitate to get in touch with me.  Also, please be sure to send any signatures you might have made!

ShodanSearch.py for Command Line Searches

By now, everyone should know what Shodan is, and how to use it.  It’s been out for a couple of years, has had multiple presentations on it, and its capabilities have been added to at least a few tools out there (I believe) when used for reconnaissance.  Shodan indexes a large amount of data, which is really helpful when searching for specific devices which happen to be connected to the internet.

In my case, I wanted to start adding signatures of different devices to EyeWitness, but I needed something that could quickly find the devices I wanted to write a signature for.  Quite obviously, Shodan was my answer.  Something else that I wanted to do, was to stage multiple searches for different devices on Shodan.  However, if I were to do this via the web interface, I would either have to perform a search, and then perform the new search, or manage a large number of tabs.  I figured it would be easier to write a quick script that utilizes Shodan’s API (grab an API key here), as it would give me flexibility to script up a large number of search for review later on.  This spawned in a quick script to search Shodan, fittingly called, ShodanSearch.

ShodanSearch

The simplest way to use this script is to call it with the -search option, and provide a string to search for.  This is just like searching for a string on the website.  So you could perform that search by typing something similar to the following:

./ShodanSearch.py -search Apache

And see something similar to this:

String Search

Another feature that can be useful, is to search Shodan by IP.  This will return everything Shodan has indexed about the services available on the provided IP.  There’s three different ways to do this within ShodanSearch, you can either use the -ip, -cidr, or -f options.  The -ip option will perform a Shodan search for a single IP address, the -cidr option will perform a search on Shodan for every ip within the provided CIDR network range, and the -f option will take a file that contains IPs, and search for all results on those IP addresses.  Your searches could look similar to the following:

IP Search

These last few search options have been helpful when my team is on assessments, and we just want to script up a way to see what’s been publicly indexed about our targets.  Most of the time, it’s purely informational documents, but it’s something that has been valuable to our customers, so we provide it to them.

The only thing you’ll need to do to get up and running, is to add your Shodan API key in the script.  After that, you should be good to go!  Hope this helps, feel free to get in touch with me for any questions you may have.

DNS Modification with DNSInject for Nessus Plugin 35372

Part of our normal pen test process, when performing an external assessment, is running a Nessus scan against the in-scope IP range(s) provided by our customer.  We usually have this running in the background while carrying out our own analysis against the IP ranges.  On a past assessment, we started with this same process.  After some time went by, I checked our scan results that we had so far, and found an interesting vulnerability listed.  Specifically, Nessus plugin 35372:

Nessus Plugin Info

Looking at the finding details, Nessus also provided the DNS zone that is vulnerable to modification.  However, one thing that I didn’t see was an existing tool that allowed me to perform the record injection attack (see note below).  I have only seen a finding similar to this on an internal assessment, and in that case I used dnsfun.  However, I wasn’t sure dnsfun would work in this case, and I wanted to learn how to write a script that would perform this attack myself, so I decided to do just that.

I started off by checking out RFC 2136, and learned that I’m going to need to specify the zone that I want to modify (add/remove) a record for and the resource record itself that will be modified, while being sure to set the DNS packet’s opcode to 5 (Update).  This is something that could be easily done with scapy.

Scapy Packet Definition

The great thing about scapy, is you can define any specific packet attribute values that you wish (ttl, record type, etc.), and the attributes that aren’t specified are automatically populated by scapy with their proper values.  The above code states that I want to send a packet to a specific destination, it’s a DNS UDP packet, with the opcode set to 5 (update), and the DNS specific information is set by the command line options provided by the user.  And… that’s it!

I wrapped this up into a script that lets you either add or delete A records on a vulnerable name server pretty easily.  It’s called, simply, DNSInject.

DNSInject Options

To add a record with DNSInject.py, just specify the add action, provide the vulnerable name server, the A record you wish to create, and the IP it will point to.  Your command should look similar to the following:

./DNSInject.py --add -ns 192.168.23.1 -d thisisa.test.local -ip 192.168.23.5

Injection

To delete a record, you only need to provide the vulnerable name server, and the record to delete.  Again, your command could look similar to the following:

./DNSInject.py --delete -ns 192.168.23.1 -d thisisa.test.local

Deletion

To get and use DNSInject, just clone the following github repo – https://github.com/ChrisTruncer/PenTestScripts

Hope this helps, and if you have any questions, feel free to ask!

 

Note: Of course, after completing writing this script, I discovered two other options which can help carry out this attack, so I wanted to be sure to mention them.  Scapy has a built in function to both add and delete records, and you could also use nsupdate. Definitely be sure to check out those options as well!

EyeWitness – A Rapid Web Application Triage Tool

More than half of the assessments that myself, and our team, go on include web applications.  Even on network level assessments, as we identify live machines within a target network, it’s fairly common for us to find a large number of web applications.  These web apps can be their own application for the customer’s purpose, or web front ends for various appliances (switches, VOIP phones, etc.).  I needed a way to be able to quickly get a quick look of all the devices serving up a web page, which would allow me to try to figure out the websites to prioritize.  Tim Tomes developed an awesome tool called PeepingTom which does what I needed.  It works great, and I recommend everyone check it out.

However, PeepingTom requires PhantomJS, and needs to be downloaded separately.  I’ve had a couple issues where it fails to grab a screenshot of the web application, and it intrigued me.  I started researching different ways to take screenshots with a python script, and stumbled upon Ghost.py.  Ghost is a self described “webkit based scriptable web browser for python”, and is able to very easily screenshot web pages.  At this point, I thought it would be a fun task to try to create my own tool which captures screenshots and generates a report as a thought exercise, and the end result is EyeWitness.

EyeWitnessUI

EyeWitness is designed to take a file, parse out the URLs, take a screenshot of the web pages, and generate a report of the screenshot along with some server header information.  EyeWitness is able to parse three different types of files, a general text file with each url on a new line, the xml output from a NMap scan, or a .nessus file.  Jason Hill (@jasonhillva) worked on creating the XML parsing code for EyeWitness, and provided a lot of feedback throughout writing it.  We also compared the results of both the XML and nessus parser to Tim Tomes’s in PeepingTom, and they are near identical, so we’re happy with the parsing capabilities.

In addition to providing the file name, you can also optionally provide a maximum timeout value.  The timeout value is the maximum amount of time EyeWitness waits for a web page to render, before moving on to the next URL in the list.

EyeWitnessCLI

EyeWitness will generate a report based on the screenshots it was able to grab, and will provide the header information alongside it.  The report is extremely similar to PeepingTom’s output because I honestly thought it contained a lot of useful information.

EyeWitnessReport

There is a couple things EyeWitness does to differentiate itself.  EyeWitness is able to identify web application default credentials for the web page that it is looking at.  When EyeWitness recognizes a web application, it will provide the default credentials along with the server header info.  Currently, EyeWitness has a small number of devices/webpages it can recognize in its signature file, however, that’s simply because I don’t have direct access to other machines at the moment.

Also, screenshots captured by EyeWitness are near full-size of the web application itself, and contains the entire page of the URL specified.  You’re able to easily look at the full screenshot by moving the slider around within the table, or simply click on the picture and access it in its own tab.

Another option EyeWitness provides is the ability to open all URLs within a web browser (on Kali) automatically, as it goes through the list of URLs.  So, as the tool runs, an iceweasel web browser will open tabs of all the URLs you provided within the input file.

I’d like to introduce a call to action.  As you find web pages that use default credentials for a web app, or networked devices, I’d love if you could send me the source code of the index page, along with the default credentials, to EyeWitness [at] christophertruncer [dot] com, or simply send a pull request to me with the signature you created in the signature file.  As I encounter applications with default credentials, or I am sent them, I will update EyeWitness to be able to identify and provide those default creds.

To add signatures to the signatures.txt file, simply add the “signature” which is used to uniquely identify the web app/device on a new line, use the “|” (pipe) as the delimiter, and then add the default credentials on the same line.

Thanks again for checking EyeWitness out, and hope that it can help you out on assessments!

EyeWitness can be cloned from – https://github.com/ChrisTruncer/EyeWitness

A slide deck I made for a NOVAHackers presentation is available here.

Developing a Self-Brute Forcing Payload for Veil

I’ve always thought the concepts that Hyperion utilizes to encrypt and hide an executable are very interesting.  As a result, I thought it would be a fun exercise to try to create a Veil payload that utilizes the following concepts:

  • Encrypt the shellcode stored within the executable
  • Only contain part of the decryption key within the executable
  • Make the payload brute force itself to find the complete decryption key

Hopefully, it’ll be worthwhile to walk you through how this payload works, so that’s what I’ll do. 🙂

Encrypting and decrypting shellcode is the easy part, this is something that is already done in Veil’s AES, DES, and ARC4 encrypting payloads.  But I needed to create a script that attempts to decrypt our ciphertext, thousands of times until it finds the decryption key.  I incorrectly assumed that when using the incorrect decryption key, and exception would be thrown, but that isn’t the case.  The decryption routine is still run on our ciphertext, and garbage data is returned as out “cleartext” data.  Since I can’t trigger an event based on an exception of the wrong decryption key being used, I needed a different method to determine when the real key has been found.  My implementation is to encrypt a known string with the same key used to encrypt the shellcode.  

Each round of the decryption routine will decrypt the ciphertext containing our known cleartext string.  The decrypted value is then compared to the known plaintext string.  If they don’t match, then the code assumes the wrong decryption key was used, and changes to another key.  If the decrypted string matches our known string, the code then assumes that the real key has been found.

BruteForcing Payload

The picture above is the obfuscated source code to the brute-forcing payload.  Line 5 contains our partial decryption key, but not all of it.  They key was artificially constrained to ensure the final few ascii characters used as the decryption key are numerical.  The numbers chosen are within a known range, so while we don’t know the exact number used, we can simply try all numbers within the known keyspace until the correct decryption key is identified.

Line 8 creates a for loop which will loop through all numbers within the known keyspace, and line 9 creates a decryption key by concatenating our partial key plus the “current number” of our for loop.  Line 11 is our attempt to decrypt our known string, and line 12 is checking the decrypted value against our known string.  If it’s a match, we can assume that this is our decryption key.

Once the key has been found, the script then drops into the if statement, and acts like any of Veil’s other encrypted payloads; system memory is allocated for use, the shellcode is decrypted, placed into memory, and then the decrypted shellcode is executed in memory.

The timeframe it takes it receive the callback from this payload obviously varies based on the “random” number that was generated and used in the decryption key.  This payload will be released shortly as one of Veil’s upcoming V-Days.

Introduction to Hasher

Nearly every pen test I’ve been on, we’ve been able to obtain hashes of some sort.  These hashes could be generated by a web application, database, operating system, or more.  Typically, there will come a point where I either need to generate a hash myself, or compare the hashes I’ve obtained with their potential plaintext value.  The problem that we face is it’s not operationally safe to blindly submit cleartext passwords or hashes to online websites.  I/we don’t know with 100% certainty what is happening to the hash or cleartext password and if they are being copied to another location.  In the end, I don’t trust anything online for anything sensitive in nature.

As a result, I needed a way to quickly generate password hashes and/or compare a hash that I have with a cleartext string and determine if they match, but I need to do this locally to my computer.  As a thought exercise, I wanted to make my own application that can meet these needs, so I’m happy to introduce Hasher.

Hasher

Hasher allows you to generate a hash in a hashing algorithm that you choose, with a cleartext string of your choice, all locally on your machine.  Additionally, Hasher lets you compare a cleartext string with a hashed value to determine if they match, again, all locally to your machine.  One item to note, Hasher is NOT designed to be a password/hash cracking program.  It’s designed for locally creating hashed, or comparing passwords and hashes locally, not for cracking passwords.

Current supported hashing algorithms:

  • md5
  • sha1
  • sha256
  • sha512
  • ntlm
  • msdcc
  • msdcc2
  • md5_crypt
  • sha1_crypt
  • sha256_crypt
  • sha512_crypt
  • MSSQL2000
  • MSSQL2005
  • MySQL v3.2.3
  • MySQL v4.1
  • Oracle 10G
  • Oracle 11G
  • Postgres_md5

Hasher is easily used with a Menu driven interface.  Just select the option you want to use, provide the cleartext string or hash, and you’ll get your result.  I’ve also made Hasher easily scriptable via the command line.  Not all CLI options are required, it’s dependent upon the hashtype you are using, and even then, if you don’t provide a required option, one is typically generated.  The CLI options looks like the following:

HAshercli

If you have any questions, or encounter any bugs, please be sure to submit an issue or pull request via github and I will be sure to address it shortly.  Also, if you have any specific hash type requests, please be sure to submit a request or github issue to me and I can look into adding that hash type.

To get a copy of Hasher, simply:

git clone https://github.com/ChrisTruncer/Hasher.git

Some sample uses are below:

Creating a NTLM hash with the password of “Password”:

Createpass

Comparing the password “Password” with a NTLM hash for the correct value:

Comparingtrue

Comparing the password “password” with a NTLM hash for an incorrect value:

Comparefalse