Skip to content

Instantly share code, notes, and snippets.

@olliencc
Last active July 4, 2020 16:20
Show Gist options
  • Save olliencc/c2432972ea46bc3eca99b5dc382ef371 to your computer and use it in GitHub Desktop.
Save olliencc/c2432972ea46bc3eca99b5dc382ef371 to your computer and use it in GitHub Desktop.
########################################################################
#
# Thinkst Canary user module
# to turn into a high interactive honeypot
# https://canary.tools/
#
# Ingrediants used:
# - WSL
# - Developer documentation - https://canary.tools/help/user-modules
# - Opencanary for development - https://github.com/thinkst/opencanary/
# - Twisted proxy - https://gist.github.com/fiorix/1878983
#
#
########################################################################
INCIDENT_NAME = "CANARYPROXY"
VERSION = "0.2"
MODULE_DESCRIPTION = "CANARYPROXY"
AUTHOR = "Ollie Whitehouse"
AUTHOR_EMAIL = "ollie.whitehouse@nccgroup.com"
# Configuration for the TCP proxy
serverport = 823
clienthost = "towel.blinkenlights.nl"
clientport = 23
proxydesc = "Telnet Starwars Proxy"
from opencanary.modules import CanaryService
from twisted.internet import ssl,reactor, protocol, defer
from twisted.internet.protocol import Protocol
from twisted.internet.protocol import Factory
from twisted.internet.protocol import ClientCreator
from twisted.internet.protocol import ClientFactory
from twisted.application import internet
from pprint import pprint
from inspect import getmembers
# Proxy client
class ProxyClientProtocol(protocol.Protocol):
def connectionMade(self):
self.cli_queue = self.factory.cli_queue
self.cli_queue.get().addCallback(self.serverDataReceived)
def serverDataReceived(self, chunk):
if chunk is False:
self.cli_queue = None
self.factory.continueTrying = False
self.transport.loseConnection()
elif self.cli_queue:
self.transport.write(chunk)
self.cli_queue.get().addCallback(self.serverDataReceived)
else:
self.factory.cli_queue.put(chunk)
def dataReceived(self, chunk):
self.factory.srv_queue.put(chunk)
def connectionLost(self, why):
if self.cli_queue:
self.cli_queue = None
# Proxy client Twisted Factory
class ProxyClientFactory(protocol.ReconnectingClientFactory):
maxDelay = 10
continueTrying = True
protocol = ProxyClientProtocol
def __init__(self, srv_queue, cli_queue):
self.srv_queue = srv_queue
self.cli_queue = cli_queue
# Proxy server protocol handler class
class ProxyServer(protocol.Protocol):
# Constructor
def __init__(self, clienthost=None, clientport=None):
self.srv_queue = defer.DeferredQueue()
self.cli_queue = defer.DeferredQueue()
self.srv_queue.get().addCallback(self.clientDataReceived)
print(clienthost)
print(clientport)
self.factoryclient = ProxyClientFactory(self.srv_queue, self.cli_queue)
# Connection handled
# - we connect to the actual end server here
def connectionMade(self):
reactor.connectTCP(clienthost, clientport, self.factoryclient)
logdata = {"DESCRIPTION": INCIDENT_NAME, "Proxy" : proxydesc}
self.factory.canaryservice.log(logdata, transport=self.transport)
def clientDataReceived(self, chunk):
self.transport.write(chunk)
self.srv_queue.get().addCallback(self.clientDataReceived)
def dataReceived(self, chunk):
self.cli_queue.put(chunk)
def connectionLost(self, why):
self.cli_queue.put(False)
# Main class used as the entry point
class canaryproxy(Factory, CanaryService):
NAME = 'canaryproxy'
# Constructor
def __init__(self, config=None, logger=None):
CanaryService.__init__(self, config=config, logger=logger)
# Configuration passed to us on which interface to listen
self.listen_addr = config.getVal('device.listen_addr', default='')
# Log type
self.logtype = logger.LOG_USER_2
# This returns the service it wants
def getService(self):
# Build our protocol factory
f = protocol.ServerFactory()
f.canaryservice=self
f.logger=self.logger
f.protocol=ProxyServer # this is our protocol handler class defined above
# Return the server object
return internet.TCPServer(serverport, f, interface=self.listen_addr)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment