WinDivert redirect to proxy - windows

I'm trying to redirect all tcp packets to my local proxy to modify html content(adblocker like). I wanted to use WinDivert but it doesn't seem to work.
Im starting the driver like this:
handle = WinDivertOpen("outbound", WINDIVERT_LAYER_NETWORK, 0, 0);
then when capturing and modifying packets:
if (ip_header != NULL && tcp_header != NULL) {
//redirect to proxy
if (ntohs(tcp_header->DstPort) == 80)
{
UINT32 dst_addr = ip_header->DstAddr;
ip_header->DstAddr = ip_header->SrcAddr;
ip_header->SrcAddr = dst_addr;
tcp_header->DstPort = htons(PROXY);
addr.Direction = DIVERT_DIRECTION_INBOUND;
}
else if (ntohs(tcphdr->SrcPort) == PROXY)
{
// proxy to browser
uint32_t dst_addr = iphdr->DstAddr;
iphdr->DstAddr = iphdr->SrcAddr;
iphdr->SrcAddr = dst_addr;
tcphdr->SrcPort = htons(80);
addr.Direction = DIVERT_DIRECTION_INBOUND;
}
WinDivertHelperCalcChecksums(packet, packet_len, 0);
if (!WinDivertSend(handle, packet, packet_len , &addr, &send_len))
{
qWarning() << "warning: failed to reinject packet" << GetLastError() << send_len;
}
But on the proxy side i cant see any incoming traffic and pages are not loading in the web browser.

The code snippet will transform outbound (port HTTP) packets into inbound (port PROXY) packets. This part is OK. But there is currently nothing that handles the reverse path.
For example, consider the TCP handshake. The code snippet will redirect a (DstPort=80) SYN packet to the proxy server, which will reply with a (SrcPort=PROXY) SYN/ACK. However, this SYN/ACK is not handled by the above code and will be lost. You need to add code to redirect outbound (SrcPort=PROXY) packets to inbound (SrcPort=80) packets.
See the TorWall example: https://github.com/basil00/TorWall/blob/082b7ff0fa86abfa2df480ece8cb31e25a29c1bc/tor_wall.c
Edit: Also see the streamdump WinDivert sample: https://github.com/basil00/Divert/blob/master/examples/streamdump/streamdump.c

Related

Closing connection to client in Vertx without restarting the server

I am using Vertx for my backend.
This is a TCP server and the server is connected to several clients.
I am trying to disconnect the client when reaching a certain condition.
The code that I used is as follows.
vertx.createNetServer(new NetServerOptions().setIdleTimeout(601))
.connectHandler(socket -> {
Instant start = Instant.now();
writerId = socket.writeHandlerID();
log.info("[TCPServerVerticle] first Tcp Server Instance Id : {}", serverId);
socket.handler(input -> { // input을 받았을 때 실행
writerId = socket.writeHandlerID();
SocketAddress localAddr = socket.localAddress();
SocketAddress remoteAddr = socket.remoteAddress();
central.setWriterId(writerId);
byte[] bytes = input.getBytes();
String inputString = Utils.byteArrayToHex(bytes);
central.inputMessage(inputString, writerId, vertx, localAddr, remoteAddr, versionMap).onComplete(ok -> {
String result = ok.result();
if (result.equals("nak")) {
socket.close();
}
});
});
When I execute this code, when the condition for "nak" is met, the server seems to restart and not the client.
Would there be a way to close the connection to the client without restarting the server?
Thank you in advance

ZeroMQ server client start sequence

Facing a issue if the client is started before server
Specs : ubuntu 16.04 with c++11,libzmq : 4.2.3
problem : sample codes
server.cpp
int main()
{
zmq::context_t context(1);
zmq::socket_t requester(context,ZMQ_ROUTER);
.
//code to get address
.
requester.bind(address);
while(true)
{
zmq::message_t message;
requester.recv(&message);
.
//remaining code
.
}
return 0;
}
client.cpp
int main()
{
zmq::context_t context(1);
zmq::socket_t requester(context,ZMQ_DEALER);
.
//code to get address
.
requester.connect(address);
zmq::message_t message;
.
//populate the message to send
.
requester.send(message);
return 0;
}
I know that in zmq i can start client even if the server is not running,but my client application has to include a safety check which requires the server to be started.Is there any way i can achieve by making connect fail or someother workaround.Timeout options doesnt work for me
Make the send non blocking, if there there is no server(s) available the send will fail and set an errno
http://api.zeromq.org/4-2:zmq-send
ZMQ_DONTWAIT
For socket types (DEALER, PUSH) that block when there are no available peers
(or all peers have full high-water mark), specifies that the operation should
be performed in non-blocking mode. If the message cannot be queued on the
socket, the zmq_send() function shall fail with errno set to EAGAIN.

ZMQ - forwarding request between sockets or one-time proxy

I'm struggling with connecting two sockets:
frontend (ROUTER) - which handles clients request and forward them to backend
backend (ROUTER) - which receives request from frontend and deals with them with the use of number of workers ( which require some initialization, configuration etc).
The server code looks like this:
void server_task::run() {
frontend.bind("tcp://*:5570");
backend.bind("inproc://backend");
zmq::pollitem_t items[] = {
{ frontend, 0, ZMQ_POLLIN, 0 },
{ backend, 0, ZMQ_POLLIN, 0}
};
try {
while (true) {
zmq::poll(&items[0], 2, -1);
if (items[0].revents & ZMQ_POLLIN) {
frontend_h();
}
if (items[1].revents & ZMQ_POLLIN) {
backend_h();
}
}
}
catch (std::exception& e) {
LOG(info) << e.what();
}
}
frontend_h and backend_h are handler classes, each having access to both sockets.
The question is:
Considering synchronous execution of frontend_h() and backend_h() how can I forward the request dealt in frontend_h() to backend_h()?
I tried to simply re-send the message using backend socket like that:
void frontend_handler::handle_query(std::unique_ptr<zmq::message_t> identity, std::unique_ptr<zmq::message_t> request) {
zmq::message_t req_msg, req_identity;
req_msg.copy(request.get());
req_identity.copy(identity.get());
zmq::message_t header = create_header(request_type::REQ_QUERY);
backend.send(header, ZMQ_SNDMORE);
backend.send(message);
}
But it stucks on zmq::poll in run() after the execution of handle_query().
Stucks on zmq::poll()?
Your code has instructed the .poll() method to block, exactly as documentation states:
If the value of timeout is -1, zmq_poll() shall block indefinitely until a requested event has occurred...
How can I forward the request?
It seems pretty expensive to re-marshall each message ( +1 for using at least the .copy() method and avoiding re-packing overheads ) once your code is co-located and the first, receiving handler, can request and invoke any appropriate method of the latter directly ( and without any Context()-processing associated efforts and overheads.

Arduino Ethernet client.available() not working

I eventually want to send a GET request to my Amazon EC2 server, but for now I just need to get the GET request to work in some fashion. To do that, I am trying to send a GET request to google as a test.
I am using a Arduino Uno with an Ethernet shield connected to the internet via DHCP.
My issue is that although client.connect() seems to work, client.available doesn't work either with google or with my EC2 server. Although, if my issue lies elsewhere, please tell me.
I am able to ping google and do a Telnet GET request simulation using:
-telnet www.google.com 80
-GET /search?q=arduino HTTP/1.0
Arduino Code:
#include <SPI.h>
#include <Ethernet.h>
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0F, 0xD2, 0xAF };
//byte mac[] = {0xf0, 0x1f, 0xaf, 0x33, 0x62, 0x2f };
IPAddress ip(192,168,1,11);
// initialize the library instance:
EthernetClient client;
//char server[] = "ec2-54-69-168-77.us-west-2.compute.amazonaws.com";
char server[] = "www.google.com";
double dummyValue = 7.5;
void setup()
{
Serial.begin(9600);
// attempt a DHCP connection:
Serial.println("Attempting to get an IP address using DHCP:");
if (!Ethernet.begin(mac)) {
// if DHCP fails, start with a hard-coded address:
Serial.println("failed to get an IP address using DHCP, trying manually");
Ethernet.begin(mac, ip);
}
Serial.print("My address:");
Serial.println(Ethernet.localIP());
}
void loop()
{
// connect to the server
for(int i = 0;i <100 ; i++) {
if (client.connect(server, 80)) {
// print to serial monitor
Serial.println("connected...");
Serial.println("ARDUINO: forming HTTP request message");
// send data the server through GET request
//client.print("GET /~sclaybon3/firstdatatest.php?reading=3 HTTP/1.0\r\n");
client.print("GET /search?q=arduino HTTP/1.0\r\n");
Serial.println("Get request");
//client.print(dummyValue);
//client.print(" HTTP/1.1");
//client.print("Host: ec2-54-69-168-77.us-west-2.compute.amazonaws.com\r\n");
client.print("Host: www.google.com\r\n");
//Serial.println("Host:www.google.com");
//client.print("Connection: close\r\n\r\n");
client.print("\r\n");
Serial.println("ARDUINO: HTTP message sent");
// give server some time to receive and store data
// before asking for response from it
delay(1000);
// get the response from the page and print it to serial port
// to ascertain that data was received properly
if(client.available())
{
Serial.println("ARDUINO: HTTP message received");
Serial.println("ARDUINO: printing received headers and script response...\n");
while(client.available())
{
char c = client.read();
Serial.print(c);
}
}
else
{
Serial.println("ARDUINO: no response received / no response received in time");
}
client.stop();
}
}
// do nothing forever after:
while(true);
}
Arduino output:
Attempting to get an IP address using DHCP:
My address:192.168.1.11
connected...
ARDUINO: forming HTTP request message
Get request
ARDUINO: HTTP message sent
ARDUINO: no response received / no response received in time

No connection could be made because the target machine actively refused it 127.0.0.1:8118

trying to create web request using Tor. getting this error - "Unable to connect to the remote server".
Tor default proxy - 8118.
i have goggled for it found solution for it using Tor as Proxy but it didn't worked for me.
Code-
Process p = new Process();
p.StartInfo = new ProcessStartInfo(#"C:\Users\king\Downloads\Tor Browser\App\tor.exe", "ControlPort 9151 CircuitBuildTimeout 10");
p.Start();
Thread.Sleep(5000);
Regex regex = new Regex("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}", RegexOptions.Multiline);
do
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://whatismyipaddress.com/");
request.Headers.Add("Cache-Control", "max-age=0");
request.Proxy = new WebProxy("127.0.0.1:8118");
request.KeepAlive = false;
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (var reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding("utf-8")))
{
string contenu = reader.ReadToEnd();
Console.WriteLine(regex.Match(contenu).Groups[0].Value);
}
}
Console.Write("en attente : continuez ?");
string line = Console.ReadLine();
if (line != "y")
break;
}
while (true);
p.Kill();
Console.ReadLine();
any idea what doing wrong in above code.
thank's
Just download the Privoxy here
the reason to run tor through privoxy is because c# does not work with socks proxies. and tor is a socks proxy, so it needs to be ran through a html proxy that runs through tor
Tor default proxy port is 8118. you have to first download privoxy here
To chain Privoxy and Tor, both running on the same system, you would use something like:
forward-socks5 / 127.0.0.1:9050
change its config to work with tor by uncommenting the above line
c# does not use sock proxies so that we have to run Tor and Provoxy at same. now you can send every web request using tor.

Resources