Wednesday, 23 March 2011

An alternative way to do "psexec" on Backtrack 4

If you need a way of issuing remote commands to a Windows system (where you have a username and password) you could use the popular psexec.exe tool.

Here I discuss an alternative you can easily install on Backtrack, which gives very similar functionality to the psexec.exe tool, but natively in Linux.


First, install the wmi-client and winexe tools with the following command:

apt-get install wmi-client



Running winexe

These are the options for winexe


winexe version 0.80
This program may be freely redistributed under the terms of the GNU GPL
Usage: winexe [-?|--help] [--usage] [-d|--debuglevel DEBUGLEVEL]
        [--debug-stderr] [-s|--configfile CONFIGFILE] [--option=name=value]
        [-l|--log-basename LOGFILEBASE] [--leak-report] [--leak-report-full]
        [-R|--name-resolve NAME-RESOLVE-ORDER]
        [-O|--socket-options SOCKETOPTIONS] [-n|--netbiosname NETBIOSNAME]
        [-W|--workgroup WORKGROUP] [--realm=REALM] [-i|--scope SCOPE]
        [-m|--maxprotocol MAXPROTOCOL] [-U|--user [DOMAIN\]USERNAME[%PASSWORD]]
        [-N|--no-pass] [--password=STRING] [-A|--authentication-file FILE]
        [-S|--signing on|off|required] [-P|--machine-pass]
        [--simple-bind-dn=STRING] [-k|--kerberos STRING]
        [--use-security-mechanisms=STRING] [-V|--version] [--uninstall]
        [--reinstall] [--system] [--runas=[DOMAIN\]USERNAME%PASSWORD]
        [--interactive=INT] //host command


As you can see, you get very similar functionality to the psexec tool (this tool uses the same interfaces and methods)

Here are a couple of examples; ipconfig output, and an interactive shell


winexe --user Administrator --password=mypassword //192.168.1.52  ipconfig


Windows IP Configuration


Ethernet adapter Local Area Connection:


   Connection-specific DNS Suffix  . :
   IPv4 Address. . . . . . . . . . . : 192.168.1.52
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Default Gateway . . . . . . . . . : 192.168.1.254


This runs the command and exits, where as the shell below is fully interactive:

winexe --user Administrator --password=mypassword //192.168.1.52 cmd.exe

Microsoft Windows [Version 6.0.6001]
Copyright (c) 2006 Microsoft Corporation.  All rights reserved.


C:\Windows\system32>  


Another interesting thing you can do (if the account you have has the appropriate privileges) is to run commands as system, here for example is a system shell:


winexe --system --user Administrator --password=mypassword //192.168.1.52 cmd.exe
Microsoft Windows [Version 6.0.6001]
Copyright (c) 2006 Microsoft Corporation.  All rights reserved.


C:\Windows\system32>whoami
whoami
nt authority\system


C:\Windows\system32>



Running wmic

I've not been able to get the wmic working effectively on many systems, with my limited testing (I'm guessing there is a non-default setting to enable this functionality on the target systems)

Here are the options:

wmic
Usage: [-?|--help] [--usage] [-d|--debuglevel DEBUGLEVEL] [--debug-stderr]
        [-s|--configfile CONFIGFILE] [--option=name=value]
        [-l|--log-basename LOGFILEBASE] [--leak-report] [--leak-report-full]
        [-R|--name-resolve NAME-RESOLVE-ORDER]
        [-O|--socket-options SOCKETOPTIONS] [-n|--netbiosname NETBIOSNAME]
        [-W|--workgroup WORKGROUP] [--realm=REALM] [-i|--scope SCOPE]
        [-m|--maxprotocol MAXPROTOCOL] [-U|--user [DOMAIN\]USERNAME[%PASSWORD]]
        [-N|--no-pass] [--password=STRING] [-A|--authentication-file FILE]
        [-S|--signing on|off|required] [-P|--machine-pass]
        [--simple-bind-dn=STRING] [-k|--kerberos STRING]
        [--use-security-mechanisms=STRING] [-V|--version] [--namespace=STRING]
        //host query


