4
4
5
5
module Msf
6
6
module Handler
7
-
8
7
###
9
8
#
10
9
# This module implements the reverse TCP handler. This means
@@ -16,7 +15,6 @@ module Handler
16
15
#
17
16
###
18
17
module ReverseTcp
19
-
20
18
include Msf ::Handler
21
19
include Msf ::Handler ::Reverse
22
20
include Msf ::Handler ::Reverse ::Comm
@@ -26,7 +24,7 @@ module ReverseTcp
26
24
# 'reverse_tcp'.
27
25
#
28
26
def self . handler_type
29
- return "reverse_tcp"
27
+ "reverse_tcp"
30
28
end
31
29
32
30
#
@@ -55,7 +53,6 @@ def initialize(info = {})
55
53
self . conn_threads = [ ]
56
54
end
57
55
58
-
59
56
#
60
57
# Closes the listener socket if one was created.
61
58
#
@@ -64,9 +61,13 @@ def cleanup_handler
64
61
65
62
# Kill any remaining handle_connection threads that might
66
63
# be hanging around
67
- conn_threads . each { |thr |
68
- thr . kill rescue nil
69
- }
64
+ conn_threads . each do |thr |
65
+ begin
66
+ thr . kill
67
+ rescue
68
+ nil
69
+ end
70
+ end
70
71
end
71
72
72
73
# A string suitable for displaying to the user
@@ -84,137 +85,132 @@ def start_handler
84
85
85
86
local_port = bind_port
86
87
87
- self . listener_thread = framework . threads . spawn ( "ReverseTcpHandlerListener-#{ local_port } " , false , queue ) { |lqueue |
88
+ handler_name = "ReverseTcpHandlerListener-#{ local_port } "
89
+ self . listener_thread = framework . threads . spawn ( handler_name , false , queue ) { |lqueue |
88
90
loop do
89
91
# Accept a client connection
90
92
begin
91
- client = self . listener_sock . accept
92
- if ! client
93
- wlog ( "ReverseTcpHandlerListener- #{ local_port } : No client received in call to accept, exiting..." )
93
+ client = listener_sock . accept
94
+ if !client
95
+ wlog ( "#{ handler_name } : No client received in call to accept, exiting..." )
94
96
else
95
97
self . pending_connections += 1
96
98
lqueue . push ( client )
97
99
end
98
- rescue :: Exception
99
- wlog ( "ReverseTcpHandlerListener- #{ local_port } : Exception raised during listener accept: #{ $! } \n \n #{ $@ . join ( "\n " ) } " )
100
+ rescue StandardError
101
+ wlog ( "#{ handler_name } : Exception raised during listener accept: #{ $ERROR_INFO } \n \n #{ $ERROR_POSITION . join ( "\n " ) } " )
100
102
break
101
103
end
102
104
end
103
105
}
104
106
105
- self . handler_thread = framework . threads . spawn ( "ReverseTcpHandlerWorker-#{ local_port } " , false , queue ) { |cqueue |
107
+ worker_name = "ReverseTcpHandlerWorker-#{ local_port } "
108
+ self . handler_thread = framework . threads . spawn ( worker_name , false , queue ) { |cqueue |
106
109
loop do
107
110
begin
108
111
client = cqueue . pop
109
112
110
- if ! client
111
- elog ( "ReverseTcpHandlerWorker-#{ local_port } : Queue returned an empty result, exiting..." )
112
- break
113
+ unless client
114
+ elog ( "#{ worker_name } : Queue returned an empty result, exiting..." )
113
115
end
114
116
115
117
# Timeout and datastore options need to be passed through to the client
116
118
opts = {
117
- : datastore => datastore ,
118
- : expiration => datastore [ 'SessionExpirationTimeout' ] . to_i ,
119
- : comm_timeout => datastore [ 'SessionCommunicationTimeout' ] . to_i ,
120
- : retry_total => datastore [ 'SessionRetryTotal' ] . to_i ,
121
- : retry_wait => datastore [ 'SessionRetryWait' ] . to_i
119
+ datastore : datastore ,
120
+ expiration : datastore [ 'SessionExpirationTimeout' ] . to_i ,
121
+ comm_timeout : datastore [ 'SessionCommunicationTimeout' ] . to_i ,
122
+ retry_total : datastore [ 'SessionRetryTotal' ] . to_i ,
123
+ retry_wait : datastore [ 'SessionRetryWait' ] . to_i
122
124
}
123
125
124
126
if datastore [ 'ReverseListenerThreaded' ]
125
- self . conn_threads << framework . threads . spawn ( "ReverseTcpHandlerSession-#{ local_port } -#{ client . peerhost } " , false , client ) { |client_copy |
127
+ thread_name = "#{ worker_name } -#{ client . peerhost } "
128
+ conn_threads << framework . threads . spawn ( thread_name , false , client ) do |client_copy |
126
129
handle_connection ( wrap_aes_socket ( client_copy ) , opts )
127
- }
130
+ end
128
131
else
129
132
handle_connection ( wrap_aes_socket ( client ) , opts )
130
133
end
131
- rescue :: Exception
132
- elog ( "Exception raised from handle_connection: #{ $! . class } : #{ $! } \n \n #{ $@ . join ( "\n " ) } " )
134
+ rescue StandardError
135
+ elog ( "Exception raised from handle_connection: #{ $ERROR_INFO . class } : #{ $ERROR_INFO } \n \n #{ $ERROR_POSITION . join ( "\n " ) } " )
133
136
end
134
137
end
135
138
}
136
-
137
139
end
138
140
139
141
def wrap_aes_socket ( sock )
140
- if datastore [ "PAYLOAD" ] !~ / java\/ / or ( datastore [ "AESPassword" ] || "" ) == ""
142
+ if datastore [ "PAYLOAD" ] !~ %r{ java/} || ( datastore [ "AESPassword" ] || "" ) == ""
141
143
return sock
142
144
end
143
145
144
- socks = Rex ::Socket :: tcp_socket_pair ( )
146
+ socks = Rex ::Socket . tcp_socket_pair
145
147
socks [ 0 ] . extend ( Rex ::Socket ::Tcp )
146
148
socks [ 1 ] . extend ( Rex ::Socket ::Tcp )
147
149
148
150
m = OpenSSL ::Digest . new ( 'md5' )
149
151
m . reset
150
152
key = m . digest ( datastore [ "AESPassword" ] || "" )
151
153
152
- Rex ::ThreadFactory . spawn ( 'Session-AESEncrypt' , false ) {
154
+ Rex ::ThreadFactory . spawn ( 'Session-AESEncrypt' , false ) do
153
155
c1 = OpenSSL ::Cipher . new ( 'aes-128-cfb8' )
154
156
c1 . encrypt
155
- c1 . key = key
157
+ c1 . key = key
156
158
sock . put ( [ 0 ] . pack ( 'N' ) )
157
- sock . put ( c1 . iv = c1 . random_iv )
159
+ sock . put ( ( c1 . iv = c1 . random_iv ) )
158
160
buf1 = socks [ 0 ] . read ( 4096 )
159
- while buf1 and buf1 != ""
161
+ while buf1 && buf1 != ""
160
162
sock . put ( c1 . update ( buf1 ) )
161
163
buf1 = socks [ 0 ] . read ( 4096 )
162
164
end
163
- sock . close ( )
164
- }
165
- Rex ::ThreadFactory . spawn ( 'Session-AESDecrypt' , false ) {
165
+ sock . close
166
+ end
167
+
168
+ Rex ::ThreadFactory . spawn ( 'Session-AESDecrypt' , false ) do
166
169
c2 = OpenSSL ::Cipher . new ( 'aes-128-cfb8' )
167
170
c2 . decrypt
168
- c2 . key = key
169
- iv = ""
170
- while iv . length < 16
171
- iv << sock . read ( 16 - iv . length )
172
- end
171
+ c2 . key = key
172
+
173
+ iv = ""
174
+ iv << sock . read ( 16 - iv . length ) while iv . length < 16
175
+
173
176
c2 . iv = iv
174
177
buf2 = sock . read ( 4096 )
175
- while buf2 and buf2 != ""
178
+ while buf2 && buf2 != ""
176
179
socks [ 0 ] . put ( c2 . update ( buf2 ) )
177
180
buf2 = sock . read ( 4096 )
178
181
end
179
- socks [ 0 ] . close ( )
180
- }
181
- return socks [ 1 ]
182
+ socks [ 0 ] . close
183
+ end
184
+
185
+ socks [ 1 ]
182
186
end
183
187
184
188
#
185
189
# Stops monitoring for an inbound connection.
186
190
#
187
191
def stop_handler
188
192
# Terminate the listener thread
189
- if ( self . listener_thread and self . listener_thread . alive? == true )
190
- self . listener_thread . kill
191
- self . listener_thread = nil
192
- end
193
+ listener_thread . kill if listener_thread && listener_thread . alive? == true
193
194
194
195
# Terminate the handler thread
195
- if ( self . handler_thread and self . handler_thread . alive? == true )
196
- self . handler_thread . kill
197
- self . handler_thread = nil
198
- end
196
+ handler_thread . kill if handler_thread && handler_thread . alive? == true
199
197
200
- if ( self . listener_sock )
198
+ if listener_sock
201
199
begin
202
- self . listener_sock . close
200
+ listener_sock . close
203
201
rescue IOError
204
202
# Ignore if it's listening on a dead session
205
203
dlog ( "IOError closing listener sock; listening on dead session?" , LEV_1 )
206
204
end
207
- self . listener_sock = nil
208
205
end
209
206
end
210
207
211
- protected
208
+ protected
212
209
213
210
attr_accessor :listener_sock # :nodoc:
214
211
attr_accessor :listener_thread # :nodoc:
215
212
attr_accessor :handler_thread # :nodoc:
216
213
attr_accessor :conn_threads # :nodoc:
217
214
end
218
-
219
215
end
220
216
end
0 commit comments