jueves, 16 de mayo de 2013

smb-psexec.nse: owning Windows, fast!

You can use Metasploit psexec module, it's more easy but some time we have prohibited/cannot use Metasploit in some cases.

  1. What does smb-psexec do?
  2. Sample configurations ("sample.lua")
  3. Default configuration ("default.lua")

1) What does smb-psexec do?

Getting started

smb-psexec.nse script (source) for Nmap or you can execute:
nmap --script-updatedb #to update nmap nse scripts.
It's a fairly new script, but as I use it and play with it, I'm getting more confident in its usefulness/stability.
So anyway, let's start off simple. Today's post will be, what does smb-psexec.nse do?

What does it do?

Well, simply enough, it runs programs somewhere else. Specfically, on a remote Windows machine. It uses the same concepts as Microsoft Sysinternals' psexec tool, which does essentially the same thing (but in a more limited sense). It also uses the same techniques as the Metasploit Framework's psexec module. These tools are great, and do the job perfectly, so why did I bother writing my own?

Why should I care?

I'll get deeper into some of these points in later blog postings, but for now here's a quick list::
  • Multi-platform -- smb-psexec.nse, including its required SMB/MSRPC libraries, is implemented from scratch in Lua, and therefore can run on any operating system that Nmap runs on. That means it'll run on nearly ever platform, including Linux, Windows, BSD, OSX, etc.
  • Multiple executables -- While other tools are designed to run a single remote service, smb-psexec, is designed to run any number of executables in a single execution.
  • Multiple targets -- Nmap's scanning capabilities are leveraged here; with Nmap scanning, a wide range of hosts is as easy as scanning a single host.
  • Local or remote executables -- The executable files can be stored locally on the attacker system (say, fgdump.exe) or can already be on the target system (say, ping.exe or tracert.exe).
  • Configuration-based -- Each scan uses a configuration file to set its options. As a result, scans are easily configurable and repeatable.
  • Output formatting -- The configuration files make it easy to format the output from each remote process, allowing you to filter out excess output.
The biggest downside with smb-psexec.nse is the loss of interactivity. Because Nmap is written as a scanner, and these scripts are run in parallel, there is no opportunity for user input. But we aren't focusing on the bad stuff today!

What do you need?

So, that's what the script does. Now, before you can run it, what do you need? You'll need the following:
  • Administrator account on the remote system
  • TCP port 139 or 445 open on the remote system
  • The ability to create services on the remote system

Admin account

So, the first requirement is easy. You need an administrator account to run services on the machine. Thank $favourite_deity for that; if anybody could run a process on any machine, things would be a lot easier for the bad guys.
The most obvious way to provide credentials is to pass them on the commandline:
nmap -p139,445 --script=smb-psexec --script-args=smbuser=ron,smbpass=Password1 <target>
But, if you either don't know the username/password, or you have many machines with different accounts, you can combine smb-psexec.nse with smb-brute.nse:
nmap -p139,445 --script=smb-brute,smb-psexec <target>
Obviously, when you're performing a bruteforce, there's the possibility of locking out accounts. For that reason, only do that on machine(s) that either you own, or you know the policies on!

Ports

The second requirement is that TCP port 139 or 445 has to be open. These ports are functionally equivalent for our purposes, so it doesn't matter which one is open; TCP/445 is raw SMB, and TCP/139 is SMB over NetBIOS -- Nmap will autodetect and function accordingly. For what it's worth, TCP/445 is preferred because it has less overhead.
Anyway, as I'm sure you all know, modern versions of Windows (Windows XP SP2, Windows 2003 SP1, Windows Vista, etc) enable the Windows firewall by default. Likewise, many organizations have software firewalls, hardware firewalls, or both. These will obviously block your SMB traffic, and rightly so. Would you want an external entity running smb-psexec.nse?
So, if you're going to run smb-psexec.nse, double check that those ports are open.

Service creation

The final requirement is the ability to create services on the remote system. It sounds simple, but the problem is twofold. The first problem is, the appropriate services have to be enabled; starting with Vista, they're disabled by default. From a quick look, I didn't find the specific services, but there is a generic way to enable them. See the link at the bottom of this section.
The second problem is that User Account Control (UAC) has to be turned off. Starting on Vista, administrators are treated as ordinary users as long as UAC is enabled. In an odd way this makes sense because the point of UAC is that Windows refuses to grant elevated privileges to any accounts without a user explicitly allowing it.
If you want to run smb-psexec.nse against a modern Windows version, here's a guide for setting it up.

Running this script from Windows

It came to my attention this weekend that, up to and including Nmap 5.10BETA1, the Windows version of Nmap is missing some of the required files for smb-psexec.nse to run. Your best bet is to download the Linux version found here, grab the folder nselib/data/psexec, and place it in c:\program files\Nmap\nselib\data. This will be resolved in any version newer than 5.10BETA1.

2) Sample configurations ("sample.lua")

For what it's worth, this information is lifted, though heavily modified, from the NSEDoc for the script.

Configuration files

The configuration file for smb-psexec.nse is stored in the nselib/data/psexec directory. Depending on which operating system you're on, and how you install Nmap, it might be in one of the following places:
  • /usr/share/nmap/nselib/data/psexec
  • /usr/local/share/nmap/nselib/data/psexec
  • C:\Program Files\Nmap\nselib\data\psexec
Note that up to and including Nmap 5.10BETA1, this folder will be missing on Windows. You'll need to download the Linux install and extract the 'psexec' folder.
The configuration file is mostly a module list. Each module is a program to run, and it's defined by a Lua table. It has, for example, the executable to run and the arguments to pass to it. There are all kinds of options, but it's probably easiest just to look at an example (note: all examples can be found in examples.lua, which is included with Nmap).
To test this stuff out, copy one of the built-in configuration files (such as example.lua), edit it, and run it with:
nmap -p139,445 -d --script=smb-psexec
    --script-args=smbuser=<username>,smbpass=<password>,config=<yourfilename> <target>
For example:
nmap -p139,445 -d --script=smb-psexec
    --script-args=smbuser=ron,smbpass=nor,config=experimental 10.0.0.123

Example 1: Getting started

  mod = {}
  mod.upload           = false
  mod.name             = "Example 1: Membership of 'administrators'"
  mod.program          = "net.exe"
  mod.args             = "localgroup administrators"
  table.insert(modules, mod)
Let's take a closer look at the fields.
mod.upload is false, indicating that the program is already present on the remote system. Since the program is 'net.exe', it's installed by default on Windows and, obviously, doesn't have to be uploaded.
mod.name is simply used as part of the output.
mod.program and mod.args obviously define which program to run and the arguments to run it with. In this case, we're running "net localgroup administrators", which displays the list of administrators on the remote system. The output for this script is this:
  |  Example 1: Membership of 'administrators'
  |  | Alias name     administrators
  |  | Comment        Administrators have complete and unrestricted access to the
computer/domain
  |  |
  |  | Members
  |  |
  |  | -------------------------------------------------------------------------------
  |  | Administrator
  |  | ron
  |  | test
  |  | The command completed successfully.
  |  |
  |  |_
That works, but it's pretty ugly. If you're scanning a lot of systems, you're going to end up with a lot of empty lines and other junk that you just don't need.

Example 2: Cleaning it up

But, there's a solution! We can use some other fields to clean up the output, including:
  • mod.find -- Like 'grep', only lines that match the given pattern will be displayed.
  • mod.remove -- The opposite of 'find'; any lines containing the pattern are not displayed.
  • mod.replace -- A typical match/replace.
  • mod.noblank -- Remove blank lines.
A couple things worth noting here. This cleanup is done on the client, after the data has been returned from the server. So, if you're worried about a password field crossing the wire, or your output is thousands of lines, this isn't going to speed anything up. Additionally, the patterns are Lua patterns.
So let's apply a few of these fields to our previous output:
  mod = {}
  mod.upload           = false
  mod.name             = "Example 2: Membership of 'administrators', cleaned"
  mod.program          = "net.exe"
  mod.args             = "localgroup administrators"
  mod.remove           = {"The command completed", "%-%-%-%-%-%-%-%-%-%-%-", "Members",
                                 "Alias name", "Comment"}
  mod.noblank          = true
  table.insert(modules, mod)
Now we're using mod.remove to remove some of the crap, as well as mod.noblank to remove the blank lines.
We can see that the output is now much cleaner:
  |  Example 2: Membership of 'administrators', cleaned
  |  | Administrator
  |  | ron
  |  |_test

Example 3: Find/replace

For our next command, we're going to run ipconfig.exe, which outputs a significant amount of information. Let's say that all we want is the IP address and MAC address. Let's look at how to do it.
  mod = {}
  mod.upload           = false
  mod.name             = "Example 3: IP Address and MAC Address"
  mod.program          = "ipconfig.exe"
  mod.args             = "/all"
  mod.maxtime          = 1
  mod.find             = {"IP Address", "Physical Address", "Ethernet adapter"}
  mod.replace          = {{"%. ", ""}, {"-", ":"}, {"Physical Address", "MAC Address"}}
  table.insert(modules, mod)
Go ahead and type ipconfig /all to see what it looks like; I'll wait right here.
This time, we use the mod.find to list the lines we want. Obviously, we're looking for three patterns: "IP Address", "Physical Address", and "Ethernet adapter". Then, we use mod.replace to replace ". " with nothing, "-" with ":", and "Physical Address" with "MAC Address" (arguably unnecessary). Here's the final output:
  |  Example 3: IP Address and MAC Address
  |  | Ethernet adapter Local Area Connection:
  |  |    MAC Address: 00:0C:29:12:E6:DB
  |  |_   IP Address: 192.168.1.21

Example 4 and 5: Variables

Next topic: variables!
Variables can be used in any field in the configuration file, such as find/replace, arguments, program name, etc. There are two types of variables: built-in and user-supplied.
Built-in variables are set by the script. There are tons of them available, ranging in usefulness. Here are a bunch of them (I tried to put the more useful ones at the top):
  • $lhost: The address of the scanner
  • $rhost: The address being scanned
  • $path: The path to which the scripts were uploaded (eg, "C:\WINDOWS")
  • $share: The share where the script was uploaded (eg, "\\ADMIN$")
  • $lport: local port (meaningless; it'll change by the time the module is uploaded since multiple connections are made).
  • $rport: remote port (likely going to be 445 or 139).
  • $lmac: local mac address as a string in the xx:xx:xx:xx:xx:xx format (note: only set if the Nmap is running as root).
  • $service_name: the name of the service that is running this program
  • $service_file: the name of the executable file for the service
  • $temp_output_file: The (ciphered) file where the programs' output will be written before being renamed to $output_file
  • $output_file: The final name of the (ciphered) output file. When this file appears, the script downloads it and stops the service
  • $timeout: The total amount of time the script is going to run before it gives up and stops the process


User-supplied variables are provided on the commandline (in the --script-args argument) by the user when he or she runs the program. For example, to set the $test variable to 123, the user would pass --script-args=123. The required variables are controlled by the mod.req_args field in the configuration file, so to make $test a required field, you'd add mod.req_args to "test".
Here is a module that pings the local ip address, $lhost, which is a built-in variable:
  mod = {}
  mod.upload           = false
  mod.name             = "Example 4: Can the host ping our address?"
  mod.program          = "ping.exe"
  mod.args             = "$lhost"
  mod.remove           = {"statistics", "Packet", "Approximate", "Minimum"}
  mod.noblank          = true
  mod.env              = "SystemRoot=c:\\WINDOWS"
  table.insert(modules, mod)
And the output:
  |  Example 4: Can the host ping our address?
  |  | Pinging 192.168.1.100 with 32 bytes of data:
  |  | Reply from 192.168.1.100: bytes=32 time<1ms TTL=64
  |  | Reply from 192.168.1.100: bytes=32 time<1ms TTL=64
  |  | Reply from 192.168.1.100: bytes=32 time<1ms TTL=64
  |  |_Reply from 192.168.1.100: bytes=32 time<1ms TTL=64
And this module pings an arbitrary address that the user is expected to give, $host:
 mod = {}
 mod.upload           = false
 mod.name             = "Example 5: Can the host ping $host?"
 mod.program          = "ping.exe"
 mod.args             = "$host"
 mod.remove           = {"statistics", "Packet", "Approximate", "Minimum"}
 mod.noblank          = true
 mod.env              = "SystemRoot=c:\\WINDOWS"
 mod.req_args         = {'host'}
 table.insert(modules, mod)
And the output:
$ ./nmap -n -d -p445 --script=smb-psexec --script-args=smbuser=test,smbpass=test,config=examples,host=1.2.3.4 192.168.1.21
 |  Example 5: Can the host ping 1.2.3.4?
 |  | Pinging 1.2.3.4 with 32 bytes of data:
 |  | Request timed out.
 |  | Request timed out.
 |  | Request timed out.
 |  |_Request timed out.

Example 6: Uploading

For the final example, we'll use the 'upload' setting to upload the "fgdump.exe", run it, download its output file, and clean up its logfile. You'll have to put fgdump.exe in the same folder as the script for this to work:
  mod = {}
  mod.upload           = true
  mod.name             = "Example 6: FgDump"
  mod.program          = "fgdump.exe"
  mod.args             = "-c -l fgdump.log"
  mod.url              = "http://www.foofus.net/fizzgig/fgdump/"
  mod.tempfiles        = {"fgdump.log"}
  mod.outfile          = "127.0.0.1.pwdump"
  table.insert(modules, mod)
The -l argument for fgdump (in mod.args) supplies the name of the logfile. That file is listed in the mod.tempfiles field. What, exactly, does mod.tempfiles do? It simply gives Nmap a list of files to delete after the program runs. It's good for deleting logfiles other other artifacts your programs leave.
mod.url is displayed to the user in an error message if mod.program isn't found in Nmap's data directory. And finally,mod.outfile is the file that is downloaded from the system, since fgdump.exe doesn't print to stdout (pwdump6, for example, doesn't require mod.outfile).

Fields in 'mod'

The following is a list of all possible fields in the 'mod' variable:
  • upload (boolean) true if it's a local file to upload, false if it's already on the host machine. If upload is true, program has to be in nselib/data/psexec.
  • name (string) The name to display above the output. If this isn't given, program .. args are used.
  • program (string) If upload is false, the name (fully qualified or relative) of the program on the remote system; if upload is true, the name of the local file that will be uploaded (stored in nselib/data/psexec).
  • args (string) Arguments to pass to the process.
  • env (string) Environmental variables to pass to the process, as name=value pairs, delimited, per Microosft's spec, by NULL characters (string.char(0)).
  • maxtime (integer) The approximate amount of time to wait for this process to complete. The total timeout for the script before it gives up waiting for a response is the total of all 'maxtime' fields.
  • extrafiles (string[]) Extra file(s) to upload before running the program. These will not be renamed (because, presumably, if they are then the program won't be able to find them), but they will be marked as hidden/system/etc. This may cause a race condition if multiple people are doing this at once, but there isn't much we can do. The files are also deleted afterwards as tempfiles would be. The files have to be in the same directory as programs (nselib/data/psexec), but the program doesn't necessarily need to be an uploaded one.
  • tempfiles (string[]) A list of temporary files that the process is known to create (if the process does create files, using this field is recommended because it helps avoid making a mess on the remote system)
  • find (string[]) Only display lines that contain the given string(s) (for example, if you're searching for a line that contains 'IP Address', set this to {'IP Address'}. This allows Lua-style patterns, see: (don't forget to escape special characters with a '%'). Note that this is client-side only; the full output is still returned, the rest is removed while displaying. The line of output only needs to match one of the strings given here.
  • remove (string[]) Opposite of find; this removes lines containing the given string(s) instead of displaying them. Like find, this is client-side only and uses Lua-style patterns. If 'remove' and 'find' are in conflict, the 'remove' takes priority.
  • noblank (boolean) Setting this to true removes all blank lines from the output.
  • replace (table) A table of values to replace in the strings returned. Like find and replace, this is client-side only and uses Lua-style patterns.
  • headless (boolean) If 'headless' is set to true, the program doesn't return any output; rather, it runs detached from the service so that, when the service ends, the program keeps going. This can be useful for, say, a monitoring program. Or a backdoor, if that's what you're into (a Metasploit payload should work nicely). Not compatible with: find, remove, noblank, replace, maxtime, outfile.
  • enabled (boolean) Set to false, and optionally set disabled_message, if you don't want a module to run. Alternatively, you can comment out the process.
  • disabled_message (string) Displayed if the module is disabled.
  • url (string) A module where the user can download the uploadable file. Displayed if the uploadable file is missing.
  • outfile (string) If set, the specified file will be returned instead of stdout.
  • req_args (string[]) An array of arguments that the user must set in --script-args.
As you can see, there are a ton of options. Check out my default scripts for more ideas/examples!

3 ) Default configuration ("default.lua")

