Пример #1
0
class HTTPService(ServiceBaseModel):
    now = datetime.now()
    timeNow = time.mktime(now.timetuple())

    responseHeadersOkStatus = Config.http.response_headers
    responseHeadersForbidden = {'Date': format_date_time(timeNow)}
    responseHeadersNotFound = {
        'Date': format_date_time(timeNow),
        'Content-Type': 'text/html; charset=UTF-8'
    }
    okStatus = "HTTP/1.1 200 OK"
    forbiddenStatus = "HTTP/1.1 403 Forbidden"
    notFoundStatus = "HTTP/1.1 404 Not Found"
    htdb = HoneytokenDataBase("HTTP")
    html_dictionary = Config.http.html_dictionary_content
    supportedSites = []

    def __init__(self):
        super(HTTPService, self).__init__()

        self._name = Config.http.name
        self._port = Config.http.port
        self._limiter = Limiter(self._fService, Config.http.name,
                                Config.http.connections_per_host)

        self.protocol = HTTPProtocol
        self._fService.protocol = self.protocol

    def startService(self):
        try:
            self._stop = False
            self._transport = reactor.listenTCP(self._port,
                                                self._fService,
                                                interface=self._address)

            sites = []
            for key in HTTPService.html_dictionary:
                sites.append(key)
            HTTPService.supportedSites = sites

        except Exception as e:
            self._stop = True

            raise e

    def stopService(self):
        self._stop = True
        self._transport.stopListening()
        try:
            self._transport.connectionLost(
                "Force close/cleanup due to next service scheduling")
        except AttributeError as err:
            log.err("HTTPService.connectionLost threw AttributeError: " + err)

    def parseHeaderLine(self, line):
        pdata = line.split(':', 1)[0]
        if (pdata == "Host"):
            return pdata
        elif (pdata == "Accept"):
            return pdata
Пример #2
0
class FTPService(ServiceBaseModel):

    credchecker = HoneytokenDataBase("FTP")
    # Make name and port accessible for logging in FTPProtocol
    _name = config.ftpName
    _port = config.ftpPort

    def __init__(self):

        super(FTPService, self).__init__()

        portal = Portal(FTPRealm('./'), [self.credchecker])

        self._fService = FTPFactory(portal)

        self._name = config.ftpName
        self._port = config.ftpPort

        self._limiter = Limiter(self._fService, self._name, config.FTP_conn_per_host)

        self.protocol = FTPProtocol
        self._fService.protocol = self.protocol

    def startService(self):
        self._stop = False
        self._transport = reactor.listenTCP(self._port, self._limiter)

    def stopService(self):
        self._stop = True
        self._transport.stopListening()
Пример #3
0
class SSHService(ServiceBaseModel):
    honeytokendb = HoneytokenDataBase(servicename=Config.ssh.name)

    def __init__(self):
        super(SSHService, self).__init__()

        self._name = Config.ssh.name
        self._port = Config.ssh.port

        p = Portal(SSHRealm())
        p.registerChecker(SSHService.honeytokendb)

        self._fService = factory.SSHFactory()
        self._fService.services[b'ssh-userauth'] = groveUserAuth

        self._limiter = Limiter(self._fService, Config.ssh.name,
                                Config.ssh.connections_per_host)

        self._fService.portal = p

        # self.protocol = SSHProtocol
        # self._fService.protocol = self.protocol
        home = expanduser('~')

        # XXX: These paths should be configurable
        privateKeyPath = home + '/.ssh/id_honeygrove'
        publicKeyPath = home + '/.ssh/id_honeygrove.pub'

        # Generate RSA keys if they don't exist
        if not (exists(privateKeyPath) and exists(publicKeyPath)):
            key = keys.rsa.generate_private_key(public_exponent=65537,
                                                key_size=4096,
                                                backend=default_backend())
            private_key = key.private_bytes(
                serialization.Encoding.PEM,
                serialization.PrivateFormat.TraditionalOpenSSL,
                serialization.NoEncryption())
            public_key = key.public_key().public_bytes(
                serialization.Encoding.OpenSSH,
                serialization.PublicFormat.OpenSSH)

            # make .ssh directory, if it doesn't exist
            os.makedirs(dirname(publicKeyPath), exist_ok=True)

            with open(privateKeyPath, 'w') as f:
                f.write(private_key.decode())
            with open(publicKeyPath, 'w') as f:
                f.write(public_key.decode())

        self._fService.privateKeys = {
            b'ssh-rsa': keys.Key.fromFile(privateKeyPath)
        }
        self._fService.publicKeys = {
            b'ssh-rsa': keys.Key.fromFile(publicKeyPath)
        }
