decode passwords using XOR ciphering

- retrieve phone number from phone rather than hardcoding
This commit is contained in:
2024-06-21 12:31:58 -04:00
parent 76bd47869d
commit e5b22ec65e
5 changed files with 369 additions and 2 deletions

View File

@@ -6,6 +6,9 @@
android:name="android.hardware.telephony"
android:required="false" />
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<uses-permission android:name="android.permission.READ_PHONE_NUMBERS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<application
android:allowBackup="true"

View File

@@ -2,21 +2,29 @@ package us.beckmeyer.vvmsmsreceiver
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Context.TELEPHONY_SERVICE
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.provider.Telephony
import android.telephony.SmsMessage
import android.telephony.TelephonyManager
import android.util.Log
import kotlin.io.encoding.Base64
import kotlin.io.encoding.ExperimentalEncodingApi
class SmsReceiver : BroadcastReceiver() {
private val TAG = "SmsReceiver"
@OptIn(ExperimentalStdlibApi::class)
@OptIn(ExperimentalStdlibApi::class, ExperimentalEncodingApi::class)
override fun onReceive(context: Context, intent: Intent) {
val phoneNumber = getNumber(context)
Log.d(TAG, "got phoneNumber = $phoneNumber")
if (intent.action == Telephony.Sms.Intents.SMS_RECEIVED_ACTION ||
intent.action == Telephony.Sms.Intents.DATA_SMS_RECEIVED_ACTION) {
intent.action == Telephony.Sms.Intents.DATA_SMS_RECEIVED_ACTION
) {
val bundle: Bundle? = intent.extras
bundle?.let {
val pdus = bundle.get("pdus") as Array<ByteArray>
@@ -26,6 +34,15 @@ class SmsReceiver : BroadcastReceiver() {
smsMessage?.let {
if (intent.action == Telephony.Sms.Intents.DATA_SMS_RECEIVED_ACTION) {
Log.d(TAG, "Data SMS received on port 5499")
val bodyUri = Uri.parse("advvm://" + smsMessage.messageBody)
bodyUri.getQueryParameter("p")?.let { p ->
val ciphertext = Base64.decode(p).toString(Charsets.US_ASCII)
Log.d(TAG, "ciphertext = $ciphertext")
if (phoneNumber != null) {
val password = decode(ciphertext, phoneNumber)
Log.d(TAG, "password = $password")
}
}
}
val messageBody = smsMessage.messageBody
Log.d(TAG, "Message body: $messageBody")
@@ -36,4 +53,37 @@ class SmsReceiver : BroadcastReceiver() {
}
}
}
fun getNumber(context: Context): String? {
// Create obj of TelephonyManager and ask for current telephone service
val telephonyManager = context.getSystemService(TELEPHONY_SERVICE) as TelephonyManager
val phoneNumber = telephonyManager.line1Number
return phoneNumber.replace("\\D".toRegex(), "").takeLast(10)
}
private fun stripPrefix(char: Char): Int {
return char.code and 0x0F
}
private fun getStripped(text: String): ByteArray {
val stripped = text.map { stripPrefix(it).toByte() }
return stripped.toByteArray()
}
fun decode(cipher: String, phoneNumber: String): String {
val cipherStripped = getStripped(cipher)
val phoneNumberStripped = getStripped(phoneNumber)
val secret = byteArrayOf(12, 5, 3, 11, 9, 4, 5, 3, 8, 14)
val text = cipherStripped.zip(phoneNumberStripped)
.zip(secret.asIterable()) { (c, p), s -> (c.toInt() xor p.toInt() xor s.toInt()).toByte() }
.toMutableList()
if (cipherStripped.size > 10) {
text.addAll(cipherStripped.slice(10 until cipherStripped.size).toMutableList())
}
return text.toByteArray().map { (it + 0x30).toChar() }.joinToString("")
}
}