Example: wmic -U [domain/]adminuser%password //host "select * from Win32_ComputerSystem"

Here are a couple of example test wmi database queries:


wmic -U Administrator --password=password234 //192.168.1.53 "select * from Win32_ComputerSystem"


CLASS: Win32_ComputerSystem
AdminPasswordStatus|AutomaticResetBootOption|AutomaticResetCapability|BootOptionOnLimit|BootOptionOnWatchDog|BootROMSupported|
...etc...


And here, looking at high-priority process information:


wmic -U Administrator --password=password234 //192.168.1.53 "Select Caption,ProcessId From Win32_Process Where Priority > 8 "


CLASS: Win32_Process
Caption|Handle|ProcessId
smss.exe|164|164
csrss.exe|188|188
WINLOGON.EXE|184|184
services.exe|236|236
LSASS.EXE|248|248
LLSSRV.EXE|664|664
VMwareService.e|892|892

... and you could also use these methods to run remote processes (though this is rather complex to go into detail on here)


So, what are the differences between these tools?

wmic uses RPC - TCP port 135 (and 1025) and winexe uses SMB - TCP port 139

With winexe, you are basically issuing standard command line tools and options, this is a very easy tool to use.

wmic is a bit more complex to use for issuing commands, but could be useful in some circumstances, and can certainly be used to gain information about the target system (many network monitoring tools use the WMI interface to monitor an manage remote hosts)


Tuesday, 22 March 2011

The eEye 0-Day Watchlist

Many thousands of vulnerabilities have been discovered in software products over the years, and there are huge resources of example code and exploit information online, regarding many of these issues.

A good proportion of these issues have been patched/fixed over the years, so as long as a company has a very effective patch-management program, and software management systems, for all the software they use (which is surprisingly rare) fixed vulnerabilities "should" not pose a threat

However, there is a class of vulnerability that is very difficult to mitigate, the 0-Day exploit.

0-Day exploits can be either public (widely known about, often with example code in the public domain) or private (only know about by a few people; the vendor, security researchers, or hackers)

Vulnerabilities are probably at their most challenging when they are 0-Day with code examples in the public domain. I.e, many people have access to use the exploit, but there is no solution available from the software vendor, yet.

This eEye site offers a good resource to keep track of some of the most serious issues involving 0-Day vulnerabilities from some of the worlds biggest software vendors:

http://www.eeye.com/Resources/Security-Center/Research/Zero-Day-Tracker

This represents only a small fraction of the exploits published each day, but focuses on some of the most serious (because of the wide deployment of the software involved) so this information is worth keeping an eye on.

(this list continues...)

As you can see if you look through the list, and drill into the details, many of these issues involve remote code execution, privilege escalation, or information disclosure.

There is a good mix of major vendors in there, but at the time of publishing this list was heavily populated by Microsoft issues (which is generally the norm).

Here is some further research to show how 0-Day exploits can overlap (in this case in Internet Explorer, during 2006) which could provide sophisticated hackers with almost continuous and unmitigated access to exploit users and systems.

http://www.washingtonpost.com/wp-srv/technology/daily/graphics/index20070104.html

Though this is out of date, this is a rather interesting analysis (and probably took a good bit time to put together, so worth taking a look at).

If you were to look at all the client-side exploits from different vendors, for a typical desktop system, you could probably map-out a continuous set of exploits that make the system potentially vulnerable 24/7, 365 days a year.

Defense in depth seems to be the only solution that keeps these issues under control; with anti-virus, firewalls, content-security, network monitoring, privilege-management, password-management, patch-management, configuration control and encryption being the key elements. In short, these software flaws cost a lot of money to mitigate.

More efficient port-scanning in Python and Perl

