Hasher Re-Write/Update

Github Repo: https://github.com/ChrisTruncer/Hasher

I have made some changes to Hasher, ideally I’d like to think for the better. Hasher was originally a single, large, python script that was used to hash plaintext strings, and compare a hash value to a plaintext string.  Hasher still performs the same actions, generates hashes or compares them with a plaintext string, but Hasher now has been converted into a framework which will allow myself, or anyone else, to easily add in support for different hashes.

Usage is still essentially the same, however there is no longer an interactive menu.  Hasher is now completely command line based.

Hasher Menu

To see a list of all hash-types that Hasher currently supports, simply run ./Hasher.py –list

HashTypes

Once you have the hash-type you want to generate a hash for, it’s fairly simple to generate.  For example, if you were looking to generate (-G) a md5 hash for the string “password123”, you would do it this way:

./Hasher.py -G --plaintext password123 --hash-type md5

You should see output similar to the following:

MD5 Generated

Harmj0y provided me with a great idea when using Hasher.  He had a use case where he just wanted Hasher to dump out all possible hashes for a specific plaintext string, but didn’t want to have to generate all hashes manually.  I added in the ability to generate all possible hash types based on the information provided.  To do this, you would run the following command:

./Hasher.py --plaintext password123 --hash-type all -G

When you run this, you should see output similar to the following:

Hasher All Output

Another capability that Hasher has, is it can take a plaintext string and hash, and then compare (-C) the the plaintext string to ensure it matches the hash.  This has been useful for me when needing to check if a hash and string “equal” each other, without submitting any of the information online.  So, lets continue the previous example.  If you wanted to verify that the plaintext string “password123” matches the md5 hash “482c811da5d5b4bc6d497ffa98491e38”, your command should look like this:

./Hasher.py -C --plaintext password123 --hash 482c811da5d5b4bc6d497ffa98491e38 --hash-type md5

True Comparison

For testing purposes, if the hash and plaintext string didn’t match up, it would look like the following:

False Hasher Comparison

 

Hash Module Development

Adding in support for new hash types is significantly easier now.  Every *.py file within the “hash_ops” folder is automatically picked up and parsed by Hasher.  Within the hash_ops folder, is a text file called “hash_template.txt”.  To add in a new hash-type, simply copy the template file and rename it with a .py extension.  There’s only two required methods within each module:

  • __init__ – This method needs to contained a self.hash_type attribute.  This is what is used by the user from the command line to select a specific hash.  Any other information within the __init__ method is optional.
  • generate – The generate method is called by Hasher to generate a hash.  This method has complete access to all options passed in from the command line by the user.  It must return the hash of the plaintext string.

For a sample, this is what the md5 module looks like:

Hasher MD5 Updated

Hopefully, this helps explain the minor usability changes to Hasher, and elaborates on how it’s now easier to add support for new hashes.  If anyone has any questions, feel free to reach out to me on twitter (@ChrisTruncer) or in #Veil on Freenode!

How to Develop Egress-Assess Modules

This post will document how to create server, client, and datatype modules for Egress-Assess.  I’ll document the necessary functions and attributes that the framework requires, and hopefully try to give some helpful info.

Some basic info before diving into the specifics of the differences between the module types.  All __init__ methods are able to access any command line parameter passed in by the user.  If any module requires information from the command line (hint, all of them do in one way or another), you should declare attributes (based off of the command line options) for each class instance within the __init__ method.

All template modules are currently a .txt file.  Once you’ve created your module and want to test/use it, rename it to a .py file within its respective folder.

Server Modules

servermoduletemplate

The first module type to discuss are server modules.  These modules will allow the framework to be put into a “server mode” which typically entails listening and waiting for the client to connect into the server, and transmit data to the server.  A blank server module template is available at this link to use as a base for creating a server module.

The self.protocol attribute is the only required attribute for server modules.  This attribute is what is displayed to the user when typing --list-servers.  This is also the value that is used to identify and use the server module when used in conjunction with the --server flag.

The serve function is the only required function for the server class.  It is what is used by the framework to start the server.  You can create as many different functions as needed for the server class, but the serve function should be considered the “main” of the server module.

Client Modules

clientmoduletemplate

The client module will typically be used to transmit data over a specific protocol, vs. receiving any data.  A blank client module template can be found at this location.

The self.protocol attribute is the only required attribute for client modules.  This attribute is what is displayed to the user when typing --list-clients.  This is also the value that is used to identify and use the server module when used in conjunction with the --client flag.

The transmit function is the only required function for client modules.  It is the function called by the framework  to transmit data.  The transmit function has a variable passed into it (data_to_transmit) which is the data that the client is supposed to transmit to the server.  Similar to server modules, the transmit function should be considered like the “main” function of client modules.  You can create as many additional functions necessary for the client module’s use, but the transmit function is what will be invoked by the framework.

Datatype Modules

datatype template

The datatype module is used to generate any sort of data.  Currently, there’s support for modules that generate social security numbers or credit card numbers.  A blank datatype template can be found at this location.

The self.cli, self.description, and self.filetype attributes are required for datatype modules.  The self.cli attributes is part of what is displayed when the user types --list-datatypes and is what is used to uniquely select the specific datatype to use with the --datatype flag.  This should be short since it is what is passed in by the user in the command line.

The self.description attribute can be used to better describe the datatype that is generated by the module.  This is also displayed when a user types --list-datatypes.  For example, the credit card module has “cc” as the self.cli attribute and “Credit Card Numbers” as the self.description attribute.

The self.filetype is currently only used when attempting to exfil data over ftp, but it is a required attribute.  This is to let the framework know if the data is text or binary data.  If text, keep the filetype attribute as text. Otherwise, change it.

The generate_data function is a required function for datatype modules.  It is what is invoked by the framework to generate the specific type of data requested by the user.  It must also return the total “data” generated.  As an example, the social security number datatype module generates X number of credit cards, and they are returned into the framework at the conclusion of the generate_data function.

Helper Functions

There are a few helper functions that are accessible to all modules.  The functions are in the helpers.py file within the framework.  However, a brief description of this is:

  • helpers.randomNumbers(X) – returns “X” number of random numbers
  • helpers.ea_path() – returns the current path the Egress-Assess is in
  • helpers.writeout_text_data(incoming_data) – writes out a file containing the data passed into function, and returns the name of the file

 

I hope this helps explain how to write any of the currently available modules.  If anyone has any questions, feel free to hit me up on twitter or on IRC in #veil!

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 – 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

Veil – A Payload Generator to Bypass Antivirus

NOTE: Please, be kind, and don’t submit any payloads to ANY online virus scanner!  Please be sure to check out https://www.veil-framework.com, Veil’s website for the latest tutorials, updates, and repo location.  Any questions on using Veil?  Join us in #veil on Freenode!

On nearly every assessment, pen testers have to fight a battle against antivirus solutions.  The level of effort that goes into each “battle” relies on the AV solution, its definitions, etc.  Researching methods to bypass antivirus solutions has been an interest of mine on and off  for the past 6 months. About two months ago I started to take a more serious look in how I could take my recent research and turn it into something that more usable and useful.  I set out with a couple goals:

  • Bypass common AV solutions that I/we routinely encounter in most network environments
  • Utilize payloads that are compatible with the Metasploit framework, and expand upon these in future releases
  • Attempt to make each payload file as random as possible

With these goals in mind, I continued researching methods of bypassing AV.  Since I wanted to maintain metasploit compatibility, I chose to use shellcode generated by the metasploit framework, specifically msfvenom. To accomplish this, I began looking into other available research, which is where I discovered a number of interesting techniques that a variety of people, such as Dave Kennedy and Debasish Mandal, already began to develop.  From their research, I learned about really interesting ways to inject shellcode into memory through python.  These methods were the foundation of the rest of my research.

Since the majority of our assessment are against predominantly Windows environments, it was important that the tool worked reliably against these systems.  Since I chose to write the tool in Python, I had to figure out how to package the Python output files containing the obfuscated shellcode to execute on Windows without requiring Python to be installed on the target machine.  One of the solutions I looked into was using Py2Exe.  I knew other software used this method to convert their Python-based scripts or tools into an executable that could run on Windows and figured I could do the same.  I began testing Py2Exe with the payload files I developed and was successful running the executables on various versions of Windows, so I stuck with that solution.  The final part was for me to develop a tool that automated the payload generation process, and I’m happy to release Veil.

Veil

Veil is currently capable of using 7 different methods to make 21 different payloads, all of which result in meterpreter connections.  Veil provides the user with the option of using either Pyinstaller or Py2Exe to convert their python payload into an executable.  With Pyinstaller, Veil users and have their file converted into an executable all within Kali and does not require the use of a second VM/Machine.  When using Py2Exe,Veil will generate three files to which are required to create the final executable; a payload file (in Python), a file with runtime instructions for Py2Exe, and a batch script which handles converting the payload file into an executable. To generate the final payload, copy the three output files to a Windows host with Python, Py2Exe, and PyCrypto installed and execute the batch script. This will build the final executable that is uploaded to the target. The executable file can be dropped anywhere, on any Windows system, as all required libraries are stored within the exe file.  Once dropped on a system and executed, the payload will result in a meterpeter callback that is undetected by AV.

Py2Exe

I’ve tested the packaged executable against multiple AV solutions (MSE, Kaspersky, AVG, Symantec, and McAfee), on both test systems and “in the wild,” and have a very high success rate, bypassing detection in almost every circumstance. I hope that, by releasing this tool, I can enable others in the community to provide more effective assessments by allowing them to focus their efforts on security risks and spend less time bypassing ineffective security measures that wouldn’t deter an actual adversary.

Scanned with MSE

Setup:

For Kali:

  1. Run the setup script (setup.sh) and follow the installation process.
  2. Once the setup script has completed, delete the setup script.

For Windows (when using Py2Exe)

  1. Install Python 2.7 – (tested with x86 – http://www.python.org/download/releases/2.7/)
  2. Install Py2Exe – (http://sourceforge.net/projects/py2exe/files/py2exe/0.6.9/)
  3. Install PyCrypto – (http://www.voidspace.org.uk/python/modules.shtml)

Instructions for Use:

  1. Run Veil from Kali and generate your payload.
  2. If using Pyinstaller, your payload will be converted into an executable and is available for immediate use.
  3. If using Py2Exe
    • Move the payload.py along with its two accompanying files onto your Windows machine (that already has python and the other dependencies from above installed).  All three files should be placed in the root of the directory Python was installed to (likely C:\Python27).
    • Run the batch script to convert the Python payload into an executable format.
  4. Place the payload file on your target machine through any means necessary!

Future Direction:

  • Research new methods of encrypting or obfuscating the payload.
  • Research other languages with direct access to the Windows API for delivering the payload.

Want to play with Veil?  Feel free to do so.  Download, clone, do anything you’d like with it.  You can download Veil  here – https://github.com/Veil-Framework/Veil-Evasion.

I hope that it can help others on their tests just as it has helped me.  Please, if anyone has additional functionality they would like to add, I’d love to have input from the community!

References:

Dave Kennedy – http://www.trustedsec.com/files/BSIDESLV_Secret_Pentesting_Techniques.pdf

Debasish Mandal – http://www.debasish.in/2012/04/execute-shellcode-using-python.html

Red Teaming a CCDC Practice Event

This weekend I was invited to be a member of a red team for a local CCDC team. I’ve been interested in checking out how CCDC works, and this was my first opportunity to be part of it.

For the 20 minutes before the red team was allowed to go, we began mapping out different strategies and attack paths that each member would carry out. Off the break, I was in charge of exploiting systems, and attempting to get shells. We had two other members who were in charge of mapping services active on hosts, one member in charge of scanning hosts for vulnerabilities, and one for post-exploitation work and establishing persistance once the team received a shell. We decided to centralize our work and I setup a team server for use with Armitage. In the end, this was a great decision. We were very easily able to share sessions opened up with targets, and allow everyone to access all information as we obtained it from hosts (such as hashes that were dumped, keystrokes logged, etc.). Any CCDC or team CTF event should absolutely use this awesome capability.

Immediately after we started, 08_067 was sent to the entire blue team IP range, and followed quickly by 09_050. Within 5 seconds we were in one of their boxes as system and we immediately began post-exploitation by dumping hashes, creating accounts, and creating services that call back to us. While on the box, we were watching the blue team attempt to install patches to prevent us from re-exploiting and regaining access. However, a red team member killed the update process, which caused the machine to endlessly reboot.

The blue team decided to revert the entire machine, take the machine offline, and then patch the entire machine. After talking with others on the rules, we found out that this is definitely an illegal action (taking the machine off the network) and would cost the blue team points. However, it appeared to be an incomplete patch performed against the machine because once the machine went back online, we were able to re-exploit it with 08_067. Getting onto the machine when we did let us gain control of their domain controller.

Immediately when we jumped back on the machine, we took a screenshot and saw that the blue team was in the process of trying to join the computer to their domain. We immediately activated a key logger, and obtained 3+ different passwords that must have been used throughout their network (it appears the blue team forgot which password was the password for their domain admin account, so they were trying them all). After about 20 minutes of keylog dumping, we obtained the domain admin account credentials and were able to psexec onto the domain controller. We immediately dumped hashes and obtained credentials.

Both machines we were on were a constant battle as the blue team loaded on a significant number of tools to monitor processes and outgoing connections from their machines. This led to constant battles as processes were constantly being killed due to the very active defense of the blue team.

Overall, these were the only two machines we were able to control (out of 10 total). Probably the biggest reason for this was because at least half of the IP range were computers that weren’t actually brought online. Another reason, the blue team had (accidentally) uninstalled required services on the few machines that were online. This significantly reduced the attack surface on nearly all their active machines.

Some of the overall notes that we provided to the blue team in our wrap up was:

  • The blue team needed to work immediately on patching their machines, but to prioritize the patches by starting with any patch eliminating remote code execution. Additionally, they need to ensure the patches were applied to the machine and are active. The blue team had thought that they patched certain exploits, only to have the red team break back in with the same exploit they thought was patched.
  • The blue team needs to assume once the red team breaks in, that everything related to that machine is compromised, such as account credentials. We suggested that the blue team should rotate passwords regularly (if possible), but definitely after a compromise of the machine.
  • Ensure that all default credentials for services or web applications are changed.

What the blue team did well:

  • Active defense. The blue team very actively monitored processes running and monitoring connections from their boxes. This led to multiple battles where the blue team was killing our connection while we began re-establishing them. This was definitely their strong point. They seemed to know exactly what was running on their boxes and were good at determining what we were running.

What the red team can do:

  • In my opinion, the best thing we could do for the next practice session is automate a large portion of our post-exploitation activities. By all means we performed post-exploitation effectively, but I think it would be great to create a couple cortana scripts that are triggered upon certain events. For example, on a meterpreter session, we immediately dump hashes, create user accounts, create persistent services, and attempt to pass obtained hashes to other windows machines within the target range. Automating these tasks will free up the red team to perform other activities and automate the manual work.