Table of Contents

Capture raw packets

Before starting, ensure that you've install the necessary prerequisites.

To enable this feature, we will use a CapturedTcpConnectionProvider instead of the default DefaultTcpConnectionProvider used by fluxzy.

This implementation is provided with the package Fluxzy.Core.Pcap and, in addition of having the responsibility to create new remote connection, enables dumping an active TCP connection to a PCAPNG file.

{.csharp}

await using var tcpConnectionProvider = await CapturedTcpConnectionProvider.CreateInProcessCapture();
await using var proxy = new Proxy(fluxzyStartupSetting, tcpConnectionProvider: tcpConnectionProvider);

Full example

Find below a full working sample that will capture the raw PCAPNG file of an System.Net.HttpClient making a request to "https://www.example.com".

using System.Net;
using Fluxzy;
using Fluxzy.Core.Pcap;
using Fluxzy.Core.Pcap.Pcapng.Merge;
using Fluxzy.Readers;

var tempDirectory = "fluxzy_dump_folder";

var fluxzyStartupSetting = FluxzySetting
    .CreateDefault()
    .SetOutDirectory(tempDirectory);

await using (var tcpConnectionProvider = await CapturedTcpConnectionProvider.CreateInProcessCapture())
{
    await using var proxy = new Proxy(fluxzyStartupSetting, tcpConnectionProvider: tcpConnectionProvider);

    var endpoints = proxy.Run();

    using var httpClient = new HttpClient(new HttpClientHandler()
    {
        // We instruct the HttpClient to use the proxy
        Proxy = new WebProxy("127.0.0.1", endpoints.First().Port),
        UseProxy = true
    });

    // Make a request to a remote website
    using var response = await httpClient.GetAsync("https://www.example.com/");

    // Fluxzy is in full streaming mode, this means that the actual body content 
    // is only captured when the client reads it. 
    await (await response.Content.ReadAsStreamAsync()).CopyToAsync(Stream.Null);
}

using var archiveReader = new DirectoryArchiveReader(tempDirectory);

// We retrieve back the exchange related to the request to example.com
var requestExchange =
    archiveReader.ReadAllExchanges().First(r => r.KnownAuthority == "www.example.com");

using var pcapFileStream = File.Create("example.com.pcapng");

// We copy the raw packets to a pcap file
await archiveReader.GetRawCaptureStream(requestExchange!.ConnectionId!)!.CopyToAsync(pcapFileStream);

using var mergePcapFileStream = File.Create("all-captures.pcapng");
PcapMerge.MergeDumpDirectory(tempDirectory, mergePcapFileStream);

Enable NSS Key log collection

SSL can be enabled when using the managed SSL provider Bouncy Castle instead of the OS default.

There are few changes from the previous example to enable NSS key log collection.

First, we need to use the Bouncy Castle SSL provider.

{.csharp}

var fluxzyStartupSetting = FluxzySetting
    .CreateDefault()
    .SetOutDirectory(tempDirectory)
    .UseBouncyCastleSslProvider(); // Add this line

At, this point when reading a dump directory the method IArchiveReader.GetRawCaptureKeyStream(connectionId) should returns the NSS key log related to the connectionId.

Fluxzy provides an useful helper, PcapngUtils.CreatePcapngFileWithKeys to combine the raw capture file with the NSS Key log datas.

Let's replace the two last line of the previous sample to make it work.

{.csharp}

// create the stream to store the final pcapng file 
using var finalPcapStream = File.Create("example.com.deciphered.pcapng");

// retrieve the encrypted raw pcapng file as stream
using var encryptedRawPcapStream = archiveReader.GetRawCaptureStream(requestExchange.ConnectionId)!; 

// read the NSS Key log 
var nssKeyLog = archiveReader.GetRawCaptureKeyStream(requestExchange.ConnectionId)
    !.ReadToEndGreedy(); // This method is reads a stream to end and return the result as string, assuming UTF8.

// The helper that will combine the NSS key log and the encrypting pcapng file to a final pcapng file 
await PcapngUtils.CreatePcapngFileWithKeysAsync(nssKeyLog, encryptedRawPcapStream, finalPcapStream); 

After running with this changes, you should be able to see deciphered HTTP sessions when opening example.com.deciphered.pcapng file with Wireshark.

Merge all PCAPNG into single

By default, each connection is stored in a separate PCAPNG file. You can use the utility PcapMerge to merge pcapng from a dump directory or a fluxzy archive into a single file.

{.csharp}

using var mergePcapFileStream = File.Create("all-captures.pcapng");
PcapMerge.MergeDumpDirectory(tempDirectory, mergePcapFileStream);