W najnowszym wordpressie (5.7) wykryto podatność typu XXE, czyli XML External Entities. Podatność pozwala na odczytanie plików z serwera (w tym także tak wrażliwych jak np. wp-config.php) i może być wykorzystana przez osoby mające dostęp do funkcji uploadu plików.

Warunki wykorzystania podatności to:

  • WordPress musi działać na PHP 8
  • Atakujący musi posiadać rolę „autor” – pozwalającą na wygrywanie multimediów
  • Podatność może być wykorzystana przez osoby niezalogowane, jeżeli możliwość wgrywania multimediów jest im udzielona np. przez jakiś przeznaczony do tego plugin

Zaleca się pilną aktualizację do wersji 5.7.1.

Źródło podatności

WordPress korzysta z biblioteki zwanej ID3 do parsowania plików multimedialnych, w celu odczytania z nich np. metadanych, które mogą posiadać format XML. Ale jak pozornie nieszkodliwy upload np. filmu na serwer może być wektorem ataku? Podatność występuje dopiero w PHP8, za co odpowiada poniższy fragment kodu:

if (PHP_VERSION_ID < 80000) {

// This function has been deprecated in PHP 8.0 because in libxml 2.9.0, external entity loading is

// disabled by default, so this function is no longer needed to protect against XXE attacks.

$loader = libxml_disable_entity_loader(true);

}

$XMLobject = simplexml_load_string($XMLstring, 'SimpleXMLElement', LIBXML_NOENT);

Kod ten mówi, że jeżeli wersja PHP jest mniejsza od 8, to wymagane jest wyłączenie parsowania encji funkcją

libxml_disable_entity_loader(true);

Jednak jeżeli wersja PHP to 8 i więcej, to parsujemy XML z użyciem ostatniej linijki. Problem w tym, że wywołując bezpośrednio funkcję simplexml_load_string() z argumentem LIBXML_NOENT, wcale nie wyłączamy encji – flaga ta wbrew pozorom służy do czegoś innego!

Cytując jednego z użytkowników portalu stackoverflow:

Substitute entities isn’t very informative (what entities? when are they substituted?). But I think it’s fair to assume that NOENT is short for NO_ENTITIES or NO_EXTERNAL_ENTITIES, so to me it seems to be a fair assumption that this flag disables the parsing of (external) entities. But that is indeed not the case(…)

Zastosowanie więc flagi LIBXML_NOENT wcale nie eliminuje ryzyka związanego z XXE. Znalezienie tego typu podatności nie należało do łatwych, natomiast dalsze wykorzystanie jest już dużo prostsze – przykładowo, plik do wgrania na serwer, służący do ataku może posiadać format podobny do:

RIFFXXXXWAVEBBBB<?xml version... ?>

Gdzie na początku mamy tzw. nagłówek formatu multimedialnego, a dalej konieczne jest umieszczenie pełnego payloadu podatności XXE, która jest dość dobrze znana, a opisy jej wykorzystania są powszechne w sieci, więc potencjalnie atakujący nie powinni mieć problemu ze zdobyciem działającego exploita.

Patch WordPressa – do wersji 5.7.1 – polega na ponownym wprowadzeniu do użycia funkcji libxml_disable_entity_loader(true) niezależnie od wersji oprogramowania.

Źródła:

https://blog.sonarsource.com/wordpress-xxe-security-vulnerability/

https://stackoverflow.com/questions/38807506/what-does-libxml-noent-do-and-why-isnt-it-called-libxml-ent

https://owasp.org/www-project-top-ten/2017/A4_2017-XML_External_Entities_(XXE)