mirror of https://github.com/n1nj4sec/pupy.git
Add more checks to DNSCNC server
[+] Omit non-A requests. SOA and DS will bombard server in stealth mode [+] Check that nonce is growing, or at least the same. Because of size, our AES-CTR scheme usage is insecure to CPA. While we really don't care about that, lets check at least that nobody plays with nonces. Growing nonce will kill the channel withing timeout time range.
This commit is contained in:
parent
240c503769
commit
fe2d6b3fcb
|
@ -29,6 +29,8 @@ class Session(object):
|
||||||
self._last_access = 0
|
self._last_access = 0
|
||||||
self.system_info = None
|
self.system_info = None
|
||||||
self.commands = commands
|
self.commands = commands
|
||||||
|
self.last_nonce = None
|
||||||
|
self.last_qname = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def idle(self):
|
def idle(self):
|
||||||
|
@ -321,6 +323,11 @@ class DnsCommandServerHandler(BaseResolver):
|
||||||
qname = request.q.qname
|
qname = request.q.qname
|
||||||
reply = request.reply()
|
reply = request.reply()
|
||||||
|
|
||||||
|
if request.q.qtype != QTYPE.A:
|
||||||
|
reply.header.rcode = RCODE.NXDOMAIN
|
||||||
|
logging.debug('Request unknown qtype: {}'.format(QTYPE.get(request.q.qtype)))
|
||||||
|
return reply
|
||||||
|
|
||||||
# TODO:
|
# TODO:
|
||||||
# Resolve NS?, DS, SOA somehow
|
# Resolve NS?, DS, SOA somehow
|
||||||
if not qname.matchSuffix(self.domain):
|
if not qname.matchSuffix(self.domain):
|
||||||
|
@ -342,10 +349,25 @@ class DnsCommandServerHandler(BaseResolver):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
request, session, nonce = self._q_page_decoder(qname)
|
request, session, nonce = self._q_page_decoder(qname)
|
||||||
|
if session and session.last_nonce:
|
||||||
|
if nonce < session.last_nonce:
|
||||||
|
logging.error('Ignore nonce from past: {} < {}'.format(
|
||||||
|
nonce, session.last_nonce))
|
||||||
|
reply.header.rcode = RCODE.NXDOMAIN
|
||||||
|
return reply
|
||||||
|
elif session.last_nonce == nonce and session.last_qname != qname:
|
||||||
|
logging.error('Last nonce but different qname: {} != {}'.format(
|
||||||
|
session.last_qname, qname))
|
||||||
|
reply.header.rcode = RCODE.NXDOMAIN
|
||||||
|
return reply
|
||||||
|
|
||||||
for command in Parcel.unpack(request):
|
for command in Parcel.unpack(request):
|
||||||
for response in self._cmd_processor(command, session):
|
for response in self._cmd_processor(command, session):
|
||||||
responses.append(response)
|
responses.append(response)
|
||||||
|
|
||||||
|
if session:
|
||||||
|
session.last_nonce = nonce
|
||||||
|
|
||||||
except DnsCommandServerException as e:
|
except DnsCommandServerException as e:
|
||||||
nonce = e.nonce
|
nonce = e.nonce
|
||||||
responses = [e.error, Policy(self.interval, self.kex), Poll()]
|
responses = [e.error, Policy(self.interval, self.kex), Poll()]
|
||||||
|
|
Loading…
Reference in New Issue