หลังจากอธิบาย PHP Serialization ไปแล้ว ก็มาต่อกับ Java Serialization กันครับ โดยในโพสต์นี้ผมจะไม่ได้โพสต์เริ่มใหม่นะครับ เพราะได้อธิบายหลักการของ Serialization และ Unserialization ไปหมดแล้ว แต่จะมาอธิบายความแตกต่างระหว่าง PHP กับ Java ว่ามีลักษณะในการทำ Serialization และ Unserialization แตกต่างกันยังไงแค่นั้นครับ

ตัวอย่าง Code ของการทำ Serialization ใน Java

ตัว code จะทำการ serialization name แล้วเก็บไว้ในไฟล์ “file.bin” ด้วย writeObject function

ถ้าดูรายละเอียดของ file.bin จะพบรายละเอียดดังนี้

  • เริ่มด้วย “AC ED” – เป็น “magic number” ที่บ่งบอกถึง serialized data
  • Serialization protocol version “00 05”
  • มีแค่ String โดยระบุด้วย “74”
  • ความยาวของ string “00 05”
  • และสุดท้ายตามด้วย string

Code สำหรับ Deserialize

รันโดยใช้คำสั่ง

Vulnerable Class

ทีนี้มาดูตัวอย่าง code ที่มีช่องโหว่กันบ้าง

LogFile.java

จาก code จะเห็นว่าเราสร้าง Class Logfile ขึ้นมาโดยมี function readObject ที่ถูกใช้เมื่อกระทำการ deserialize object แล้วจะทำการ write ข้อมูลจากตัวแปล filecontent ไปยังไฟล์ที่อ่านมา

ทีนี้เรามาลองดูว่า readObject จะทำงานจริงมั้ย โดยทำการสร้าง code เป็น

เพื่อให้ง่ายต่อการทำ serialization (SerializeToFile) และ unserialization (DeserializeFromFile) จากนั้นให้เราเขียน code เรียกใช้ function เหล่านี้เป็น

จะเห็นว่าสิ่งที่เกิดขึ้นคือ

1. มีการสร้าง object จาก LogFile class

2. serialize object แล้วเก็บไว้ใน serialization log

ทีนี้ถ้าเราเขียนโค้ดเพื่อทำ deserialize

เมื่อเป็นแบบนั้นก็จะมีการเรียกใช้ readObject() ที่เราทำไว้ใน LogFile.java test.log ของเราจะถูกสร้างขึ้นตอนกำลังจะ destroy object นั่นเอง

จะเห็นว่า readObject() ของเรานั้นไม่อันตรายอะไร เพราะมันแค่เอาค่าของ deserialize จาก serialization.log ไปใส่ไว้ในไฟล์ดังเดิมที่กำหนดไว้ใน file เดิม

ทีนี้เรามาลองใช้ lib ที่มีช่องโหว่กัน โดย Apache Commons Collections library มีช่องโหว่นั่นคือ Apache Commons Collections version 3.2.1 โดยเราทำการ download มาก่อน

จากนั้น download เครื่องมือสำหรับการทำ serialization ในการโจมตี นั่นคือ Ysoserial

สร้างไฟล์ที่มีช่องโหว่เป็น

จากนั้น compile (หมายเหตุในที่นี้ใช้ Java version 1.7.0 นะครับ ผมลองใช้ version 1.8.0 แล้วไม่เวิร์คครับ)

สร้าง serialize object ที่ฝังคำสั่ง ‘touch /tmp/pwned’ ไว้

จากนั้นรัน SerializeTest โดยการกำหนด lib คือ Common-Collections-3.2.1 และ input เป็น test_ysoserial.bin ซึ่งเราทำ Serialize object ที่ฝังคำสั่งไว้

จะเห็นว่าพบไฟล์ pwned อยู่ใน /tmp

ทดสอบเล่นกับ WebLogic

ทีนี้เรามาเล่นกับ Web Application ที่มีการใช้งาน Apache Commons Collections แล้วมีช่องโหว่อย่าง WebLogic กัน โดยเริ่มต้นด้วย setup vulnerability server ก่อน

จากนั้น download exploit.py จาก https://hk.saowen.com/a/35b42d3000ba1347f8a25102625f9f15e095db016de375c5af587430a04f50d2

ทำการสร้าง serialization สำหรับการ exploit

นำ payload ที่ได้ไปใส่ใน PAYLOAD ใน exploit.py

แล้วที่เครื่อง 172.0.0.2 รัน netcat รอรับ connection ไว้โดยใช้คำสั่ง

จากนั้นรันคำสั่ง

กลับไปดูที่ฝั่ง 172.0.0.2 ก็จะพบว่าได้ shell เรียบร้อยครับ

วิธีการแก้ไข

อย่างในตัวอย่างนี้สิ่งที่แก้ไขได้คือการ update Lib ให้มันเป็น up to date เพื่อปิดช่องโหว่ครับ

Source::