Tuesday 27 October 2015

Parse Mimikatz Output One-Liner

Love mimikatz but hate the output? Yeah me too. In this post I'll show you how to parse the output with one simple line.

The Output

Running either the mimikatz binary or powershell equivalent Invoke-Mimikatz will give you output similar to the following:
Authentication Id : 0 ; 92831308 (00000000:05889d8c)
Session           : RemoteInteractive from 3
User Name         : john.smith
Domain            : ACME
SID               : S-1-5-21-2052118978-2816230894-3584936141-8335
 msv : 
  [00000003] Primary
  * Username : john.smith
  * Domain   : ACME
  * NTLM     : 1acd1a77416c50969d66867cd1e27e91
  * SHA1     : fc1a13cdf5e6d8da249812b320764fbaac0cb1bb
  [00010000] CredentialKeys
  * NTLM     : 1acd1a77416c50969d66867cd1e27e91
  * SHA1     : fc1a13cdf5e6d8da249812b320764fbaac0cb1bb
 tspkg : 
 wdigest : 
  * Username : john.smith
  * Domain   : ACME
  * Password : Myl0ngs3cretP@ssword
 kerberos : 
  * Username : john.smith
  * Domain   : ACME.mycompany
  * Password : (null)
 ssp : 
 credman : 
In most situations you'll often just want to know the users and passwords however this is hidden among a whole load of other output. Now we could go and patch the mimikatz code or we could use a cheeky one-liner...

I Love A One-Liner

My goal was to obtain a list of all usernames with domains and passwords from a set of mimikatz output files. This is simple to do with the following one-liner:
cat *|tr -d '\011\015' |awk '/Username/ { user=$0; getline; domain=$0; getline; print user " " domain " " $0}'|grep -v "* LM\|* NTLM\|Microsoft_OC1\|* Password : (null)"|awk '{if (length($12)>2) print $8 "\\" $4 ":" $12}'|sort -u

Parsing the example above you get the following:

Hows it work?
  • I start by outputting all files in the current directory and removing carriage return characters as these seemed to break awk. I also remove tab characters to clean up the output.
  • Next up I used awk to effectively put the username, domain and password all on the same line. This makes greppping, cutting or more awking easier.
  • I used grep to remove lines I didn't care about. For example NTLM hashes and null passwords.
  • I then did a final awk to remove hex string passwords. I'm not sure how/why mimikatz generates this output, if anyone knows please leave a comment! :)
  • And finally I sorted and uniqued the list.

I modified the one-liner to also output just the usernames and passwords without the domain:
cat *|tr -d '\011\015' |awk '/Username/ { user=$0; getline; getline; print user " " $0}'|grep -v "* LM\|* NTLM\|Microsoft_OC1\|* Password : (null)"|awk '{if (length($8)>2) print $4 ":" $8}'|sort -u
And also output usernames and NTLM hashes ready for use with pth-winexe:
cat *|tr -d '\011\015' |awk '/Username/ { user=$0; getline; domain=$0; getline; print user " " domain " " $0}'|grep -v "* LM\|* Password\|Microsoft_OC1"|awk '{if (length($12)>2) print $8 "/" $4 "%aad3b435b51404eeaad3b435b51404ee:" $12}'|sort -u
If you want a different output format just modify the final print statement.

Final Thoughts

Mimikatz is such an awesome tool unfortunately the default output is not that user/grep friendly. Luckily with a simple one-liner we can easily work the output into something more useful. As mentioned in my smb-share enumeration post, don't be afraid to jump in and learn some grep/awk/sed, these tools can speed up data analysis massively!

Hopefully this post has been useful, if you have any suggestions for improvements or better ways to get usable output then leave a comment below.

Pwndizzle out.

Thursday 23 July 2015

XSS, Extensions and Content-Types

In this post I'll look at which Content-Types and Extensions can actually be used for XSS in modern browsers.

Why does Content-Type and Extension matter?

Applications come in many different shapes and sizes and XSS can occur all over the place. It's easy to assume that just because an application returns you a response with unfiltered/unencoded output you've found an exploitable XSS issue but this is often not the case. Browsers render content based on a number of factors including content-type returned by the server, page content and page extension, without the correct combination XSS won't be possible.

To try and get a definitive answer of what works and what doesn't I thought I'd do some testing. I used multiple file types each containing their legitimate content however I also embedded a JavaScript alert payload in each. Each test case was ran against Chrome 43, IE 11 and Firefox 39. In the tables below "yes" means the payload rendered and "no" means it didn't.

Test #1 - Following Best Practice

In the first test I forced the server to return the correct extension and content-type for each test page.

Extension Chrome IE Firefox
None None yes yes yes
text/plain txt no no no
text/html html yes yes yes
application/javascript js no no no
application/json json no no no
application/xml xml yes yes yes
text/css css no no no
image/jpeg jpeg no no no

Following best practice modern browsers appeared to be pretty secure. The one exception appears to be XML, it seems odd that the browser would allow the rendering of JavaScript in an XML file.

Test #2 - Modifying Extension

In the second test I made the server return the correct content-type but forced a .html extension.

Extension Chrome IE Firefox
None html yes yes yes
text/plain html no no no
text/html html yes yes yes
application/javascript html no yes no
application/json html no no no
application/xml html yes yes yes
text/css html no no no
image/jpeg html no no no

This test seemed to show that browsers will prioritize the use of the content-type over the extension.

Test #3 - Using a text/html Content-Type

In the third test I used the correct extension for each file but made the server return a text/html content-type.

Extension Chrome IE Firefox
text/html None yes yes yes
text/html txt yes yes yes
text/html html yes yes yes
text/html js yes yes yes
text/html json yes yes yes
text/html xml yes yes yes
text/html css yes yes yes
text/html jpeg yes no yes

It looks like browsers rely heavily on the content-type returned by the server. It doesn't matter about the extension or contents of the file, the browser will blindly follow the content-type returned.

Test #4 - Using a text/plain Content-Type

Next I used the correct extension for each file but made the server return a text/plain content-type.

Extension Chrome IE Firefox
text/plain txt no no no
text/plain html no no no
text/plain js no no no
text/plain json no no no
text/plain xml no no no
text/plain css no no no
text/plain jpeg no no no

When using a content-type of text/plain none of the payloads executed. I can't remember for sure, but I believe in the past text/plain used to allow XSS? Looks like this is no longer possible.

Test #5 - MIME sniffing

In this last test case I accessed a page that had no extension and received no content-type header from the server. This should have caused the browser to fall back on mime sniffing to render the page.

Content-Type Extension Chrome IE Firefox
text/plain None None no yes no
text/html None None yes yes yes
application/javascriptNoneNone yes yes yes
application/json None None no yes no
application/xml None None no yes no
text/css None None no yes no
image/jpeg None None no no no

Both Chrome and Firefox refused to render pages that contained additional non-html content. IE however didn't seem to care what the page content was, if it contained HTML it rendered!


Performing application testing on a regular basis I find content-type and extension XSS issues arise quite a lot. This test showed that modern browsers are relatively secure as long as the correct content-type is returned. All browsers also seemed to implement the same analysis techniques aside from IE which seemed slightly more permissive.

Hopefully you guys have found this post useful, if anyone has any suggestions for bypasses to achieve XSS in any of the above, or if I've listed any findings incorrectly (quite possible) drop me a message below :)

Pwndizzle out.

Thursday 30 April 2015