Пример #4
0
class HoneyTokenDBTest(unittest.TestCase):

    databasefile = 'testresources/testdatabase.txt'
    servicename = 'MyServiceName'
    sep = ':'

    def addCredentials(self, credstring):
        with open(self.databasefile, 'w') as file:
            file.write(credstring)

    def clearCredentials(self):
        with open(self.databasefile, 'w') as file:
            file.seek(0)

    def setUp(self):
        HoneytokenDataBase.filepath = self.databasefile
        self.db = HoneytokenDataBase(self.servicename)

    def test_validCreds(self):
        username = '******'
        pw = 'pass'
        c = credentials.UsernamePassword(username, pw)

        # Write them to Database
        credstring = self.servicename + self.sep + username + self.sep + pw + self.sep
        self.addCredentials(credstring)

        # Make sure you got UserName back ==> creds are valid
        actual = self.db.requestAvatarId(c).result
        self.assertEqual(username, actual)

        # Delete creds from file
        self.clearCredentials()

    def test_inValidCreds(self):
        c = credentials.UsernamePassword('idontexist', 'hahahahah')
        actual = self.db.requestAvatarId(c).result.value
        self.assertTrue(isinstance(actual, UnauthorizedLogin))
Пример #5
0
class FTPService(ServiceBaseModel):

    credchecker = HoneytokenDataBase("FTP")
    # Make name and port accessible for logging in FTPProtocol
    _name = Config.ftp.name
    _port = Config.ftp.port

    def __init__(self):

        super(FTPService, self).__init__()

        portal = Portal(FTPRealm('./'), [self.credchecker])

        self._fService = FTPFactory(portal)

        self._name = Config.ftp.name
        self._port = Config.ftp.port

        self._limiter = Limiter(self._fService, self._name,
                                Config.ftp.connections_per_host)

        self.protocol = FTPProtocol
        self._fService.protocol = self.protocol
Пример #6
0
class SSHService(ServiceBaseModel):
    c = HoneytokenDataBase(servicename=config.sshName)

    def __init__(self):
        super(SSHService, self).__init__()

        self._name = config.sshName
        self._port = config.sshPort

        p = Portal(SSHRealm())
        p.registerChecker(SSHService.c)

        self._fService = factory.SSHFactory()
        self._fService.services[b'ssh-userauth'] = groveUserAuth

        self._limiter = Limiter(self._fService, config.sshName,
                                config.SSH_conn_per_host)

        self._fService.portal = p

        # self.protocol = SSHProtocol
        # self._fService.protocol = self.protocol
        home = expanduser('~')

        privateKeyPath = home + '/.ssh/id_rsa'
        publicKeyPath = home + '/.ssh/id_rsa.pub'

        # Generate RSA keys if they don't exist

        if not (exists(privateKeyPath) and exists(publicKeyPath)):
            key = keys.rsa.generate_private_key(public_exponent=65537,
                                                key_size=2048,
                                                backend=default_backend())
            private_key = key.private_bytes(
                serialization.Encoding.PEM,
                serialization.PrivateFormat.TraditionalOpenSSL,
                serialization.NoEncryption())
            public_key = key.public_key().public_bytes(
                serialization.Encoding.OpenSSH,
                serialization.PublicFormat.OpenSSH)

            # make .ssh directory, if it doesn't exist
            os.makedirs(dirname(publicKeyPath), exist_ok=True)

            with open(privateKeyPath, 'w') as f:
                f.write(private_key.decode())
            with open(publicKeyPath, 'w') as f:
                f.write(public_key.decode())

        self._fService.privateKeys = {
            b'ssh-rsa': keys.Key.fromFile(privateKeyPath)
        }
        self._fService.publicKeys = {
            b'ssh-rsa': keys.Key.fromFile(publicKeyPath)
        }

    def startService(self):
        self._stop = False
        self._transport = reactor.listenTCP(self._port, self._limiter)

    def stopService(self):
        self._stop = True
        self._transport.stopListening()
