
PoC-Code für eine Schwachstelle in webmod v0.48. Ursprünglich im Jahr 2007 geschrieben, zugewiesen CVE-2007-1260.
von cybermind (Kevin Masterson)
[email protected]
WebMod-Seite (archiviert): https://web.archive.org/web/20080517044559/http://djeyl.net/w.php
Verwundbare Versionen:
0.48, sowohl Win32 als auch Linux. Frühere Versionen könnten verwundbar sein. Dies sollte mit jeder Version von HLDS funktionieren.
Art der Sicherheitslücke:
DoS, Remote-Code-Ausführung unter dem Benutzer, unter dem HLDS läuft.
Beschreibung: Beim Empfangen einer HTTP-POST-Anfrage werden 11 Bytes auf dem Stack alloziert, um den Wert für Content-Length zu speichern, aber es wird in diesen Puffer geschrieben, bis ein Zeilenumbruch oder Null-Terminator empfangen wird. Sobald Ihr Content-Length-String 158308 Bytes erreicht, beginnt er, den EIP zu überschreiben. Diese Zahl kann unter Linux aufgrund von Padding geringfügig abweichen. Ihr Shellcode darf keine 0x00, 0x0A oder 0x0D enthalten, da sonst das Lesen von Daten aus dem Socket gestoppt wird.
Dies kann bei der Ausführung Ihres Shellcodes helfen:
Proof-of-Concept-Code:
w48crash.c
Hinweis: Der im PoC verwendete "Shellcode" ist fest codiert, um speziell mit einem Server zu funktionieren, der auf Win2K SP4/kernel32.dll/user32.dll v5.0.2195.6688 läuft. Der eigentliche Pufferüberlauf funktioniert jedoch unverändert auf jeder Windows-Version. Um dies zu testen, können Sie die globale Variable "our_eip" auf 0xFFFFFFFF setzen, um einfach einen Absturz zu verursachen.
Ursache/Behebung:
Der problematische Code stammt aus den Zeilen 542-552 in server.cpp:
542 char clbuf[11];
543
544 for(i=0;(size_t)i<strlen(input)-17;i++)
545 {
546 if(!strnicmp(input+i,"\nContent-Length: ",17))
547 {
548 LOG_DBG_SERVER(("Content-length spotted"));
549 i+=17;
550 for(j=0;input[i]!='\n'&&input;[i];i++,j++)
551 clbuf[j]=input[i];
552 clbuf[j]='\0';
Der Puffer clbuf, der in Zeile 542 alloziert wird, wird mit der Schleife in den Zeilen 550-551 beschrieben und dann mit Null terminiert. Die Behebung besteht darin, Zeile 550 zu ersetzen mit:
550 for(j=0;input[i]!='\n'&&input[i]&&j<10;i++,j++)