コード例 #1
0
        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);
                }
            }
        }
コード例 #2
0
        /// <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);
        }
コード例 #3
0
 protected async Task RedirectQuestrionToMasterServer(DNSFrame frame)
 {
     socket.SendTo(frame.data, RemoteServer);
     await Task.Run(() =>
     {
         Thread.Sleep(Timeout);
     });
 }
コード例 #4
0
        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);
        }
コード例 #5
0
        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);
        }
コード例 #6
0
 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);
     }
 }
コード例 #7
0
        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);
        }
コード例 #8
0
        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);
            });
        }
コード例 #9
0
        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);
        }
コード例 #10
0
        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);
            }
        }
コード例 #11
0
        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;
            }
        }
コード例 #12
0
        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);
            }
        }
コード例 #13
0
 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);
     }
 }
コード例 #14
0
        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());
        }
コード例 #15
0
        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);
        }
コード例 #16
0
        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);
            }
        }
コード例 #17
0
        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);
        }
コード例 #18
0
        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);
        }
コード例 #19
0
 protected abstract void ResolveResponse(DNSFrame frame);
コード例 #20
0
 protected abstract void ResolveQuestion(DNSFrame frame, EndPoint sender);
コード例 #21
0
        /// <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);
                                }
                            }
                        }
                    }
                }
            }
        }