solarwinds

Sunburst ส่งข้อมูลกลับไปยังผู้โจมตีอย่างไร

ในการวิเคราะห์ติดตามผลการโจมตี SolarWinds เราจะให้รายละเอียดว่าข้อมูลถูกส่งไปยังผู้โจมตีอย่างไร

หากมีการส่งข้อมูลไปยังผู้โจมตีอันเป็นผลมาจากคำสั่ง แทนที่จะดำเนินการตามคำขอ HTTP(S) GET ซึ่งเป็นสิ่งที่เราอธิบายไว้ในบล็อกที่แล้ว Sunburst จะเริ่มต้นคำขอ HTTP(S) POST

Sunburst ใช้เส้นทาง URL ที่สร้างแบบสุ่มสำหรับคำขอ HTTP(S) POST ที่แตกต่างจากคำขอ HTTP(S) GET

หากข้อมูลที่ส่งมากกว่า 10,000 ไบต์ เส้นทาง URL จะเป็นดังนี้:

  • /pki/crl/{0}{1}-{2}.crl
    • element 0 is a number between 100 and 10,000
    • element 1 is optionally one of the following:
      • -root
      • -cert
      • -universal_ca
      • -ca
      • -primary_ca
      • -timestamp
      • -global
      • -secureca
    • element 2 is the last error code

ส่วนหัว Content-Type ถูกตั้งค่าเป็น application/octet-stream และข้อมูล POST จะตามมา ข้อมูล POST ประกอบด้วยข้อมูลที่ส่งแบบเข้ารหัส UTF8 เชื่อมกับรหัสข้อผิดพลาดล่าสุด ต่อด้วยรหัสผู้ใช้ และบีบอัดในภายหลัง ทุกๆ ไบต์ของ Blob ที่บีบอัดจะถูกรวมเข้าด้วยกัน และใช้ไบต์ต่ำสุดของค่าผลรวมเป็นคีย์ Blob ที่บีบอัดคือ XOR โดยไบต์ของคีย์และไบต์ของคีย์จะถูกเพิ่มไว้ข้างหน้าข้อมูลที่เข้ารหัส

Figure 1. Structure of Sunburst POST data

รูปที่ 1. โครงสร้างของข้อมูล Sunburst POST

หากข้อมูลที่ส่งน้อยกว่าหรือเท่ากับ 10,000 ไบต์ เส้นทาง URL จะใช้รูปแบบใดรูปแบบหนึ่งจากสองรูปแบบดังนี้:

  • /fonts/woff/{0}-{1}-{2}-webfont{3}.woff2
    • element 0 is a random number between 100 and 10,000
    • element 1 is “opensans” or “noto”
    • element 2 is one of the following:
      • bold
      • bolditalic
      • extrabold
      • extrabolditalic
      • italic
      • light
      • lightitalic
      • regular
      • semibold
      • semibolditalic
    • element 3 is the last error code
  • or /fonts/woff/{0}-{1}-{2}{3}.woff2
    • element 0 is a random number between 100 and 10,000
    • element 1 is one of the following:
      • freefont
      • SourceCodePro
      • SourceSerifPro
      • SourceHanSans
      • SourceHanSerif
    • element 2 is one of the following:
      • Bold
      • BoldItalic
      • ExtraBold
      • ExtraBoldItalic
      • Italic
      • Light
      • LightItalic
      • Regular
      • SemiBold
      • SemiBoldItalic
    • element 3 is the last error code

นอกจากนี้ แทนที่จะส่งข้อมูลที่เข้ารหัสโดยตรง เนื่องจากเมื่อข้อมูลมีขนาดใหญ่กว่า 10,000 ไบต์ ข้อมูลจะถูกส่งแบบ steganographically ในรูปแบบ faux JSON blob

JSON blob มีฟิลด์ต่อไปนี้:

  • userId – มี ID ผู้ใช้ที่สับสนใน GUID
  • sessionId – GUID ที่สร้างขึ้นแบบสุ่มต่อเซสชัน HTTP
  • Timestamp – มิลลิวินาทีตั้งแต่ปี 1970/1/1 ลบห้านาที บวกกับค่าสุ่มระหว่าง 0-512 โดยปกติบิตที่สองตั้งค่าเป็น 1
  • Index – ค่าที่เพิ่มขึ้น
  • EventType – ตั้งค่าเป็น Orion
  • EventName – ตั้งค่าเป็น EventManager
  • DurationMs – ค่าสุ่มเดียวกันระหว่าง 0-512 ที่ใช้ใน Timestamp
  • Succeeded – ตั้งค่าเป็นจริง
  • Message – ส่วนของข้อมูลที่เข้ารหัส Base64

ข้อมูลที่เข้ารหัสเพื่อส่งแบ่งออกเป็นกลุ่มขนาดหลายตัวแปร ขนาดของแต่ละส่วนจะถูกกำหนดแบบสุ่ม แต่โดยทั่วไปจะเปลี่ยนจากเล็กไปใหญ่ หากขนาดที่เลือกแบบสุ่มเป็น 0 อันที่สุ่มระหว่าง 16 ถึง 28 ไบต์จะถูกสร้างขึ้นแทน และค่าการประทับเวลาคือ AND มีค่า 18446744073709551613 ซึ่งสำคัญกว่าคือตั้งค่าบิตที่สองเป็น 0 จากนั้นแต่ละอันจะถูกเข้ารหัสและเพิ่มลงใน JSON blob และส่งเป็นข้อมูล HTTP(S) POST โดยตั้งค่าส่วนหัวประเภทเนื้อหาเป็น application/json

Figure 2. A contrived example of a JSON file that would be sent by Sunburst

รูปที่ 2 ตัวอย่างที่ประดิษฐ์ขึ้นของไฟล์ JSON ที่จะส่งโดย Sunburst

เมื่อได้รับแล้ว ผู้โจมตีจะต้องถอดรหัสและเชื่อมส่วนข้อความทั้งหมดเข้าด้วยกัน โดยข้ามกลุ่มขยะที่ไม่ได้ตั้งค่าบิตการประทับเวลาที่สอง