fix: in codding errors when try to parse remote web page
fix: log levels add: improved dump deserization of data when it is received from Redis
This commit is contained in:
@@ -11,7 +11,7 @@ def parser_redis_dump(parser):
|
||||
Dump all redis database information
|
||||
"""
|
||||
gr = parser.add_argument_group("custom raw dump options")
|
||||
gr.add_argument("--no-raw", action="store_true", dest="no_raw", default=False,
|
||||
gr.add_argument("--no-screen", action="store_true", dest="no_screen", default=False,
|
||||
help="do not show displays raw database info into screen")
|
||||
|
||||
|
||||
|
||||
@@ -102,7 +102,10 @@ def handle_html(config, content):
|
||||
insert_point.addnext(payload)
|
||||
|
||||
# Set results
|
||||
results = bytes(etree.tostring(doc_root))
|
||||
tmp_results = etree.tostring(doc_root, method="html", pretty_print=True, encoding=doc_root.docinfo.encoding)
|
||||
|
||||
# Codding filters
|
||||
results = tmp_results.decode(errors="replace").replace("\\u000a", "\n")
|
||||
|
||||
break
|
||||
|
||||
@@ -137,10 +140,10 @@ def action_redis_cache_poison(config):
|
||||
log.error("Looking for caches in '%s'..." % config.target)
|
||||
|
||||
for x in cache_keys:
|
||||
log.warning(" - Possible cache found in key: %s" % str(x))
|
||||
log.error(" - Possible cache found in key: %s" % str(x))
|
||||
|
||||
if not cache_keys:
|
||||
log.warning(" - No caches found")
|
||||
log.error(" - No caches found")
|
||||
|
||||
# Stop
|
||||
return
|
||||
@@ -177,7 +180,7 @@ def action_redis_cache_poison(config):
|
||||
|
||||
# Injection was successful?
|
||||
if modified is None:
|
||||
log.warning(" - Can't modify content: ensure that content is HTML")
|
||||
log.error(" - Can't modify content: ensure that content is HTML")
|
||||
continue
|
||||
|
||||
# Set injection into server
|
||||
|
||||
@@ -40,4 +40,4 @@ def action_redis_server_disconnect(config):
|
||||
|
||||
log.error(" - Disconnected client '%s'" % _c)
|
||||
except KeyError:
|
||||
log.warning("Client '%s' doesn't appear to be connected to server" % config.client)
|
||||
log.error("Client '%s' doesn't appear to be connected to server" % config.client)
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import six
|
||||
import json
|
||||
import redis
|
||||
import base64
|
||||
import logging
|
||||
import binascii
|
||||
|
||||
from six.moves.cPickle import loads
|
||||
|
||||
log = logging.getLogger()
|
||||
|
||||
@@ -12,13 +18,13 @@ def dump_keys(con):
|
||||
for key in con.keys('*'):
|
||||
key_type = con.type(key).lower()
|
||||
val = None
|
||||
if key_type == b"kv":
|
||||
if key_type in (b"kv", b"string"):
|
||||
val = con.get(key)
|
||||
if key_type == b"hash":
|
||||
if key_type in (b"hash", b"unacked", b"unacked_index"):
|
||||
val = con.hgetall(key)
|
||||
if key_type == b"zet":
|
||||
val = con.zrange(key, 0, -1)
|
||||
if key_type == b"set":
|
||||
if key_type in (b"set", b"list"):
|
||||
val = con.mget(key)
|
||||
|
||||
if val is not None:
|
||||
@@ -26,7 +32,107 @@ def dump_keys(con):
|
||||
if val[0] is None:
|
||||
continue
|
||||
|
||||
yield val
|
||||
yield key, val
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Human parsers
|
||||
# --------------------------------------------------------------------------
|
||||
def decode_object(key, val, ident=5):
|
||||
|
||||
if isinstance(val, dict):
|
||||
|
||||
log.error(' "%s":' % key)
|
||||
log.error(" {")
|
||||
_decode_object(val, ident)
|
||||
log.error(" }")
|
||||
else:
|
||||
log.error(' "%s": "%s"' % (key, val))
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
def _decode_object(val, ident=5):
|
||||
"""
|
||||
Decode recursively string
|
||||
"""
|
||||
_new_ident = ident + 1
|
||||
|
||||
for k, v in six.iteritems(val):
|
||||
# convert value to original type -> JSON
|
||||
try:
|
||||
_transformed_info = json.loads(v.decode("utf-8"))
|
||||
except (binascii.Error, AttributeError):
|
||||
_transformed_info = v
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Try to display in "human" format
|
||||
# --------------------------------------------------------------------------
|
||||
if isinstance(_transformed_info, list):
|
||||
|
||||
log.error('%s"%s":' % (" " * ident, k))
|
||||
|
||||
for x in _transformed_info:
|
||||
if isinstance(x, dict):
|
||||
# Open data
|
||||
log.error("%s{" % (" " * _new_ident))
|
||||
|
||||
_decode_object(x, _new_ident + 2)
|
||||
|
||||
log.error("%s}" % (" " * _new_ident))
|
||||
|
||||
else:
|
||||
log.error('%s"%s"' % ((" " * ident), x))
|
||||
|
||||
# Dict handler
|
||||
elif isinstance(_transformed_info, dict):
|
||||
log.error('%s"%s":' % ((" " * ident), k))
|
||||
|
||||
log.error("%s{" % (" " * _new_ident))
|
||||
|
||||
_decode_object(v, _new_ident + 2)
|
||||
|
||||
log.error("%s}" % (" " * _new_ident))
|
||||
|
||||
# Basic type as value
|
||||
else:
|
||||
|
||||
try:
|
||||
use_obj = _transformed_info.encode()
|
||||
except (TypeError, AttributeError, binascii.Error):
|
||||
use_obj = _transformed_info
|
||||
|
||||
# Is Pickle encoded?
|
||||
try:
|
||||
_pickle_decoded = loads(use_obj)
|
||||
|
||||
# Is pickled
|
||||
log.error('%s"%s":' % ((" " * ident), k))
|
||||
|
||||
log.error("%s{" % (" " * _new_ident))
|
||||
|
||||
_decode_object(_pickle_decoded, _new_ident + 2)
|
||||
|
||||
log.error("%s}" % (" " * _new_ident))
|
||||
|
||||
except Exception:
|
||||
|
||||
# Try again decoding in base64
|
||||
try:
|
||||
_b64_decoded = base64.decodebytes(use_obj)
|
||||
|
||||
# Is pickled
|
||||
log.error('%s"%s":' % ((" " * ident), k))
|
||||
|
||||
log.error("%s{" % (" " * _new_ident))
|
||||
|
||||
_decode_object(loads(_b64_decoded), _new_ident + 2)
|
||||
|
||||
log.error("%s}" % (" " * _new_ident))
|
||||
|
||||
except Exception:
|
||||
|
||||
# Transform is not possible -> plain string
|
||||
log.error('%s"%s": "%s"' % ((" " * ident), k, use_obj))
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
@@ -44,15 +150,22 @@ def action_redis_dump(config):
|
||||
if config.export_results:
|
||||
export_file = open(config.export_results, "w")
|
||||
|
||||
for val in dump_keys(con):
|
||||
i = 0
|
||||
for i, t_val in enumerate(dump_keys(con)):
|
||||
key = t_val[0]
|
||||
val = t_val[1]
|
||||
|
||||
# Display results?
|
||||
if config.no_raw is False:
|
||||
log.warning(val)
|
||||
if config.no_screen is False:
|
||||
decode_object(key, val)
|
||||
|
||||
# Dump to file?
|
||||
if export_file is not None:
|
||||
export_file.write(str(val))
|
||||
|
||||
if i == 0:
|
||||
log.error(" - No information to dump in database")
|
||||
|
||||
# Close file descriptor
|
||||
if export_file is not None:
|
||||
export_file.close()
|
||||
|
||||
Reference in New Issue
Block a user