Пример #7
0
class HTTPService(ServiceBaseModel):
    now = datetime.now()
    timeNow = time.mktime(now.timetuple())

    responseHeadersOkStatus = config.httpResponseHeader
    responseHeadersForbidden = {'Date': format_date_time(timeNow)}
    responseHeadersNotFound = {'Date': format_date_time(timeNow),
                               'Content-Type': 'text/html; charset=UTF-8'}
    okStatus = "HTTP/1.1 200 OK"
    forbiddenStatus = "HTTP/1.1 403 Forbidden"
    notFoundStatus = "HTTP/1.1 404 Not Found"
    htdb = HoneytokenDataBase("HTTP")
    port = ""
    resourceLocation = config.resources + '/http_resources/'
    supportedSites = []

    def __init__(self):
        super(HTTPService, self).__init__()
        self._name = config.httpName
        self._port = config.httpPort
        self._fService.protocol = self.protokoll
        HTTPService.port = self._port

    # -----Protokoll----#
    class protokoll(Protocol):

        def __init__(self):
            self.state = None

            self.peerOfAttacker = ""
            self.page = ""
            self.path = config.resources
            self.attackingSite = ""
            self.loginSuccessfulSite = ""
            self.notFoundSite = ""
            self.requestType = ""
            self.short = ""

        def connectionMade(self):
            # Aktuelle Verbindung zum Dict hinzufügen
            self.factory.clients[self] = ("<" + str(self.transport.getPeer().host) + ":" \
                                          + str(self.transport.getPeer().port) + ">")
            self.peerOfAttacker = self.transport.getPeer().host

        def dataReceived(self, data):
            from honeygrove.services.HTTPService import HTTPService

            data = data.decode('utf-8')

            self.requestType = data.split(' ', 1)[0]

            if self.requestType == "GET":
                self.page = data[data.find("GET ") + 4: data.find(" HTTP/1.1")]
            elif self.requestType == "POST":
                self.page = data[data.find("POST ") + 5: data.find(" HTTP/1.1")]

            pageNotFound = True

            for serviceLink in HTTPService.supportedSites:
                if self.page == serviceLink:
                    pageNotFound = False
                    self.attackingSite = HTTPService.resourceLocation + config.httpHTMLDictionary[serviceLink][0]
                    if config.httpHTMLDictionary[serviceLink].__len__() > 1:
                        self.loginSuccessfulSite = HTTPService.resourceLocation + \
                                                   config.httpHTMLDictionary[serviceLink][1]
                    else:
                        self.loginSuccessfulSite = HTTPService.resourceLocation + config.httpHTMLDictionary['404'][0]
                    self.short = serviceLink
                    break

            if pageNotFound:
                self.notFoundSite = HTTPService.resourceLocation + config.httpHTMLDictionary['404'][0]

            # Beantwortung von GET Requests
            if self.requestType == "GET" and (
                                                '.gif' in self.page or '.png' in self.page or '/dashboard_files/' in self.page or
                                        '.jpg' in self.page or '.woff' in self.page or '.ttf' in self.page or '.svg' in self.page):
                message = HTTPService.notFoundStatus + "\n"
                for k in HTTPService.responseHeadersNotFound.keys():
                    message = message + k + ": " + HTTPService.responseHeadersNotFound[k] + "\n"
                self.transport.write(message.encode('UTF-8'))
                self.transport.loseConnection()

            elif self.requestType == "GET" and self.page in HTTPService.supportedSites:

                log.request("HTTP", self.peerOfAttacker, HTTPService.port, self.page, "", "GET")

                message = HTTPService.okStatus + "\n"
                for k in HTTPService.responseHeadersOkStatus.keys():
                    message = message + k + ": " + HTTPService.responseHeadersOkStatus[k] + "\n"

                with  open(self.attackingSite, encoding='utf8') as file:
                    message = message + "\n" + file.read()

                self.transport.write(message.encode('UTF-8'))
                if self.page in HTTPService.supportedSites:
                    log.response("HTTP", self.peerOfAttacker, HTTPService.port, self.page, "", "200 OK")

                self.transport.loseConnection()

            # Beantwortung von POST Requests
            elif (self.requestType == "POST" and self.page in HTTPService.supportedSites):
                self.page = data[data.find("POST ") + 5: data.find(" HTTP/1.1")]
                login_string = ""
                password_string = ""
                login_index = data.find("log=") + 4
                if login_index == 3:
                    login_string = "fritz.box"
                else:
                    login_string = data[login_index:data.find("&")]
                password_index = data.find("pwd=") + 4
                if data[password_index:data.find("&")] != -1:
                    password_string = data[password_index:len(data)]
                else:
                    password_string = data[password_index:data.find("&")]

                log.request("HTTP", self.peerOfAttacker, HTTPService.port, self.page, login_string, "POST")
                result = HTTPService.htdb.requestAvatarId(HTTPAvatar(login_string, password_string))
                if isinstance(result, Deferred):
                    if isinstance(result.result, failure.Failure):  # Failure
                        result.addErrback(self.errorBack)
                        log.response("HTTP", self.peerOfAttacker, HTTPService.port, "", login_string, "403 FORBIDDEN")
                        log.login("HTTP", self.peerOfAttacker, HTTPService.port, False, login_string, password_string,
                                  str(HTTPService.htdb.getActual(login_string, password_string)))
                    else:  # Success
                        message = HTTPService.okStatus + "\n"
                        for k in HTTPService.responseHeadersOkStatus.keys():
                            message = message + k + ": " + HTTPService.responseHeadersOkStatus[k] + "\n"

                        with open(self.loginSuccessfulSite, encoding='utf8') as file:
                            message = message + "\n" + file.read()

                        self.transport.write(message.encode('UTF-8'))
                        self.page = "wp-admin_content.html"
                        log.response("HTTP", self.peerOfAttacker, HTTPService.port, self.page, login_string, "200 OK")
                        log.login("HTTP", self.peerOfAttacker, HTTPService.port, True, login_string, password_string,
                                  str(HTTPService.htdb.getActual(login_string, password_string)))
                        self.transport.loseConnection()
            else:
                message = HTTPService.notFoundStatus + "\n"
                for k in HTTPService.responseHeadersNotFound.keys():
                    message = message + k + ": " + HTTPService.responseHeadersNotFound[k] + "\n"

                with open(self.notFoundSite, encoding='utf8') as file:
                    message = message + "\n" + file.read()

                self.transport.write(message.encode('UTF-8'))
                log.request("HTTP", self.peerOfAttacker, HTTPService.port, self.page, "", "GET")
                self.page = "404_login.html"
                log.response("HTTP", self.peerOfAttacker, HTTPService.port, self.page, "", "404 Not Found")
                self.transport.loseConnection()

        def connectionLost(self, reason):
            # Delete client from dict.
            del self.factory.clients[self]

        def errorBack(self, f):
            f.trap(error.UnauthorizedLogin)

            message = HTTPService.forbiddenStatus + "\n"
            for k in HTTPService.responseHeadersForbidden.keys():
                message = message + k + ": " + HTTPService.responseHeadersForbidden[k] + "\n"

            with open(self.attackingSite, encoding='utf8') as file:
                message = message + "\n" + file.read()

            self.transport.write(message.encode('UTF-8'))
            self.transport.loseConnection()

    def startService(self):
        try:
            self._stop = False
            self._transport = reactor.listenTCP(self._port, self._fService)

            sites = []
            for key in config.httpHTMLDictionary:
                sites.append(key)
            HTTPService.supportedSites = sites

        except Exception as e:
            self._stop = True

            raise e

    def stopService(self):
        self._stop = True
        self._transport.stopListening()
        try:
            self._transport.connectionLost("Force close/cleanup due to next service scheduling")
        except AttributeError:
            log.err("HTTPService connectionLost wirft AttributeError!")

    def parseHeaderLine(self, line):
        pdata = line.split(':', 1)[0]
        if (pdata == "Host"):
            return pdata
        elif (pdata == "Accept"):
            return pdata
Пример #8
0
 def setUp(self):
     HoneytokenDataBase.filepath = self.databasefile
     self.db = HoneytokenDataBase(self.servicename)