Closed WayneJLee closed 1 year ago
How are you sending HTTP requests? Are you using send_request_cgi
?
Msf::Exploit::Remote::HttpClient
is supposed to respect the RHOST
value when setting the Host
header in HTTP/1.1 and HTTP2 requests.
msf6 > use auxiliary/scanner/http/test
msf6 auxiliary(scanner/http/test) > egrep test /etc/hosts
[*] exec: egrep test /etc/hosts
127.0.0.1 test.local
msf6 auxiliary(scanner/http/test) > set rhosts test.local
rhosts => test.local
msf6 auxiliary(scanner/http/test) > set httptrace true
httptrace => true
msf6 auxiliary(scanner/http/test) > run
####################
# Request:
####################
GET / HTTP/1.1
Host: test.local:1337
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
^C[*] Caught interrupt from the console...
[*] Auxiliary module execution completed
msf6 auxiliary(scanner/http/test) >
# nc -lvp 1337
Ncat: Version 7.91 ( https://nmap.org/ncat )
Ncat: Listening on :::1337
Ncat: Listening on 0.0.0.0:1337
Ncat: Connection from 127.0.0.1.
Ncat: Connection from 127.0.0.1:43187.
GET / HTTP/1.1
Host: test.local:1337
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient
include Msf::Auxiliary::Scanner
include Msf::Auxiliary::Report
def initialize
super(
'Name' => 'test',
'Description' => %q{
test
},
'Author' => 'bcoles',
'License' => MSF_LICENSE
)
register_options [Opt::RPORT(1337)]
end
def run_host(ip)
puts send_request_cgi({
'url' => '/test'
})
rescue OpenSSL::SSL::SSLError
rescue Errno::ENOPROTOOPT, Errno::ECONNRESET, ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::ArgumentError
rescue ::Timeout::Error, ::Errno::EPIPE
end
end
Yep I am. Below is the output of the trace and I also added print_status(datastore['RHOST'])
at the start of the function.
msf6 exploit(itop/itop_rce) > set RHOST target.site.com
RHOST => target.site.com
msf6 exploit(itop/itop_rce) > run
[*] Exploiting target 172.67.159.126
[*] 172.67.159.126
####################
# Request:
####################
GET /pages/UI.php HTTP/1.1
Host: target.site.com
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
SSL_connect returned=1 errno=0 state=error: sslv3 alert handshake failure
[-] Exploit failed [unreachable]: OpenSSL::SSL::SSLError SSL_connect returned=1 errno=0 state=error: sslv3 alert handshake failure
[*] Exploiting target 104.21.41.30
[*] 104.21.41.30
####################
# Request:
####################
GET /pages/UI.php HTTP/1.1
Host: target.site.com
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
SSL_connect returned=1 errno=0 state=error: sslv3 alert handshake failure
[-] Exploit failed [unreachable]: OpenSSL::SSL::SSLError SSL_connect returned=1 errno=0 state=error: sslv3 alert handshake failure
[*] Exploiting target 2606:4700:3036::ac43:9f7e
[*] 2606:4700:3036::ac43:9f7e
####################
# Request:
####################
GET /pages/UI.php HTTP/1.1
Host: target.site.com
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
I've also included a screencap from an intercepted request on Burp. You can see in Burp that it's sending the request to the IP address instead of the FQDN that was set, causing requests to error out. Sending the same request in Repeater also results in a handshake failure, possibly due to some security mechanism in place by Cloudflare.
If I manually replace the target in Burp, the request gets handled correctly.
Here's a link to the exploit for reference - https://github.com/attackercan/itop-2.4.0-rce/blob/master/itop_rce.rb
I've made some changes to it but not much. The original script had some important values hardcoded and that's all I tweaked (besides adding in additional print statements for debugging).
The error reported should not be for an untrusted cert. It looks like the SSL protocol requested is failing to negotiate.
SSL_connect returned=1 errno=0 state=error: sslv3 alert handshake failure
When there is a certificate mis-match the error should look like:
SSL_connect returned=1 errno=0 state=error: certificate verify failed
I suspect a supported SSL version may need to be forced for the connection with the remote host. That or the openssl version ruby is loading does not support any protocols the server will allow.
I'm encountering this issue as well when using scanner/http/dir_scanner with SSL set to true.
SSL_connect returned=1 errno=0 state=error: sslv3 alert handshake failure
When I proxy through Burp Suite I see the same thing--the request is being sent with the resolved IP address as the target and the RHOST value as the Host header. This results in an SSL failure when sent to an IP address that is hosting multiple sites.
Setting the specified RHOST as the host header isn't sufficient to negotiate SSL in these cases--the FQDN needs to be sent as the target.
@jmartin-r7 I have tried forcing diff SSL versions through Burp as well with no success. I came across this article a while back on Domain Fronting and it explains some of the magic behind CloudFlare such as the usage of Server Name Indicator fields, which I'm not sure is supported by the MSF libraries at the moment.
Hi!
This issue has been left open with no activity for a while now.
We get a lot of issues, so we currently close issues after 60 days of inactivity. It’s been at least 30 days since the last update here. If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not stale" to keep this issue open!
As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request.
I don't have replication steps to verify the original issue; but I think this was fixed by specifying the service name indication (SNI) for the ssl connections
I believe this is fixed by the SNI changes; Since there's been no replies in a while - I'll mark this as closed for now :+1:
Summary
Currently tweaking a PoC and for some reason, Metasploit is resolving the FQDN set in RHOST and using the IP address instead when making requests. This obviously poses a challenge when dealing with applications behind Cloudflare and I'm struggling to find any documentation to force
HttpClient
to use an FQDN.Does anyone have any idea on how to overcome this?