Technology

อธิบายช่องโหว่แห่งปีกับ Log4J ทำไมถึงพีคในช่วงข้ามคืน มันอันตรายยังไง (ฉบับคนทั่วไป)

By Arnon Puitrakul - 15 ธันวาคม 2021 - 1 min read min(s)

อธิบายช่องโหว่แห่งปีกับ Log4J ทำไมถึงพีคในช่วงข้ามคืน มันอันตรายยังไง (ฉบับคนทั่วไป)

เมื่อไม่กี่วันก่อน เราตื่นนอนมาเปิด Facebook อะไรอ่านไปเรื่อยจนไปสะดุดกับเรื่องนึงที่อ่านแค่หัวข้อก็ทำให้ร้อนรนได้แล้ว นั่นคือเรื่องของช่องโหว่ที่ค้นพบบน Log4J ที่บอกเลยว่า Internet was on fire fire 🔥 ของจริง เดือดร้อนกันถ้วนหน้ามาก ๆ สำหรับผู้ใช้ทั่ว ๆ ไปอาจจะ งง ว่าเอ๊ะมันเกิดอะไรขึ้น และเราควรจะต้องทำตัวยังไง วันนี้เราเลยจะมาอธิบายอย่างง่าย ๆ ละกันว่า มันเกิดอะไรขึ้นกันแน่ แล้ว เราจะต้องทำตัวอย่างไรกับเรื่องนี้

Log4J คืออะไร ?

สำหรับผู้ใช้ทั่ว ๆ ไปอาจจะไม่คุ้นเคยกับ Log4J เพราะมันเป็นส่วนที่ทำงานอยู่ข้างหลังของโปรแกรมที่เราอาจจะใช้งานอยู่ก็ได้ สิ่งที่ Log4J ทำก็คือตามชื่อมันเลยคือ การ Log ข้อมูลต่าง ๆ ที่นักพัฒนาต้องการ อาจจะเป็นเรื่องของการเข้าถึงต่าง ๆ หรือจะเป็นพวก Log เกี่ยวกับ Error ต่าง ๆ สำหรับเอาไปพัฒนา และ แก้ไข ข้อผิดพลาดของโปรแกรมได้ เป็นเรื่องปกติที่เวลาเราเขียนโปรแกรม แล้วเราจะต้องมี Log พ่นออกมาให้เราเช็คเสมอ ไม่งั้นผู้ใช้มีปัญหา แล้วเราจะไม่รู้เลยว่า ตอนนั้นมันเกิดอะไรขึ้นกันแน่ เราก็จะไม่รู้เลยว่าจะไปแก้ไขตรงไหน

ตัว Log4J เอง มันไม่ได้เป็นส่วนที่ก๊องแก๊งเลย เพราะโปรแกรมหลาย ๆ ตัวที่ทำงานบนภาษา Java เลือกใช้ Log4J เป็น ส่วนเสริม หรือที่นักพัฒนาเรียกว่า Library ในการทำ Log ทั้งนั้นเลย หรือในมุมของนักพัฒนาเอง มันอาจจะเป็น Library ของ Library ที่เราใช้อีกทีก็ได้ ทำให้จริง ๆ แล้ว Log4J มันถูกใช้เยอะมาก ๆ ในโลกของภาษา Java

และแน่นอนว่าภาษา Java ไม่ใช่ภาษาที่ใช้งานกันในกลุ่มเล็ก ๆ เลย มันถูกใช้เยอะมาก ๆ เลยนะ (ถึงแม้ว่ามันจะบอกว่า 3 Billion มาตั้งแต่เราเด็ก ๆ แล้วอะนะ) โดยเฉพาะกลุ่มของพวก Enterprise ที่ยังคงใช้งาน Java กันอยู่โดยเฉพาะพวก Java EE (Enterprise Edition) ที่มันมี Feature เด็ด ๆ หลาย ๆ ตัวที่ Enterprise ชอบอยู่ในนั้นด้วย หรือจะเป็นพวก Library ที่เป็น Framework สำหรับการทำ Web Service ต่าง ๆ บนภาษา Java

ด้วยความเป็น Java และ Log4J เอง ทำให้จำนวนผู้ใช้บอกเลยว่า ไม่ได้น้อยนะแทบจะเป็นเรื่องปกติของคนที่ทำงานบนโปรแกรมที่ทำงานโดยใช้ภาษา Java เลยก็ว่าได้ ทำให้เมื่อมันเกิดช่องโหว่ เลยทำให้ผู้ที่ได้รับผลกระทบมันเลยเป็นวงกว้างมาก ๆ ตัวอย่างที่อ่านแล้ว โอ้ชิท ไปเลยคือ Cloudflare ที่ก็ใช้งาน Library ตัวนี้เหมือนกัน แต่เขามีการแก้ไขระบบ เพื่อให้รอดจากช่องโหว่นี้เรียบร้อยแล้ว เขาเขียน Blog ออกมาอยู่ว่าภายในตอนนั้นที่ช่องโหว่มันออกมา เขาจัดการอย่างไรกับเรื่องนี้ ต้องยอมรับเลยว่าทีมของ Cloudflare เองก็มีการตอบสนองที่รวดเร็วมาก ๆ เร็วจริง ๆ

