- GPT5.6 Sol Ultra menganalisis WordPress versi stabil terbaru dan menyelesaikan rantai serangan dari injeksi SQL pra-autentikasi hingga pembuatan akun admin dan eksekusi kode jarak jauh (RCE) dalam sekitar 10 jam
- Titik awalnya adalah ketidakcocokan indeks array pada Batch API yang tersedia sejak WordPress 5.6, dengan menggabungkan permintaan Batch rekursif untuk melewati pembatasan GET dan validasi parameter
- Setelah memicu injeksi UNION lewat string
author_excludeyang tidak tervalidasi, model memasukkan postingan yang dimanipulasi ke cache memori lalu mengeksploitasi secara berantai cache oEmbed, changeset, referensi siklik, dan hook - Dengan
user_id: 1padacustomize_changeset, model memperoleh hak admin sementara dan menjalankan ulang permintaan Batch melalui hookparse_requestuntuk membuat admin baru, lalu mengunggah ZIP plugin backdoor hingga mencapai eksekusi kode - Biaya yang dihitung secara proporsional dari 50% pemakaian mingguan langganan 200 dolar per bulan adalah sekitar 25 dolar, dan peran manusia kemungkinan bergeser ke pengarahan riset tingkat tinggi seperti memilih produk dan permukaan serangan serta menyesuaikan prompt
Proses penemuan dan kondisi eksperimen
- Prompt yang diungkap OpenAI sebagai yang digunakan untuk menyelesaikan dugaan Cycle Double Cover prompt dimodifikasi untuk riset keamanan lalu diberikan ke GPT5.6 Sol Ultra
- WordPress versi stabil terbaru dikloning ke
main/dan direktori.gitdihapus, sementara direktorithird_party/kosong disiapkan agar kode dependensi bisa diteliti - Prompt menginstruksikan penggunaan maksimal 4 agen secara paralel untuk mempertahankan beragam jalur serangan selama sedikitnya 6 jam
- Menjelajahi parsing input, set karakter, unggah file, penanganan error, jalur bawaan, serialisasi, cache, race condition, kriptografi, tipe, mass assignment, dan lainnya
- Mendaftarkan keluarga pendekatan dan memindahkan agen ke area yang kurang dieksplorasi bila terlalu banyak agen menumpuk pada strategi tertentu
- Bug spesifik diverifikasi ulang oleh agen yang bersifat adversarial, dan jalur yang gagal dibuka kembali bila muncul mekanisme baru
- Pencarian dibatasi agar menemukan kerentanan baru dari kode sumber itu sendiri tanpa memakai riwayat perubahan, perbedaan dengan versi patch, atau petunjuk dari internet
- Untuk menghindari konfigurasi yang tidak realistis atau prasyarat yang tidak mungkin dipenuhi penyerang, targetnya dinyatakan sebagai “RCE pra-autentikasi pada deployment produksi umum yang memakai MySQL”
- Setelah sekitar 6 jam, model menemukan injeksi SQL pra-autentikasi dan mereproduksinya dalam hitungan menit dengan mengekstrak email admin dari server WordPress jarak jauh bawaan
- Saat diminta menaikkan ke RCE, sekitar 4 jam kemudian model menyelesaikan rantai dari injeksi SQL read-only ke hak admin tanpa cracking kata sandi atau komputasi offline
- Total waktu kerja adalah sedikit di atas 10 jam dan menghabiskan 50% kuota mingguan. Biaya proporsional dari langganan 200 dolar per bulan sekitar 25 dolar
- Selama akhir pekan sebelum publikasi, operator diberi waktu untuk meng-upgrade WordPress, dan selama itu Calif serta Hacktron secara independen mereproduksi seluruh rantai lebih cepat daripada PoC lain di GitHub
- Instance yang sedang berjalan dapat diperiksa kerentanannya di wp2shell.com
Ketidakcocokan validasi pada Batch API
- Batch API yang diperkenalkan di WordPress 5.6 memproses beberapa permintaan API virtual dalam satu permintaan. Endpoint-nya sendiri bisa diakses tanpa autentikasi, tetapi setiap subpermintaan menerima informasi autentikasi
- Permintaan REST biasa diproses dalam urutan berikut
- Memeriksa nilai wajib dan validitas dengan
has_valid_params() - Membersihkan nilai dengan
sanitize_params() - Menjalankan callback izin
- Menjalankan callback endpoint
- Memeriksa nilai wajib dan validitas dengan
- Demi performa, Batch API memisahkan validasi dan eksekusi ke dalam dua loop
- Pada loop pertama, semua permintaan divalidasi dan dibersihkan
- Pada loop kedua, hasil validasi diperiksa lalu callback izin dan endpoint dijalankan
- Implementasinya mengasumsikan bahwa hasil pencocokan rute
$matchesdan hasil validasi$validationsaling berpasangan pada indeks yang sama - Jika permintaan yang salah masuk ke cabang
is_wp_error($single_request), item ditambahkan ke$validation, tetapi karenacontinue, item tidak ditambahkan ke$matches- Setelah itu semua item di
$matchesbergeser satu posisi - Parameter dari satu permintaan bisa divalidasi dengan aturan milik permintaan lain, lalu dieksekusi pada handler endpoint yang semula tidak dimaksudkan
- Setelah itu semua item di
- Dengan memanfaatkan ketidakcocokan indeks ini, hasil validasi dari endpoint lain yang tidak membersihkan parameter bisa diterapkan ke endpoint yang mendukung Batch
Injeksi SQL pada author__not_in
GET /wp/v2/postsmenggunakan variabel kueri internalauthor__not_inuntuk mengecualikan penulis tertentu dari hasil- Jika nilainya array,
absintditerapkan ke tiap elemen agar menjadi integer, tetapi jika nilainya skalar, nilainya langsungimplodelalu dimasukkan ke klausa SQLNOT IN - Pada pemanggilan normal, parameter publik
author_excludeharus berupa array integer sehingga masalah ini tidak terlihat - Dengan memanfaatkan ketidakcocokan indeks Batch, string
author_excludebisa divalidasi memakai aturanDELETE /wp/v2/posts/1yang tidak mengenal parameter itu, lalu diteruskan keGET /wp/v2/posts - Pembatasan Batch API yang tidak mengizinkan subpermintaan GET juga dilewati dengan pemanggilan Batch rekursif
- Pada Batch luar, ketidakcocokan indeks dibuat agar validasi
methoduntuk permintaan dalam terlewati - Pada Batch dalam, ketidakcocokan indeks dibuat lagi agar validasi
author_excludeterlewati
- Pada Batch luar, ketidakcocokan indeks dibuat agar validasi
- Dengan memasukkan nilai seperti
0) OR 1=1 --, semua baris postingan dikembalikan sehingga injeksi dapat dikonfirmasi - Setelah itu, injeksi berbasis UNION dapat membuat baris berbentuk seperti
wp_postsuntuk membocorkan nilai basis data arbitrer - Kata sandi, token reset, API key, dan lainnya di-hash di basis data, jadi selama kata sandi admin tidak lemah, kebocoran data saja tidak langsung berujung pada pengambilalihan akun
Manipulasi cache postingan dalam permintaan
- WordPress menyimpan objek
WP_Postyang dirujuk berulang dalam satu permintaan di cache memori untuk mengurangi bolak-balik ke basis data - Jika injeksi UNION mengembalikan baris postingan palsu, banyak field seperti ID postingan, tipe, status, relasi induk, isi, dan lainnya bisa dimasukkan ke cache sesuai pilihan penyerang
- Karena isi postingan juga diproses ulang dalam respons API, isi yang dimanipulasi dapat menjalankan jalur kode tambahan
- Cache ini hilang saat permintaan selesai dan postingan palsu juga tidak ada di basis data, sehingga manipulasi cache saja tidak memberi persistensi antarpermintaan
Membuat baris basis data lewat cache oEmbed
- Fitur embeds di WordPress menyisipkan konten jarak jauh yang didukung melalui sintaks
[embed]...[/embed]pada isi postingan - Agar tidak mengirim permintaan HTTP setiap kali, hasilnya disimpan ke basis data sebagai postingan bertipe
oembed_cachediwp_posts - Jika postingan WordPress lokal di-embed memakai jalur relatif, permintaan HTTP dilewati, dan tidak diperiksa apakah ID postingan yang dirujuk benar-benar ada
- Bahkan bila postingan lokal yang tidak ada seperti
/?p=10di-embed, barisoembed_cacheuntuk data itu bisa dibuat - Saat baris yang dibuat itu dibaca lagi melalui injeksi SQL sambil tipe postingan di memori dimanipulasi menjadi
postdan sebagainya, representasi basis data dan cache menjadi berbeda - Saat WordPress menyelaraskan kedua representasi itu,
wp_update_post()dipanggil, dan untuk field selainIDsertapost_contentyang ditentukan secara eksplisit, nilai memori buatan penyerang lebih diutamakan - Akibatnya, baris
oembed_cachedapat diubah menjadi postingan biasa, tetapi pada pemanggilan inipost_contentditimpa hasil embed sehingga penyerang tidak bisa mengendalikan isi sampai level itu
Hak admin sementara melalui customize_changeset
- Draf pekerjaan kustomisasi tema disimpan di
wp_postssebagai postingan khusus bertipecustomize_changeset post_contentberisi JSON dengan nilai perubahan, tipe, dan ID pengguna yang melakukan perubahan untuk tiap kunci pengaturan- Saat changeset diterapkan, WordPress membaca
user_iddari tiap item dan sementara mengubah pengguna saat ini denganwp_set_current_user() - Jika penyerang menerapkan changeset dengan
user_id: 1, identitas admin dapat dipakai sementara bahkan dalam permintaan anonim - Karena pemanggilan penyelarasan oEmbed sebelumnya menimpa
post_content, dibutuhkan jalurwp_update_post()terpisah untuk mempertahankan JSON changeset berbahaya
Mempertahankan isi dengan siklus parent postingan
- Postingan WordPress dapat memiliki satu parent, tetapi struktur siklik yang menjadikan dirinya sendiri atau turunannya sebagai parent tidak diizinkan
- Filter
wp_insert_post_parentmenelusuri hierarki parent untuk memeriksa siklus, dan bila menemukan siklus, memanggilwp_update_post()yang mengubahpost_parentpostingan itu menjadi 0 - Pemanggilan kedua ini hanya menentukan
IDdanpost_parent, dan tidak menimpapost_content - Jika postingan di memori disamarkan melalui injeksi SQL sebagai
customize_changesetyang menjadikan dirinya sendiri sebagai parent, proses pemulihan siklus akan menulis JSON changeset berbahaya yang ditentukan penyerang ke basis data - Jika changeset dengan status
futurediberi tanggal lampau, WordPress akan menerapkannya dan menjalankan perubahan pengaturan yang ditentukan dengan hak admin sesuaiuser_id: 1 - Hak admin hanya bertahan selama pekerjaan changeset berlangsung dan akan kembali menjadi hak tamu setelah selesai
Menjalankan ulang seluruh permintaan lewat hook dinamis
- Hook WordPress dibagi menjadi action dan filter, memungkinkan plugin ikut campur di berbagai titik siklus hidup seperti login, publikasi, dan registrasi skrip
- Saat status postingan berubah, WordPress menjalankan action dinamis berbentuk
"{$new_status}_{$post->post_type}"- Untuk postingan normal, namanya akan menjadi seperti
publish_post - Postingan palsu di memori bisa diberi status dan tipe arbitrer sehingga nama action yang diinginkan dengan satu atau lebih underscore dapat disusun
- Untuk postingan normal, namanya akan menjadi seperti
- Karena argumen hook dibatasi pada ID postingan dan objek
WP_Postyang ditentukan penyerang, tidak mudah memanggil action arbitrer secara langsung dengan hasil yang berguna - Rantai serangan memanipulasi status menjadi
parsedan tipe menjadirequestuntuk memanggil hookparse_request - Karena
parse_requestadalah hook yang dijalankan di awal siklus hidup permintaan, memanggilnya lagi membuat seluruh permintaan Batch asli diproses ulang dari awal - Pemrosesan ulang berlangsung sementara identitas admin sementara yang ditetapkan changeset masih aktif, sehingga permintaan khusus admin yang gagal pada eksekusi pertama karena kurang izin bisa berhasil pada eksekusi kedua
Rantai RCE lengkap dengan dua permintaan
- Eksploit akhir memakai dua permintaan HTTP dan memberi ID besar pada postingan palsu agar tidak berbenturan dengan postingan asli
-
Permintaan pertama: menyiapkan baris persisten
- Injeksi SQL mengembalikan postingan palsu dengan tiga embed lokal untuk membuat 3 baris
oembed_cacheyang sesuai denganO,C, danD - Ketiga embed menunjuk ke postingan yang sama
S, tetapi memakai query string berbeda untuk menghasilkan hash cache oEmbed terpisah
- Injeksi SQL mengembalikan postingan palsu dengan tiga embed lokal untuk membuat 3 baris
-
Permintaan kedua: merakit enam postingan
- Enam postingan palsu berikut disusun dalam cache memori
O: cache lama dengan status/tipepublish/oembed_cachedan parentCC:future/customize_changesetyang menjadikan dirinya sendiri sebagai parent dan memuat JSON changeset berbahayaP:draft/pagedengan parentDD:parse/requestyang menjadikan dirinya sendiri sebagai parentS:publish/postyang menyediakan data embedT:publish/postyang memuat embed luar- Embed pada
TmembacaO, lalu karena waktu modifikasi lama, memicu pembaruan cache untukS - Saat pembaruan
Omendeteksi siklus pada parentC, parentCdiubah menjadi 0 dancustomize_changesetdi memori beserta JSON berbahaya ditulis ke basis data - Changeset
futurebertanggal lampau diterapkan, lalu memublikasikanPdengan identitas admin dariuser_id: 1 - Pembaruan
Pmenemukan siklus pada parentD, menulisD, dan memanggil actionparse_requestdengan status serta tipe yang dimanipulasi - Sejak awal, permintaan Batch sudah memuat permintaan pembuatan admin baru
- Pada pemrosesan pertama, ini gagal karena haknya masih tamu
- Saat dijalankan ulang lewat
parse_request, ini berhasil karena hak admin sementara masih aktif - Setelah login dengan akun admin baru, mengunggah ZIP plugin backdoor akhirnya menghasilkan eksekusi kode jarak jauh
Peran yang berubah dalam riset keamanan AI
- Langkah yang paling kreatif dalam keseluruhan rantai ini adalah melewati pembatasan GET dengan pemanggilan Batch rekursif, memperoleh hak admin dengan menggabungkan cache dan changeset, lalu menjalankan ulang permintaan dengan memanggil
parse_requestmelalui postingan palsu - Tidak bisa langsung disimpulkan sebagai keunggulan umum, tetapi penilaiannya adalah bahwa tanpa AI, peneliti keamanan tidak mungkin menemukan dan menyelesaikan rantai yang sama dalam 10 jam
- Bahkan jika bug Batch awal diberikan terlebih dahulu, masih diragukan apakah RCE bisa dirangkai dalam waktu tersebut
- GPT5.6 Sol Ultra dinilai jauh lebih maju daripada GPT5.5 sebelumnya dalam kemampuan menemukan beberapa gadget kode yang terpisah lalu menghubungkannya menjadi satu rantai
- Semakin model menangani pengembangan eksploit teknis, manusia akan semakin fokus pada memilih produk dan permukaan serangan yang akan diteliti, menentukan waktu dan arah riset, serta mengoreksi model saat melenceng
- Kemampuan meta-riset seperti ini masih belum dikuasai AI dengan baik, dan diperkirakan akan makin penting seiring meningkatnya kemampuan teknis model
1 komentar
Komentar Hacker News
Tidak ada dasar bahwa $500 ribu pernah atau akan dibayar untuk exploit seperti ini. Tulisan itu bilang prompt-nya disunting dengan hati-hati seperti mengedit kitab suci, jadi mungkin lebih baik prompt itu saja dijual seharga $500 ribu
Penulis bekerja di https://www.assetnote.io/, yang menyediakan produk AI pemindaian otomatis
Broker seperti ini biasanya tidak membayar jumlah besar sekaligus, melainkan menjual akses ke aktor negara lalu membayar bertahap selama bug belum ditambal. Strukturnya memang begitu untuk mencegah penjualan ulang atau cepat habis, jadi sepertinya hampir tidak ada orang yang bisa memastikan apakah nilai penuh benar-benar pernah dibayar untuk kerentanan serupa
Contoh terdekatnya adalah remaja Florida yang memasukkan malware ke game Steam untuk mencuri akun lalu tertangkap. Mereka mungkin tetap akan tertangkap, tetapi tanpa pamer di media sosial penyelidikannya pasti akan memakan waktu jauh lebih lama
Dari https://github.com/WordPress/WordPress/commit/3a640e1c5e39aa... terlihat bahwa SQL injection lewat konkatenasi string masih muncul bahkan pada 2026
Mereka menyuruh memakai
dbDeltaalih-alih menjalankan SQL langsung, tetapi menuntut aturan format yang sangat rewel, seperti setiap field harus di baris terpisah, harus ada dua spasi di antaraPRIMARY KEY, dan harus memakaiKEYalih-alihINDEX. Nama field juga tidak boleh memakai tanda kutip atau backtick, tipe data harus huruf kecil, kata kunci SQL harus huruf besar, dan semua parameter panjang harus ditentukansprintfPayload berbentuk
/wp/v2/widgets?author_exclude=1%29+AND+1%3D0+UNION+ALL+SELECT...disisipkan di requestPOSTdanGETPrincipal Software Engineer @ Bluehost,WordPress Core Committer, tetapi dengan kode seperti ini, kata ‘principal’ terdengar agak anehSaya sudah muak dengan gaya penulisan FOMO. Ini bukan ditemukan hanya dengan $25, melainkan berkat pengetahuan industri tentang harus melihat ke mana dan bagaimana menjelajah, plus bahan yang terkumpul selama bertahun-tahun
Kita perlu berhenti menyebarkan narasi ala judi dan ilusi bahwa semua orang sedang ketinggalan peluang
Bagian yang mengejutkan adalah harga tinggi untuk kerentanan yang sudah diketahui, dan itu pun mungkin tidak benar. WordPress bahkan sering disebut remote root shell dengan fitur blog
Saya paham bahwa untuk pengguna umum, lebih mudah memandu drag-and-drop daripada menyuruh mereka commit ke repositori GitHub lalu build dengan Hugo. Tetapi dari sudut pandang keamanan, strukturnya seperti hanya menunggu munculnya kerentanan di core atau salah satu dari ribuan plugin lalu membuka remote code execution as a service
Ini tulisan yang menarik, dan penemuan serta pengungkapan exploit berbasis LLM memang hal yang patut dikhawatirkan. Saya juga pernah membuat model menghasilkan kode pelarian kontainer dari kerentanan eskalasi privilese lokal Linux dengan relatif cepat
Namun tetap mengejutkan bahwa GPT-5.6 tidak memblokir prompt tersebut lewat guardrail. GPT-5.5 ke atas biasanya enggan melakukan pekerjaan keamanan ofensif, seperti Opus 4.7+/Fable, jadi tampaknya ada kemungkinan penulis mendapat persetujuan keamanan siber dari OpenAI untuk melonggarkan guardrail
Bahkan alat static application security testing (SAST) non-AI sebelum 2020 pun sudah banyak menangkap injeksi SQL seperti ini, dan setidaknya seharusnya ditemukan saat code review. Jadi muncul pertanyaan apakah WordPress tidak menggunakan code review atau SAST
Salah satu situs web saya diretas lewat kerentanan ini, tapi untungnya tidak punya pengguna
Penyerang membuat dua akun admin di database, lalu memasang web shell eksekusi perintah jarak jauh
wp-core-[12 karakter acak].phpdiwp-content/plugins/wp-core. Dimu-plugins, mereka menaruh backdoorfirewall.phpyang membuat admin lewatGET ?sergei, juga menambahkan backdoorcache-seo-helper.php, serta memakaifixer.phpuntuk mengubah nomor versi WordPress agar terlihat seperti versi yang sudah ditambal. Akhirnya saya memutuskan untuk berhenti memakai WordPressMenjelang akhir tulisan, penulis mulai menyebut post dengan nama-nama aneh sehingga jadi sulit dipahami. Satu ID dibuat sebagai
O, yang lain0, dan saya penasaran kenapa memakai satu huruf sertaOCPDSTyang tampak acak alih-alihEMBED_01atauABCDEFOberartipublish/oembed_cache,Cberartifuture/customize_changeset,Pberartidraft/page,Dberartiparse/request,Sberartipublish/postyang menyediakan data embed, danTberartipublish/postyang berisi embed eksternalSaya penasaran apakah ini mengasumsikan bahwa orang yang mau membayar 500 ribu dolar tidak punya kemampuan untuk memanfaatkan GPT-5.6 secara langsung
Saya juga mencari kerentanan keamanan dengan LLM, tetapi saya tidak bisa begitu saja menyerahkan hasilnya mentah-mentah dan selesai, meski banyak orang mencoba melakukannya
Apakah GPT-5.6 Sol itu manusia super bukanlah pertanyaan ya-tidak yang sederhana. Komputer sudah melampaui manusia dalam catur sejak puluhan tahun lalu, dan dari tulisan ini tampaknya sekarang juga sudah melampaui manusia dalam memahami kode