Getting started

Hopefully you all read the last two posts. I started with an introduction to smb-psexec.nse in the first post, then went over some "example" configurations in the second. The example configurations are nice to study because I designed them to be instructive, but today's post is going to look at some real configurations I'm including. You'll notice that many are actually the same or very similar to the example configurations, and that's intentional. As of the Nmap 5.10beta1 and beta2 versions, these are included in default.lua.

Configuration files

The configuration file for smb-psexec.nse is stored in the nselib/data/psexec directory. Depending on which operating system you're on, and how you installed Nmap, it might be in one of the following places:
  • /usr/share/nmap/nselib/data/psexec
  • /usr/local/share/nmap/nselib/data/psexec
  • C:\Program Files\Nmap\nselib\data\psexec
Note that up to and including Nmap 5.10BETA2, this folder will be missing on Windows. You'll need to download the Linux install and copy over the folder.
Now, without further ado, let's take a look at the configurations, one at a time.

Command 1: Windows version

mod = {}
mod.upload           = false
mod.name             = "Windows version"
mod.program          = "cmd.exe"
mod.args             = "/c \"ver\""
mod.maxtime          = 1
mod.noblank          = true
table.insert(modules, mod)
This command displays the full version of Windows by running the "ver" command.
Interestingly, this command wouldn't work when I tried running it directly. You'll see this theme running throughout my configuration files -- bugs where certain programs require certain variables to be set or certain environments that don't seem to make sense. I've learned how to work around many of them, but be warned if you're writing configurations yourself: things may not always work as you expect.
Output on Windows 2000:
|   Windows version
|     Microsoft Windows 2000 [Version 5.00.2195]
Windows Server 2003:
|   Windows version
|     Microsoft Windows [Version 5.2.3790]

Command 2: IP/MAC address

mod = {}
mod.upload           = false
mod.name             = "IP Address and MAC Address from 'ipconfig.exe'"
mod.program          = "ipconfig.exe"
mod.args             = "/all"
mod.maxtime          = 1
mod.find             = {"IP Address", "Physical Address", "Ethernet adapter"}
mod.replace          = {{"%. ", ""}, {"-", ":"}, {"Physical Address", "MAC Address"}}
table.insert(modules, mod)
I believe this one is either similar to or the same as the sample configuration from examples.lua, so I won't dwell on it.
Output:
|   IP Address and MAC Address from 'ipconfig.exe'
|     Ethernet adapter Local Area Connection 2:
|       MAC Address: 00:50:56:A1:24:C2
|       IP Address: 10.0.0.30
|     Ethernet adapter Local Area Connection:
|       MAC Address: 00:50:56:A1:00:65

Commands 3 and 4: List of users

mod = {}
mod.upload           = false
mod.name             = "User list from 'net user'"
mod.program          = "net.exe"
mod.args             = "user"
mod.maxtime          = 1
mod.remove           = {"User accounts for", "The command completed",
                        "%-%-%-%-%-%-%-%-%-%-%-"}
mod.noblank          = true
table.insert(modules, mod)

mod.upload           = false
mod.name             = "Membership of 'administrators' from 'net localgroup administrators'"
mod.program          = "net.exe"
mod.args             = "localgroup administrators"
mod.maxtime          = 1
mod.remove           = {"The command completed", "%-%-%-%-%-%-%-%-%-%-%-", "Members",
                       "Alias name", "Comment"}
mod.noblank          = true
table.insert(modules, mod)
As before, these commands were discussed previously. Strictly speaking, these aren't the most useful commands to run because identical information can be obtained from running smb-enum-users.nse and smb-enum-groups.nse.
Output:
|   User list from 'net user'
|     Administrator            AKolmakov                Guest
|     IUSR_RON-WIN2K-TEST      IWAM_RON-WIN2K-TEST      nmap
|     rontest123               sshd                     SvcCOPSSH
|     test1234                 Testing                  TsInternetUser
|   Membership of 'administrators' from 'net localgroup administrators'
|     Administrator
|     SvcCOPSSH
|     test1234
|     Testing

Ping the scanner

mod = {}
mod.upload           = false
mod.name             = "Can the host ping our address?"
mod.program          = "ping"
mod.args             = "-n 1 $lhost"
mod.maxtime          = 5
mod.remove           = {"statistics", "Packet", "Approximate", "Minimum"}
mod.noblank          = true
mod.env              = "SystemRoot=c:\\WINDOWS"
table.insert(modules, mod)
Although this one was also discussed in the last post, I do want to bring up one noteworthy issue. It seems that many Windows programs that deal with IP addresses will fail in a spectacularily weird way. Here is the proper output
|   Can the host ping our address?
|     Pinging 10.0.0.138 with 32 bytes of data:
|     Reply from 10.0.0.138: bytes=32 time<10ms TTL=64
And here is the output without the environmental variable set:
|   Can the host ping our address?
|     Pinging $\x98\x07 with 32 bytes of data:
|     Reply from 10.0.0.138: bytes=32 time<10ms TTL=64
Notice how the ip got totally whacked. The outputted ip address, while consistent across multiple iterations, is completely wrong. tracert has the same problem.

Tracert to the scanner

mod = {}
mod.upload           = false
mod.name             = "Traceroute back to the scanner"
mod.program          = "tracert"
mod.args             = "-d -h 5 $lhost"
mod.maxtime          = 20
mod.remove           = {"Tracing route", "Trace complete"}
mod.noblank          = true
mod.env              = "SystemRoot=c:\\WINDOWS"
table.insert(modules, mod)
Speaking of tracert, this command performs a traceroute from the target back to the scanner. This could be useful if you're trying to determine network layout or something, and you can't get a forward traceroute to work. Like ping, it requires the SystemRoot variable.
Output:
|   Traceroute back to the scanner
|       1    <1 ms    <1 ms    <1 ms  10.0.0.138

arp cache

mod = {}
mod.name             = "ARP Cache from arp.exe"
mod.program          = 'arp.exe'
mod.upload           = false
mod.args             = '-a'
mod.remove           = "Interface"
mod.noblank          = true
table.insert(modules, mod)
This one is easy -- dump the arp cache of the host using the "arp -a" command. No special options are required.
|   ARP Cache from arp.exe
|       Internet Address      Physical Address      Type
|       10.0.0.138            00-50-56-a1-27-4b     dynamic

Connected ports

mod = {}
mod.upload           = false
mod.name             = "List of listening and established connections (netstat -an)"
mod.program          = "netstat"
mod.args             = "-an"
mod.maxtime          = 1
mod.remove           = {"Active"}
mod.noblank          = true
mod.env              = "SystemRoot=c:\\WINDOWS"
table.insert(modules, mod)
Dump the list of listening and established connections using "netstat -an". Like most other network-related configurations, this requires the SystemRoot variable to be set.
|   List of listening and established connections (netstat -an)
|       Proto  Local Address          Foreign Address        State
|       TCP    0.0.0.0:22             0.0.0.0:0              LISTENING
|       TCP    0.0.0.0:25             0.0.0.0:0              LISTENING
|       TCP    0.0.0.0:80             0.0.0.0:0              LISTENING
|       TCP    0.0.0.0:135            0.0.0.0:0              LISTENING
|       TCP    0.0.0.0:443            0.0.0.0:0              LISTENING
|       TCP    0.0.0.0:445            0.0.0.0:0              LISTENING
|       TCP    0.0.0.0:1025           0.0.0.0:0              LISTENING
|       TCP    0.0.0.0:1027           0.0.0.0:0              LISTENING
|       TCP    0.0.0.0:1028           0.0.0.0:0              LISTENING
|       TCP    0.0.0.0:3389           0.0.0.0:0              LISTENING
|       TCP    0.0.0.0:4933           0.0.0.0:0              LISTENING
|       TCP    0.0.0.0:27453          0.0.0.0:0              LISTENING
|       TCP    10.0.0.30:139          0.0.0.0:0              LISTENING
|       TCP    10.0.0.30:445          10.0.0.138:34913       ESTABLISHED
|       TCP    127.0.0.1:1030         127.0.0.1:40000        ESTABLISHED
|       TCP    127.0.0.1:5152         0.0.0.0:0              LISTENING
|       TCP    127.0.0.1:40000        0.0.0.0:0              LISTENING
|       TCP    127.0.0.1:40000        127.0.0.1:1030         ESTABLISHED
|       UDP    0.0.0.0:135            *:*
|       UDP    0.0.0.0:445            *:*
|       UDP    0.0.0.0:1029           *:*
|       UDP    0.0.0.0:3456           *:*
|       UDP    10.0.0.30:137          *:*
|       UDP    10.0.0.30:138          *:*
|       UDP    10.0.0.30:500          *:*
|       UDP    10.0.0.30:4500         *:*
|       UDP    127.0.0.1:1026         *:*

Routing table

