Friday, August 29, 2014

Introducing Gupt: A Backdoor which uses Wireless network names for command execution

Few weeks back, I was playing with my mobile WiFi hotspot and powershell. Using powershell, I was listing the SSIDs created by the mobile hotspot, wondering if it could be exploited some way? It turned out to be a yes but with some help.

Behold, I give you Gupt (which means secret), a powershell backdoor which could execute commands and scripts on a target if a specially crafted SSID is brought into its proximity. Gupt is very small yet powerful !

Like other backdoors, Gupt, a powershell script, has to be executed on the target. This could be done using Powershell Remoting and PsExec (needs crdentials of a user or hashes of built-in Administrator), with an exploit, using client side attacks (I will talk about these at DeepSec), using a Human Interface Device etc. Previous posts on this blog details above methods.

Executing Commands

Gupt checks all wireless network names for a pattern every 5 seconds, it asks for two parameters, first one, MagicString, is used to identify the SSID which contains commands for it. It needs to be four characters long. For example, if we set MagicString as "op3n", it would compare SSIDs of all available wireless networks if first four characters of any matches "op3n". Gupt needs the network name in a special format. While the first four characters must match MagicString, the 5th character is used to decide if we want it to execute a command or download-execute a powershell script.

If the 5th character is 'c', it means that rest of the network name is a command! For example, while looking for Wireless Networks, if Gupt encounters a network with name "op3ncwhoami" it would execute whoami on the target. Simple, isn't it? :)

Lets see it in action.We use the following:

Great! We executed command on the target without forcing it to connect to the wireless network. Lets have a look at the attacker's SSID/Network name.
As we saw, everything after the 'c' is considered a single command.
Lets see another example, this time with powershell cmdlet Get-Process. The SSID being "holacget-process"
Gupt waits for 10 seconds after executing a command, we can execute more commands by changing the SSID name.

Executing Scripts

Now, how do we execute a script using Gupt? Since maximum length for an SSID could only be 32 characters (with restrictions on special characters), passing scripts in SSID name is not possible. To achieve script execution, Gupt downloads and executes a script. If the 5th character of SSID is 'u', Gupt looks for the id part of a URL shortened by Google URL shortener. For example, a SSID "op3nunJEuug" would use http://goo.gl/nJEuug to download and execute the script. The script would be executed in memory. The second parameter, Arguments could be used to pass arguments to the downloaded script.

Lets see it in action with the Get-Information script from Nishang. We use the following command:

Attacker's SSID being 'op3nunJEuug'
We could also execute Powerpreter module on a target using Gupt the same way, powerpreter would provide much wider functionality.

Lets see if we could get a meterpreter session with this. We will use the powershell script generated using msfpayload.
And we have a meterpreter.

This is how our SSIDs look like.

Cool!

Here is the full source code.
Gupt waits for 10 seconds after executing a script, we can execute more commands by changing the SSID name.

We ccold force Gupt to exit by naming our network, in above case, "op3ncexit".

Use cases of Gupt are many like bypassing network traffic monitoring, backdooring a machine completely on an internal network or simply to show off something new to the clients.

Gupt is available at github repo of Nishang and would soon be a part of Kautilya too.

If you like this post and presently in Europe and/or coming to DeepSec, Vienna, join me for interesting hands-on hacks, concepts and code in my two-day training "Powershell for Penetration Testers". Details here: https://deepsec.net/speaker.html#WSLOT145

Hope you enjoyed this. Please leave comments.


Thursday, August 21, 2014

Script Execution and Privilege Escalation on Jenkins Server

Disclaimer: We would use only existing features of Jenkins, no 'exploits' here.

During a recent penetration test I came across a Jenkins server. Having written a blog post on it, I was really excited and jumped straight to the /script url for the Groovy script console. But, it redirected me to a login page. Bummer!

Anyway, I registered as a user (yes it was allowed), and then tried to go the script console, but (all screenshots from my test machine)


After that, I put the initial excitement aside and started to explore whatever was available and read Jenkins documentation. Some interesting links are given below. All of these are publicly/anonymously accessible in Jenkins Standard Security Setup detailed here:

List of users:
http://[jenkinsurl]/asynchPeople/
List of all builds:
http://[jenkinsurl]/view/All/builds
(Seems to be fixed in the latest version 1.575)
List publilcy available content:
http://[jenkinsurl]/userContent/
Type of the Operating System:
http://[jenkinsurl]/computer/

It turned out that in Standard Security Setup, a registered user and anonymous user have same privileges unless otherwise configured.

During the pen test, I found links to couple of repositories in build details (console outputs) which were a treasure trove. but nothing on the Jenkins server itself. It be noted here that I was unable to see the build details on my test machine which is the latest version.

Anyway, the list of available users got my attention. From my experience working in the industry, I almost knew there would be some easy passwords as developers and build management guys are not really good at passwords :P 

 I quickly ran a brute force on all the listed users using Burp and 500 worst passwords list from Skullsecurity. I ran it on POST request to  /j_acegi_security_check. If you use Burp intruder, make sure it is configured to follow redirects.
No points for guessing, I got password for a user. Yay! Login and jump to the script console but



Few minutes later, I got password for two more users but none had access to the script console. Aaargghhh!

After further exploring Jenkins console, I saw that one of the users could configure build jobs (could not create new ones) and there are couple of very interesting things in the "AddBuild Step" option:

I added a small script, saved the configuration and built the task. Recall that we can get the OS type using http://[jenkinsurl]/computer/
But, damn it:

The script didn't execute. There had to be a way out! I called up my elder brother (he is on twitter, follow him!) who is a veteran in configuration and build management. He suggested me to see if there is any task running before the "Execute Shell" build step and is failing. There was one indeed.
He further suggested if I could re-order the build steps. Quick duck search returned a way, I just need to drag my Build Step to top, save and build. Aaand, finally!

Now, you can try getting a meterpreter session using built-in perl, python, ruby etc. And if it is a windows machine use powershell for various attacks as mentioned in my earlier post. Note that unlike script console we need not use Groovy script if we use the build step.

If you want to get admin access to Jenkins, read on. As per, Jenkins documentation here, you can disable security by setting the [useSecurity]true[/useSecurity] to false in config.xml in $JENKINS_HOME or by deleting the config,xml.

Lets check for $JENKINS_HOME, we use "ps -ef | grep jenkins" in the Shell Execute step.
Now lets see if we can delete config.xml
UPDATE: You must have sudo privileges to be able to restart Jenkins. My test machine had a bad configuration. But if Jenkins is running on a Windows machine, you can restart the service as it runs with SYSTEM privileges (or at least Admin privileges) on Windows. Note that, you may need to move to a reverse shell or meterpreter before you can restart Jenkins service on Windows.
Save, build and refresh. Bingo! Admin access for everyone!
UPDATE: Deleting config.xml is absolutely not required. You could always run a sed command to replace [useSecurity]true[/useSecurity] with [useSecurity]false[/useSecurity] for same results (service restart required).


Hope this would be useful. Please leave comments.