mirror of
https://github.com/Pennyw0rth/NetExec
synced 2026-06-06 16:34:30 +00:00
Add upload/download function to mssql
This commit is contained in:
@@ -47,6 +47,10 @@ class mssql(connection):
|
||||
psgroup.add_argument('--obfs', action='store_true', help='Obfuscate PowerShell scripts')
|
||||
psgroup.add_argument('--clear-obfscripts', action='store_true', help='Clear all cached obfuscated PowerShell scripts')
|
||||
|
||||
tgroup = mssql_parser.add_argument_group("Files", "Options for put and get remote files")
|
||||
tgroup.add_argument("--put-file", nargs=2, metavar="FILE", help='Put a local file into remote target, ex: whoami.txt C:\\Windows\\Temp\\whoami.txt')
|
||||
tgroup.add_argument("--get-file", nargs=2, metavar="FILE", help='Get a remote file, ex: C:\\Windows\\Temp\\whoami.txt whoami.txt')
|
||||
|
||||
return parser
|
||||
|
||||
def proto_flow(self):
|
||||
@@ -279,6 +283,32 @@ class mssql(connection):
|
||||
ps_command = create_ps_command(payload, force_ps32=force_ps32, dont_obfs=dont_obfs)
|
||||
return self.execute(ps_command, get_output)
|
||||
|
||||
@requires_admin
|
||||
def put_file(self):
|
||||
self.logger.info('Copy {} to {}'.format(self.args.put_file[0], self.args.put_file[1]))
|
||||
with open(self.args.put_file[0], 'rb') as f:
|
||||
try:
|
||||
data = f.read()
|
||||
self.logger.info('Size is {} bytes'.format(len(data)))
|
||||
exec_method = MSSQLEXEC(self.conn)
|
||||
exec_method.put_file(data, self.args.put_file[1])
|
||||
if exec_method.file_exists(self.args.put_file[1]):
|
||||
self.logger.success('File has been uploaded on the remote machine')
|
||||
else:
|
||||
self.logger.error('File does not exist on the remote system.. erorr during upload')
|
||||
except Exception as e:
|
||||
self.logger.error('Error during upload : {}'.format(e))
|
||||
|
||||
@requires_admin
|
||||
def get_file(self):
|
||||
self.logger.info('Copy {} to {}'.format(self.args.get_file[0], self.args.get_file[1]))
|
||||
try:
|
||||
exec_method = MSSQLEXEC(self.conn)
|
||||
exec_method.get_file(self.args.get_file[0], self.args.get_file[1])
|
||||
self.logger.success('File {} was transferred to {}'.format(self.args.get_file[0], self.args.get_file[1]))
|
||||
except Exception as e:
|
||||
self.logger.error('Error reading file {}: {}'.format(self.args.get_file[0], e))
|
||||
|
||||
# We hook these functions in the tds library to use CME's logger instead of printing the output to stdout
|
||||
# The whole tds library in impacket needs a good overhaul to preserve my sanity
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import logging
|
||||
|
||||
import binascii
|
||||
|
||||
class MSSQLEXEC:
|
||||
|
||||
@@ -31,3 +31,43 @@ class MSSQLEXEC:
|
||||
|
||||
def disable_xp_cmdshell(self):
|
||||
self.mssql_conn.sql_query("exec sp_configure 'xp_cmdshell', 0 ;RECONFIGURE;exec sp_configure 'show advanced options', 0 ;RECONFIGURE;")
|
||||
|
||||
def enable_ole(self):
|
||||
self.mssql_conn.sql_query("exec master.dbo.sp_configure 'show advanced options',1;RECONFIGURE;exec master.dbo.sp_configure 'Ole Automation Procedures', 1;RECONFIGURE;")
|
||||
|
||||
def disable_ole(self):
|
||||
self.mssql_conn.sql_query("exec master.dbo.sp_configure 'show advanced options',1;RECONFIGURE;exec master.dbo.sp_configure 'Ole Automation Procedures', 0;RECONFIGURE;")
|
||||
|
||||
def put_file(self, data, remote):
|
||||
try:
|
||||
self.enable_ole()
|
||||
hexdata = data.hex()
|
||||
self.mssql_conn.sql_query("DECLARE @ob INT;"
|
||||
"EXEC sp_OACreate 'ADODB.Stream', @ob OUTPUT;"
|
||||
"EXEC sp_OASetProperty @ob, 'Type', 1;"
|
||||
"EXEC sp_OAMethod @ob, 'Open';"
|
||||
"EXEC sp_OAMethod @ob, 'Write', NULL, 0x{};"
|
||||
"EXEC sp_OAMethod @ob, 'SaveToFile', NULL, '{}', 2;"
|
||||
"EXEC sp_OAMethod @ob, 'Close';"
|
||||
"EXEC sp_OADestroy @ob;".format(hexdata, remote))
|
||||
self.disable_ole()
|
||||
except Exception as e:
|
||||
logging.debug('Error uploading via mssqlexec: {}'.format(e))
|
||||
|
||||
def file_exists(self, remote):
|
||||
try:
|
||||
res = self.mssql_conn.batch("DECLARE @r INT; EXEC master.dbo.xp_fileexist '{}', @r OUTPUT; SELECT @r as n".format(remote))[0]['n']
|
||||
return res == 1
|
||||
except:
|
||||
return False
|
||||
|
||||
def get_file(self, remote, local):
|
||||
try:
|
||||
self.mssql_conn.sql_query("SELECT * FROM OPENROWSET(BULK N'{}', SINGLE_BLOB) rs".format(remote))
|
||||
data = self.mssql_conn.rows[0]['BulkColumn']
|
||||
|
||||
with open(local, 'wb+') as f:
|
||||
f.write(binascii.unhexlify(data))
|
||||
|
||||
except Exception as e:
|
||||
logging.debug('Error downloading via mssqlexec: {}'.format(e))
|
||||
Reference in New Issue
Block a user