Module: PWN::Plugins::Frida

Defined in:
lib/pwn/plugins/frida.rb

Overview

Frida attach/spawn + script injection.

Constant Summary collapse

SSL_PINNING =
<<~JS
  Java.perform(function () {
    try {
      var TrustManager = Java.use('javax.net.ssl.X509TrustManager');
      var SSLContext = Java.use('javax.net.ssl.SSLContext');
      var TrustManagers = [Java.registerClass({
        name: 'pwn.TrustAll',
        implements: [TrustManager],
        methods: {
          checkClientTrusted: function () {},
          checkServerTrusted: function () {},
          getAcceptedIssuers: function () { return []; }
        }
      }).$new()];
      var ctx = SSLContext.getInstance('TLS');
      ctx.init(null, TrustManagers, null);
      SSLContext.getDefault.implementation = function () { return ctx; };
    } catch (e) {}
  });
JS

Class Method Summary collapse

Class Method Details

.attach(opts = {}) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/pwn/plugins/frida.rb', line 40

public_class_method def self.attach(opts = {})
  PWN::Plugins::PreflightChecker.require_bin!(name: 'frida')
  target = opts[:target] || opts[:name]
  script = opts[:script].to_s
  raise 'ERROR: target is required' if target.to_s.empty?

  cmd = ['frida', '-n', target.to_s]
  cmd += ['-l', opts[:script_path].to_s] if opts[:script_path]
  cmd += ['-e', script] unless script.empty?
  stdout, stderr, status = Open3.capture3(*cmd)
  { stdout: stdout, stderr: stderr, exit: status.exitstatus }
end

.authorsObject



70
71
72
# File 'lib/pwn/plugins/frida.rb', line 70

public_class_method def self.authors
  "AUTHOR(S):\n  0day Inc. <[email protected]>\n"
end

.helpObject



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/pwn/plugins/frida.rb', line 74

public_class_method def self.help
  puts "USAGE:
    # List host binaries this module expects to be installed.
    #{self}.required_bins

    # List processes via frida-ps.
    #{self}.ps(
      extra: 'optional - extra frida-ps argv'
    )

    # Attach to a running process and optionally inject a script.
    #{self}.attach(
      target: 'required - process name (defaults to opts[:name])',
      name: 'optional - alias for target',
      script: 'optional - JavaScript source to pass with -e',
      script_path: 'optional - path to a .js file for -l'
    )

    # Spawn a binary under Frida and inject a script.
    #{self}.spawn(
      path: 'required - filesystem path to the binary',
      file: 'optional - alias for path',
      script: 'optional - JavaScript source to pass with -e',
      script_path: 'optional - path to a .js file for -l'
    )

    # Return an SSL-pinning bypass JavaScript template.
    #{self}.ssl_pinning_script(
      android: 'optional - currently always returns the Java TrustManager template'
    )

    # Print the AUTHOR(S) string for this module.
    #{self}.authors
  "
  constants.sort
end

.ps(opts = {}) ⇒ Object



34
35
36
37
38
# File 'lib/pwn/plugins/frida.rb', line 34

public_class_method def self.ps(opts = {})
  PWN::Plugins::PreflightChecker.require_bin!(name: 'frida')
  stdout, stderr, status = Open3.capture3('frida-ps', *Array(opts[:extra]))
  { stdout: stdout, stderr: stderr, exit: status.exitstatus }
end

.required_binsObject



30
31
32
# File 'lib/pwn/plugins/frida.rb', line 30

public_class_method def self.required_bins
  %w[frida]
end

.spawn(opts = {}) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
# File 'lib/pwn/plugins/frida.rb', line 53

public_class_method def self.spawn(opts = {})
  PWN::Plugins::PreflightChecker.require_bin!(name: 'frida')
  path = (opts[:path] || opts[:file]).to_s
  raise 'ERROR: path is required' if path.empty?

  cmd = ['frida', '-f', path]
  cmd += ['-l', opts[:script_path].to_s] if opts[:script_path]
  cmd += ['-e', opts[:script].to_s] unless opts[:script].to_s.empty?
  stdout, stderr, status = Open3.capture3(*cmd)
  { stdout: stdout, stderr: stderr, exit: status.exitstatus }
end

.ssl_pinning_script(opts = {}) ⇒ Object



65
66
67
68
# File 'lib/pwn/plugins/frida.rb', line 65

public_class_method def self.ssl_pinning_script(opts = {})
  opts[:android]
  SSL_PINNING
end