ช่องโหว่นี้ทำอะไรได้

ตัวช่องโหว่นี้ เราบอกเลยว่า มันเปรี้ยว_น มาก เพราะมันสามารถโยน Script หรือโปรแกรมอะไรก็ได้เข้าไปที่เครื่องของเป้าหมาย ทำให้จริง ๆ แล้วช่องโหว่นี้ ทำให้ผู้ที่โจมตี สามารถทำอะไรก็ได้กับเครื่องปลายทางเลย เช่น การปรับแก้ค่าบางอย่างทำให้เข้าถึงไม่ได้ การขโมยข้อมูล การลบข้อมูลได้ทั้งระบบ จนไปถึง การเข้าควบคุมเครื่อง Server เป้าหมายได้เลย ทำให้มันเป็นช่องโหว่ที่น่ากลัวมาก ๆ เราเรียกช่องโหว่ที่มีลักษณะที่เราสามารถเอา Script หรือ Code ต่าง ๆ ไปรันบนเครื่องของเป้าหมายว่า Remote Code Execution (RCE)

ส่วนต่อจากนี้จะ Technical มาก ๆ ถ้าไม่อยากอ่านข้ามได้เลย

โดยสาเหตุของช่องโหว่นี้เกิดจาก Package ตัวนึงของ Log4J ที่ชื่อว่า JNDILookup ที่มันถูกใส่เข้ามาตั้งแต่ Beta ของ Log4J version 2.0 เลย ซึ่งสิ่งที่มันทำคือ มันจะเข้าไปคุยกับ JNDI (Java Naqming Directory Interface) ซึ่งตัว JNDI มันใช่พึ่งมีนะ มันมีมานานมาก ๆ แล้วใน Java ตั้งแต่ยังไม่ปี 2000 เลย สิ่งที่มันทำคือ มันเป็นความสามารถที่ทำให้โปรแกรมสามารถเข้าถึงส่วนพวก Directory Service ต่าง ๆ เช่น LDAP, DNS และอื่น ๆ ได้

คือจริง ๆ การมี JNDILookup มันก็ไม่ได้ผิดอะไรหรอก แต่... ปัญหานึงที่เราเรียกว่า Improper input validation มันเกิดขึ้นโดยไม่ได้ตั้งใจ อาจจะลืมเช็คอะไรแบบนั้น มันคือ การที่เราเชื่อใจข้อมูลที่เข้ามาจากข้างนอกมากเกินไป จนเราไม่ได้เช็คให้ครบทุกเคส เลยทำให้อาจจะมีคนหัวหมอ เอาของที่เราไม่ได้เช็คนี่แหละใส่เข้ามา ก็อาจจะทำให้โปรแกรมของเราพังไปเลย หรือ อาจจะทำให้โปรแกรมของเรามีช่องโหว่ทางด้านความปลอดภัยเหมือนกับ Log4J เนี่ยแหละ แต่เราจะโทษนักพัฒนาทั้งหมดเลยก็ไม่ได้นะ เพราะเอาเข้าจริง ถึงมันจะเป็นสิ่งที่เราจะต้องคิดเสมอตอนเราเขียนโปรแกรม แต่ บางทีมันก็เยอะมาก ๆ จนเรามองข้ามไป เลยทำให้เกิดเรื่องได้ ถือว่าเป็นแบบฝึกหัดแรก ๆ ตอนเราเริ่มเขียนโปรแกรมเลย

 #include <stdio.h>
 
 int main(int argc, char **argv) {
    printf(argv[1]);
    return 0;
 }
print_me.c

เราลองมาดูตัวอย่างง่าย ๆ กันดีกว่า เราลองเขียนโปรแกรมง่าย ๆ ละกัน โดยที่เราจะรับ String เข้ามา แล้วให้มันแสดง String นั้นออกมาผ่านทางหน้าจอ ถ้าใครที่เคยผ่านภาษา C มาก่อน ก็จะมองว่า อื้ม มันก็เป็นการแสดงค่าที่เราใส่เข้ามาตามปกติเลยนิ ไม่ได้มีอะไรแปลก ๆ ที่น่าจะเกิดขึ้นได้เลย

> gcc print_me.c -o print_me
> ./print_me "Hello World"
Hello World

ถ้าเราลอง Compile แล้วลองรันดู ก็อื้ม.. ก็ออกมาอย่างที่เราคิดเลยนะ แล้วมันจะเป็นช่องโหว่ได้ยังไง เราจะบอกว่า คนทั้งโลกเขาไม่ได้เป็นคนดีค่ะ ตัวอย่างเช่น Tester และ User เป็นต้น ผู้ที่เข้ามาทำให้โปรแกรมเราพังเป็นเรื่องปกติ

> ./print_me "%X %X %X %X %X" 
6F4175E0 B06B3C 6F417750 2 6F417730%

แน่นอนว่า ถ้าเราลองกวนมันดูละ เราลองใส่อะไรแปลก ๆ เข้าไป เรารู้ว่า %X คือการเอาค่าตัวต่อไปใน Memory ของเราออกมา ทำให้คนที่ทำแบบนี้ ก็จะพอเดาได้แล้วว่าใน Memory ของเรามีอะไร ซึ่งเป็นเรื่องที่ไม่ดีเอาซะเลย เพราะ เราไม่ได้ Encrypt ข้อมูลของเราใน Memory ทั้งหมดนิ เผลอ ๆ เราเอาค่าจริงนี่แหละ ใส่ไว้เลยก็มีเหมือนกัน

ถามว่า พอรู้แล้วยังไงต่อ เขาก็อาจจะเข้าไปทำสิ่งที่เรียกว่า Reverse Engineering แล้ว เข้าไปแก้ไขส่วนต่าง ๆ ของโปรแกรม เพื่อทำในสิ่งที่เขาต้องการได้ ตัวอย่างที่เห็นได้ชัด ๆ เลย และ เป็นสิ่งที่เราเชื่อว่าหลาย ๆ คนโดยเฉพาะเด็กช่วง 90s ต้องผ่านมาแล้วคือ Cheat Engine โปรแกรมนี้แหละ มันทำให้เราสามารถจะเข้าถึง Memory และแก้ไขได้หมดเลย ทำให้เราโกงเงิน หรือ Level หรือ Item ในเกมได้นั่นเอง ฮ่า ๆ

ทำให้เราเห็นได้ว่า การที่เราเชื่อถือข้อมูลที่ออกมาจากข้างนอกมากเกินไป หรือกระทั่งส่วนต่าง ๆ ของโปรแกรมเราเอง ก็ทำให้เกิดความเสียหายได้ ทำให้ Programmer ต่าง ๆ จะต้องมีการเขียนส่วนนึงของโปรแกรมเพื่อเช็คค่าที่รับเข้ามา เพื่อให้ลดปัญหาเหล่านี้ลงไปได้นั่นเอง

ช่องโหว่นี้ได้รับการแก้ไขแล้ว

หลังจากการค้นพบช่องโหว่นี้ออกมา ทำให้ทาง Log4J เองก็ออก Emergency Patch ออกมาให้กับผู้ใช้โดยทันที โดยที่นักพัฒนาจะต้องทำการ Update Version ของ Log4J บนโปรแกรมของตนเองเป็น 2.15.0

ส่วนโปรแกรมที่เราใช้ต้องไปเช็คกับนักพัฒนาที่ทำโปรแกรมให้เราว่าเขาจัดการเรื่องนี้หรือยัง ตัวอย่างเช่น ณ วันที่เขียนตัว Elasticsearch และ Logstash ก็ได้รับผลกระทบเช่นกัน แต่ยังไม่ได้แก้ไข ดังนั้น เราจะต้องไปเช็คกับนักพัฒนาของโปรแกรมแต่ละตัวด้วย

นอกจากนั้นแนะนำนักพัฒนาคุยกับ Network Admin ให้มีการตรวจสอบ Firewall เพื่อป้องกัน การเชื่อมต่อที่ไม่พึงประสงค์ หรือก็คือ ไม่ควรจะเกิด เพราะถ้ามันติด Firewall แล้วต่อไม่ได้ มันก็จะทำอะไรเราไม่ได้เลย

ส่วนผู้ใช้ทั่ว ๆ ไปก็แนะนำให้ทำการ Update Software ที่เราใช้งานให้เป็น Version ล่าสุดเสมอ เพราะโปรแกรมที่เราใช้งาน ก็อาจจะได้รับผลกระทบของช่องโหว่นี้ก็ได้ การ Update ให้เป็น Version ล่าสุด ก็ทำให้เราได้รับ Patch ทั้งการแก้บัคต่าง ๆ และ เรื่องความปลอดภัยล่าสุด ทำให้เราลดการเป็นเหยื่อได้เป็นอย่างดีเลยเชียว

สรุป

ช่องโหว่ที่เกิดขึ้นกับ Log4J ถือว่าเป็นช่องโหว่ที่เผ็ดช์ร้อนมาก ๆ เพราะมันเป็นช่องโหว่ที่ทำให้ผู้โจมตีสามารถรัน Script หรือโปรแกรมต่าง ๆ บนเครื่องเป้าหมาย ซึ่งเป็นวิธีในการโจมตีรูปแบบนึงที่ทำให้สามารถทำอะไรก็ได้เลย ตั้งแต่เบา ๆ จนไปถึงการเข้าควบคุมเครื่อได้เลย นอกจากนั้นอีกเรื่องที่มันทำให้น่ากลัวมาก ๆ ขึ้นอีกคือ Log4J มีผู้ใช้เยอะมาก ๆ ทั่วโลก จนมันแทบจะกลายเป็น Library สามัญในการทำ Log บน Java ซะแล้ว จากทั้ง 2 เหตุผลเลยทำให้ Log4J เป็นช่องโหว่ที่เผ็ดช์ร้อนน่าจะเรียกว่าที่สุดของปีนี้เลยก็ว่าได้ ทำเอา Programmer วิ่งกันตึกสั่นได้เลย