Skip to content

Instantly share code, notes, and snippets.

@ayende
Created January 29, 2019 21:10
Show Gist options
  • Save ayende/434175a252bea84b02f374a5ff304c83 to your computer and use it in GitHub Desktop.
Save ayende/434175a252bea84b02f374a5ff304c83 to your computer and use it in GitHub Desktop.
using System;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
namespace TlsSpy
{
class Program
{
static void Main(string[] args)
{
if (args.Length != 5)
{
Console.WriteLine(@"TLS Spy Proxy usage:
tlspy.exe listen-port forward-host-and-port server-cert-path client-cert-path dir-name
");
return;
}
if(int.TryParse(args[0], out var listenPort) == false)
{
Console.WriteLine("Unable to parse listen port: " + args[0]);
return;
}
var forwardParts = args[1].Split(':');
if(forwardParts.Length != 2)
{
Console.WriteLine("Unable to parse forward host and port: " + args[1]);
return;
}
string forwardHost = forwardParts[0];
if (int.TryParse(forwardParts[1], out var forwardPort) == false)
{
Console.WriteLine("Unable to parse forward port: " + forwardParts[1]);
return;
}
X509Certificate2 serverCert, clientCert;
try
{
serverCert = new X509Certificate2(args[2]);
}
catch (Exception e)
{
Console.WriteLine("Unable to open server cert: " + args[2]);
Console.WriteLine(e);
return;
}
try
{
clientCert = new X509Certificate2(args[3]);
}
catch (Exception e)
{
Console.WriteLine("Unable to open client cert: " + args[3]);
Console.WriteLine(e);
return;
}
string outputDir;
try
{
if(!Directory.Exists(args[4]))
Directory.CreateDirectory(args[4]);
outputDir = args[4];
}
catch (Exception e)
{
Console.WriteLine("Unable to create directory: " + args[4]);
Console.WriteLine(e);
return;
}
TcpListener tcpListener;
try
{
tcpListener = new TcpListener(IPAddress.Any, listenPort);
tcpListener.Start();
}
catch (Exception e)
{
Console.WriteLine("Unable to listen to port: " + listenPort);
Console.WriteLine(e);
return;
}
}
private static int counter;
private static async Task ForwardAndClone(TcpClient client, string forwardHost, int forwardPort, X509Certificate2 serverCert, X509Certificate2 clientCert, string outputDir)
{
var current = Interlocked.Increment(ref counter);
using (var output = File.Create(Path.Combine(outputDir, DateTime.Now.ToString("o") + "-" + current)))
using(var src = new SslStream(client.GetStream(), false,
(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) => true))
{
await src.AuthenticateAsServerAsync(serverCert);
using (var server = new TcpClient())
{
await server.ConnectAsync(forwardHost, forwardPort);
using (var dst = new SslStream(server.GetStream(), false,
(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) => true))
{
await dst.AuthenticateAsClientAsync(forwardHost, new X509CertificateCollection{ clientCert }, false);
var a = dst.CopyToAsync(src);
var b = src.CopyToAsync(dst);
await Task.WhenAll(a, b);
}
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment