รวมคำสั่งติดตั้ง CA certificate ของ Burp ใน System รวดเดียว บนเครื่องจริง (ภาค 2)

บทความนี้นำเสนอ Script ที่พัฒนาขึ้นเพื่อการติดตั้ง Burp Suite บน Android โดยใช้ LazyFrida ซึ่งมีความสามารถในการตรวจสอบการเชื่อมต่อผ่าน ADB, สถานะการ root ของอุปกรณ์, ดาวน์โหลดและติดตั้งใบรับรอง CA ของ Burp Suite บน Android และทำการรีบูตอุปกรณ์ผ่าน ADB ทั้งหมดนี้ทำให้การติดตั้ง Burp Suite บน Android เพื่อช่วยในการทำเจาะระบบ Application บน Android (Android Mobile Application Penetration Test) เร็วขึ้นและสะดวกมากยิ่งขึ้น

Warunyou Sunpachit และ Boonperm Mark
Cybersecurity consultant

LazyFrida

  • เปิด Burp Suite เพื่อการสร้าง, การเข้าถึง, และการส่งออก certificate ที่จะใช้งานร่วมกับ Burp Suite.
  • เอาสายเสียบ Android (เครื่องต้อง Root เรียบร้อย) เพื่อสามารถติดต่อกับอุปกรณ์ผ่านสาย USB เพื่อรันคำสั่ง, ติดตั้งแอป, และดำเนินการอื่น ๆ ที่ต้องการสิทธิ์สูง
  • เปิด USB debugging เพื่อสามารถเชื่อมต่อกับอุปกรณ์ Android ผ่านสาย USB และส่งคำสั่งต่าง ๆ ไปยังอุปกรณ์ได้
  • ตั้งค่า Burp Suite เพื่อให้โปรแกรม LazyFrida สามารถ Export Certificate ได้
  • ดาวน์โหลดเพื่อใช้งาน https://github.com/thaisingle/lazyfrida
  • เรียกใช้คำสั่งตามข้างล่างเมื่อเสร็จสิ้นเครื่อง Android Mobile จะ Restart ตัวเองอัตโนมัติ
ตัวอย่างการใช้งาน LazyFrida เพื่อติดตั้ง Burp certificate ใน System

อธิบายการทำงานที่สำคัญ

ตรวจสอบว่าอุปกรณ์ Android เชื่อมต่อสำเร็จผ่าน ADB

#Usb Proxy
def check_adb():
	print('Command: adb shell\n')
	command = ['adb', 'shell', 'echo', 'Connected']
	result = subprocess.run(command, capture_output=True, text=True)

	if "Connected" in result.stdout:
		print('ADB shell connected successfully.', result.stdout)
		return result.stdout
	else:
		print('Please check USB/ADB connection or restart Android devices.')
		return None

ฟังก์ชันนี้จะดำเนินการดังนี้:

  1. def check_adb():บรรทัดนี้เป็นการกำหนดฟังก์ชันใหม่ชื่อ check_adb.
  2. print('Command: adb shell\n'):แสดงข้อความบนคอนโซลเพื่อแจ้งให้ผู้ใช้รู้ว่า ฟังก์ชันจะดำเนินการตามคำสั่ง adb shell.
  3. command = ['adb', 'shell', 'echo', 'Connected']:สร้างรายการของคำสั่งที่จะถูกดำเนินการ ซึ่งเมื่อรันจะเป็นเสมือนกับการรันคำสั่ง adb shell echo Connected.
  4. result = subprocess.run(command, capture_output=True, text=True):ใช้ฟังก์ชัน subprocess.run เพื่อดำเนินการคำสั่ง และจับผลลัพธ์ที่ได้ โดย capture_output=True จะทำการจับผลลัพธ์จากคำสั่ง และ text=True แปลว่าผลลัพธ์ที่ได้จะถูกแปลงเป็นข้อความ.
  5. if "Connected" in result.stdout::ตรวจสอบว่าคำว่า “Connected” อยู่ในผลลัพธ์ของคำสั่งหรือไม่.
  6. print('ADB shell connected successfully.', result.stdout):ถ้าพบคำว่า “Connected” จะแสดงข้อความบอกว่า adb เชื่อมต่อสำเร็จ.
  7. return result.stdout:ส่งกลับผลลัพธ์ที่ได้จากคำสั่ง adb.
  8. else::ถ้าไม่พบคำว่า “Connected” ในผลลัพธ์ บรรทัดที่อยู่ภายใต้บล็อก else จะถูกดำเนินการ.
  9. print('Please check USB/ADB connection or restart Android devices.'):แสดงข้อความเพื่อแนะนำให้ตรวจสอบการเชื่อมต่อ USB หรือรีสตาร์ทอุปกรณ์ Android.
  10. return None:ถ้ามีปัญหาในการเชื่อมต่อ ฟังก์ชันจะส่งค่ากลับเป็น None แสดงว่าไม่สำเร็จ.

