Langsung saja, jadi disini aku bakal memberikan write up dan solusi terkait challenge yang aku share dengan judul CVE reversing pada plugin wordpress StoryChief.

pada challenge ini, kita diharuskan untuk crafting PoC atau exploit dari refrensi dan deskripsi singkat pada CVE-2025-7441. Karena CVE ini tergolong masih baru jadi tidak ada satupun source yang mempublikasikan PoC atau exploitnya di internet. Cara satu satunya dengan melakukan research dan mencoba untuk menemukan secara mandiri.

Sebelum itu penting sekali untuk mengerti syntax dasar dan terbiasa menggunakan PHP dan juga sedikit perlu paham terkait struktur dari CMS wordpress. Mari kita lihat deskripsi dari CVE-nya

Intinya dikatakan jika plugin StoryChief pada versi dan sebelum 1.0.42 terdapat vulnerabiilty yang dimana attacker bisa melakukan arbitrary file upload melalui /wp-json/storychief/webhook, dan ngerinya lagi bug ini bisa dipicu tanpa login terlebih dahulu atau unauthenticated, nah maka dari sini kenapa CVSS score pada vulnerability ini sangat critical yaitu 9.8.

CVE reversing itu merupakan suatu upaya atau proses untuk membuat Proof-Of-Concept dari suatu kerentanan yang sudah diketahui(CVE) atau bisa kita sebut juga sebagai 1-day, secara umum caranya yaitu dengan melakukan patch diff(perbandingan) source code dari versi rentan dan yang sudah diperbaiki untuk melihat kerentanan yang dapat dimanfaatkan.

Tapi beruntungnya, tidak seperti pada vendor atau product perusahaan besar yang close source, pada wordpress sendiri melakukan CVE reversing ini masih tergolong mudah karena source code dipublikasikan ya setidaknya kita tidak perlu effort melakukan reverse engineering dan memahami di sisi low levelnya. Karena untuk melakukan patch diff pada wordpress kita bisa langsung mengunjungi https://plugins.trac.wordpress.org/ dan melihat perbandingan kode antar versi

Pada CVE ini, wordfence juga menyediakan refrensi diffing dan hal ini sangat berguna untuk kita identifikasi dan melakukan source code review

https://plugins.trac.wordpress.org/changeset/3344874

Disini terlihat beberapa file yang diubah pada versi baru, atau dalam hal ini developer melakukan patching dari kerentanan pada CVE tersebut.

Pada file class.imageuploader.php terdapat banyak perubahan, disini kita bisa melihat jika block merah artinya code yang dihapus dan block hijau yaitu code yang ditambahkan. pada file ini juga terdapat instansiasi CURL yang dalam hal ini kita mendapat gambaran sekilas bagaimana kerentanan terjadi.

Mari kita lihat source codenya secara utuh pada https://github.com/Story-Chief/wordpress/releases yang pada github ini merupakan versi 1.0.41 sedangkan patching dilakukan pada v1.0.43 jadi pada github ini masih tergolong versi rentan yang belum di patch

Seperti pada deskripsi yang mengatakan jika kerentanan dipicu melalui endpoint /wp-json/storychief/webhook jadi kata kunci penting disini ada pada webhook, yang pada plugin StoryChief juga terdapat file dengan nama webhook.php

Disini kita bisa mulai melakukan source code review, tapi sebelum itu kita perlu tau konsep saat melakukan source code review dan tidak melakukan asal asalan. Bahkan owasp sendiri juga mempublikasikan standar guide untuk ini yaitu SAST(Static Analysis Security Testing) https://owasp.org/www-project-code-review-guide/assets/OWASP_Code_Review_Guide_v2.pdf yang berisi panduan bagaimana best practice saat melakukan source code review. Agar lebih singkat, yang perlu kita pahami saat melakukan source code review yaitu “source” dan “sinks”, source merupakan dimana code yang kemungkinan terjadi kerentanan dan sinks yaitu tempat kerentanan sebenarnya terjadi.

yang pada webhook.php disini kita menemukan input yang bisa kita kontrol yaitu fungsi register_routes() yang dimana pada array “callback” memanggil fungsi handle() dan pada fungsi handle() juga terdapat json_decode() yang melakukan decode pada inputan POST kita, pada blok kode ini bisa kita katakan “source” atau sumber terjadinya kerentanan, dan untuk “sinks” kita akan mencoba identifikasi lebih lanjut

fungsi upload pada PHP dan wordpress sendiri kita bisa klasifikasikan sebagai berikut :

