basil00 / WinDivert

WinDivert: Windows Packet Divert
https://reqrypt.org/windivert.html
Other
2.46k stars 500 forks source link

How Do I Modify Domain Responses? #101

Closed volomike closed 7 years ago

volomike commented 7 years ago

Let's say I want to make an ad blocker on a web page that shows a message like "Ad Blocked By ___ Ad Blocker" when pulling an ad from some domain. I see that I can modify packets, but can this be done? And will it work even if the ad is pulled via https?

Or would it be better to intercept domain requests and reroute them to a mini web server in memory on an alternative port?

TechnikEmpire commented 7 years ago

This can't be done easily. You can take control of packets sure but that's where the library ends and your work begins. You need to handle one or more protocols above and beyond that, either http/s or DNS or both to accomplish this. If you just hijack dns and nxdomain stuff, web pages are going to have errors all over them.

volomike commented 7 years ago

That's what I thought. So what I need to do is make a browser extension, and see how the source code of Ad Block extension for Chrome works.

volomike commented 7 years ago

So here's a question. Can I use this driver to intercept x.com and HTTP redirect them to y.com? That way, I could show a message perhaps?

TechnikEmpire commented 7 years ago

@volomike I have an open source implementation url filtering via the adblock plus filter syntax here but it's in C#. The CSS selector filter side of things is not complete, and the URL filter syntax is not 100% complete but it's more than sufficient to apply 99.99% of ABP filters to urls.

With regards to intercepting sure you can do that, it would be trivial to capture and synthesize plain HTTP requests and responses. Look at the webfilter example in this same repo. The problem you're going to have is HTTP/S. That's not trivial, you'd need to MITM such requests and that's non-trivial.

TechnikEmpire commented 7 years ago

@volomike btw your website's certificate expired 3 days ago. I thought my filter was broken when I visited it :(

volomike commented 7 years ago

@TechnikEmpire yeah, on my website -- I started the transition last night to a new cert with Namecheap but am interacting with their live support because their processing of it is taking way too long and so I can't get the HTTP validation I need.

It sounds like it might be better to use Qt/C++ to add a DNS rule into Windows so that x.com requests go to y.com, and then on y.com I can serve up the replacement messsage. I know that I can do this via the HOSTS file on Windows, but it's an inefficient system. So, I'm looking on stackoverflow.com on how to do this via a DNS rule added into the OS network stack somehow.

TechnikEmpire commented 7 years ago

@volomike If you have command line access to your server, letsencrypt is free.

Anyway sorry to get off topic. I dunno about DNS, you could capture DNS queries with WinDivert instead and just process them that. Unfortunately, tools in C/C++ land for managing DNS are few and far between and generally a pain. I'm not sure what languages you work in but there's a very nice, easy to use and complete DNS library in C#, I used to grab DNS with WinDivert and pass it to that lib and then spoof etc.

Whatever you do, just reply to every query at your fake server with HTTP 204 No Content. That way your web pages won't show that they're broken apart.

basil00 commented 7 years ago

As @TechnikEmpire hints, it is possible to do this kind of stuff, but WinDivert is rather low-level and only handles the network layer (raw IP packets). All higher protocols (even including transport) must be correctly handled by your application, which can be non-trivial. You should look at some of TechnikEmpire's projects that use WinDivert for HTTP(S) interception and modification.