ตรวจสอบว่าอุปกรณ์ Android ที่เชื่อมต่อผ่าน ADB มีสถานะการ root หรือไม่

def check_root():
	# Check if it's an emulator or a real device
	if is_emulator():
		# It's an emulator
		command = ['adb', 'shell', 'su', '0', 'id']
	else:
		# It's a real device
		command = ['adb', 'shell', 'su', '-c', 'id']

	output = run_command(command, False, "Root status check")
	return output

ฟังก์ชันนี้จะดำเนินการดังนี้:

  1. # Check if it's an emulator or a real device: ความเห็นบอกว่าขั้นตอนต่อไปจะตรวจสอบว่าเป็น emulator หรืออุปกรณ์จริง
  2. if is_emulator():: เช็คว่าเป็น emulator หรือไม่ โดยใช้ฟังก์ชัน is_emulator() (ซึ่งไม่มีในส่วนของโค้ดที่คุณให้มา)
  3. command = ['adb', 'shell', 'su', '0', 'id']: ถ้าเป็น emulator คำสั่งนี้จะถูกกำหนดเพื่อตรวจสอบสถานะ root โดยใช้คำสั่ง su 0 id ภายใน adb shell
  4. else:: ถ้าไม่เป็น emulator คำสั่งด้านล่างจะถูกดำเนินการ
  5. command = ['adb', 'shell', 'su', '-c', 'id']: ถ้าเป็นอุปกรณ์จริง คำสั่งนี้จะถูกกำหนดเพื่อตรวจสอบสถานะ root โดยใช้คำสั่ง su -c id ภายใน adb shell
  6. output = run_command(command, False, "Root status check"): ใช้ฟังก์ชัน run_command()เพื่อดำเนินการคำสั่งที่กำหนดและจับผลลัพธ์ที่ได้
  7. return output: ส่งผลลัพธ์ของคำสั่งกลับ

ดาวน์โหลดใบรับรอง CA ของ Burp Suite มายังเครื่องคอมพิวเตอร์

#Installin CA certification of Burp as system level.
def download_cert(ip_address):
    # Download the DER certificate file
    curl_command = f'curl --proxy http://{ip_address}:8080 -o cacert.der http://burp/cert'
    output = run_command(curl_command, True, "Downloading the certificate file")
    if output is None: print("Please check if your Burp Suite is properly configured and running")
    return output

ฟังก์ชันนี้จะดำเนินการดังนี้:

  1. def download_cert(ip_address):: กำหนดฟังก์ชันใหม่ชื่อ download_cert โดยมีพารามิเตอร์เป็น ip_address
  2. curl_command = f'curl --proxy http://{ip_address}:8080 -o cacert.der http://burp/cert': สร้างคำสั่ง curl สำหรับดาวน์โหลดใบรับรอง โดยใช้ proxy ที่กำหนดผ่านพารามิเตอร์ ip_address และพอร์ต 8080
  3. output = run_command(curl_command, True, "Downloading the certificate file"): ดำเนินการคำสั่ง curl ที่สร้างขึ้นด้วยฟังก์ชัน run_command()
  4. if output is None: print("Please check if your Burp Suite is properly configured and running"): ถ้าผลลัพธ์เป็น None คือมีปัญหาในการดาวน์โหลด, แสดงข้อความแนะนำให้ตรวจสอบการตั้งค่าของ Burp Suite
  5. return output: ส่งผลลัพธ์ที่ได้จากการดำเนินการคำสั่งกลับ

เพื่อติดตั้งใบรับรอง CA (Certificate Authority) ลงบนอุปกรณ์ Android

def install_cert():
	command = 'openssl x509 -inform DER -in cacert.der -out cacert.pem'
	output = run_command(command, True, "Converting DER to PEM format")

	if output is not None:
		command = "openssl x509 -inform PEM -subject_hash_old -in cacert.pem | head -1"
		cert_hash = run_command(command, True, "Extracting the subject hash")

	if cert_hash is not None:
		rename_command = f'cp cacert.pem {cert_hash}.0'
		output = run_command(rename_command, True, "Renaming the PEM file")

	if output is not None:
		command = f'adb shell su -c "mount -o rw,remount /" && adb push {cert_hash}.0 /sdcard/Download/'
		output = run_command(command, True, "Pushing the certificate to the device")

	if output is not None:
		command = f'adb shell su -c "cp /sdcard/Download/{cert_hash}.0 /system/etc/security/cacerts/{cert_hash}.0"'
		output = run_command(command, True, "Copying the certificate to the system cacerts directory")

	if output is not None:
		command = f'adb shell su -c "chmod 644 /system/etc/security/cacerts/{cert_hash}.0"'
		output = run_command(command, True, "Setting permissions for the certificate")
	return output

ฟังก์ชันนี้จะดำเนินการดังนี้:

  1. การแปลงใบรับรอง: โดยเริ่มจากคำสั่ง openssl เพื่อแปลงใบรับรองจากรูปแบบ DER ไปเป็น PEM
  2. การหาแฮชของ subject: หลังจากแปลงเป็นรูปแบบ PEM จะใช้ openssl อีกครั้งเพื่อหาแฮช (hash) ของ subject ซึ่งใช้ในการตั้งชื่อไฟล์
  3. การเปลี่ยนชื่อไฟล์ใบรับรอง: หลังจากได้แฮชมาแล้ว จะเปลี่ยนชื่อไฟล์ PEM ให้ตรงกับแฮชที่ได้
  4. การส่งไฟล์ใบรับรองเข้าอุปกรณ์: ใช้ adb เพื่อส่งไฟล์ใบรับรองที่เปลี่ยนชื่อแล้วเข้าไปใน /sdcard/Download/ ของอุปกรณ์
  5. การคัดลอกไฟล์ใบรับรองเข้าไปยัง directory cacerts: ใช้ adb และคำสั่ง su (สำหรับการเข้าถึงระบบเป็น superuser) เพื่อคัดลอกไฟล์ใบรับรองไปยัง /system/etc/security/cacerts/
  6. การตั้งค่าสิทธิ์ให้กับไฟล์ใบรับรอง: เพื่อให้แน่ใจว่าไฟล์ใบรับรองมีสิทธิ์ที่เหมาะสม, จะใช้คำสั่ง chmod เพื่อตั้งค่าสิทธิ์

เพื่อทำการรีบูตอุปกรณ์ Android ผ่านการใช้เครื่องมือ adb (Android Debug Bridge)

def reboot_device():
    command = ['adb', 'reboot']
    run_command(command, False, "Reboots the device")

ฟังก์ชันนี้จะดำเนินการดังนี้:

  1. command = ['adb', 'reboot']: กำหนดคำสั่ง adb reboot ซึ่งเมื่อใช้งาน จะทำการเริ่มการเปิดใหม่ของอุปกรณ์ Android
  2. run_command(command, False, "Reboots the device"): ใช้ฟังก์ชัน run_command() เพื่อดำเนินการคำสั่งที่กำหนดไว้ใน

อ้างอิง