public void Route(Input input) { input = Common.InputFillParams(input); input = Common.RunFilters(InPacketFilters, input); if (input.TlType == TransportLayerType.Tcp) { IPEndPoint _client = new IPEndPoint(IPAddress.Parse(input.IPv4_source_ip), input.TCP_source_port); IPEndPoint _remote = new IPEndPoint(IPAddress.Parse(input.IPv4_destination_ip), input.TCP_destination_port); MitmSession mitm_session = ProvideMitm(input, _client, _remote); lock (mitm_session.deletion_locker) { Traffic.TcpRewriteSend(mitm_session, input); } return; } if (input.TlType == TransportLayerType.Udp) { IPEndPoint _client = new IPEndPoint(IPAddress.Parse(input.IPv4_source_ip), input.UDP_source_port); IPEndPoint _remote = new IPEndPoint(IPAddress.Parse(input.IPv4_destination_ip), input.UDP_destination_port); MitmSession mitm_session = ProvideMitm(input, _client, _remote); lock (mitm_session.deletion_locker) { Traffic.UdpRewriteSend(mitm_session, input); } return; } return; }
private MitmSession ProvideMitm(Input input, IPEndPoint client, IPEndPoint remote) { Zitm this_obj = this; MitmSession rmitm = mitmSessions.GetOrAdd( GetKey(client, remote), _ => { MitmSession mitm = Common.CreateMitmSession(input, this_obj); if (input.TlType == TransportLayerType.Udp) { Task.Run(() => Traffic.T_UdpReceiver(mitm)); } if (input.TlType == TransportLayerType.Tcp) { Task.Run(() => Traffic.T_TcpReceiver(mitm)); } return(mitm); } ); return(rmitm); }
public static void UdpRewriteSend(MitmSession session, Input input) { session.r_allow.WaitOne(); byte[] packet = input.received_packet; packet = Common.RewriteIpHeader(packet, session.local.Address, RewriteType.Source); packet = Common.RewriteUdpHeader(packet, (ushort)session.local.Port, RewriteType.Source); bool succ = WinDivert.WinDivertSend(session.forward_handle, new WinDivertBuffer(packet), (uint)packet.Length, ref session.addr_send); return; }
public void RemoveSession(MitmSession session) { MitmSession unused; mitmSessions.TryRemove(GetKey(session.client, session.remote), out unused); lock (session.deletion_locker) { WinDivert.WinDivertClose(session.forward_handle); session.binded_socket.Close(); WinDivert.WinDivertClose(session.listener_handle); session.listener_buffer.Dispose(); } return; }
public static byte[] TcpRewriteRecv(MitmSession session) { bool succ = WinDivert.WinDivertRecv(session.listener_handle, session.listener_buffer, ref session.addr_recv); UInt16 ulen = BitConverter.ToUInt16(new byte[2] { session.listener_buffer[3], session.listener_buffer[2] }, 0); byte[] packet = new byte[ulen]; for (int i = 0; i < ulen; ++i) { packet[i] = session.listener_buffer[i]; } packet = Common.RewriteIpHeader(packet, session.client.Address, RewriteType.Destination); packet = Common.RewriteTcpHeader(packet, (ushort)session.client.Port, RewriteType.Destination); return(packet); }
public static void T_TcpReceiver(MitmSession session) { session.r_allow.Set(); for (; ;) { byte[] packet = new byte[0]; IAsyncResult result; Action action = () => { packet = TcpRewriteRecv(session); }; result = action.BeginInvoke(null, null); if (result.AsyncWaitHandle.WaitOne(1000)) { Input output = new Input { received_packet = packet, time_received = DateTime.UtcNow, workSocket = session.workSocket }; session.zit.Response(output); Thread.Sleep(0); } else { break; } } session.zit.RemoveSession(session); return; }
//******************************************************************************// public static MitmSession CreateMitmSession(Input input, Zitm zit) { TransportLayerType tltype = input.TlType; if (tltype != TransportLayerType.Tcp && tltype != TransportLayerType.Udp) { throw new NotImplementedException(); } string stltype = ""; if (tltype == TransportLayerType.Tcp) { stltype = "tcp"; } if (tltype == TransportLayerType.Udp) { stltype = "udp"; } MitmSession ret = new MitmSession(); ret.tltype = tltype; ret.zit = zit; ret.r_allow = new System.Threading.ManualResetEvent(false); if (tltype == TransportLayerType.Tcp) { ret.client = new IPEndPoint( IPAddress.Parse(input.IPv4_source_ip), input.TCP_source_port); ret.remote = new IPEndPoint( IPAddress.Parse(input.IPv4_destination_ip), input.TCP_destination_port); Socket stcp = new Socket(zit._local.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp); IPEndPoint ep = new IPEndPoint(zit._local.Address, 0); stcp.Bind(ep); ret.local = new IPEndPoint( zit._local.Address, Common.GetPort(stcp)); ret.binded_socket = stcp; } if (tltype == TransportLayerType.Udp) { ret.client = new IPEndPoint( IPAddress.Parse(input.IPv4_source_ip), input.UDP_source_port); ret.remote = new IPEndPoint( IPAddress.Parse(input.IPv4_destination_ip), input.UDP_destination_port); Socket sudp = new Socket(zit._local.Address.AddressFamily, SocketType.Dgram, ProtocolType.Udp); IPEndPoint ep = new IPEndPoint(zit._local.Address, 0); sudp.Bind(ep); ret.local = new IPEndPoint( zit._local.Address, Common.GetPort(sudp)); ret.binded_socket = sudp; } ret.workSocket = input.workSocket; //***// ret.addr_send = new WinDivertAddress(); ret.addr_send.Reset(); ret.addr_send.Direction = WinDivertDirection.Outbound; ret.addr_recv = new WinDivertAddress(); ret.addr_recv.Reset(); ret.addr_recv.Direction = WinDivertDirection.Outbound; ret.forward_handle = WinDivert.WinDivertOpen("false", WinDivertLayer.Network, 0, WinDivertOpenFlags.None); //***// UInt32 ulocal_ip = Common.IpToUint32(ret.local.Address.ToString()); UInt32 uremote_ip = Common.IpToUint32(ret.remote.Address.ToString()); string filter = "ip.DstAddr == " + ulocal_ip.ToString() + " and ip.SrcAddr == " + uremote_ip.ToString() + " and " + stltype + ".DstPort == " + ret.local.Port.ToString() + " and " + stltype + ".SrcPort == " + ret.remote.Port.ToString(); ret.listener_handle = WinDivert.WinDivertOpen(filter, WinDivertLayer.Network, 0, WinDivertOpenFlags.None); ret.listener_buffer = new WinDivertBuffer(); return(ret); }