ประมาณต้นเดิือน พฤษภาคมที่ผ่านมา ผมได้รับข้อความผ่านทาง Facebook Fanpage ของ Thai Zimbra จาก คุณ Mana Saringkanratana ว่ามีการพบ ช่องโหว่ด้านความปลอดภัย ของ Zimbra สามตัว คือ CVE-2016-9924, CVE-2018-20160, CVE-2019-9670 ซึ่ง hacker สามารถใช้ช่องโหว่ทั้งสามตัวนี้ประกอบกัน เป็นช่องทางเรียกใช้คำสั่ง ของ Linux บนเครื่อง Zimbra ได้ (ศัพท์เทคนิคเรียกว่า Remote Code Execution) ซึ่งทำให้ผมต้องลองหาข้อมูลดูว่าร้ายแรงแค่ไหน อาการเป็นอย่างไร และป้องกันอย่างไร
เท่าที่พบ มีหลาย web site ที่พูดถึง ซึ่งถ้าสนใจเชิงลึก ลองไปศึกษาดูกันเองละกันครับ ดูได้ตาม website อ้างอิงท้ายบทความ
Version ของ Zimbra ที่มีปัญหา
เท่าที่มีการรายงาน จะเกิดขึ้นกับ Zimbra Version 8.5 ถึง 8.7.11 โดยจะเกิดกับเครื่องที่มีการเปิด Port 80 หรือ 443 เพื่อให้มีการใช้ web client ของ Zimbra จาก Network ภายนอกได้ ซึ่งก็เปิดกันเป็นปกติอยู่แล้ว แปลว่า Zimbra version ข้างต้นไม่ปลอดภัย
อาการ
ถ้าถามผม โดน Remote Code Execution ไปเนี่ย โดนเจาะไปถึงระดับ Linux เรียกว่าทำอะไรได้เกือบทุกอย่างเลยครับ ถ้าให้ดี คงต้องมีการตรวจสอบไปถึงระดับ Linux เลยว่ามีโปรแกรมแปลกปลอมอะไรถูกฝังไว้ หรือ มีโปรแกรมแปลกๆ อะไรทำงานอยู่หรือเปล่า
อาการของเครื่องที่โดน hack นี้ เท่าที่มีรายงาน และที่ผมเจอ จะมีอาการเป็นสามกลุ่มใหญ่ๆ คือ
1) Zimbra ไม่ทำงานหรือทำงานผิดพลาด เช่น Start เสร็จแล้ว ตาย Restart แล้วก็ตาย
2) Zimbra ดูเหมือนทำงานปกติดี แต่มีการฝังโปรแกรม บน Linux และเรียกโปรแกรมนี้ขึ้นมาทำงาน โดย โปรแกรมที่เจอว่ามีการฝังไว้ คือ
2.1 /tmp/zmcat, /var/tmp/zcat , /tmp/l.sh, /tmp/s.sh
พวกนี้จะเป็น โปรแกรมที่ hacker เอามาวางไว้ ถึงแม้จะชื่อเหมือนหรือคล้ายกับ คำสั่งของ zimbra ก็ตาม แต่ปกติ ไม่น่าจะมี คำสั่งมาอยุ่ที่ /tmp หรือ /var/tmp
2.2 /opt/zimbra/log/zmswatch
ซึ่งถ้าใช้คำสั้ง file ตรวจสอบดูไฟล์นี้ จะพบว่าเป็นคำสั่งทีเรียกใช้งานได้ (executable) ซึ่งผิด ปกติครับ ตัวอย่างเช่น
[zimbra@zimbra log]$ file /opt/zimbra/log/zmswatch zmswatch: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, stripped
ปกติแล้วใน /opt/zimbra/log จะเก็บ log file ของ Zimbra ซึ่งเป็น Text ไฟล์ หรือไม่ก็เป็น log file ที่ถุก zip ไว้ (ไฟล์ลงท้ายด้วย .gz) ไม่ควรจะมีคำสั่งใดๆมาเก็บไว้ที่ directory นี้
3) มีแอบสร้าง การสร้าง Account ของ Zimbra ขึ้นมา อันนี้ต้องลองไล่ดูเองนะครับ ถ้าเห็นมี account บน Zimbra ชื่อแปลกๆ ละก็ตรวจสอบให้ดีๆ ว่าเป็นของ Zimbra หรือของคนในองค์กรหรือเปล่า
การปิดช่องโหว่
จากข้อมูลที่หามา มีสองวิธีที่พวกเราน่าจะพอทำกันได้ครับ
วิธีแรก คือ Upgrade เป็น Version 8.7.11 หรือ 8.8.x ครับ ซึ่งถ้าจะใช้การ Upgrade มีคำแนะนำอยู่สองข้อ คือ Backup ของเดิมไว้กันเหนียว และ ทดลองที่ระบบ Test ก่อนทำที่เครื่องจริงหรือที่เราเรียกว่าระบบ Production ที่ต้องทำแบบนี้เพราะเคยมีประวัติว่ามีคน Upgrade Zimbra ที่เครื่อง Production พอทำเสร้จแล้วเจอว่า Zimbra ทำงานผิดพลาด เรื่องนี้อย่าชะล่าใจนะครับ บางที่การ Upgrade จากต้นทาง Version เดียวกัน ไปเป็น Version ใหม่เดียวกัน เครือง A ไม่มีปัญหาแต่เครื่อง B มีปัญหา ก็เจอมาแล้ว
วิธีที่สอง สำหรับ zimbra version ตั้งแต่ 8.5 แก้ไขไฟล์ ปิดช่องโหว่ซะ โดยแก้ไขไฟล์ที่ชื่อ /opt/zimbra/mailboxd/etc/service.web.xml.in (อย่าลืม copy ไฟล์ดั้งเดิมเก็บไว้ด้วยนะครับ กันเหนียว )
ขั้นตอนก็คือ เปิดไฟล์ที่ว่านี้ขึ้นมาหาบรรทัด ทีมีคำว่า ProxyServlet กับบรรทัดที่มีคำว่า AutoDiscoveryServlet
...
<servlet-name>ProxyServlet</servlet-name>
<servlet-class>com.zimbra.cs.zimlet.ProxyServlet</servlet-class>
<async-supported>true</async-supported>
<init-param>
<param-name>allowed.ports</param-name>
<param-value>%%zimbraMailPort%%, %%zimbraMailSSLPort%%, 7070</param-value>
...
<servlet-name>AutoDiscoverServlet</servlet-name>
<servlet-class>com.zimbra.cs.service.AutoDiscoverServlet</servlet-class>
<async-supported>true</async-supported>
<init-param>
<param-name>allowed.ports</param-name>
<param-value>%%zimbraMailPort%%, %%zimbraMailSSLPort%%, %%zimbraAdminPort%%, 7070, 7443</param-value>
</init-param>
...
ซึ่งใน Tag ทั้งสองอันนี้ ให้ดูที่บรรทัด <param-value> ให้หาคำว่าคำว่า %%zimbraMailPort%%, %%zimbraMailSSLPort%%,
แล้วลบออก ผลลัพท์จะได้ตามนี้ครับ
<servlet>
<servlet-name>ProxyServlet</servlet-name>
<servlet-class>com.zimbra.cs.zimlet.ProxyServlet</servlet-class>
<async-supported>true</async-supported>
<init-param>
<param-name>allowed.ports</param-name>
<param-value>7070</param-value>
</init-param>
<load-on-startup>8</load-on-startup>
</servlet>
...
<servlet>
<servlet-name>AutoDiscoverServlet</servlet-name>
<servlet-class>com.zimbra.cs.service.AutoDiscoverServlet</servlet-class>
<async-supported>true</async-supported>
<init-param>
<param-name>allowed.ports</param-name>
<param-value>%%zimbraAdminPort%%, 7070, 7443</param-value>
</init-param>
<load-on-startup>12</load-on-startup>
</servlet>
เสร้จแล้ว save file และทำการ restart zimbra สักรอบเป็นอันเสร็จ
วิธีนี้อาจจะดูซับซ้อนไปหน่อย แต่ก็สะดวกดีเพราะแก้ไขแค่สองไฟล์ก็จบแล้ว
ถ้ามีข้อมูลหรือเจออะไรแปลกๆ ที่น่าจะเป็นผลจากช่องโหว่ด้านความปลอดภัยของ Zimbra ชุดนี้ ส่งข้อมูลมา update กันหน่อยนะครับ
website อ้างอิง
https://portswigger.net/daily-swig/multiple-rce-vulnerabilities-impact-all-versions-of-zimbra-email-software
https://lorenzo.mile.si/zimbra-cve-2019-9670-being-actively-exploited-how-to-clean-the-zmcat-infection/961/
https://blog.tint0.com/2019/03/a-saga-of-code-executions-on-zimbra.html
https://forums.zimbra.org/viewtopic.php?t=66005