protected override void ResolveResponse(DNSFrame frame) { foreach (var record in frame.Question.Records) { if (frame.FrameHeader.AdditionalCount > 0 && frame.FrameHeader.NameServerCount > 0) { helper.HelpResolveResponse(frame); } var dataForCache = new List <Record>(); foreach (var answerRecord in frame.Answer.Records) { if (answerRecord.Name == record.Name) { dataForCache.Add(answerRecord); } } if (!Cache.ContainsKey(record.Name)) { Cache.TryAdd(record.Name, new CasheValue(dataForCache)); } else { Cache[record.Name] = new CasheValue(dataForCache); } } }
/// <summary> /// Checks for DNS frames in this frame and spoofes the response, if a response entry does match /// </summary> /// <param name="fInputFrame">The frame to handle</param> /// <returns>The modified frame</returns> protected override Frame ModifyTraffic(Frame fInputFrame) { if (!bPause) { IPFrame ipFrame = GetIPFrame(fInputFrame); UDPFrame udpFrame = GetUDPFrame(fInputFrame); DNSFrame dnsFrame = (DNSFrame)GetFrameByType(fInputFrame, FrameTypes.DNS); if (dnsFrame != null && ipFrame != null) { if (dnsFrame.QRFlag) { foreach (DNSResourceRecord r in dnsFrame.GetAnswers()) { ProcessDNSRecord(r, ipFrame.DestinationAddress); } foreach (DNSResourceRecord r in dnsFrame.GetAuthorotives()) { ProcessDNSRecord(r, ipFrame.DestinationAddress); } foreach (DNSResourceRecord r in dnsFrame.GetAdditionals()) { ProcessDNSRecord(r, ipFrame.DestinationAddress); } } if (udpFrame != null) { udpFrame.Checksum = new byte[2]; //Empty checksum } } } return(fInputFrame); }
protected async Task RedirectQuestrionToMasterServer(DNSFrame frame) { socket.SendTo(frame.data, RemoteServer); await Task.Run(() => { Thread.Sleep(Timeout); }); }
public void HelpResolveResponse(DNSFrame frame) { var newDns = new DNSFrame(); newDns.Answer = frame.Authority; newDns.Additional = frame.Additional; newDns.data = frame.data; newDns.Question = frame.Question; ResolveResponse(newDns); }
private void SendSuccessfulResponse(DNSFrame dnsFrame, ExtensionResourceRecords answer, EndPoint ipAddress) { var responseFrame = dnsFrame; responseFrame.Header.QR = 1; responseFrame.Header.ANCOUNT = (ushort)answer.Records.Count; responseFrame.Answers = answer; var frameAsBytes = Converter.DnsFrameToByte(responseFrame); socket.SendTo(frameAsBytes, ipAddress); }
private void SendBadResponse(DNSFrame dnsFrame, EndPoint ipAddress) { dnsFrame.Header.RCODE = 2; try { socket.SendTo(Converter.DnsFrameToByte(dnsFrame), ipAddress); } catch (Exception e) { Logger.LogError(e.Message, dnsFrame); } }
private async void ResolveQuestion(DNSFrame dnsFrame, EndPoint ipAddress) { var answer = new ExtensionResourceRecords(); foreach (var question in dnsFrame.Questions.Records) { var source = DomainToIp; //Console.WriteLine(question.QType + "<-QType"); if (question.QType == 12) { //Console.WriteLine("12"); source = IpToDomain; } if (source.ContainsKey(question.DomainName)) { var responces = source[question.DomainName]; foreach (var responce in responces) { var dnsResponce = new Record(question, responce); answer.Records.Add(dnsResponce); } } else { //Если в кэше нет данных, то делать запрос к вышестоящиму серверу //делаьь это нужно ассинхронно, т.е awat void у этого метода т.к нам не //важен резульатат, и если таймаут истёк, ну шо поделать отправляем клиенту //наши сожиления по этому поводу await SendQueryAsync(dnsFrame); if (!source.ContainsKey(question.DomainName)) { SendBadResponse(dnsFrame, ipAddress); break; } var responces = source[question.DomainName]; foreach (var responce in responces) { var dnsResponce = new Record(question, responce); answer.Records.Add(dnsResponce); } } } SendSuccessfulResponse(dnsFrame, answer, ipAddress); }
private async Task SendQueryAsync(DNSFrame dnsFrame) { try { socket.SendTo(dnsFrame.FrameAsByte, remoteServer); } catch (Exception e) { Logger.LogError(e.Message, dnsFrame); } await Task.Run(() => { Thread.Sleep(timeout); }); }
private void ResolveNsRecord(DNSFrame dnsFrame, Record answer, int numberAnswer) { var queryFrame = new DNSFrame { Header = dnsFrame.Header }; queryFrame.Header.QR = 0; queryFrame.Questions = new ResourceRecords { Records = new List <Record>() { new Record(answer.DomainName, dnsFrame.Questions.Records[numberAnswer].QType, answer.QClass, answer.Ttl) } }; ResolveQuestion(dnsFrame, socket.LocalEndPoint); }
protected override async void ResolveQuestion(DNSFrame frame, EndPoint sender) { foreach (var question in frame.Question.Records) { if (Cashe.ContainsKey(question.Name)) { SendResponce(frame, Cashe[question.Name], sender, question); continue; } await RedirectQuestrionToMasterServer(frame); if (!Cashe.ContainsKey(question.Name)) { continue; } SendResponce(frame, Cashe[question.Name], sender, question); } }
protected override void ResolveResponse(DNSFrame frame) { var questionPos = 12; foreach (var question in frame.Question.Records) { var answers = new List <Record>(); var additionals = new List <Record>(); if (Cashe.ContainsKey(question.Name)) { continue; } var pointer = frame.sizeOfHeader + question.LengthRecord + 49152; foreach (var answer in frame.Answer.Records) { if (answer.Name != question.Name) { continue; } answers.Add(answer); answer.CompressionPointer = (ushort)(questionPos + 49152); var name = GetName(answer.PointerToData, frame.data); answer.Data = ConvertData(name); answer.LengthRecord -= answer.DataLenght; answer.DataLenght = (ushort)(name.Count() + 2); answer.LengthRecord += answer.DataLenght; pointer += answer.LengthRecord; foreach (var record in frame.Additional.Records) { if (DeleteDot(name) != record.Name) { continue; } record.CompressionPointer = (ushort)(pointer - answer.DataLenght); additionals.Add(record); } } Cashe.TryAdd(question.Name, new Pair(answers, additionals)); questionPos += question.LengthRecord; } }
public void Updata(DNSFrame frame, EndPoint sender) { foreach (var record in frame.Question.Records) { if (record.QType != QType) { return; } } if (frame.FrameHeader.FrameFlags.isResponse) { ResolveResponse(frame); } else { ResolveQuestion(frame, sender); } }
private void Listen() { while (serverIsOn) { EndPoint clientIpPoint = new IPEndPoint(IPAddress.None, 53); var buffer = new byte[4096]; var countReceiveData = socket.ReceiveFrom(buffer, ref clientIpPoint); var dnsFrame = new DNSFrame(buffer.Take(countReceiveData).ToArray()); if (dnsFrame.Header.QR == 0) { // Console.WriteLine("Query"); Logger.Log(dnsFrame); ResolveQuestion(dnsFrame, clientIpPoint); continue; } Logger.Log(dnsFrame); ResolveResponce(dnsFrame); } }
public static byte[] ToByte(DNSFrame frame) { var sequence = new List <byte>(); sequence.AddRange(GetHeaderAsByte(frame.FrameHeader)); sequence.AddRange(frame.data.Skip(frame.sizeOfHeader).Take(frame.Question.LenghtResource)); if (frame.FrameHeader.AnswerCount > 0) { sequence.AddRange(GetDataFromRecords(frame.Answer)); } if (frame.FrameHeader.NameServerCount > 0) { sequence.AddRange(GetDataFromRecords(frame.Authority)); } if (frame.FrameHeader.AdditionalCount > 0) { sequence.AddRange(GetDataFromRecords(frame.Additional)); } return(sequence.ToArray()); }
private void SendResponse(DNSFrame frame, List <Record> answers, EndPoint sender) { var responseFrame = new DNSFrame(); responseFrame.Question = frame.Question; responseFrame.FrameHeader = frame.FrameHeader; responseFrame.FrameHeader.FrameFlags.isResponse = true; responseFrame.FrameHeader.AnswerCount = (ushort)answers.Count; responseFrame.FrameHeader.NameServerCount = 0; responseFrame.FrameHeader.AdditionalCount = 0; var offset = (ushort)frame.sizeOfHeader; responseFrame.Answer = new Resource(); responseFrame.data = frame.data; for (int i = 0; i < answers.Count; i++) { responseFrame.Answer.Records.Add(answers[i]); } socket.SendTo(DNSFrameConverter.ToByte(responseFrame), sender); }
private void ResolveResponce(DNSFrame dnsFrame) { var answers = dnsFrame.Answers != null ? dnsFrame.Answers.Records : dnsFrame.AuthorityRecords.Records; for (int i = 0; i < answers.Count; i++) { Console.WriteLine(answers[i].Ttl + "<--ttl"); var answer = answers[i]; if (answer.QType == 1) { AddNewPairInDomainToIp(answer); continue; } if (answer.QType == 12) { AddNewPairInIpToDomain(answer); continue; } ResolveNsRecord(dnsFrame, answer, i); } }
protected override async void ResolveQuestion(DNSFrame frame, EndPoint sender) { var answers = new List <Record>(); foreach (var record in frame.Question.Records) { if (Cache.ContainsKey(record.Name)) { answers = Cache[record.Name].Records; continue; } await RedirectQuestrionToMasterServer(frame); if (!Cache.ContainsKey(record.Name)) { return; } answers = Cache[record.Name].Records; } SendResponse(frame, answers, sender); }
private void SendResponce(DNSFrame frame, Pair answer, EndPoint sender, Record question) { var newFrame = new DNSFrame(); newFrame.Question = new Resource(); newFrame.Question.LenghtResource = question.LengthRecord; newFrame.Question.Records = new List <Record>() { question }; newFrame.FrameHeader = frame.FrameHeader; newFrame.FrameHeader.FrameFlags.isResponse = true; newFrame.Answer = new Resource { Records = answer.Answer }; newFrame.Additional = new Resource { Records = answer.Additional }; newFrame.FrameHeader.AnswerCount = (ushort)answer.Answer.Count; newFrame.FrameHeader.AdditionalCount = (ushort)answer.Additional.Count; newFrame.data = frame.data; socket.SendTo(DNSFrameConverter.ToByte(newFrame), sender); }
protected abstract void ResolveResponse(DNSFrame frame);
protected abstract void ResolveQuestion(DNSFrame frame, EndPoint sender);
/// <summary> /// Checks whether the input frame contains a DNS component. /// If it contains a DNS frame, the DNS frame will be parsed and logged /// </summary> /// <param name="fInputFrame">The frame to analyze</param> protected override void HandleTraffic(Frame fInputFrame) { UDPFrame fUDP = GetUDPFrame(fInputFrame); IPFrame ipFrame = GetIPFrame(fInputFrame); DNSFrame dFrame = (DNSFrame)GetFrameByType(fInputFrame, FrameTypes.DNS); if (fUDP != null && ipFrame != null && dFrame != null) { bool bFound = false; foreach (DNSItem di in lLog) { foreach (DNSQuestion qs in dFrame.GetQuestions()) { if ((di.QueryingHost.Equals(ipFrame.SourceAddress) || di.QueryingHost.Equals(ipFrame.DestinationAddress)) && di.TransactionID == dFrame.Identifier && di.QueryName == qs.Query && !di.TransactionComplete) { bFound = true; } } } if (!bFound) { foreach (DNSQuestion qs in dFrame.GetQuestions()) { DNSItem dsItem; if (dFrame.QRFlag) { dsItem = new DNSItem(qs.Query, ipFrame.DestinationAddress, ipFrame.SourceAddress, TimeSpan.Zero, dFrame.Identifier); } else { dsItem = new DNSItem(qs.Query, ipFrame.SourceAddress, ipFrame.DestinationAddress, TimeSpan.Zero, dFrame.Identifier); } AddLogItem(dsItem); } } if (dFrame.QRFlag) { foreach (DNSItem dsItem in lLog) { if (dFrame.Identifier == dsItem.TransactionID && !dsItem.TransactionComplete) { foreach (DNSResourceRecord rr in dFrame.GetAnswers()) { if (rr.Type == DNSResourceType.CNAME) { if (rr.Name == dsItem.QueryName) { string strTMPName = ASCIIEncoding.ASCII.GetString(rr.ResourceData); foreach (DNSResourceRecord rr2 in dFrame.GetAnswers()) { if (rr2.Type == DNSResourceType.A && rr2.Name == strTMPName) { IPAddress ipa = new IPAddress(rr2.ResourceData); if (!dsItem.ContainsAnswer(ipa)) { dsItem.AddAnswer(ipa); } dsItem.ChacheTime = new TimeSpan(0, 0, rr2.TTL); dsItem.TransactionComplete = true; dsItem.AnsweringServer = ipFrame.SourceAddress; InvokeUpdated(dsItem); } } } } if (rr.Type == DNSResourceType.A && rr.Name == dsItem.QueryName) { IPAddress ipa = new IPAddress(rr.ResourceData); if (!dsItem.ContainsAnswer(ipa)) { dsItem.AddAnswer(ipa); } dsItem.ChacheTime = new TimeSpan(0, 0, rr.TTL); dsItem.AnsweringServer = ipFrame.SourceAddress; dsItem.TransactionComplete = true; InvokeUpdated(dsItem); } } } } } } }