def __call__(self, pattern=""): """Nicely display self dict's items as a formatted multiline string array. The optionnal argument `pattern` can be used to limit item display to keys whose name starts with it's value. """ # get matching vars list if not self.keys(): raise ValueError("No such " + self.title) keys = [k for k in self.keys() if k.startswith(pattern)] if not keys: msg = "No such {} matching «{}»" raise ValueError(msg.format(self.title, pattern)) # process formatted string tpl = (" {:%s} {}\n") % max(8, len(max(keys, key=len))) buffer = self.title + "\n" + ("=" * len(self.title)) + "\n\n" buffer += tpl.format("Variable", "Value") buffer += tpl.format("--------", "-----") for id, key in enumerate(sorted(keys)): buffer += colorize(["%Reset", "%Reset"][id % 2], tpl.format(key, self[key])) return "\n" + buffer + colorize("%Reset")
def doc_help(docLines): """print the formated command's docstring""" # reject empty docstrings (description + empty line) if len(docLines) < 2: return False docLines.pop(0) # remove the description line while not docLines[0].strip(): docLines.pop(0) # remove heading empty lines # remove junk leading spaces (due to python indentation) trash = len(docLines[0]) - len(docLines[0].lstrip()) docLines = [line[trash:].rstrip() for line in docLines] # hilight lines with no leading spaces (man style) result = str() for line in docLines: if line == line.lstrip(): line = colorize("%BoldWhite", line) elif line.startswith(" * "): line = colorize(" * ", "%Yellow", line[6:]) elif line.startswith(" > "): line = colorize(" > ", "%Cyan", line[6:]) result += line + "\n" print(result)
def doc_help(doc_lines): """print the formated command's docstring""" # reject empty docstrings (description + empty line) if len(doc_lines) < 2: return False doc_lines.pop(0) # remove the description line while not doc_lines[0].strip(): doc_lines.pop(0) # remove heading empty lines # remove junk leading spaces (due to python indentation) trash = len(doc_lines[0]) - len(doc_lines[0].lstrip()) doc_lines = [line[trash:].rstrip() for line in doc_lines] # hilight lines with no leading spaces (man style) result = str() for line in doc_lines: if line == line.lstrip(): line = colorize("%BoldWhite", line) elif line.startswith(" * "): line = colorize(" * ", "%Yellow", line[6:]) elif line.startswith(" > "): line = colorize(" > ", "%Cyan", line[6:]) elif line.startswith(" # "): line = colorize("%Dim", line) elif line.startswith(" -") and line[5] != " ": line = colorize("%Green", line) result += line + "\n" print(result)
def __str__(self): val = self._raw_value() if val == 'disabled': return colorize('%Red', val) elif val: return colorize('%Cyan', val) else: return colorize('%Cyan', "default")
def __str__(self): low, big = [str(x).rstrip('0').rstrip('.') for x in self] main = colorize('%Bold', '%s', '%Basic') if low == big: text = main %low comment = '(fixed interval)' else: text = ' <= '.join((low, main %'x', big)) comment = '(random interval)' return colorize('%Pink', text, " ", '%DimWhite', comment)
def print_node(node): if 'dn' in node: print(colorize('%BlueBold', node['dn'])) else: print(colorize('%BlueBold', '----------------------')) for key, val in node.items(): if isinstance(val, dict): del val['count'] line = " %s : %s" % (colorize('%Bold', "%20s" % key), ' | '.join(val.values())) print(line) print()
def __str__(self): low, big = [str(x).rstrip('0').rstrip('.') for x in self] main = colorize('%Bold', '%s', '%Basic') if low is big: text = main % low comment = '(fixed interval)' else: text = ' <= '.join((low, main % 'x', big)) comment = '(random interval)' return colorize('%Pink', text, " ", '%DimWhite', comment)
def debug_cmdrepr(argv): """Returns a nice representation of given command arguments """ cmdrepr = [] for arg in argv: if not isinstance(arg, str): continue argrepr = repr(arg) sep = argrepr[0], argrepr[-1] argrepr = colorize("%DimCyan", argrepr[1:-1]) cmdrepr.append(sep[0] + argrepr + sep[1]) args = " ".join(cmdrepr) return colorize("%BoldCyan", "CMD(", "%Reset", args, "%BoldCyan", ")")
def debug_cmdrepr(argv): """Returns a nice representation of given command arguments """ cmdrepr = [] for arg in argv: if not isinstance(arg, str): continue argrepr = repr(arg) sep = argrepr[0], argrepr[-1] argrepr = argrepr[1:-1].join(colorize("%DimCyan", "%Reset")) cmdrepr.append(sep[0] + argrepr + sep[1]) args = " ".join(cmdrepr) return colorize("%BoldCyan", "CMD(", "%Reset", args, "%BoldCyan", ")")
def default_console(self): print(colorize("%BoldWhite", self.banner)) while True: try: exec(input("> ")) except EOFError: return 0 except SystemExit as err: if err.code is not None: print(err.code) return int(bool(err.code)) except BaseException as e: e = traceback.format_exception(type(e), e, e.__traceback__) e.pop(1) print(colorize("%Red", "".join(e)))
def __str__(self): """Return a color string representation of the setting var object. If the buffer has no multiple lines, single choice's string representation is returned. Otherwise, the multi line choices buffer is represented. >>> str( RandLineBuffer("singleChoice") ) 'singleChoice' >>> str( RandLineBuffer("file:///etc/passwd") ) '<RandLine@/etc/passwd (24 choices)>' >>> str( RandLineBuffer("choice1\\nchoice2") ) '<RandLine (2 choices)>' """ # if buffer have one line only, return line string's obj repr if not self.file and len(self.buffer.splitlines()) == 1: return str(self._getobj(self.buffer.strip())) # objID is file path OR buffer's md5sum if self.file: objID = self.file else: objID = hashlib.md5(self.buffer.encode('utf-8')).hexdigest() # choices is the string that show available choices num = len(self.choices()) choices = " (%s choice%s)" % (num, ('', 's')[num > 1]) return colorize("%BoldBlack", "<", "%BoldBlue", "RandLine", "%BasicCyan", "@", "%Bold", objID, "%BasicBlue", choices, "%BoldBlack", ">")
def __str__(self): """Return a color string representation of the setting var object. If the buffer has no multiple lines, the buffer is just represented as a string. Otherwise, multiplie buffer is represented. >>> str( MultiLineBuffer("monoline") ) 'monoline' >>> str( MultiLineBuffer("file:///etc/passwd") ) '<MultiLine@/etc/passwd (24 lines)>' >>> str( MultiLineBuffer("line1\\nline2") ) '<MultiLine (2 lines)>' """ # if buffer have one line only, return line string's obj repr if not self.file and len(self.buffer.splitlines()) == 1: return str(self._getobj(self.buffer.strip())) # obj_id is file path OR buffer's md5sum if self.file: obj_id = self.file else: obj_id = hashlib.md5(self.buffer.encode('utf-8')).hexdigest() lines_str = " (%s lines)" % len(self.buffer.splitlines()) return colorize("%BoldBlack", "<", "%BoldBlue", "MultiLine", "%BasicCyan", "@", "%Bold", obj_id, "%BasicBlue", lines_str, "%BoldBlack", ">")
def run(self, argv): from api import server try: ExecPlugin(self) except KeyboardInterrupt: raise KeyboardInterrupt except SystemExit as e: retval = e.args[0] if e.args else e.code if not isinstance(retval, int): lines = self.help.splitlines() if len(lines) > 1 and str(retval) == self.help: print() print("[*] %s: %s" % (self.name, lines.pop(0))) for line in lines: if line == line.lstrip(): line = colorize("%BoldWhite", line) print(line) print() else: print("[-] %s: %s" % (self.name, retval)) retval = 1 return retval except server.payload.PayloadError as err: print("[-] %s: %s" % (self.name, err)) return 64 except BaseException as err: msg = "Python runtime error (exception occured)" print("[-] %s: %s:" % (self.name, msg)) raise err
def diff(self, file=None, display_diff=False): """This function returns True is the given `file` is a phpsploit session which differs from current session. Otherwise, False is returned. Additionally, if `display_diff` is set, the session differences will be displayed in common unix `diff` style. """ if isinstance(file, Session): diff = self.deepcopy(file) else: if file is None: diff = Session() diff.File = self.File else: diff = self.deepcopy() diff.update(file) diff = decolorize(diff).splitlines() orig = decolorize(self).splitlines() if display_diff: color = {' ': '%Reset', '-': '%Red', '+': '%Green', '?': '%Pink'} if file is None: difflines = difflib.Differ().compare(diff, orig) else: difflines = difflib.Differ().compare(orig, diff) for line in difflines: # dont be too much verbose... if line.startswith('?'): continue print(colorize(color[line[0]], line)) return diff != orig
def run(self, argv): """run current plugin """ self.argv = argv from api import server try: ExecPlugin(self) except KeyboardInterrupt: raise KeyboardInterrupt except SystemExit as e: retval = e.args[0] if e.args else e.code if not isinstance(retval, int): lines = self.help.splitlines() if len(lines) > 1 and str(retval) == self.help: print() print("[*] %s: %s" % (self.name, lines.pop(0))) for line in lines: if line == line.lstrip(): line = colorize("%BoldWhite", line) print(line) print() else: print("[-] %s: %s" % (self.name, retval)) retval = 1 return retval except server.payload.PayloadError as err: print("[-] %s: %s" % (self.name, err)) return 64 except BaseException as err: msg = "Python runtime error (exception occured)" print("[-] %s: %s:" % (self.name, msg)) raise err return 0
def diff(self, file, display_diff=False): """This function returns True is the given `file` is a phpsploit session which differs from current session. Otherwise, False is returned. Additionally, if `display_diff` is set, the session differences will be displayed in common unix `diff` style. """ # non-failing copy.deepcopy(self) equivalent: diff = self._obj_value(self._raw_value(self)) diff.update(file) diff = decolorize(diff).splitlines() orig = decolorize(self).splitlines() retval = diff != orig if display_diff: color = {' ': '%Reset', '-': '%Red', '+': '%Green', '?': '%Pink'} for line in difflib.Differ().compare(orig, diff): # dont be too much verbose... if line.startswith('?'): continue print(colorize(color[line[0]], line)) return retval
def build_forwarder(self, method, decoder): """build the effective payload forwarder, which is in fact a header using the PASSKEY setting as name. The payload forwarder is called by the remote backdoor, and then formats the final payload if necessary before executing it. """ decoder = decoder % "$x" template = self.forwarder_template[method] template = template.replace('%%PASSKEY%%', self.passkey) rawForwarder = template % decoder b64Forwarder = base64.b64encode(rawForwarder.encode()).decode() # here we delete the ending "=" from base64 payload # because if the string is not enquoted it will not be # evaluated. on iis6, apache2, php>=4.4 it dont seem # to return error, and is a hacky solution to eval a payload # without quotes, preventing header quote escape by server # eg: "eval(base64_decode(89jjLKJnj))" b64Forwarder = b64Forwarder.rstrip('=') hdr_payload = self.header_payload forwarder = hdr_payload % b64Forwarder if not self.is_first_payload: # if the currently built request is not the first http query # sent to the server, it means that it works as it is. Therefore, # additionnal payload warnings and verifications are useless. return {self.passkey: forwarder} err = None # if the base64 payload is not enquoted by REQ_HEADER_PAYLOAD # setting and contains non alpha numeric chars (aka + or /), # then warn the user in case of bad http response. if "'%s'" not in hdr_payload and \ '"%s"' not in hdr_payload and \ not b64Forwarder.isalnum(): # create a visible sample of the effective b64 payload oneThirdLen = float(len(forwarder) / 3) oneThirdLen = int(round(oneThirdLen + 0.5)) sampleSeparator = colorize("%Reset", "\n[*]", "%Cyan") lineList = [''] + split_len(forwarder, oneThirdLen) showForwarder = sampleSeparator.join(lineList) # set the payload forwarder error err = ("[*] do not enquotes the base64 payload which" " contains non alpha numeric chars (+ or /)," " blocking execution:" + showForwarder) # if the current request is not concerned by the previous case # an other kind of error may happen because the contents of # the header that forwards the payload contains quotes. elif '"' in hdr_payload or \ "'" in hdr_payload: err = ("[*] contains quotes, and some http servers " "defaultly act escaping them in request headers.") self.payload_forwarder_error = err return {self.passkey: forwarder}
def ipython_console(self): """IPython console interpreter https://ipython.org/ """ # pylint: disable=import-error import IPython print(colorize("%BoldWhite", self.banner)) IPython.embed() return 0
def __str__(self): """Get a nice string representation of current session """ title = "PhpSploit session dump ({})".format(self.File) # deco = "\n" + colorize("%Blue", "=" * len(title)) + "\n" deco = "\n" + colorize("%Blue", "=" * 68) + "\n" data = deco + title + deco ordered_keys = ["Conf", "Env", "Alias"] for name in ordered_keys: if self[name]: data += str(self[name]) + "\n" return data
def default_console(self): """Simple python console interpreter Used as fallback when neither of other consoles are available It basically consists in an exec(input("> ")) loop """ print(colorize("%BoldWhite", self.banner)) while True: try: # pylint: disable=exec-used exec(input("> ")) except EOFError: print() return 0 except SystemExit as e: if e.code is not None: print(e.code) return int(bool(e.code)) except BaseException as e: e = traceback.format_exception(type(e), e, e.__traceback__) e.pop(1) print(colorize("%Red", "".join(e)))
def do_exploit(self, argv): """Spawn a shell from target server SYNOPSIS: exploit [--get-backdoor] DESCRIPTION: This command send an HTTP request to the remote server url (defined by the $TARGET setting). If $TARGET is correctly backdoored with the phpsploit backdoor, the request remotely executes the session opener in order to retrieve environment variables, and spawn the phpsploit remote shell. OPTIONS: --get-backdoor Only display current backdoor, as it should be injected on the current or future target url. NOTE: The $TARGET setting should be a valid http(s) url, previously infected with the phpsploit backdoor. """ obj = str(session.Conf.BACKDOOR(call=False)) obj = obj.replace("%%PASSKEY%%", session.Conf.PASSKEY().upper()) if len(argv) > 1: if argv[1] == "--get-backdoor": print(obj) return True else: self.interpret("help exploit") return False print("[*] Current backdoor is: " + obj + "\n") if tunnel: m = ("[*] Use `set TARGET <VALUE>` to use another url as target." "\n[*] To exploit a new server, disconnect from «{}» first.") print(m.format(session.Env.HOST)) return False elif session.Conf.TARGET() is None: m = ("To run a remote tunnel, the backdoor shown above must be\n" "manually injected in a remote server executable web page.\n" "Then, use `set TARGET <BACKDOORED_URL>` and run `exploit`.") print(colorize("%BoldCyan", m)) return False else: return tunnel.open() # it raises exception if fails
def __call__(self, pattern=""): """Display self dict's items as a formatted multiline string array. The optionnal argument `pattern` is an optional prefix to only display matching items. """ # get matching vars list sing_title = self.title if sing_title.endswith("s"): sing_title = sing_title[:-1] if not self.keys(): raise ValueError("No such " + sing_title) keys = [k for k in self.keys() if k.startswith(pattern)] if not keys: msg = "No {} matching «{}»" raise ValueError(msg.format(sing_title, pattern)) tpl = (" {:%s} {}\n") % max(8, len(max(keys, key=len))) buffer = self.title + "\n" + ("=" * len(self.title)) + "\n\n" buffer += tpl.format("Variable", "Value") buffer += tpl.format("--------", "-----") for idx, key in enumerate(sorted(keys)): buffer += colorize(["%Reset", "%Reset"][idx % 2], tpl.format(key, self[key])) return "\n" + buffer + colorize("%Reset")
def __str__(self): """Gives a nice string representation of current session""" title = "PhpSploit session dump ({})".format(self.File) # deco = "\n" + colorize("%Blue", "=" * len(title)) + "\n" deco = "\n" + colorize("%Blue", "=" * 68) + "\n" data = deco + title + deco ordered_keys = ["Conf", "Env", "Alias"] for name in ordered_keys: obj = self[name] if isinstance(obj, objects.MetaDict): try: data += str(obj) + "\n" except: pass return data
def format_docstring(self, name, metatype, desc): indent = lambda buf: buf.strip().replace("\n", "\n ") doc = ("\n" "DESCRIPTION:\n" " {description}\n" "\n" "BUFFER TYPE:\n" " {objtype!r}\n" "\n" " {typedesc}") typedesc = metatype.desc.format(var=colorize("%Lined", name)) return doc.format(description=indent(desc), objtype=metatype, typedesc=typedesc.strip())
def onexception(self, exception): """Add traceback handler to onexception""" exc = traceback.format_exception(type(exception), exception, exception.__traceback__) # a small patch for traceback from plugins, remove trash lines for idx, line in enumerate(exc): if ('File "<frozen importlib._bootstrap>"' in line and '_call_with_frames_removed' in line): exc = exc[(idx + 1):] header = "Traceback (most recent call last):" exc.insert(0, header + os.linesep) break self.last_exception = "".join(exc).splitlines() for line in self.last_exception: print(colorize("[#] ", "%Red", line)) return super().onexception(exception)
def format_docstring(name, linebuf_type, desc): """formet help docstring per settings """ indent = lambda buf: buf.strip().replace("\n", "\n ") doc = ("\n" "DESCRIPTION:\n" " {description}\n" "\n" "BUFFER TYPE:\n" " {objtype!r}\n" "\n" " {typedesc}") typedesc = linebuf_type.desc.format(var=colorize("%Lined", name)) return doc.format(description=indent(desc), objtype=linebuf_type, typedesc=typedesc.strip())
def do_run(self, argv): """Spawn a shell from target server. USAGE: run DESCRIPTION: Connect to remote target URL (`help set TARGET`). If payload (`run --get-payload`) is correctly injected in target URL, Omega spawns a remote shell. OPTIONS: --get-payload Display current payload code, as it should be injected on target URL. """ obj = str(session.Conf.PAYLOAD(call=False)) obj = obj.replace("%%PASSKEY%%", session.Conf.PASSKEY().upper()) if len(argv) > 1: if argv[1] == "--get-payload": print(obj) return True self.interpret("help run") return False print("[*] Current payload is: " + obj + "\n") if tunnel: m = ("[*] Use `set TARGET <value>` to use another url as target." "\n[*] To exploit a new server, disconnect from «{}» first.") print(m.format(session.Env.HOST)) return False if session.Conf.TARGET() is None: m = ("To run a remote tunnel, the payload shown above must be\n" "manually injected in a remote server executable web page.\n" "Then, use `set TARGET <payloaded_url>` and run `run`.") print(colorize("%BoldCyan", m)) return False return tunnel.open() # it raises exception if fails
def do_exploit(self, argv): """Spawn a shell from target server SYNOPSIS: exploit [--get-backdoor] DESCRIPTION: Connect to remote target URL (`help set TARGET`). If backdoor (`exploit --get-backdoor`) is correctly injected in target URL, phpsploit spawns a remote shell. OPTIONS: --get-backdoor Display current backdoor code, as it should be injected on target URL. """ obj = str(session.Conf.BACKDOOR(call=False)) obj = obj.replace("%%PASSKEY%%", session.Conf.PASSKEY().upper()) if len(argv) > 1: if argv[1] == "--get-backdoor": print(obj) return True self.interpret("help exploit") return False print("[*] Current backdoor is: " + obj + "\n") if tunnel: m = ("[*] Use `set TARGET <VALUE>` to use another url as target." "\n[*] To exploit a new server, disconnect from «{}» first.") print(m.format(session.Env.HOST)) return False if session.Conf.TARGET() is None: m = ("To run a remote tunnel, the backdoor shown above must be\n" "manually injected in a remote server executable web page.\n" "Then, use `set TARGET <BACKDOORED_URL>` and run `exploit`.") print(colorize("%BoldCyan", m)) return False return tunnel.open() # it raises exception if fails
def __init__(self, path): if path.endswith(os.sep) or path.endswith("/"): path = path[:-1] self.path = path self.name = os.path.basename(path) self.argv = [] # redefined at runtime on run() try: Path(path, mode='drx')() except ValueError as e: print("[#] Couldn't load plugin: «%s»" % self.path) print("[#] Plugin directory error: %s" % e) print("[#] ") raise BadPlugin category = os.path.basename(os.path.dirname(path)) self.category = category.replace("_", " ").capitalize() self.help = "" try: script = Path(self.path, "plugin.py", mode='fr').read() except ValueError as e: print("[#] Couldn't load plugin: «%s»" % self.path) print("[#] File error on plugin.py: %s" % e) print("[#] ") raise BadPlugin if not script.strip(): print("[#] Couldn't load plugin: «%s»" % self.path) print("[#] File plugin.py is empty") print("[#] ") raise BadPlugin try: code = compile(script, "", "exec") except BaseException as e: print("[#] Couldn't compile plugin: «%s»" % self.path) e = traceback.format_exception(type(e), e, e.__traceback__) for line in "".join(e).splitlines(): print(colorize("[#] ", "%Red", line)) # print("[#] " + "\n[#] ".join("".join(e).splitlines())) print("[#] ") raise BadPlugin if "__doc__" in code.co_names: self.help = code.co_consts[0]
def postcmd(self, retval, argv): """Post command hook Redraw shell prompt """ int_retval = self.return_errcode(retval) print("[#] %s: Returned %d" % (self.debug_cmdrepr(argv), int_retval)) # redraw shell prompt after each command prompt_elems = ["%Lined", "phpsploit"] if tunnel: # if remote shell, add target hostname to prompt prompt_elems += ["%Reset", "(", "%BoldRed", tunnel.hostname, "%Reset", ")"] if self.bind_command: # If a command is binded to the prompt prompt_elems += ["%ResetBoldWhite", " #", self.bind_command] prompt_elems += ["%Reset", " > "] self.prompt = colorize(*prompt_elems) return retval
def postcmd(self, retval, argv): """Post command hook Redraw shell prompt """ int_retval = self.return_errcode(retval) print("[v] %s: Returned %d" % (self.debug_cmdrepr(argv), int_retval)) # redraw shell prompt after each command prompt_elems = ["%Lined", "omega"] if tunnel: # if remote shell, add target hostname to prompt prompt_elems += ["%Reset", "(", "%BoldRed", tunnel.hostname, "%Reset", ")"] if self.bind_command: # If a command is binded to the prompt prompt_elems += ["%ResetBoldWhite", " #", self.bind_command] prompt_elems += ["%Reset", "> "] self.prompt = colorize(*prompt_elems) return retval
def __str__(self): """Get a colored string representation of current object >>> MultiLineBuffer("monoline") monoline >>> MultiLineBuffer("file:///etc/passwd") <MultiLine@/etc/passwd (24 lines)> >>> MultiLineBuffer("line1\\nline2") <MultiLine (2 lines)> """ # if buffer has a single line, use it as representation: if not self.file and len(self.buffer.splitlines()) == 1: return str(self._validator(self.buffer.strip())) # otherwise, use complex representation: obj_id = self.file if not obj_id: obj_id = hashlib.md5(self.buffer.encode('utf-8')).hexdigest() lines_str = " (%s lines)" % len(self.buffer.splitlines()) return colorize("%BoldBlack", "<", "%BoldBlue", "MultiLine", "%BasicCyan", "@", "%Bold", obj_id, "%BasicBlue", lines_str, "%BoldBlack", ">")
def doc_help(docLines): """print the formated command's docstring""" # reject empty docstrings (description + empty line) if len(docLines) < 2: return None docLines.pop(0) # remove the description line while not docLines[0].strip(): docLines.pop(0) # remove heading empty lines # remove junk leading spaces (due to python indentation) trash = len(docLines[0]) - len(docLines[0].lstrip()) docLines = [line[trash:].rstrip() for line in docLines] # hilight lines with no leading spaces (man style) result = str() for line in docLines: if line == line.lstrip(): line = colorize("%BoldWhite", line) result += line + "\n" print(result)
def __str__(self): self_str = super().__str__() if self == 1: return "1 byte" number = float(self) for index in range(len(self._metrics)): if number < 1024.0 or index == len(self._metrics) - 1: break number /= 1024.0 intLen = len(str(int(number))) precision = max(0, (3 - intLen)) number = str(round(number, precision)).rstrip('0').rstrip('.') byteNames = ('bytes', 'KiB', 'MiB', 'GiB', 'TiB') result = number + " " + byteNames[index] if index > 0: result += colorize(" ", '%DimWhite', "(%s bytes)" % self_str) return result
def __str__(self): """Get a colored string representation of current object >>> RandLineBuffer("singleChoice") singleChoice >>> RandLineBuffer("file:///etc/passwd") <RandLine@/etc/passwd (24 choices)> >>> RandLineBuffer("choice1\\nchoice2") <RandLine (2 choices)> """ # if buffer has a single line, use it as representation: if not self.file and len(self.buffer.splitlines()) == 1: return str(self._validator(self.buffer.strip())) # otherwise, use complex representation: obj_id = self.file if not obj_id: obj_id = hashlib.md5(self.buffer.encode('utf-8')).hexdigest() num = len(self.choices()) choices = " (%s choice%s)" % (num, ('', 's')[num > 1]) return colorize("%BoldBlack", "<", "%BoldBlue", "RandLine", "%BasicCyan", "@", "%Bold", obj_id, "%BasicBlue", choices, "%BoldBlack", ">")
def __str__(self): self_str = super().__str__() if self == 1: return "1 byte" number = float(self) for index in range(len(self._metrics)): if number < 1024.0 or index == len(self._metrics)-1: break number /= 1024.0 intLen = len(str(int(number))) precision = max(0, (3 - intLen)) number = str(round(number, precision)).rstrip('0').rstrip('.') byteNames = ('bytes', 'KiB', 'MiB', 'GiB', 'TiB') result = number + " " + byteNames[index] if index > 0: result += colorize(" ", '%DimWhite', "(%s bytes)" % self_str) return result
def Send(self, request): """Main request Sender: if takes the concerned request object as argument and returns the unparsed and decapsulated phpsploit response """ multiReqLst = request[:-1] lastRequest = request[-1] def updateStatus(curReqNum): curReqNum += 1 # don't belive the fact that humans count from 1 ! numOfReqs = str(len(multiReqLst) + 1) curReqNum = str(curReqNum).zfill(len(numOfReqs)) statusMsg = "Sending request %s of %s" % (curReqNum, numOfReqs) sys.stdout.write('\r[*] %s' % statusMsg) sys.stdout.flush() # considering that the multiReqLst can be empty, is means that the # following loop is only executer on multipart payloads. for curReqNum in range(len(multiReqLst)): interrupt_err = ('Send Error: Multipart transfer interrupted\n' 'The remote temporary payload «%s» must be ' 'manually removed.' % self.tmpdir) sent = False while not sent: updateStatus(curReqNum) response = self.send_single_request(multiReqLst[curReqNum]) error = response['error'] # keyboard interrupt imediately leave with error if error == 'HTTP Request interrupted': return interrupt_err # on multipart reqs, all except last MUST return the string 1 if not error and response['data'] != b'1': error = 'Execution error' # if the current request failed if error: msg = " (Press Enter or wait 1 minut for the next try)" sys.stdout.write(colorize("\n[-] ", error, "%White", msg)) waitkey = ui.input.Expect(None) waitkey.timeout = 60 waitkey.skip_interrupt = False try: waitkey() except (KeyboardInterrupt, EOFError): return interrupt_err # if the request has been corretly executed, wait the # REQ_INTERVAL setting, and then go to the next request else: try: time.sleep(session.Conf.REQ_INTERVAL()) except: return interrupt_err sent = True # if it was a multipart payload, print status for last request if len(multiReqLst): updateStatus(len(multiReqLst)) print('') # treat the last or single request response = self.send_single_request(lastRequest) if response['error']: return response['error'] return response
def get_description(docLines): """return the command description (1st docstring line)""" try: return docLines[0].strip() except: return colorize("%Yellow", "No description")
def do_corectl(self, argv): """Advanced core debugging utils SYNOPSIS: corectl <TOOL> CORECTL TOOLS: -------------- stack-traceback Print the full track trace of last python exception. Error messages (lines that starts with a `[!]` red tag) are generated by a thrown exception. The `stack-traceback` tool displays the full python stack trace of the last thrown exception. This command is useful for debugging purposes. NOTE: stack traceback is NOT saved in session files reload-plugins Reload all phpsploit plugins. By default, the list of phpsploit plugins is loaded once only, when the framework starts. Therefore, plugin developpers may want to reload the plugins in order to be able to test their plugin modifications without having to restart the framework each time. python-console Run a python interpreter. The python console interpreter is a good gateway for deep debugging, or to get help about a phpsploit module, class, object, such as the plugin developpers API. For help with the API, run the following commands inside of the python console: >>> import api >>> help(api) display-http-requests Display HTTP(s) request(s) for debugging Shows all HTTP(s) request(s) that where sent in the last remote command execution. NOTE: http requests are NOT saved in session files WARNING: don't works with HTTPS requests (see issue #29 on github) """ argv.append('') if argv[1] == "stack-traceback": try: e = self.last_exception e = traceback.format_exception(type(e), e, e.__traceback__) # a small patch for traceback from plugins, remove trash lines for index, line in enumerate(e): if ('File "<frozen importlib._bootstrap>"' in line and '_call_with_frames_removed' in line): e = e[(index + 1):] header = "Traceback (most recent call last):" e.insert(0, header + os.linesep) break e = colorize("%Red", "".join(e)) except: e = "[-] Exception stack is empty" print(e) elif argv[1] == "reload-plugins": plugins.reload(verbose=True) elif argv[1] == "python-console": import ui.console console = ui.console.Console() console.banner = "Phpsploit corectl: python console interpreter" console() elif argv[1] == "display-http-requests": requests = enumerate(tunnel.get_raw_requests(), 1) if not requests: print("[-] No HTTP(s) requests were sent up to now") return for num, request in requests: print("#" * 78) print("### REQUEST %d" % num) print("#" * 78) print(encoding.decode(request)) else: self.interpret("help corectl")
rows_hdr = ["Mode", "Owner", "Group", "Size", "Last Modified", "Name"] rows = ([l[0], l[2], l[3], l[4], l[5], l[6]] for l in lines) # otherwise, use windows-like formatter else: rows_hdr = ["Mode", "Size", "Last Modified", "Name"] rows = ([x[1], x[4], x[5], x[6]] for x in lines) # format rows the right way rows = sorted(rows, key=(lambda elem: elem[-1])) rows.insert(0, rows_hdr) rows.insert(1, [("-" * len(elem)) for elem in rows_hdr]) # format and display output title header = "Listing: %s" % target if regex: header += " (matching r'%s')" % colorize("%White", regex) print("\n" + header + "\n" + ("=" * len(decolorize(header))) + "\n") widths = [max(map(len, col)) for col in zip(*rows)] for i, row in enumerate(rows): if i > 0: if row[0].startswith('d'): row[-1] = colorize("%BoldBlue", row[-1]) elif not row[0].startswith('-'): row[-1] = colorize("%BoldPink", row[-1]) print(" ".join((val.ljust(width) for val, width in zip(row, widths)))) print() sys.exit(status)
def __str__(self): return colorize("%BoldCyan", "True" if self else "False")
def __str__(self): if self: return colorize('%Cyan', self._raw_value()) else: return colorize('%Cyan', "default")