unsafe private static void RunDiversion(IntPtr handle, string origPort, string divertPort) { var packet = new WinDivertBuffer(); var addr = new WinDivertAddress(); uint recvLength = 0; NativeOverlapped recvOverlapped; IntPtr recvEvent = IntPtr.Zero; recvEvent = WinDivertSharp.WinAPI.Kernel32.CreateEvent(IntPtr.Zero, false, false, IntPtr.Zero); if (recvEvent == IntPtr.Zero || recvEvent == new IntPtr(-1)) { return; } uint recvAsyncIoLen = 0; ushort[] _v4ReturnPorts = new ushort[ushort.MaxValue + 1]; Span <byte> payloadBufferPtr = null; IPAddress original_client_ip = null; IPAddress original_server_ip = null; ushort orig_client_tcpSrcPort = 0; _originalPort = (ushort)IPAddress.HostToNetworkOrder((short)(Int32.Parse(origPort))); _modifiedPort = (ushort)IPAddress.HostToNetworkOrder((short)(Int32.Parse(divertPort))); while (s_running) { payloadBufferPtr = null; recvLength = 0; addr.Reset(); recvAsyncIoLen = 0; recvOverlapped = new NativeOverlapped(); recvOverlapped.EventHandle = recvEvent; #region Packet Reading Code if (!WinDivert.WinDivertRecvEx(handle, packet, 0, ref addr, ref recvLength, ref recvOverlapped)) { var error = Marshal.GetLastWin32Error(); // 997 == ERROR_IO_PENDING if (error != 997) { Console.WriteLine(string.Format("[-] Unknown IO error ID {0} while awaiting overlapped result.", error)); Kernel32.CloseHandle(recvEvent); continue; } while (Kernel32.WaitForSingleObject(recvEvent, 1000) == (uint)WaitForSingleObjectResult.WaitTimeout) { ; } if (!Kernel32.GetOverlappedResult(handle, ref recvOverlapped, ref recvAsyncIoLen, false)) { Console.WriteLine("[-] Failed to get overlapped result."); Kernel32.CloseHandle(recvEvent); continue; } recvLength = recvAsyncIoLen; } #endregion Packet Reading Code var parseResult = WinDivert.WinDivertHelperParsePacket(packet, recvLength); if ((parseResult.TcpHeader->Syn == 0x1) && (parseResult.TcpHeader->Ack == 0x0)) { original_client_ip = parseResult.IPv4Header->SrcAddr; original_server_ip = parseResult.IPv4Header->DstAddr; orig_client_tcpSrcPort = parseResult.TcpHeader->SrcPort; } if (parseResult.TcpHeader->DstPort == _originalPort) { parseResult.TcpHeader->DstPort = _modifiedPort; } //if (parseResult.TcpHeader->SrcPort == _modifiedPort && parseResult.TcpHeader->DstPort == orig_client_tcpSrcPort) if (parseResult.TcpHeader->SrcPort == _modifiedPort) { parseResult.TcpHeader->SrcPort = _originalPort; //parseResult.TcpHeader->DstPort = orig_client_tcpSrcPort; //parseResult.IPv4Header->SrcAddr = original_server_ip; //parseResult.IPv4Header->DstAddr = original_client_ip; } var sumsCalculated = WinDivert.WinDivertHelperCalcChecksums(packet, recvLength, ref addr, WinDivertChecksumHelperParam.All); WinDivert.WinDivertSendEx(handle, packet, recvLength, 0, ref addr); } }
public void TestFilterMatch94() { var tcpPacket = PacketDotNet.TcpPacket.RandomPacket(); var ipPacket = (PacketDotNet.IPv4Packet)PacketDotNet.IPPacket.RandomPacket(PacketDotNet.IPVersion.IPv4); //var ethernetPacket = PacketDotNet.EthernetPacket.RandomPacket(); // put these all together into a single packet ipPacket.PayloadPacket = tcpPacket; //ethernetPacket.PayloadPacket = ipPacket; // and get a byte array that represents the single packet var bytes = ipPacket.Bytes; var winDivertBuffer = new WinDivertBuffer(bytes); var result = WinDivert.WinDivertHelperParsePacket(winDivertBuffer, winDivertBuffer.Length); Assert.AreNotEqual(result.IsIPv4, false, "IPv4 header should not be null."); Assert.AreNotEqual(result.TcpHeader, false, "Tcp header should not be null."); //pdmIpv4.UpdateCalculatedValues(); //pdmIpv4.CalculateIPChecksum(); //pdmTcp.UpdateCalculatedValues(); Assert.AreEqual(ipPacket.SourceAddress, result.IPv4Header.SrcAddr, "Source IP addresses do not match."); Assert.AreEqual(ipPacket.DestinationAddress, result.IPv4Header.DstAddr, "Destination IP addresses do not match."); Assert.AreEqual(tcpPacket.Checksum, result.TcpHeader.Checksum, "Checksums do not match."); Assert.AreEqual(ipPacket.Checksum, result.TcpHeader.Checksum, "Checksums do not match."); Assert.AreEqual(tcpPacket.Checksum, 0, "Checksums do not match."); Assert.AreEqual(result.TcpHeader.Checksum, 0, "Checksums do not match."); tcpPacket.CalculateTCPChecksum(); tcpPacket.UpdateCalculatedValues(); tcpPacket.UpdateTCPChecksum(); ipPacket.CalculateIPChecksum(); ipPacket.UpdateCalculatedValues(); ipPacket.UpdateIPChecksum(); WinDivert.WinDivertHelperCalcChecksums(winDivertBuffer, winDivertBuffer.Length, WinDivertChecksumHelperParam.All); //Assert.AreEqual(tcpPacket.Checksum, result.TcpHeader.Checksum, "Checksums do not match."); Assert.AreEqual(ipPacket.Checksum, (ushort)IPAddress.NetworkToHostOrder((short)result.IPv4Header.Checksum), "Checksums do not match."); Assert.AreEqual(tcpPacket.Checksum, (ushort)IPAddress.NetworkToHostOrder((short)result.TcpHeader.Checksum), "Checksums do not match."); ipPacket.SourceAddress = IPAddress.Parse("8.8.8.8"); result.IPv4Header.SrcAddr = IPAddress.Parse("8.8.8.8"); result.TcpHeader.SrcPort = (ushort)IPAddress.NetworkToHostOrder((short)8888); tcpPacket.SourcePort = 8888; tcpPacket.CalculateTCPChecksum(); tcpPacket.UpdateCalculatedValues(); tcpPacket.UpdateTCPChecksum(); ipPacket.CalculateIPChecksum(); ipPacket.UpdateCalculatedValues(); ipPacket.UpdateIPChecksum(); WinDivert.WinDivertHelperCalcChecksums(winDivertBuffer, winDivertBuffer.Length, WinDivertChecksumHelperParam.All); //Assert.AreEqual(tcpPacket.Checksum, result.TcpHeader.Checksum, "Checksums do not match."); Assert.AreEqual(ipPacket.Checksum, (ushort)IPAddress.NetworkToHostOrder((short)result.IPv4Header.Checksum), "Checksums do not match."); Assert.AreEqual(tcpPacket.Checksum, (ushort)IPAddress.NetworkToHostOrder((short)result.TcpHeader.Checksum), "Checksums do not match."); }
public static void Main(string[] args) { if (args.Length == 2) { if (args[0] == "uninstall") { if (ServiceInstaller.ServiceIsInstalled(args[1])) { Console.WriteLine("[-] Removing service for loading driver..."); ServiceInstaller.Uninstall(args[1]); Console.WriteLine("[-] Service " + args[1] + " was removed successfully!"); return; } else { Console.WriteLine("[!] Service " + args[1] + " is not installed on the target!"); Console.WriteLine("[!] Exiting..."); return; } } Console.WriteLine("Unknown arguments!\n" + "Example: SharpRelay.exe uninstall ServiceNameToRemove"); return; } if (args.Length != 4) { Console.WriteLine("Incorrect number of arguments!\n" + "Example: SharpRelay.exe NewServiceName PathToWinDivertDriver OriginalPort DiversionPort"); return; } Console.WriteLine("[+] Checking if service already exists..."); if (!ServiceInstaller.ServiceIsInstalled(args[0])) { Console.WriteLine("[+] Service not found! Creating new service to load driver..."); try { ServiceInstaller.InstallAndStart(args[0], args[0], @"\??\" + args[1]); } catch { Console.WriteLine("[!] Service could not be created!"); return; } Console.WriteLine("[+] Service created and started successfully!"); } else { Console.WriteLine("[!] Service " + args[0] + " already exists... Try again with a different service name!"); return; } string filter = "(inbound and tcp.DstPort == " + args[2] + ") or (outbound and tcp.SrcPort == " + args[3] + ")"; //string filter = "((tcp.DstPort == " + args[2] + " ) or (tcp.SrcPort == " + args[3] + " ))"; //string filter = "tcp"; Console.WriteLine("[+] Creating interception handle..."); var handle = WinDivert.WinDivertOpen(filter, WinDivertLayer.Network, -1000, 0); if (handle == IntPtr.Zero || handle == new IntPtr(-1)) { Console.WriteLine("[-] Invalid handle. Failed to open."); Console.ReadKey(); return; } // Set everything to maximum values. WinDivert.WinDivertSetParam(handle, WinDivertParam.QueueLen, 16384); WinDivert.WinDivertSetParam(handle, WinDivertParam.QueueTime, 8000); WinDivert.WinDivertSetParam(handle, WinDivertParam.QueueSize, 33554432); Console.WriteLine("[+] Diverting packets from " + args[2] + " to " + args[3] + "...\n"); var threads = new List <Thread>(); for (int i = 0; i < Environment.ProcessorCount; ++i) { threads.Add(new Thread(() => { RunDiversion(handle, args[2], args[3]); })); threads.Last().Start(); } foreach (var dt in threads) { dt.Join(); } WinDivert.WinDivertClose(handle); }