Sometimes it is useful to be able to perform some TCP port-scanning from a host, without installing any additional tools (such as nmap for example). This could be performed from intermediary systems which have been compromised in an attack, for example.

If the host in question has Python or Perl installed (or many other languages for that matter) then in should be fairly simple to write and customize short scripts for specific tasks such as banner-grabbing and port-scanning.

It is useful to optimize these tasks, to reduce the footprint and make the task more efficient. Here I look at a simple example of two port-scanners I have optimized, to scan a minimal number of the most popular TCP ports.

I had several aims here; to be lightweight, targeted, cross-platform, efficient, and without installing any new software (and with minimal changes to the scanning machine, other than the uploading the script).

Additionally, it would be good to scan the most important ports first, and the rest in decreasing order of importance.

These techniques are for educational and testing purposes only.


Port-scanning in Perl

Here is a simple port-scanner in Perl that I found online:

#!/usr/bin/perl


use IO::Socket;
my ( $target, $daddr, $port, $maxport );


$maxport=1024; $port=0;


( $target = $ARGV[0] ) || &error;
$port=$ARGV[1] if $ARGV[1];
$maxport=$ARGV[2]  if $ARGV[2];


$daddr = inet_aton($target) || die("Failed to find host: $target");


print "Scanning : $target ports $port to $maxport\n";
foreach (; $port<=$maxport; $port++) {
    print "\nPort $port is open" if ( IO::Socket::INET->new(PeerAddr=>"$target:$port",Proto=>'tcp',Timeout=>1));
}
print "\nDone\n";
exit (0);


sub error {
    print "./portscan.pl \n";
    exit (1);
}

This is fairly basic, and scans the first 1024 TCP ports (unless you specify otherwise). However, this is a pretty slow and inefficient way to do this, as many of the top 1024 ports are not used, and some of the higher ports are more important.


Finding the most important ports from the nmap configuration files

A lot of research has been done by the nmap team in order to find the statistically most popular ports. Rather than reinventing the wheel here, let's reuse some of this information.

Port information and statistics are stored in the "nmap-services" file in /usr/share/nmap". This contains all the information we need, but in the wrong format. We will parse this file to extract and reformat the information we need.

To do this we need to remove the comments, reverse the order of the first 3 parameters, sort it, filter the tcp ports, and take the top 150 lines, and trim them, as follows:

grep -v ^# /usr/share/nmap/nmap-services | awk '{ print $3 " " $2 " " $1 }' | sort -r | grep  "/tcp " | head -n 150 | cut -d " " -f2 | cut -d "/" -f1 > top150tcp.txt

Next, we will put this data in a form which is ready to go into our port-scanner.

cat top150tcp.txt | sed 's/$/,/' | tr "\n" " ">  scriptlist150.txt

This creates our port list in the following form, ready to go into our Perl or Python script:

80, 23, 443, 21, 22, 25, 3389, 110, 445, 139, 143, 53, ...

(This process could be customised to find any number of top ports. 3000 is a good number as that covers pretty much 100% of popular ports, but I have chosen 150 ports here for brevity)


Optimized Perl script

So, with a bit of adjustment of our Perl script, and the addition of the prioritised port-list, we have:

#!/usr/bin/perl


use IO::Socket;
my ( $target, $daddr );