mod = {}
mod.upload           = false
mod.name             = "Full routing table from 'netstat -nr'"
mod.program          = "cmd.exe"
mod.args             = "/c \"netstat -nr\""
mod.env              = "PATH=C:\\WINDOWS\\system32;C:\\WINDOWS;C:\\WINNT;C:\\WINNT\\system32"
mod.maxtime          = 1
mod.noblank          = true
table.insert(modules, mod)
Dump the routing table using netstat -nr. This command has to be run in a separate command session (that's why we have cmd.exe /c "netsat -nr"). It also requires the PATH variable to contain the 'windows' and 'system32' folders -- I don't know why that is.
Output:
|     IPv4 Route Table
|     ===========================================================================
|     Interface List
|     0x1 ........................... MS TCP Loopback interface
|     0x2 ...00 0b db 94 12 58 ...... Broadcom NetXtreme Gigabit Ethernet - Trend Micro Common Firewall Miniport
|     0x10004 ...00 0b db 94 12 59 ...... Broadcom NetXtreme Gigabit Ethernet #2 - Trend Micro Common Firewall Miniport
|     ===========================================================================
|     ===========================================================================
|     Active Routes:
|     Network Destination        Netmask          Gateway       Interface  Metric
|               0.0.0.0          0.0.0.0         10.0.0.1       10.0.0.250     20
|              10.0.0.0    255.255.255.0       10.0.0.250       10.0.0.250     20
|            10.0.0.250  255.255.255.255        127.0.0.1        127.0.0.1     20
|        10.255.255.255  255.255.255.255       10.0.0.250       10.0.0.250     20
|             127.0.0.0        255.0.0.0        127.0.0.1        127.0.0.1      1
|             224.0.0.0        240.0.0.0       10.0.0.250       10.0.0.250     20
|       255.255.255.255  255.255.255.255       10.0.0.250       10.0.0.250      1
|       255.255.255.255  255.255.255.255       10.0.0.250            10004      1
|     Default Gateway:          10.0.0.1
|     ===========================================================================
|     Persistent Routes:
|       None

Boot configuration

mod = {}
mod.upload           = false
mod.name             = "Boot configuration"
mod.program          = "bootcfg"
mod.args             = "/query"
mod.maxtime          = 5
table.insert(modules, mod)
Displays the boot configuration for the system. Only works on Windows XP or 2003 and above (not on Windows 2000). It'll tell you if you're on a system with multiple boot configurations, provided they're all Microsoft.
Output:
|   Boot configuration
|
|     Boot Loader Settings
|     --------------------
|     timeout:30
|     default:multi(0)disk(0)rdisk(0)partition(1)\WINDOWS
|
|     Boot Entries
|     ------------
|     Boot entry ID:    1
|     OS Friendly Name: Windows Server 2003, Standard
|     Path:             multi(0)disk(0)rdisk(0)partition(1)\WINDOWS
|     OS Load Options:  /fastdetect /NoExecute=OptOut

Drive details

mod = {}
mod.upload           = false
mod.name             = "Drive list (for more info, try adding --script-args=config=drives,drive=C:)"
mod.program          = "fsutil"
mod.args             = "fsinfo drives"
mod.replace          = {{string.char(0), " "}}
mod.maxtime          = 1
Finally, this is probably the simplest script, in terms of output. It simply prints a list of the known drive letters on the system. The trick to this one, though, is that for some insane reason the spaces in the output are actually NULL characters ('\0'). Originally, only one drive was showing up. After troubleshooting it for awhile and finding the issue, I added the mod.replace line and everything worked find. It just goes to show that some developers are just plain insane.
Output:
|   Drive list (for more info, try adding --script-args=config=drives,drive=C:)
|     Drives:
|     A:\ C:\ D:\ F:\

Conclusion

So there you have it, my default configuration file on smb-psexec.nse. I tried to balance the output between speed, size, and usefulness of information, and I hope you agree that the information is valuable.
I'm always happy to change the defaults, though, if you have some better ideas/options/whatever.

Fuente: skullsecurity

miércoles, 15 de mayo de 2013

SSH Gymnastics and Tunneling with ProxyChains | Pivoting


Introduction - Jumping through hoops
Ever heard the expression "I had to jump through hoops to get there"? 

With the ever increasing complexness of network topologies and designs, 
along with the security defenses to protect them. Jumping through hoops 
is a fairly common practice in the security world. This paper will 
examine how to create tunnels into a network using some SSH Gymnastics and 
Proxychains. In the end it will cover scanning anonymously using the TOR 
network and proxychains. 
  
WTF is Proxychains?!?

Proxychains is a tool that can intercept any TCP and/or UDP traffic from
 a specific process and tunnel it over a proxy. 
The proxies supported by proxychains are: HTTP, SOCKS4, and SOCKS5.

Diagram 1 - Network Overview
Setting up the launch pad - The pivot machine If you were to target the internal network in the diagram above with only external access, you will have a very limited view into the inside of the network. Using SSH and proxychains this can be very easily worked around by creating a dynamic port forwarder using SSH on the attackers localhost and connecting to one of the host(s) you have access to externally via SSH. You first need to create the dynamic listener on attacker machine on a specific port using the ssh -D option. Once you have established a connection to the remote machine, you will then need to configure proxychains to use the listening port created for this tunnel in order to access the internal network. ssh -D 127.0.0.1:9050
 Taken from ssh(1)
         -D [bind_address:]port
      Specifies a local "dynamic" application-level port forwarding.
      This works by allocating a socket to listen to port on the local
      side, optionally bound to the specified bind_address.  Whenever a
      connection is made to this port, the connection is forwarded over
      the secure channel, and the application protocol is then used to
      determine where to connect to from the remote machine.  Currently
      the SOCKS4 and SOCKS5 protocols are supported, and ssh will act
      as a SOCKS server.  Only root can forward privileged ports.
      Dynamic port forwardings can also be specified in the configura-
      tion file.

      IPv6 addresses can be specified with an alternative syntax:
      [bind_address/]port or by enclosing the address in square brack-
      ets.  Only the superuser can forward privileged ports.  By
      default, the local port is bound in accordance with the
      GatewayPorts setting.  However, an explicit bind_address may be
      used to bind the connection to a specific address.  The
      bind_address of "localhost" indicates that the listening port be
      bound for local use only, while an empty address or '*' indicates
      that the port should be available from all interfaces.
         
Configuring proxychains The proxychains config file is located at: /etc/proxychains.conf. Under the [ProxyList] directive, make sure you the config file contains the following: socks4 127.0.0.1 9050 Attack Scenario #1: The attacker beings by establishing a connection to 210.210.210.160 on the SSH service. The SSH service has been port-forwarded by the remote firewall to the internal host at 192.168.2.5. Using the -D option the attacker then creates a local dynamic listener on port 9050 for this connection. ssh -D 127.0.0.1:9050 username@210.210.210.160
Diagram 2 - Establishing an SSH session to the pivot machine
Once the SSH session had been established, the attacker would then have visibility into the network (TCP/UDP). You will then be able to scan machines on the internal network located at 192.168.2.5 and 192.168.2.10 using the tunnel that has just been created. proxychains nmap -PN -n -sTV 192.168.2.X -p1-65535
Diagram 3 - Overview of an established tunnel
The machine that you are using as a pivot point does NOT have to straddle the firewall in any sort of way. It either needs layer 2 connectivity into the others or have rules on the firewall allowing the traffic. In this example, the machines located at 192.168.2.5 and 192.168.2.10 will see the source of the attack as being from 210.210.210.160 or 192.168.2.2. Attack Scenario #2 - The Rabbit hole does go deeper. Setting up advanced tunnels Note: This works with dual homed host, or host with special rules through a firewall segment.
Diagram 4 - Advanced tunnels using dual homed host(s) overview
Now that you have configure the first basic tunnel, you can now use this tunnel to go deeper into the network. As an example, imagine there was yet another network '10.10.10.0/24' living behind 192.168.2.5, which has been discovered to be a dual homed host on the DMZ network. Using proxy chains we can piggy back the existing tunnel to create a new one into the DMZ network. proxychains ssh -D 127.0.0.1:9051 USERNAME@10.10.10.1 Once this tunnel is established into the DMZ network, the host at 10.10.10.1 will see the source connection coming from: 192.168.2.2 on the LAN side.
Diagram 5 - Advanced tunnels with dual homed host(s). Example of an established session
Re-cap of what just happened... The first step was to create a dynamic listener on the attackers machine listening on port 9050 which gets the connection into 192.168.2.2 via SSH. Then another dynamic listener was created on the attackers machine listening on port 9051, which has a tunnel into 10.10.10.1. These tunnels can very easily go on and on, as you should et the idea by now. Each port in use should have it's very own proxychains.conf file. To do so you simply copy the /etc/proxychains.conf into a newly created directory. Ie port9051/. After copying the config file into this directory, you can then modify proxychains.conf and change the socks4 port. cat /etc/proxychains.conf | sed "s/127.0.0.1 9050/127.0.0.1 9051/g" > ./proxychains.conf Proxychains will search for a config file within the current working directory. Once the file has been changed, you can now issue the proxychains command from this directory with whatever command you choose. proxychains nmap...




             pauldotcom.com

miércoles, 8 de mayo de 2013

[cheet sheet] Network Enumeration and Reconnaissance


Network Scanning and Mapping
------------------------------------------------------------------------
Network Service Discovery
Nmap
nmap -sSV -vv -PN --send-ip -A -O -oG <address-range>_`date +%Y-%m-%d_%H:%M`\
<address-range>nmap -A -vv -PN --send-ip -oG <address-range>_`date +%Y-%m-%d_%H:%M`
 <address-range>

Unicorn Scan
us -H -msf -Iv <address> -p 1-65535
us -H -mU -Iv <address> -p 1-65535

Layer 2 - Arp - netdiscover
netdiscover -i <interface> -r <address-range>

------------------------------------------------------------------------
TCPDump Sniffing
tcpdump -s0 -xxXX -vv -i eth0 'host <address> and\
 (dst port <num> or <num> )' | tee <address>_<service>_`date +%Y-%m-%d_%H:%M`.txt
or save the pcap file with additional flag (filename shortcut):
-w <address>_<service>_`date +%Y-%m-%d_%H:%M`.pcap

Locate VLAN Tags
tcpdump -vv -i <interface> -s &ltsnap-length> -c <num-packet-count> 'ether[20:2] == 0x2000'

------------------------------------------------------------------------ 
Specific Service Queries

DNS TCP:53/UDP:53
DNS  TCP and UDP 53 - DNS walking and Zone transfers
dig <domain> @<dns-server> AXFR | tee dns_<domain>_axfr._`date +%Y-%m-%d_%H:%M`.txt

DNS  TCP and UDP 53 - DNS cache poisoning check
dig +short @<dns-server> porttest.dns-oarc.net txt

porttest.y.x.w.v.u.t.s.r.q.p.o.n.m.l.k.j.i.h.g.f.e.d.c.b.a.pt.dns-oarc.net.
"<dns-server> is GREAT: 26 queries in 4.4 seconds from 26 ports with std dev 22336"

------------------------------------------------------------------------
HTTP Web applications TCP 80,8000
nikto -h -p -C all -Display D -output nikto_<target-server><port>_`date +%Y-%m-%d_%H:%M`.txt -Format txt

DirBuster
 cd /pentest/web/dirbuster && java -jar DirBuster-0.12.jar

WFuzz
wfuzz.py -c -z file,<wordlist> --hc 404 -o <html|magictree> http://<site-url>/FUZZ
e.g.
./wfuzz.py -c -z file,/pentest/passwords/wordlists/combined --hc 404 -o html http://<site-url>/FUZZ 2> /dev/null

HTTP commands for webserver enumeration 
nc <target-address> <port>
HEAD / HTTP/1.0
or
OPTIONS / HTTP/1.0
or
TRACE / HTTP/1.0

WebDAV

IIS 6.0
HTTPS/SSL  TCP 443
openssl s_client -connect <target-server>443 -state -debug
HEAD / HTTP/1.0

CONNECTED(00000003)
SSL_connect:before/connect initialization
... ... ... cut ... ... ...
SSL_connect:SSLv3 write client key exchange A
... ... ... cut ... ... ... 
 HTTP/1.1 302 Found
Date: Mon 02 Apr 2012 06:53:49 GMT
Server IBM_HTTP_Server/6.0.2.33 Apache/2.0.47 (Unix)
... ... ... cut ... ... ...

------------------------------------------------------------------------
SNMP commands UDP 161

SNMPWalk
snmpwalk -c public -v[1|2c] <target-server> tee <address>_snmp_`date +%Y-%m-%d_%H:%M`.txt
SNMPv2-MIB::sysDescr.0 = STRING: hp AlphaServer ES80 7/1000, VMS V7, MultiNet(R) for OpenVMS V4.4
SNMPv2-MIB::sysObjectID.0 = OID: SNMPv2-SMI::enterprises.58.1.1.1.2.1
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (24030770) 2 days, 18:45:07.70
SNMPv2-MIB::sysContact.0 = STRING: System contact unknown at this time
SNMPv2-MIB::sysName.0 = STRING:
SNMPv2-MIB::sysLocation.0 = STRING: System location unknown at this time
SNMPv2-MIB::sysServices.0 = INTEGER: 72
... ... ...
SNMPEnum
/snmpenum.pl public linux.txt 
    UPTIME... ... ...
    HOSTNAME... ... ...
    RUNNING SOFTWARE PATHS
... ... ...
    RUNNING PROCESSES... ... ...
    MOUNTPOINTS... ... ...
    SYSTEM INFO
... ... ...
    LISTENING UDP PORTS
... ... ...    LISTENING TCP PORTS

OneSixtyOne
./onesixtyone -c <dictionary-file> -i <hosts-file> -o <address-range>_snmp_`date`.log -w
./onesixtyone <target-address>
Scanning 1 hosts, 2 communities [public] hp AlphaServer ES80 7/1000, VMS V7, MultiNet(R) for OpenVMS V4.4

SNMPCheck
./snmpcheck-1.8.pl -c <community-name> -v <version 1,2> -t <address-range>
snmpcheck.pl v1.8 - SNMP enumerator
Copyright (c) 2005-2011 by Matteo Cantoni (www.nothink.org)
 [*] Try to connect to
 [*] Connected to
 [*] Starting enumeration at 2011-07-25 10:32:58
 [*] System information
 -----------------------------------------------------------------------------------------------
 Hostname               :
 Description            : hp AlphaServer ES80 7/1000, VMS V7, MultiNet(R) for OpenVMS V4.4
 Uptime system          : 0.00 seconds
 Uptime SNMP daemon     : 2 days, 18:17:07.01
 [*] Network information
... ... ...
 [*] Network interfaces
... ... ...
 [*] Routing information
... ... ...
 [*] Listening TCP ports and connections
... ... ...

------------------------------------------------------------------------

Samba/CIFS/NETBIOS TCP 135,139,445
nbtscan -v -s : -r <address-range>| tee <address-range>_nbtscan_`date +%Y-%m-%d_%H:%M`.txt

SMBClient - Discover and mount shares
smbclient -L \\\<target-address>\\ -U <Username>
smbclient -U <Username> -W <Workgroup> \\\\<target-address>\\\<sharename>

------------------------------------------------------------------------
RPC, PortMapper and NFS TCP/UDP:111
rpcinfo -p >target-address> | tee <address>_rpcinfo_`date +%Y-%m-%d_%H:%M`.txt

showmount -e <ip-address>

mount <ip-address>:<exported_path> <local_path>

Tunnelling and Pivoting
------------------------------------------------------------------------
SSH Tunnelling and pivoting 

ssh -v -f -N -L <localIP>:<local-port>:<dest-ip>:<dest-port> <user>@&ltpivot-host> -i <authentication-key-file>
Verbosity (-v),  Background (-f), No command execution (-N), Local port forwarding (-L)

Forward localhost port 25 to the localhost of 192.168.1.6 using ssh DSA key  
ssh -v -f -N -L 127.0.0.1:25:127.0.0.1:25 user@192.168.1.6 -i /dsa/1024/f1fb2162a02f0f7c40c210e6167f05ca-16858

Proxy Chains 
Dual-honed proxies or for proxying some port-scans
Edit the configuration file:
/etc/proxychains.conf
Under the ProxyList section:

[ProxyList]
http <proxy-server-ip><port>
Execute with:
proxychains&ltsocket-aware command>
e.g
proxychains nmap -sT -vv --send-ip -pT:21,22,25,80,443,445,3389 <target-address>