-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix sslstrip & some related issues in http(s).proxy and dns.spoof #723
Conversation
Can anybody check this please? @buffermet @evilsocket . This could fix this: #428 Could be awesome for us. Thanks. |
@OscarAkaElvis this is a pretty significant change and i won't be able to test it anytime soon, maybe you can test it to see if it fixes your usecase? |
Sorry for the delay, we were testing this deeply. The results are unpredictable. Sometimes it works... sometimes it doesn't work. Of course we know what we do and victim browser's cache is deleted on each test..... we were able to spoof successfully sometimees Another thing I saw is that it spoofs even non ssl domains ¿? so if I want to get a creds from a http non ssl site, let's suppose @Petitoto can you check this? we tested with a couple of caplet config files. One of them is this:
The other we tested with similar results is this:
Using this last caplet config file we noticed that a .com domain sometimes is redirected to .comm instead of to .corn file ¿? Thanks @JBalanza for helping me on this testing. |
Thank you for testing and for your interest. First, you should not use any caplet. I made this sslstrip because sometimes I run into troubles with hstshijack, and because I wanted to implement a “pure” sslstrip, without any javascript injection. That’s why it behaves differently (like redirecting to .comm and not to .corn). Moreover, when using it with hstshijack, it could produce other issues. Could you try without any caplet? If problem persists, could you try with various browsers, especially a more “basic” one, and inspect DNS queries and responses? During my tests I sometimes had problems resembling what you describe, but it was quite rare and seemed to be a DNS issue. Regarding non SSL domains, I will try to check the issue later this week. As far as I remember (I published this sslstrip 2 months ago 😅), it shouldn’t try to spoof them. |
Awesome, it is working!!! I've been able to sniff a password sslstripping trello.com and the BeEF injection is also working: This is the very basic used caplet:
For some reason, still can't sniff password for non-ssl pages. Please @Petitoto can you check this point? Please @evilsocket merge this awesome PR!! maybe the fix for the non-ssl pages should be done first... but this is the right path!! |
thanks a ton for the PR and for testing :D |
Thanks for testing and merging :D @OscarAkaElvis, I checked and I'm able to sniff passwords on non-ssl pages. Here is what I used :
(By the way, as it's already included in my sslstrip, you don't need to enable dns.spoof: just set http.proxy.sslstrip and possibly http.proxy.sslstrip.useIDN) Then I was able to strip https://trello.com and load http://testasp.vulnweb.com, and of course sniff passwords : If the problem persists, maybe you could open a new issue with screenshots and the configuration used ? |
@OscarAkaElvis don't use the hstshijack caplet in conjunction with the builtin sslstrip module, it will result in the proxy doing twice the amount of work, potentially interfering with one another.
👍 This is correct behaviour, bettercap can spoof HTTPS connections as long as it strips the responses.
This is true, any and all subdomains can be protected if the 'includeSubDomains' flag is set in the HSTS header, which is why I implemented the option to set your own domain replacements in the hstshijack module.
I suggest removing this as the results are incosistent across browsers and other HTTP clients, some of which only supporting ASCII characters in URL fields.
If with "tracking" you mean changing spoofed domains back to the original (and vice versa) 👍
I wasn't aware that cookies can have a secure flag, thanks :) 👍
I'm not sure if I'm following, but if you already have access to HTTPS packets (with bettercap's CA cert), you don't need to SSLstrip and probably shouldn't. Otherwise if downgrading insecure connections that were excepted by the victim, this is definitely an improvement 👍 I'd like to see some of the optionality of hstshijack in the builtin proxy, for instance the ability to choose how a TLD/domain is spoofed (e.g. .com -> .corn), currently HTTP proxy modules lack the ability to make asynchronous calls, as well as making additional HTTP requests. Because of this I built an alphanumeric domain indexer, making the module a lot faster and scalable, potentially allowing us to import the entire HSTS preload list of domains so that we don't have to request each host to learn if they use HTTPS. Domains are filtered and indexed on launch, and concatination occurs at runtime with the use of index ranges, reducing overhead: |
I might as well make Go modules for such indexers, because e.g. bettercap's hostname tracker could also benefit from this. |
@evilsocket I feel like the HTTP request dump should be part of the |
Thanks @buffermet for your report. Using both HTTPS proxy and sslstrip could be interesting if you want to try to strip websites, but if https is directly loaded, you want to send your own CA cert. In this situation, it's interesting to strip links on websites intercepted by HTTPS proxy. I totally agree with you about implementing an option like the one in hstshijack (I love the .com -> .corn). I haven't implemented it first and I have no time to do it yet, but I'd be happy to add it in the future (maybe I could do it in a few weeks :D). Indeed, regarding Internationalized Domain Names, browsers and HTTP clients will reach example.xn--com-mn4b. So, even if they support only ASCII characters, they will load stripped websites. The "problem" is what is displayed to the user: because of IDN homograph attacks, a lot of browsers have decided to display some characters as punycode (https://en.wikipedia.org/wiki/IDN_homograph_attack). However, some others are displayed as unicode (because they could not lead to an IDN homograph attack and are used in real websites). For example, I chose ノ because it's really difficult to see it if you're not aware, and because it is displayed on a lot of browsers (during my tests, only Edge and Internet Explorer displayed example.x--com-mn4b, others like Chrome and Firefox displayed correctly example.comノ). Moreover, IDN support could be interesting for a few browsers vulnerable to IDN homograph attacks (on them you could strip a domain without any visible modificiation!).
Your indexer is interesting, it would be a good improvement to make Go modules for such indexers :D |
hello, I'm unable to get a downgrade some sites from www to 'wwww' , (websites that aren't preloaded with 'HSTS'), there are lot of websites that this should work with as the previous version of Bettercap 1.6 would do this easily. Current version does not render the website at all. Any help on this please? i'm using parrot os and bettercap comes pre-installed. example commands used: set http.proxy.sslstrip true |
Hello @jepunband, Note that sslstrip won't replace www by wwww because of the "includeSubDomains" flag. Instead, it will edit top-level domains. |
Hi @Petitoto , thanks for the info i will update it with the current release and try again. |
revert changes from #723 that prevented HTTP response header spoofing
This pull request fixes sslstrip (related to #428). Some sslstrip's related issues are fixed in http(s).proxy and dns.spoof.
What was fixed:
Bettercap used to send HTTP requests to real websites, even if they tried to redirect it to HTTPS. So bettercap caused infinite redirections. Now it forwards stripped requests to the real websites with the HTTPS schema (target - bettercap uses HTTP whereas bettercap - server uses HTTPS). "Max redirections" is never reached and was removed. Moreover, a part of the code tried to forward HTTPS requests to HTTP (to the real websites). I don't understand why : because of HSTS, websites will only process HTTPS requests (so if we can handle an HTTPS request thanks to the HTTPS proxy, we need to transmit it in HTTPS).
Subdomains of the same domain can be protected by HSTS with the
includeSubDomains
flag. So now sslsttrip edits the Top-Level Domain (TLD).sslstrip.useIDN
to choose between 2 TLD modificationsIf false, sslstrip doubles the last TLD's character. If true, it adds an international character (currently ノ) to create an Internationalized Domain Name. IDN is really efficient to hide a stripped domain name (example.com is edited to example.comノ) but some browsers don't show them by default (example.xn--com-mn4b). Sslstrip only records the ASCII format (thanks to
idna
) but edits links with the internationalized one. So the target will see example.comノ on his webpages, but his browser will reach example.xn--com-mn4b. What is printed on the URL bar depends on the browser (I tested on some browsers with a European language and default configuration, and ノ was printed on a lot while setting useIDN to true).New host is stripped, not the original one. That's why we need to track the new one.
When a domain name is changed, cookies need to be edited. So now, responses of stripped requests are edited to the stripped domain. To do this, I added a function in the host tracker to get the stripped domain of an unstripped already tracked one, and now a host tracker is composed of 2 maps (easier in order to add the new function). Moreover, when editing cookies,
HttpOnly
andSecure
flags are stripped. Thus, cookies can be sent through HTTP (required to support cookies) and injected scripts can access cookies (just useful).When using HTTP and HTTPS proxies with both sslstrip activated, users want that links stripped by the HTTPS proxy can be intercepted by the HTTP proxy. So now, proxies save their stripper, and
Configure()
checks for another module using sslstrip and merges strippers (thanks to the modules'Extra()
function).When configuring an HTTP proxy, function checked that
p.jsHook
was an empty string before setting it (when users want to put a javascript code directly). So now, it resetsp.jsHook
when callingConfigure()
.When sslstrip was loaded, injectjs and script caused pages to be never loaded properly. It seems to occur because of the new response which was created by bettercap (I don't really know why). So now it modifies the current response instead of creating a new one. Moreover, you can now set together script and injectjs options.
dnsReply()
The latest updates of dns.spoof weren't available in sslstrip. Now,
dnsReply()
from dns.spoof can be called without aDNSSpoofer
, and sslstrip calls it for more stability (I removed his owndnsReply()
).When
HTTPProxy()
was called, the tag (to print information) was set to "http.proxy". HTTPS proxies had to modify it after. However, for some information (like "enabling forwarding" or my new "found another proxy using sslstrip"), it didn't work. So now, when callingHTTPProxy()
, you need to specify the tag to use.Screenshots of some target browsers I tested while sslstripping:
If you encounter issues while using this sslstrip, it could be because of: