Fév 182019
 

Playing around with intercepting traffic (diverting, mitm, etc), I needed a standalone DNS server.

Sharing it here.

You can use the local windows resolver OR use dnsquery which then allows you to choose between UDP/TCP and remote DNS server.
Remote dns server has to be set in the config.ini file (see included ini file).
Still via the config.ini, you also « spoof » A or PTR records (example : have www.facebook.com resolve to 127.0.0.1).

https://i.imgur.com/zSqyGvy.png

Fév 172019
 

Previously we have built a HTTP server.
This time, lets build a HTTPS server.

The main difference compared to previous article is that this time, we need an object of type TIdServerIOHandlerSSLOpenSSL to provide certificates details and to handle the ssl part (client hello, server hello, etc).

Main code below.


IdServerIOHandlerSSLOpenSSL1.SSLOptions.CertFile := 'device.crt';
IdServerIOHandlerSSLOpenSSL1.SSLOptions.KeyFile := 'device.key';
//IdServerIOHandlerSSLOpenSSL1.SSLOptions.RootCertFile := 'rootca.pem'; //optional since cert is signed with rootca is added to local ca authorities
IdServerIOHandlerSSLOpenSSL1.SSLOptions.Mode := sslmServer;
IdServerIOHandlerSSLOpenSSL1.SSLOptions.VerifyMode := [];
IdServerIOHandlerSSLOpenSSL1.SSLOptions.VerifyDepth := 0;
if rbtlsv12.Checked then IdServerIOHandlerSSLOpenSSL1.SSLOptions.SSLVersions := [sslvTLSv1_2];
if rbtlsv11.Checked then IdServerIOHandlerSSLOpenSSL1.SSLOptions.SSLVersions := [sslvTLSv1_1];
if rbtlsv10.Checked then IdServerIOHandlerSSLOpenSSL1.SSLOptions.SSLVersions := [sslvTLSv1];
if rbsslv3.Checked then IdServerIOHandlerSSLOpenSSL1.SSLOptions.SSLVersions := [sslvSSLv3 ];
IdServerIOHandlerSSLOpenSSL1.OnGetPassword := GetPassword; //not needed if we dont have a password on our cert

IdTCPServer1.DefaultPort := SERVER_PORT;
IdTCPServer1.IOHandler := IdServerIOHandlerSSLOpenSSL1;
IdTCPServer1.OnConnect := ServerConnect;
IdTCPServer1.OnExecute := ServerExecute;
IdTCPServer1.Active := True;

memResults.Lines.Add ('start');

Code is on github.

About the certificate part:
-generate the root ca (and add it to your client root ca’s)
openssl genrsa -out rootCA.key 2048
openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1024 -out rootCA.pem

-generate a csr (only the CN field matters and must match your local site – example : localhost or 127.0.0.1).
openssl genrsa -out device.key 2048
openssl req -new -key device.key -out device.csr

-use the root ca to generate a client cert from a csr
openssl x509 -req -in device.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out device.crt -days 500 -sha256

Fév 172019
 

In previous article we installed indy 10 in Lazarus.

Lets now build a lightweigth HTTP server.

All it is really is a tcp server listening on port 80, parsing the incoming request and sending back the content of the requested file.

All the « magic » really happens below.


lCmdLine := AContext.Connection.IOHandler.ReadLn;
memResults.Lines.Add (lCmdLine);
if lCmdLine<>'' then
begin
uri := StringReplace (lCmdLine ,'GET ','',[]);
uri := copy(uri,1,pos(' ',uri )-1);
uri :=StringReplace (uri,'/','',[]);;
if FileExists(uri)
then AContext.Connection.IOHandler.WriteFile(uri)
else AContext.Connection.IOHandler.Writeln('file not found');
AContext.Connection.Disconnect;
end;
end;

Source code can be found on github.

Fév 172019
 

In a previous article, we had built a transparent proxy for tcp (outbound) connections.

In short any tcp outbound connection on port_x would be redirected to ip:port_z.

Main usage was to implement a transparent proxy for http traffic (applications would « transparently » be redirected to a proxy accepting « intercepted » traffic).

This time, lets do the same for (outbound) UDP.

One possible scenario : intercept all outbound dns traffic and redirect to another dns server.

Syntax:

proxy-tcp 1.0 by erwan2212@gmail.com
proxy-tcp original_port new_port new_ip [local]
remember that if you divert to a local app, this local app could be diverted as well.

Example : proxy-udp 53 53 192.168.1.144 local
With a rogue dns server running locally (skip the ‘local’ if the rogue server is running on another host).

Note the warning about diverting to a local app.
For instance, you could be running your local rogue server locally but then since this rogue server will also perform dns queries, you would end up in catch 22 situation.
Possible workarounds :
-have your rogue server « escape » the filter and use a remote udp port different than the filtered one (i.e something different than 53) OR a different protocol (i.e something different than UDP)
-review the code and filter on the original dns server
-review the code and exclude the dns server used by the rogue server

Source code and binaries can be found on my github.

Fév 172019
 

Lets install Indy 10 in Lazarus.
Lazarus has this cool feature called Online Package Manager (OPM).

If you cannot find it under Package menu, go to package\install/uninstall package and move it from right column (availabe) to left column (install).

https://imgur.com/snlW7D5

Save and rebuild ide, and restart.

Now, go to OPM and install Indy and you are done : never been so easy 🙂

https://imgur.com/gxafmAz

Fév 172019
 

In the next 4 articles we will see how to build a lightweight HTTPS server which can be used in some situations to troubleshoot/test.

Step 1 : we will install Indy 10 in Lazarus
Step 2 : we will code a lightweight http server
Step 3 : we will generate a root certificate authority / use it to sign a certificate and turn our http server in https
step 4 : we will see the difference between CN field (normally matching your web server) and SAN field (nowadays required by modern browsers)

Fév 032019
 

Still playing with Windivert (see original article here), I this time decided to code a transparent proxy.

Principle is the following : divert a destination port (say tcp:80) to a new destination_ip:port.

On the destination ip, i am running privoxy (but any proxy supporting transparent mode would do).
In privoxy config file, I am setting accept-intercepted-requests=1 .

This will be completely transparent for the source application.

Nothing really fancy in the code except may be me storing the orginal remote ip (which we will need to re apply on the traffic back) in an array dynamic_source_port=remote_ip.

Source code and binaries can be found here.

Jan 272019
 

In a previous article, I did comment on a nice opensource library (Windivert) and shared a basic freepascal demo to use it.

This time I used this library to redirect (or reuse) a local port used by another application or service to another local port.

It could be handy to fool firewalls or to hijack traffic going to a service.

One of the best example that come to my mind is to redirect local port 445 to a an application/shell of your own listening on local port 1337.
Something you could not achieve like netsh port redirect as the port is already in use and/or used by a kernel service (SMB in our case).

The command line would then be tcpredir 445 1337.

Source code and binaries on Github.

One possible application example:

-divert local port 445 to port 1337
-set up a smb server on port 1337

https://i.imgur.com/kSCrC9M.png

Jan 272019
 

Quoting the original web site (here) :

Windows Packet Divert (WinDivert) is a user-mode packet capture-and-divert package for Windows 2008, Windows 7, Windows 8, Windows 10 and Windows 2016.

WinDivert allows user-mode applications to capture/modify/drop network packets sent to/from the Windows network stack. In summary, WinDivert can:

capture network packets
filter/drop network packets
sniff network packets
(re)inject network packets
modify network packets
WinDivert can be used to implement user-mode packet filters, packet sniffers, firewalls, NAT, VPNs, tunneling applications, etc.

The main features of WinDivert include:

packet interception, sniffing, or dropping modes
supports loopback (localhost) traffic
full IPv6 support
network layer
simple yet powerful API
high-level filtering language
filter priorities
silent installation
freely available under the terms of the GNU Lesser General Public License (LGPL)

Similar to the raw socket sniffer (here), i have shared a demo (in freepascal) here.

Because windivert is a kernel driver, issues inherent to the windows raw sockets will not apply here.