กระดาษทด: ช่องโหว่ Arbitrary File Write กับ DiagHub Exploit


เนื้อหาโดยส่วนใหญ่ของบล็อกนี้สรุปและแปลมาจากบล็อก Windows Exploitation Tricks: Exploting Arbitrary File Writes for Local Elevation of Privilege โดย James Forshaw จาก Google Project Zero
  • ช่องโหว่ในกลุ่มที่เป็น Arbitrary file write ทำให้ผู้ใช้งานสามารถสร้างหรือแก้ไขไฟล์ซึ่งอยู่ในตำแหน่งที่โดยปกตินั้นไม่สามารถเข้าถึงได้ อย่างไรก็ตามประโยชน์ที่แท้จริงของช่องโหว่ Arbitrary file write นั้นจะมีประโยชน์สูงสุดในมุมของการโจมตีเมื่อไฟล์ที่ถูกแก้ไขหรือเขียนทับเป็นไฟล์ส่งผลให้เกิดการยกระดับสิทธิ์หรือส่งผลกระทบต่อคุณลักษณะด้านความปลอดภัยอื่นๆ ได้
  • จากประเด็นด้านบนนั้น วิธีการใช้ช่องโหว่นี้ในลักษณะนี้ให้เป็นประโยชน์วิธีการหนึ่งคือการนำมาใช้เพื่อทำ DLL Hijacking โดยในมุมของผู้โจมตีนั้น ผู้โจมตีจะต้องทำการหาไฟล์ executable ที่รันด้วยสิทธิ์ที่สูงและจะมีการโหลดไฟล์ DLL จากตำแหน่งที่ช่องโหว่ Arbitrary file write สามารถเข้าไปแก้ไขไฟล์ได้ ผลลัพธ์ปลายทางสุดท้ายของการโจมตีในลักษณะนี้คือการยกระดับสิทธิ์
  • เงื่อนไขของการทำ DLL Hijacking นั้นส่วนหนึ่งขึ้นอยู่กับวิธีการทำ Loader ทำการค้นหาและโหลด DLL ที่โปรแกรมหนึ่งๆ จำเป็นต้องใช้งาน และจะสำเร็จก็ต่อเมื่อ DLL ที่เราต้องการให้ถูกโหลดเข้าไปนั้นไม่ถูกตรวจพบในตำแหน่งก่อนหน้า โดยทั่วไป Loader จะมีเงื่อนไขในการค้นหาและการโหลด DLL อยู่ตามลำดับของตำแหน่งดังต่อไปนี้
    • ใช้ฟีเจอร์ Known DLLs
    • ตรวจสอบหาไฟล์ DLL ในตำแหน่งพาธปัจจุบันของโปรแกรม
    • ตรวจสอบในพาธของระบบ อาทิ C:\Windows\System32 และ C:\Windows
    • ตรวจสอบใน Environment PATH
  • อย่างไรก็ตามข้อจำกัดในการทำ DLL Hijacking คือผู้โจมตีจะต้องทำการสร้างโปรเซสที่มีสิทธิ์สูงเพื่อบังคับให้เกิดการโหลด DLL ที่ใช้งานโดยส่วนใหญ่หลังจากที่ทำ Arbitrary file write เสร็จ เพื่อให้การแก้ไขไฟล์ DLL ถูกโหลดไปใช้งานจริง และตำแหน่งของไฟล์ executable/DLL ที่โดยส่วนใหญ่จะอยู่ในตำแหน่ง C:\Windows\System32 ด้วย (ถ้าไม่มีช่องโหว่ Arbitrary file write ก็ทำอะไรไม่ได้) แม้ว่าจะสามารถหาไฟล์ executable ซึ่งนำไปสู่การสร้างโปรเซสที่มีสิทธิ์สูงที่นอกพาธ C:\Windows\System32 กระบวนการแก้ไขไฟล์ DLL เพื่อทำให้กระบวนการ DLL Hijacking เกิดขึ้นอย่างสมบูรณ์ก็นำมาซึ่งปัญหาเพิ่มเติมด้วยเช่นกัน
  • ทั้งนี้หนึ่งในเซอร์วิสของระบบการชื่อ "Microsoft (R) Diagnostics Hub Standard Collector Service" หรือ DiagHub กลับถูกตรวจพบว่าเป็นเซอร์วิสหนึ่งที่มีคุณสมบัติอย่างเหมาะสมในช่วยให้เราสามารถใช้ความสามารถของช่องโหว่ Arbitrary file Write ร่วมด้วยความสามารถในการโหลดไฟล์ DLL ใดๆ ก็ได้แม้แต่ไฟล์ที่อยู่ใน C:\Windows\System32 และมีสิทธิ์ที่สูงโดยไม่จำเป็นต้องทำ DLL Hijacking
  • ความสามารถของ DiagHub ถูกอิมพลีเมนต์และสามารถเรียกใช้งานได้ผ่าน DCOM object ดังนั้นเพื่อควบคุมและใช้งาน DiagHub ให้เกิดประสิทธิภาพ ในบทความต้นฉบับของ Google Project Zero จึงได้มีการอธิบายกระบวนการ Reverse engineer เพื่อทำความเข้าใจการทำงานและนำความเข้าใจดังกล่าวมาใช้ในการสร้าง Exploit ด้วยในหัวข้อ Reverse Engineering a DCOM Object
  • ผลลัพธ์จากการ Reverse engineer กระบวนการทำงานของ DiagHub ทำให้เรารู้ว่าในการที่จะใช้ DiagHub เพื่อโหลด DLL ใดๆ นั้น เราจะต้องทำการสร้าง Diagnostics Session ด้วยเมธอด IStandardCollectorService::CreateSession และทำการเรียกเมธอด ICollectionSession::AddAgent โดยมีชื่อของไฟล์ DLL เป็นพารามิเตอร์


  • ในบทความต้นฉบับนั้น James Forshaw จะมีการสาธิตการใช้ช่องโหว่ Arbitrary file write ใน SvcMoveFileIntegeritSecurity ของ Storage service
  • ข้อจำกัดอย่างหนึ่งที่ถูกพูดถึงในบทความต้นฉบับคือไฟล์ที่จะถูกเขียนทับโดยใช้ช่องโหว่ เนื่องจากไฟล์โดยส่วนใหญ่ใน C:\Windows\System32\ นั้นมีเจ้าของไฟล์อยู่ในกลุ่มของ TrustedInstaller ซึ่งทำให้ไม่สามารถแก้ไขได้แม้ผู้แก้ไขจะมีสิทธิ์เป็น Local system การหาไฟล์ซึ่งสามารถถูกเขียนทับได้โดยไม่ส่งผลกระทบต่อการทำงานของระบบปฏิบัติการจึงเป็นประเด็นที่ควรต้องให้ความสนใจเป็นอย่างสูง ทั้งนี้เนื่องจากเมธอด  ICollectionSession::AddAgent ถูกอิมพลีเมนต์ให้ตรวจสอบเพียงแค่ชื่อของไฟล์ว่าไฟล์มีอยู่จริง จากนั้นจึงมีการใช้ฟังก์ชัน LoadLibraryEx ในการโหลดไฟล์ดังกล่าวโดยทันที นามสกุลของไฟล์ที่จะถูกแก้ไขจึงไม่ถือเป็นข้อจำกัด ในกรณีนี้นั้น James ใช้โมดูล NtObjectManager ในการค้นหาไฟล์ที่เซอร์วิส Storage service (StorSvc) ซึ่งมีช่องโหว่ Arbitrary file wirte มีสิทธิ์เขียนด้วย (WRITE_DAC) โดยผลลัพธ์ที่ James เลือกเอามาใช้ในการแก้ไขคือไฟล์ license.rtf ที่ตำแหน่ง C:\Windows\System32
  • เมื่อนำทุกอย่างมารวมกัน ผลลัพธ์ที่จะได้คือ
    • ใช้ช่องโหว่ของ Storage Service ในการแก้ไขการสิทธิ์ของไฟล์ license.rtf
    • คัดลอก DLL ที่มีการอิมพลีเมนต์ DllGetClassObject (โมดูลที่ ICollectionSession:AddAgent จะทำการเรียกจากไฟล์ DLL ที่ DiagHub โหลดเข้าไป) ทับไฟล์ license.rtf
    • ใช้เซอร์วิส DiagHub ในการโหลดไฟล์ license.rtf ที่เราแก้ไขแล้ว เพื่อให้ได้สิทธิ์ในการทำ Code execute ในระดับ Local system
ความสามารถของ DiagHub ยังถูกนำมาใช้ร่วมกันอีกหลายช่องโหว่ เช่น ช่องโหว่ CVE-2019-0836 "Microsoft Windows 10 1809 – LUAFV PostLuafvPostReadWrite SECTION_OBJECT_POINTERS Race Condition Privilege Escalation" โดยสำหรับซอร์สโค้ดของ DiagHub Exploit สามารถดาวโหลดได้ที่นี่

Office 365 Attacks by @JohnLaTwC

This is a summary from Office 365 Attacks by @JohnLaTwC. The presentation is available here.


Attack Matrix for O365

Quick Note on Nanocore Tradecraft - A Double ZIP File

Trustwave SpiderLabs published a new technique used by Nanocore to bypass an email security gateway solution that inspects file attachment content. I found this technique simple but effective with the fact that there are many file parser implemented in a current security solution and many of it interprets content differently.

The attachment hash is 9474e1517c98d4165300a49612888d16643efbf6

As pointed out by Trustwave SpiderLabs, one of the factors that make it suspicious is that there are two "end of central directory (EOCD)" records on the file, where a valid ZIP file has only one record. The EOCD record responsible to indicate the end of the ZIP file, so in this scenario there are two endings.


If we look into a valid ZIP file, we will find that there three or four main records, as noted in Wikipedia:
  • ZIPFILERECORD
  • ZIPDIRENTRY
  • ZIPENDLOCATOR
For the ZIP file that has more than one compressed file inside, the file structure should be looked like this:
  • ZIPFILERECORD record[0]
  • ZIPFILERECORD record[n]
  • ZIPDIRENTRY dirEntry[0]
  • ZIPDIRENTRY dirEntry[n]
  • ZIPENDLOCATOR
From the NanoCore sample, we can see that the attachment was built by concatenated two ZIP files together because there's no significant change made with offsets in each of ZIPFILERECORD. If we split the attachment into the two seperated ZIP file, it can be extracted without error.

To reproduce this technique, it can be done simply with system commands, for example with copy /b, Get-Content, or cat.

PS > Get-FileHash .\SHIPPING_MX00034900_PL_INV_pdf.zip -Algor SHA256 | Select Hash

Hash
----
E90B970C5E5DDF821D6F9F4D7D710D6DC01D59B517E8FB39DA726803DC52B5AD


PS > gc first.zip,second.zip -Enc Byte -Read 512 | sc new.zip -Enc Byte
PS > Get-FileHash .\new.zip -Algor SHA256 | Select Hash

Hash
----
E90B970C5E5DDF821D6F9F4D7D710D6DC01D59B517E8FB39DA726803DC52B5AD


PS >