Mart 2023’te, 600.000’den fazla aktif yüklemeye sahip “WooCommerce Payments” eklentisini etkileyen kritik bir “Kimlik Doğrulama Atlaması ve Ayrıcalık Yükseltmesi” (aka CVE-2023-28121) hakkında Wordfence tarafından yayınlanan ilginç bir güvenlik tavsiyesi fark ettim. WordPress.
Müşterilerimden biri, eklentinin savunmasız sürümünü içeren bir WooCommerce örneği çalıştırdığından, ancak o zamanlar halka açık bir PoC/istismar olmadığından, ona bakmaya ve bunun için bir istismar oluşturmaya karar verdim. Bu güvenlik açığının, savunmasız bir WordPress/WooCommerce örneğinde saldırgana yönetici hakları verebileceği ortaya çıktı.
Hatanın kritikliği nedeniyle bu blog yazısını bir süreliğine erteledim, ancak zaten ortalıkta dolaşan bazı istismarlar olduğundan, daha çok temel neden analizine odaklanan yazımı da yayınlamaya karar verdim.
Bu hatayı ilk bulmuş gibi görünen GoldNetwork’ten Michael Mazzolini’ye teşekkür ederiz.
Her Şeyi Farklılaştıran Yama
Dolayısıyla, savunmasız sürüm 5.6.1’i (aşağıdakilerin tümü de savunmasızdır) ve sabit sürüm 5.6.2’yi birbirinden ayırırken, aslında çok fazla kod değişikliği olmadığını fark edebilirsiniz.
1. Geliştiriciler bir çağrıyı kaldırdılar Platform_Checkout_Session::init()
içinde woocommerce-payments.php
:
2. Tamamen kaldırdılar /includes/platform-checkout/class-platform-checkout-session.php
sahip olan dosya Platform_Checkout_Session::init()
içindeki beyan.
Her şey bu noktaya geldiğinden beri init()
işlevi, hemen buna dalalım. Güvenlik açığını içeren kaynak kodunun tamamı burada:
Yes, that’s it.
The
init()
function adds two WordPress filters whereof thedetermine_current_user
is the most interesting one (line 25). When looking up the hook in WordPress’s official documentation, it becomes quite clear that it ultimately does what its name stands for: determining the current user.All the (vulnerable) magic happens in the
determine_current_user_for_platform_checkout()
function (lines 36 to 46), where the plugin checks for the existence of theX-WCPAY-PLATFORM-CHECKOUT-USER
request header and if it is present it simply returns the header’s value. Since the returned value represents the “determined” user, we can now trick WordPress into thinking that we’re correctly authenticated as the given userId.Triggering the Vulnerability
So to trigger the authentication bypass part, you just need to set the
X-WCPAY-PLATFORM-CHECKOUT-USER
request header and point it to a userId:GET / HTTP/1.1 Host: 192.168.178.11 Upgrade-Insecure-Requests: 1 Connection: close X-WCPAY-PLATFORM-CHECKOUT-USER: 1Bir hata ayıklayıcı ekleyip yukarıdaki isteği tetiklerken, başlangıçtaki teorimizin doğru olduğunu ve
determine_current_user_for_platform_checkout()
işlev, herhangi bir doğrulamaya gerek kalmadan kullanıcı kimliğini istekten döndürecektir:İşin özünde kancanın WordPress'e isteğin hangi kullanıcıdan geldiğini etkili bir şekilde söylemesi yatıyor. UserId bizim kontrolümüz altında olduğundan, artık yöneticiler de dahil olmak üzere WordPress örneğinde aktif/etkin olan herhangi bir kullanıcının kimliğine bürünmenin kolay bir yoluna sahibiz.
Sömürü
Yönetici kullanıcıları taklit edebildiğimiz için WordPress örneğinin tamamını tehlikeye atmak oldukça kolaydır. Bulduğum en kolay yol WordPress'i kullanmaktı'
/wp-json/wp/v2/users
Yeni kullanıcıların eklenmesine olanak sağlayan API arayüzü.Bu nedenle, aşağıdaki istek, eklenen ilk kullanıcı (genellikle bir yönetici) olan kullanıcı kimliği "1" ile kullanıcının kimliğine bürünerek, güvenlik açığı bulunan bir WordPress örneğine varsayılan "yönetici" rolüyle "hacked" adlı yeni bir kullanıcı ekleyecektir. herhangi bir WordPress örneğine:
POST /wp-json/wp/v2/users HTTP/1.1 Host: 192.168.178.11 Upgrade-Insecure-Requests: 1 Connection: close Content-Type: application/json X-WCPAY-PLATFORM-CHECKOUT-USER: 1 Content-Length: 123 { "username":"hacked", "email":"[email protected]", "password":"SuperSecure1337", "roles":["administrator"] }İstismarın başarılı olup olmadığı HTTP yanıt koduna göre belirlenebilir. Eğer 201 ise, istismar başarılı olmuştur ve yeni oluşturulan kullanıcının kullanıcı nesnesini döndürecektir:
Bu artık WordPress'in yönetimsel arka ucuna karşı kimlik doğrulaması yapmak için kullanılabilir:
Bazı durumlarda, hedeflenen, kimliğine bürünülen kullanıcı artık mevcut değildir veya devre dışı bırakılmıştır. Bu durumda, ya sorgulamanız gerekir
/wp-json/wp/v2/users
Aktif kullanıcıların bir listesini almak için API yöntemi veya kullanıcı kimlikleri aracılığıyla basitçe kaba kuvvet.