Pembaruan keamanan yang dirilis oleh Microsoft pada 11 April 2023, membahas lebih dari 90 kerentanan individu. Yang menjadi perhatian khusus adalah CVE-2023-21554, dijuluki QueueJumper, kerentanan eksekusi kode jarak jauh yang mempengaruhi layanan Microsoft MessageQueueing (MSMQ). MSMQ adalah komponen Windows opsional yang memungkinkan aplikasi untuk bertukar pesan melalui antrian pesan yang dapat dijangkau baik secara lokal maupun jarak jauh. Analisis ini dilakukan bekerja sama dengan tim Randori dan X-Force Adversary Services, oleh Valentina Palmiotti, Fabius Watson, dan Aaron Portnoy.
Kualitas CVE-2023-21554 berikut menarik perhatian awal:
Tetap terinformasi tentang tren industri yang paling penting—dan menarik—tentang AI, otomatisasi, data, dan di luarnya dengan buletin Think. Lihat Pernyataan Privasi IBM®.
Untuk menentukan cara mendeteksi keberadaan MSMQ, sistem uji dikonfigurasi dengan komponen di lingkungan lab. Saat menghubungkan ke titik akhir MSMQ pada port 1801, server tidak merespons dengan data apa pun. Dapat diasumsikan server tidak akan membalas tanpa menerima data yang dibentuk secara wajar. Untuk memahami cara melakukan percakapan dengan titik akhir, diperlukan pemeriksaan lebih lanjut terhadap kode yang mendasarinya.
Nasihat tersebut tidak secara langsung menunjukkan biner mana yang telah diperbaiki dengan patch. Langkah pertama untuk mengidentifikasi kode yang diubah adalah mengunduh file pembaruan. Hal ini diperoleh dengan mencari KB5025224 di Katalog Pembaruan Microsoft.
Hasil pencarian Katalog Pembaruan Microsoft untuk KB5025224
Secara khusus, file pembaruan kumulatif
windows10.0-kb5025224-x64_3522b1b562ed44bc949541dd1c7d08e1e967d925.msu
untuk Windows 11 untuk Sistem berbasis x86 diambil.
Ekstraktor 7-Zip digunakan untuk membongkar isi file MSU dan file CAB yang dikandungnya. Mencari string “msmq” di semua file di folder yang dihasilkan menghasilkan file Indeks Kontainer,
Windows11.0-KB5025239-x64/express.psf.cix.xml,
yang termasuk entri berikut:
<File id="21296" name="amd64_microsoft-windows-msmq-queuemanager-core_31bf3856ad364e35_10.0.22621.1555_none_5f975f8fdb349517\f\mqqm.dll" length="34811" time="133245266510000000" attr="128">
Catatan ini referensi
Untuk mengidentifikasi perubahan yang dibuat antara versi yang ditambal dan tidak ditambal dari fileMQQM.dll1.00
Hasil Bindiff antara file MQQM.dll yang ditambal dan tidak ditambal
Analisis fungsi-fungsi ini menggunakan Hex-Rays Decompiler mengungkapkan simbol untuk versi yang ditambal yang berisi nama fungsi verbose yang tampaknya merujuk pada pengidentifikasi kerentanan Microsoft Security Research Center (MSRC):
Simbol feature flag di dalam MQQM.dll
Setelah diperiksa lebih dekat, simbol yang berisi nomor kasus MSRC sesuai dengan featureflaf untuk perbaikan kerentanan. Feature flad adalah komponen Windows yang mengalihkan berbagai fungsionalitas dan eksperimen. Di sini, “feature” yang ditemukan sebenarnya adalah tambalan untuk kerentanan. Jika fitur diaktifkan, jalur kode yang aman dan ditambal dijalankan. Jika tidak, jalur kode asli yang belum ditambal dijalankan.
Cuplikan kode yang didekompilasi menunjukkan feature flag untuk perbaikan kerentanan
Pemeriksaan bendera fitur hadir untuk setiap kerentanan yang terdiri dari CVE-2023-21554 di komponen pengguna dan kernel. Analisis terhadap sisa biner yang terdapat dalam paket pembaruan keamanan menunjukkan bahwa feature flag juga diperkenalkan untuk sebagian besar atau seluruh kerentanan yang diperbaiki pada Patch Tuesday April 2023.
Dengan mencocokkan flag-flag ini, kami dapat dengan cepat menemukan lokasi kode yang telah ditambal. Secara khusus, perubahan di dalam yang terkait denganMSRC76146_MSMQ_OOBRWFixes tampak paling menarik.
Pemeriksaan untuk bendera fitur ini terjadi delapan kali dalam fungsi. Salah satu contoh pengecekan tersebut digambarkan di bawah ini:
Cuplikan kode yang didekompilasi yang menunjukkan perbaikan kerentanan
Dalam cuplikan kode yang didekompilasi yang ditunjukkan di atas, jalur kode yang ditambal memperoleh pointer ke bagian berikutnya dari pesan MSMQ melalui panggilan ke
Cuplikan dekompilasi fungsi GetNextSectionPtrSafe
Setelah menelaah seluruh kemunculan feature flag ini dan yang lainnya, disimpulkan bahwa CVE-2023-21554 terdiri dari beberapa bug yang tidak memeriksa ukuran berbagai tipe section pesan MSMQ secara memadai. Kerentanan ini memungkinkan pointer ke akhir pesan MSMQ ditingkatkan oleh offset 32-bit arbitrer ke luar batas buffer yang awalnya dialokasikan.
Setelah pemrosesan paket, langkah terakhir di
Pemeriksaan akses memori di luar batas untuk akhir pesan
Saat mengevaluasi eksploitabilitas kerentanan, kerentanan kernel tambahan diidentifikasi di driver kernel yang sesuai untuk layanan MSMQ, . Kerentanan sekali lagi ditunjukkan oleh simbol-simbol bendera fitur, yang juga merujuk pada kasus MSRC 76146 seperti yang diamati dalam .
Simbol feature flag dalam mqac.sys
Analisis dari feature flag
Untuk melakukan operasi terkait, komponen kernel mengurai berbagai bagian buffer paket MSMQ. Dua contoh seperti itu digambarkan di bawah ini:
Cuplikan kode yang didekompilasi menunjukkan feature flag untuk perbaikan kerentanan di driver kernel mqac.sys
Seperti yang terlihat pada cuplikan kode yang didekompilasi di atas, jika bendera fitur diaktifkan, fungsi “aman”
Sebagian besar kode yang berkaitan dengan parsing protokol berada di dalam perpustakaan , yang dimuat oleh prosesmqsvc.exe, permintaan MSMQ yang valid harus dikirim dari klien. Spesifikasi dan protokol pesan MSMQ sangat luas dan kompleks. Awalnya, kode publik ditemukan untuk memindai server MSMQ di GitHub yang menyediakan dasar untuk eksplorasi lebih mendalam dari pemrosesan paket. Selain itu, dokumentasi Microsoft sangat membantu untuk memahami formatpesan MSMQ.
Kode dalam DLL menerima data melalui port 1801 menggunakan panggilan ke fungsi WSARecv, seperti yang dapat dilihat dalam sesi debugging di bawah ini:
0:020> bp ws2_32!wsarecv ; g
Breakpoint 0 hit
WS2_32!WSARecv:
00007ffd`651115c0 48895c2408 mov qword ptr [rsp+8],rbx ss:000000aa`f07fef30=0000000000000006
0:019> k
# Child-SP RetAddr Call Site
00 000000aa`f07fef28 00007ffd`57ba9cb0 WS2_32!WSARecv
01 000000aa`f07fef30 00007ffd`57b9683d
MQQM!NoReceivePartialBuffer+0x38
02 000000aa`f07fefb0 00007ffd`57b2078e MQQM!CWinsockConnection::ReceivePartialBuffer+0x7d
03 000000aa`f07ff010 00007ffd`57b25b28
MQQM!CSockTransport::BeginReceive+0xe6
04 000000aa`f07ff060 00007ffd`57b2d40b
MQQM!CSockTransport::NewSession+0x194
05 000000aa`f07ff3f0 00007ffd`57b2d367 MQQM!CSessionMgr::AcceptSockSession+0x6f
06 000000aa`f07ff430 00007ffd`645e26bd MQQM!AcceptIPThread+0x6a7
07 000000aa`f07ff7d0 00007ffd`6650a9f8
KERNEL32!BaseThreadInitThunk+0x1d
08 000000aa`f07ff800 00000000`00000000 ntdll!RtlUserThreadStart+0x28
0:019> r @$t0=@rdx
0:019> pt
WS2_32!WSARecv+0x19f:
00007ffd`6511175f c3 ret
0:019> dc poi(@$t0+8) LC
000001b5`880ff490 62f06110 524f494c 00000070 5a5a5a5a .a.bLIORp…ZZZZ
000001b5`880ff4a0 0073006e 00610074 0063006e 00200065 n.s.t.a.n.c.e. .
000001b5`880ff4b0 00440049 00000000 00000000 00000000 I.D………….
0:019> ba r1 poi(@$t0+8) ; g
Breakpoint 1 hit
MQQM!CBaseHeader::SectionIsValid+0x154:
00007ffd`57b53450 7462 je
MQQM!CBaseHeader::SectionIsValid+0x1b8 (00007ffd`57b534b4) [br=1]
Fungsi bertanggung jawab untuk mem-parsing awal pesan baru, yang dimulai dengan struktur BaseHeader dari bentuk:
Struktur objek BaseHeader
Bidang pesan masuk divalidasi oleh
Kode pembongkaran untuk SectionIsValid dalam MQQM.dll
Setelah validasi awal, sebagian besar penguraian protokol terjadi dalam
Dekompilasi menunjukkan kerentanan dalam penanganan eodHeader
Dekompilasi di atas menunjukkan jalur yang telah ditambal memanggil fungsi bernama
Struktur dari
Pembongkaran menghitung ukuran total bagian EODHeader
Pada pembongkaran di atas, penunjuk ke awal
Sesi WinDbg menunjukkan pelanggaran akses saat menulis ke akhir pesan MSMQ yang salah format
Untuk mengevaluasi kekuatan out-of-bounds write yang diperoleh dari kerentanan tersebut, kami terlebih dahulu meneliti alokasi dan pengelolaan memori yang mendasarinya.
SebelumMSMQ. Fungsi ini memanggil driver kernel melaluiNtDeviceIoControl.
Dekompilasi fungsi alokasi buffer paket
Komponen kernel mengembalikan buffer yang dipartisi dari tampilan file yang dipetakan pada disk, disimpan di direktori
Tata letak memori ProcessHacker dari proses MQSVC yang menunjukkan memori buffer paket adalah pemetaan file
Alamat buffer paket, bersama dengan penanganan paket acak, dikembalikan ke ruang pengguna setelah permintaan alokasi melalui IOCTL. Driver menggunakan handle untuk menghitung alamat buffer paket saat menangani permintaan dari ruang pengguna.
Memori pendukung untuk buffer yang rentan berada di dalam file yang dipetakan, dan karenanya tidak berada di dalam heap proses. Selain itu, memori yang terpengaruh tidak menyimpan objek apa pun. Satu-satunya hal yang terkandung dalam pemetaan file adalah isi pesan MSMQ bersama dengan metadata yang disimpan di
Selanjutnya, tanpa pengetahuan sebelumnya tentang tata letak memori, tidak mungkin untuk mengetahui posisi relatif dari pemetaan file ke tumpukan proses untuk mengganti penunjuk objek. Oleh karena itu, untuk mendapatkan eksekusi kode jarak jauh secara layak, kami memerlukan beberapa metode untuk membentuk memori ke posisi yang dapat diprediksi.
Setelah melakukan percobaan dengan mengirim pesan MSMQ yang valid ke target, ditemukan bahwa alokasi heap baru yang bersebelahan dengan pemetaan file
Tata letak memori proses MQSVC menunjukkan heap baru yang dialokasikan berdekatan ke pemetaan file MQ
Namun, hal ini mengharuskan penyerang memiliki akses untuk mengirim pesan ke setidaknya satu antrean pada target; jika tidak, pesan akan dibuang dan ditimpa sehingga tidak menempati memori paket secara terus-menerus.
Dalam riset yang dilakukan, ditemukan bahwa pengguna yang tidak memiliki hak istimewa dapat membuat antrean yang terbuka bagi siapa saja untuk mengirim pesan dari jarak jauh, secara default. Antrean tersebut akan terus ada di sistem tanpa batas waktu. Meskipun sebagian besar penggunaan modern MSMQ ada sebagai komponen dan adaptor opsional, vendor seperti Oracle, Veritas, dan Xerox menawarkan perangkat lunak perusahaan yang mengandalkan MSMQ sebagai ketergantungan inti. Oleh karena itu, skenario serangan tidak realistis.
Kerentanan akses memori di luar batas memperkenalkan eksploitasi primitif yang memungkinkan
klien jahat untuk menulisOnDiskExtensionHeader
dialokasikan untuk paket.
Saat menilai kerentanan yang memungkinkan penulisan nilai ke offset, beberapa properti
harus dipertimbangkan:
Dalam kasus kerentanan QueueJumper, offset buffer yang dialokasikan ke penulisan OOB dapat dikontrol karena dihitung menggunakan data yang dikendalikan penyerang. Isi penulisan OOB, bagaimanapun, memiliki kontrol terbatas.
Di sini,Address akan ditulis. Rangkaian operasi yang terjadi adalah sebagai berikut:
0x000000000000000C
ditulis untukAddress0x00000000Address+0x2
0x0000000000000000Address+0x12
0x0000000000000000
ditulis ke Address+0x1A
0x00000094
ditulis Address+0xE
0x0000Address+0x220x0000
ditulis ke Address+0x62
memcpy(Address+0xA6, Source, Source->AddressLength+0x08)
Sourcememcpy mendefinisikan alamat transportasi tunggal dari jenis tertentu (misalnya, NetBIOS). Definisinya sebagai berikut:
typedef struct _TA_ADDRESS {
USHORT AddressLength;;
USHORT AddressType; Info;
UCHAR Address[1];;
} TA_ADDRESS, *PTA_ADDRESS;
Menentukan jumlah byte dalam alamat dari AddressType yang ditentukan.
Menentukan jenis alamat transportasi.
Menentukan array berukuran variabel yang berisi alamat transportasi.
Dalam sesi debugging di bawah ini,TA_ADDRESS
rax=0000014e1d110180 rbx=0000014e1d110180 rcx=0000014e1d110184
rdx=0000014e1ce86b10 rsi=0000014e1d110001 rdi=0000000545d7fa50
rip=00007ff843208074 rsp=0000000545d7f940 rbp=0000000545d7f980
r8=000000000000000c r9=0000000000000002 r10=0000000000000000
r11=0000000545d7f938 r12=0000000000000002 r13=0000000000001000
r14=0000014e1ce86b10 r15=0000000000000000
iopl=0 nv up ei pl nz na po nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206
MQQM!CQmPacket::CQmPacket+0x89c:
00007ff8`43208074 e8a5780a00 call MQQM!memcpy (00007ff8`432af91e)
0:017> dc rcx
0000014e`1d110184 00010004 00000000 8620a8c0 00000000 ………. …..
Di atas, objekTA_ADDRESS, sebuah tipe dari1. Mengonversi setiap byte ke oktet IPv4 menghasilkan alamat, yang merupakan alamat sumber IPv4 klien.
Skenario ini memungkinkan penulisan data yang dikendalikan oleh penyerang melalui alamat sumber ke offset yang terkontrol dari alokasi paket di memori. Meskipun sangat terbatas dan mungkin tidak praktis, secara teoretis hal ini dapat digunakan untuk mengontrol secara presisi nilai yang dituliskan ke memori dengan membuat beberapa permintaan dari alamat sumber yang berbeda pada offset paket yang menurun.
Karena banyaknya keterbatasan yang ditemui untuk mencapai eksekusi kode jarak jauh secara blind, skenario serangan alternatif seperti kebocoran informasi kemudian diteliti.
Salah satu serangan yang dipertimbangkan adalah merusak pointer ke bagian pesan tertentu agar menunjuk ke memori di luar batas, kemudian mengambil kembali pesan tersebut untuk membaca memori yang berdekatan.
Namun, pada awal proses parsing setiap section dilakukan pengecekan terhadap posisi section saat ini, sehingga kita tidak dapat mengecoh logika parsing untuk memproses bagian data yang berada di luar batas.
Skenario serangan lain yang mungkin adalah mengganti onDiskExtensionHeader dari pesan lain untuk mengelabui penerima pesan tentang asal pesan yang diterima. Demikian pula, dimungkinkan untuk mengganti isi pesan yang ditujukan untuk antrian yang tidak dapat diakses oleh penyerang. Untuk menimpa konten tertentu dari sebuah pesan, penyerang perlu memiliki informasi tentang pesan tersebut, seperti ukurannya.
Ada bagian opsional bernama SoapHeader yang rentan terhadap akses data di luar batas, dengan format berikut:
Format paket SoapHeader
Terlihat bahwa saat buffer dibebaskan, memori yang menampung data paket MSMQ tidak dikosongkan dengan benar. Akibatnya, pengiriman paket MSMQ yang berukuran lebih kecil dibandingkan paket sebelumnya akan menghasilkan tata letak memori yang berisi data paket saat ini diikuti oleh data dari paket MSMQ yang telah diproses sebelumnya.
Ditemukan bahwa
Kontrol yang terbatas terhadap isi penulisan, ditambah dengan penulisan tambahan yang tidak terkontrol yang merusak memori di sekitarnya, serta minimnya pemahaman tentang tata letak pesan, menjadi hambatan besar dalam proses eksploitasi.
Pada saat analisis, hanya kerentanan ruang pengguna yang terlibat dalam pemrosesan awal paket pesan MSMQ yang dievaluasi untuk eksploitabilitas. Analisis terhadap varian kerentanan kernel dapat mengungkap jalur eksploitasi tambahan. Sebagai contoh, menyertakan header yang tidak valid berpotensi menghasilkan write primitive pada pemetaan memori kernel dari file . Dalam beberapa kasus, pemeriksaan dalam pemrosesan ruang pengguna mencegah kernel melakukan beberapa operasi pascapemrosesan.
Selain itu, pada varian kernel, penyerang memiliki kontrol yang lebih terbatas terhadap isi pesan dan juga beroperasi pada pemetaan file yang sama dengan ruang pengguna, bukan pada kumpulan kernel (heap). Mitigasi, seperti KASLR, juga menghadirkan hambatan yang sulit diatasi untuk eksploitasi jarak jauh.
Berkat implementasi kode yang telah ditambal, klien jarak jauh dapat dengan aman mengetahui apakah suatu sistem sudah menerapkan pembaruan. Hal ini dapat dilakukan dengan mengirim pesan MSMQ yang memicu kerentanan tersebut, tetapi tidak sampai menyebabkan akses out-of-bound, sehingga proses layanan tidak mengalami crash. Jika flag HTTP disetel pada UserHeader pesan, SRMPEnvelopeHeader akan diharapkan. Di dalam patch, pemeriksaan untuk integer overflow dilakukan pada bidang dikalikan dengan 2. Panjang ini dapat diatur sehingga hasil perkalian melimpah ke angka kecil yang sama dengan ukuran data yang sebenarnya.
Cuplikan kode yang didekompilasi menunjukkan pemeriksaan luapan bilangan bulat pada SRMPEnvelopeHeader DataLength
Jika target sudah ditambal, kerentanan tersebut akan memicu pengecualian dan server akan menghentikan pemrosesan pesan, sehingga tidak ada respons yang dikirim kembali ke klien. Jika tidak ditambal, server akan memproses pesan secara normal dan mengirim respons.
Karena memori dukungan lokasi dari buffer rentan, eksekusi kode jarak jauh tampaknya lebih layak bagi penyerang dengan kemampuan untuk mengirim pesan ke antrean apa pun pada target. Dalam situasi tersebut, proses grooming memungkinkan terbentuknya alokasi heap yang saling berdekatan. Kontrol yang sangat terbatas atas konten tulis menghadirkan tantangan untuk eksploitasi jarak jauh. Karena adanya mitigasi seperti ASLR, kebocoran informasi juga harus diperoleh. Ada kemungkinan bahwa satu penulisan konstanta (0xC, 0x0
Pada akhirnya, kami menyimpulkan bahwa sementara eksploitasi jarak jauh QueueJumper mungkin bukan tidak mungkin, persyaratan yang disebutkan di atas membuatnya sulit untuk dicapai. Posting blog ini hanya menggaruk permukaan dari spesifikasi pesan, layanan, dan protokol yang sangat kompleks. Riset kerentanan lebih lanjut pada ruang pengguna dan operasi komponen kernel diperlukan.