@portlist = (80, 23, 443, 21, 22, 25, 3389, 110, 445, 139, 143, 53, 135, 3306, 8080, 1723, 111, 995, 993, 5900, 1025, 587, 8888, 199, 1720, 465, 548, 113, 81, 6001, 10000, 514, 5060, 179, 1026, 2000, 8443, 8000, 32768, 554, 26, 1433, 49152, 2001, 515, 8008, 49154, 1027, 5666, 646, 5000, 5631, 631, 49153, 8081, 2049, 88, 79, 5800, 106, 2121, 1110, 49155, 6000, 513, 990, 5357, 427, 49156, 543, 544, 5101, 144, 7, 389, 8009, 3128, 444, 9999, 5009, 7070, 5190, 3000, 5432, 3986, 1900, 13, 1029, 9, 6646, 5051, 49157, 1028, 873, 1755, 2717, 4899, 9100, 119, 37, 1000, 3001, 5001, 82, 10010, 1030, 9090, 2107, 1024, 2103, 6004, 1801, 5050, 19, 8031, 1041, 255, 3703, 2967, 1065, 1064, 1056, 1054, 1053, 1049, 1048, 17, 808, 3689, 1031, 1071, 1044, 5901, 9102, 100, 9000, 8010, 5120, 4001, 2869, 1039, 2105, 636, 1038, 2601, 7000, 1, 1069, 1066, 625);
$size = @portlist;


( $target = $ARGV[0] ) || &error;


$daddr = inet_aton($target) || die("Failed to find host: $target");


print "Scanning : $target\n";
for ($i=0; $i<$size; $i++)
{
    print "\nPort $portlist[$i] is open" if ( IO::Socket::INET->new(PeerAddr=>"$target:$portlist[$i]",Proto=>'tcp',Timeout=>1));
}
print "\nDone\n";
exit (0);


sub error {
    print "./portscan.pl \n";
    exit (1);
}

This runs in about a 6th of the time, scanning only the most popular 150 ports rather than the lowest 1024.

As it is a nonlinear scan it is less likely to be detected, and could easily be slowed, with a delay between each port, to further increase the stealthiness.


The same in Python

Having used Python more than Perl, I find Perl a bit ugly, so here is the same sort of customization for a Python script:

#!/usr/bin/python
import sys
from socket import * 


if len(sys.argv) != 2:
print "Usage: " + sys.argv[0] + ""
sys.exit(0)

portlist = [80, 23, 443, 21, 22, 25, 3389, 110, 445, 139, 143, 53, 135, 3306, 8080, 1723, 111, 995, 993, 5900, 1025, 587, 8888, 199, 1720, 465, 548, 113, 81, 6001, 10000, 514, 5060, 179, 1026, 2000, 8443, 8000, 32768, 554, 26, 1433, 49152, 2001, 515, 8008, 49154, 1027, 5666, 646, 5000, 5631, 631, 49153, 8081, 2049, 88, 79, 5800, 106, 2121, 1110, 49155, 6000, 513, 990, 5357, 427, 49156, 543, 544, 5101, 144, 7, 389, 8009, 3128, 444, 9999, 5009, 7070, 5190, 3000, 5432, 3986, 1900, 13, 1029, 9, 6646, 5051, 49157, 1028, 873, 1755, 2717, 4899, 9100, 119, 37, 1000, 3001, 5001, 82, 10010, 1030, 9090, 2107, 1024, 2103, 6004, 1801, 5050, 19, 8031, 1041, 255, 3703, 2967, 1065, 1064, 1056, 1054, 1053, 1049, 1048, 17, 808, 3689, 1031, 1071, 1044, 5901, 9102, 100, 9000, 8010, 5120, 4001, 2869, 1039, 2105, 636, 1038, 2601, 7000, 1, 1069, 1066, 625]


if __name__ == '__main__':
target = sys.argv[1]
print 'Scanning : ', target


for i in portlist:
s = socket(AF_INET, SOCK_STREAM)


result = s.connect_ex((target, i))


if(result == 0) :
print 'Port ' + str(i) + ' is open'
s.close()

That gives the following result for my home broadband router:

./portscan2.py 192.168.1.254
Scanning :  192.168.1.254
Port 80 is open
Port 23 is open
Port 443 is open
Port 21 is open
Port 1723 is open

As you can see, it is fairly straightforward to find existing code on the web, and tweak it (with some statistical knowledge) to get better results. This is something I find myself doing a lot more of recently.

Of course, you could preserve more information from the nmap stats, such as port-names, by making use of a dictionary array.

If you find this useful, let me have your feedback below.