Jika mengacu pada kerentanan Arbitrary File Upload, pasti salah satu fungsi diatas digunakan dan pada visual studio code kita bisa mencari pada fitur searching string

fungsi file_put_contents() dipanggil pada file class.imageuploader.php, persis seperti pada patch diff yang kita identifikasi sebelumnya

fungsi save() disini yang memanggil file_put_contents dan juga terdapat suatu instansiasi CURL, dan asumsi awal sepertinya fungsi ini mendownload file dari URL external yang kemudian diletakkan pada directory /wp-content/uploads/ karena terdapat fungsi wp_upload_dir()

disini “Sinks” ditemukan pada fungsi save() yaitu fungsi file_put_contents(), nah jika kita sudah mengelompokkan seperti ini baru berfikir bagaimana dari “source” / inputan user berpindah ke “sinks” yang menjalankan fungsi file_put_contents().

Sekarang kita balik ke “source” dan mencoba untuk memahaminya

terdapat 2 validasi, pada payload json yang kita inputkan. validasi pertama yaitu \Storychief\Tools\validMac($payload) yang disini memanggil fungsi validMac pada file tools.php

Disini melakukan comparison atau perbandingan jika mac tidak sama pada payload maka gagal atau return false, jadi kira kira logic sederhananya seperti ini :

  1. kita input : payload=heker
  2. maka gagal karena harus ada parameter mac
  3. jadi harusnya gini: payload=heker&mac=123
  4. ini juga tidak valid karena mac tidak sama
  5. tapi disana ada unset($payload[‘meta’][‘mac’]);
  6. artinya mac diambil atau hasil payload=heker yang dihash sha256
  7. jadi kita perlu hash sha256 pada “payload=heker” dan digunakan untuk mac

Semoga bisa dipahami, jadi kita kecualikan untuk macnya dan lanjut susun payloadnya tanpa mac terlebih dulu.

validasi kedua ada $payload[‘meta’][‘event’] yang kemudian dilakukan switch case ya, yang jika kita isi $payload[‘meta’][‘event’] publish maka akan menuju ke fungsi handlePublish() dan kira kira seperti ini payloadnya

Jadi kita disini asumsinya sudah menuju ke fungsi handlePublish

Diatas kita menemukan fungsi wordpress do_action yang memanggil fungsi callback storychief_save_featured_image_action yang jika kita search pada vscode, ditemukan pada file mapping.php

Dan yap, kita menemukan fungsi yang memanggil class ImageUploader dengan method save() dan fungsi ini yang digunakan untuk upload file, jadi sekarang kita sudah mengetahui data flow terjadinya kerentanan jadi mari kita rangkai payloadnya, dan kita sesuaikan dengan validasi pada variable $story[‘featured_image’][‘data’][‘sizes’][‘full’]

dan payloadnya akan seperti diatas, nah baru pada payload ini kita bisa meng-hasilkan hmac dengan melakukan encode dan hash ke sha256

dan setelah hmac didapatkan sekarang kita perlu menghost php file pada vps atau hosting pribadi karena nama file yang disimpan diambil dari nama path external

Juga ada sedikit restriksi, dimana content-type yang diizinkan harus image

dan kita bisa membypass-nya dengan membuat file php seperti ini pada vps/hosting :

Yang dimana akan memforce atau memaksa header jika content-type diset ke image/jpeg meskipun raw datanya merupakan plain-text, dan untuk echo “<?php phpinfo(); ?>”; bisa disesuaikan lagi, karena disini hanya untuk tujuan demontrasi jadi cukup memanggil phpinfo() saja

Kasus disini aku memakai vps dan menjalankan php webserver

Terakhir payload final dan exploit akan menjadi seperti ini

dan untuk melihat hasil uploadnya, kita bisa mengacu pada fungsi ini di file class.imageuploader.php

wp_upload_dir(date('Y/m', $this->post->post_date ? strtotime($this->post->post_date) : time()));

yang disini memanggil date dengan parameter pertama ‘Y/m’ artinya tahun/bulan, jadi jika sekarang tahun 2025 dan bulan 08 maka akan menjadi /wp-content/uploads/2025/08/cek.php

Dan exploit berhasil, untuk PoC automation lengkapnya yang ku publish di exploit-db bisa langsung kunjungi link berikut https://www.exploit-db.com/exploits/52422 . jadi mungkin sekian itu saja dan semoga bermanfaat.

“Ilmu itu cahaya, dan belajar adalah menyalakan lentera dalam kegelapan.”Imam Al-Ghazali

By xpl0dec

Tinggalkan Balasan

Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib ditandai *