Example #1
0
    def handle_incident(self, icd):
        logger.debug("storing file")
        p = icd.path
        # ToDo: use sha1 or sha256
        md5 = md5file(p)
        # ToDo: use sys.path.join()
        n = os.path.join(self.download_dir, md5)
        i = incident("dionaea.download.complete.hash")
        i.file = n
        i.url = icd.url
        if hasattr(icd, 'con'):
            i.con = icd.con
        i.md5hash = md5
        i.report()

        try:
            os.stat(n)
            i = incident("dionaea.download.complete.again")
            logger.debug("file %s already existed" % md5)
        except OSError:
            logger.debug("saving new file %s to %s" % (md5, n))
            os.link(p, n)
            i = incident("dionaea.download.complete.unique")
        i.file = n
        if hasattr(icd, 'con'):
            i.con = icd.con
        i.url = icd.url
        i.md5hash = md5
        i.report()
Example #2
0
    def handle_incident(self, icd):
        logger.debug("storing file")
        p = icd.path
        md5 = md5file(p)
        n = g_dionaea.config()["downloads"]["dir"] + "/" + md5
        i = incident("dionaea.download.complete.hash")
        i.file = n
        i.url = icd.url
        if hasattr(icd, "con"):
            i.con = icd.con
        i.md5hash = md5
        i.report()

        try:
            f = os.stat(n)
            i = incident("dionaea.download.complete.again")
            logger.debug("file %s already existed" % md5)
        except OSError:
            logger.debug("saving new file %s to %s" % (md5, n))
            os.link(p, n)
            i = incident("dionaea.download.complete.unique")
        i.file = n
        if hasattr(icd, "con"):
            i.con = icd.con
        i.url = icd.url
        i.md5hash = md5
        i.report()
Example #3
0
    def handle_incident(self, icd):
        logger.debug("storing file")
        p = icd.path
        # ToDo: use sha1 or sha256
        md5 = md5file(p)
        # ToDo: use sys.path.join()
        n = os.path.join(self.download_dir, md5)
        i = incident("dionaea.download.complete.hash")
        i.file = n
        i.url = icd.url
        if hasattr(icd, 'con'):
            i.con = icd.con
        i.md5hash = md5
        i.report()

        try:
            os.stat(n)
            i = incident("dionaea.download.complete.again")
            logger.debug("file %s already existed" % md5)
        except OSError:
            logger.debug("saving new file %s to %s" % (md5, n))
            os.link(p, n)
            i = incident("dionaea.download.complete.unique")
        i.file = n
        if hasattr(icd, 'con'):
            i.con = icd.con
        i.url = icd.url
        i.md5hash = md5
        i.report()
Example #4
0
    def handle_incident(self, icd):
        logger.debug("storing file")
        p = icd.path
        md5 = md5file(p)
        n = g_dionaea.config()['downloads']['dir'] + '/' + md5
        i = incident("dionaea.download.complete.hash")
        i.file = n
        i.url = icd.url
        if hasattr(icd, 'con'):
            i.con = icd.con
        i.md5hash = md5
        i.report()

        try:
            f = os.stat(n)
            i = incident("dionaea.download.complete.again")
            logger.debug("file %s already existed" % md5)
        except OSError:
            logger.debug("saving new file %s to %s" % (md5, n))
            os.link(p, n)
            i = incident("dionaea.download.complete.unique")
        i.file = n
        if hasattr(icd, 'con'):
            i.con = icd.con
        i.url = icd.url
        i.md5hash = md5
        i.report()
Example #5
0
    def _handle_ABC(self, msg):
        handler_name = msg.method.decode("utf-8").upper()
        # check if Call-ID header exist
        if not msg.header_exist(b"call-id"):
            return

        # Get Call-Id and check if there's already a SipSession
        call_id = msg.headers.get(b"call-id").value

        # ToDo: remove? we don't use it
        # cseq = msg.headers.get(b"cseq").get_raw()

        # Find SipSession and delete it
        if call_id not in g_call_ids or g_call_ids[call_id] is None:
            logger.warn(
                "{!s} request does not match any existing SIP session".format(
                    handler_name))
            icd = incident("dionaea.modules.python.sip.command")
            icd.con = self
            msg_to_icd(msg, d=icd)
            icd.report()
            self.send(
                msg.create_response(
                    rfc3261.CALL_TRANSACTION_DOSE_NOT_EXIST).dumps())
            return

        try:
            g_call_ids[call_id].handle_msg_in(msg)
        except AuthenticationError:
            logger.warn(
                "Authentication failed for {!s} request".format(handler_name))
Example #6
0
    def handle_incident(self, icd):
        if icd.origin == 'dionaea.connection.tcp.pending':
            con = icd.con

            lhost = con.local.host
            rhost = con.remote.host

            # avoid connecting yourself
            if False and is_local_addr(rhost):
                logger.warn("avoid self connect")
                return

            # throttle incoming SYN's
            # else port scans will consume *many* sockets
            # and things go wild&bad

            now = int(time())
            nmt = now % self.throttle_window

            if self.window[nmt][0] != now:
                #				logger.debug("New Tick")
                # we got a new tick
                for i in range(self.throttle_window):
                    # for all other ticks
                    # check the tick is 'up2date'
                    # replace outdated ticks with 0
                    nmx = (now - i) % self.throttle_window
                    if self.window[nmx][0] != now - i:
                        #						logger.debug("Reset window {:d} (was {:d}".format(i,self.window[nmx][1]))
                        self.window[nmx] = [now - i, 0]

            total = sum([x[1] for x in self.window])
            if total > self.throttle_total:
                logger.warn("throttle total %i %s" % (total, rhost))
                icd.nfaction = self.throttle_nfaction
                return
            if self.window[nmt][1] > self.throttle_slot:
                logger.warn("throttle slot %i %s" %
                            (self.window[nmt][1], rhost))
                icd.nfaction = self.throttle_nfaction
                return

            # finally, start a service on the port
            m = nfqmirrord('tcp')
            m.timeouts.listen = self.mirror_server_timeout_listen
            m.timeouts.idle = self.mirror_client_timeout_idle
            m.timeouts.sustain = self.mirror_client_timeout_sustain

            m.bind(lhost, con.local.port)
            if m.listen() != True:
                m.close()
                return

            logger.info("doing nfq on port %i" % con.local.port)
            self.window[nmt] = [now, self.window[nmt][1] + 1]

            i = incident('dionaea.connection.link')
            i.parent = con
            i.child = m
            i.report()
Example #7
0
    def handle_established(self):
        self.processors()

        self.timeouts.sustain = 60
        self._in.accounting.limit = 200 * 1024
        self._out.accounting.limit = 200 * 1024

        if is_local_addr(self.remote.host) == False:
            self.peer = nfqmirrorc(self)
            # problem:
            # the parent connection just got accepted
            # we are in the established callback for this connection
            # this connection did not report its dionaea.connection.tcp.accept incident yet
            # therefore this connection is not 'known' to logsql yet
            # but we want to associate the incoming mirror connection with the outgoing mirror connection
            # therefore we claim this is an 'early' link
            # so logsql can notice this connection has a parent, but the parent is not known yet
            # once the parent is known, we logsql will update the parent record
            # for this connection
            i = incident('dionaea.connection.link.early')
            i.parent = self
            i.child = self.peer
            i.report()
        else:
            logger.warning("closing local connection from %s" %
                           self.remote.host)
            self.close()
Example #8
0
def detect_shellshock(connection, data, report_incidents=True):
    """
    Try to find Shellshock attacks, included download commands and URLs.

    :param connection: The connection object
    :param data: Data to analyse
    :param report_incidents:
    :return: List of urls or None
    """
    from dionaea.core import incident
    regex = re.compile(b"\(\)\s*\t*\{.*;\s*\}\s*;")
    if not regex.search(data):
        return None
    logger.debug("Shellshock attack found")

    urls = []
    regex = re.compile(
        b"(wget|curl).+(?P<url>(http|ftp|https)://([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?)"
    )
    for m in regex.finditer(data):
        logger.debug("Found download command with url %s", m.group("url"))
        urls.append(m.group("url"))
        if report_incidents:
            i = incident("dionaea.download.offer")
            i.con = connection
            i.url = m.group("url")
            i.report()

    return urls
Example #9
0
	def handle_incident_dionaea_modules_python_virustotal_get_file_report(self, icd):
		f = open(icd.path, mode='r')
		j = json.load(f)

		cookie = icd._userdata
		vtr = self.cookies[cookie]

		if j['response_code'] == -2:
			logger.warn("api throttle")
			self.cursor.execute("""UPDATE backlogfiles SET status = ? WHERE backlogfile = ?""", (vtr.status, vtr.backlogfile))
			self.dbh.commit()
		elif j['response_code'] == -1:
			logger.warn("something is wrong with your virustotal api key")
		elif j['response_code'] == 0: # file unknown
			# mark for submit
			if vtr.status == 'new':
				self.cursor.execute("""UPDATE backlogfiles SET status = 'submit', lastcheck_time = strftime("%s",'now') WHERE backlogfile = ?""", (vtr.backlogfile,))
			elif vtr.status == 'query':
				self.cursor.execute("""UPDATE backlogfiles SET lastcheck_time = strftime("%s",'now') WHERE backlogfile = ?""", (vtr.backlogfile,))
			self.dbh.commit()
		elif j['response_code'] == 1: # file known
#			self.cursor.execute("""UPDATE backlogfiles SET status = 'comment', lastcheck_time = strftime("%s",'now') WHERE backlogfile = ?""", (vtr.backlogfile,))
			self.cursor.execute("""DELETE FROM backlogfiles WHERE backlogfile = ?""", (vtr.backlogfile,) )
			self.dbh.commit()

			logger.debug("report {}".format(j) )
			date = j['scan_date']

			i = incident("dionaea.modules.python.virustotal.report")
			i.md5hash = vtr.md5hash
			i.path = icd.path
			i.report()
		else:
			logger.warn("virustotal reported {}".format(j))
		del self.cookies[cookie]
Example #10
0
    def handle_incident(self, icd):
        logger.debug("submitting file")

        for name, to in self.tos.items():
            urls = to.get("urls")
            if urls is None or len(urls) == 0:
                logger.warn("your configuration lacks urls to submit to %s",
                            name)
                continue

            for url in urls:
                i = incident("dionaea.upload.request")
                i._url = url

                # copy all values for this url
                field_values = to.get("field_values")
                if field_values is None:
                    field_values = {}
                for k, v in field_values.items():
                    i.set(k, v)

                file_fieldname = to.get("file_fieldname")
                if file_fieldname is not None:
                    i.set("file://%s" % file_fieldname, icd.file)

                i.report()
Example #11
0
    def handle_established(self):
        self.processors()

        self.timeouts.sustain = 60
        self._in.accounting.limit  = 200*1024
        self._out.accounting.limit = 200*1024

        if is_local_addr(self.remote.host) == False:
            self.peer=nfqmirrorc(self)
            # problem:
            # the parent connection just got accepted
            # we are in the established callback for this connection
            # this connection did not report its dionaea.connection.tcp.accept incident yet
            # therefore this connection is not 'known' to logsql yet
            # but we want to associate the incoming mirror connection with the outgoing mirror connection
            # therefore we claim this is an 'early' link
            # so logsql can notice this connection has a parent, but the parent is not known yet
            # once the parent is known, we logsql will update the parent record
            # for this connection
            i = incident('dionaea.connection.link.early')
            i.parent = self
            i.child = self.peer
            i.report()
        else:
            logger.warning("closing local connection from %s" %
                           self.remote.host)
            self.close()
Example #12
0
    def processcmd(self, cmd, args):
        logger.debug("cmd '%s'" % cmd)
        l = [i.decode() for i in args]

        i = incident("dionaea.modules.python.ftp.command")
        i.con = self
        i.command = cmd
        i.arguments = l
        i.report()

        cmd = cmd.upper()
        if self.state == self.UNAUTH:
            if cmd != b'USER':
                self.reply("not_logged_in")
                return
            self.ftp_USER(*l)
        elif self.state == self.INAUTH:
            if cmd != b'PASS':
                self.reply("bad_cmd_seq_pass_after_user")
                return
            self.ftp_PASS(*l)
        else:
            method = getattr(self, "ftp_" + cmd.decode(), None)
            if method is not None:
                msg = method(*l)
                if isinstance(msg, str):
                    self.error(
                        "Returning messages is deprecated please report so we can fix it"
                    )
                    self.sendline(msg)
            else:
                self.reply("cmd_not_implmntd", command=cmd.decode())
Example #13
0
def detect_shellshock(connection, data, report_incidents=True):
    """
    Try to find Shellshock attacks, included download commands and URLs.

    :param connection: The connection object
    :param data: Data to analyse
    :param report_incidents:
    :return: List of urls or None
    """
    from dionaea.core import incident
    regex = re.compile(b"\(\)\s*\t*\{.*;\s*\}\s*;")
    if not regex.search(data):
        return None
    logger.debug("Shellshock attack found")

    urls = []
    regex = re.compile(
        b"(wget|curl).+(?P<url>(http|ftp|https)://([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?)"
    )
    for m in regex.finditer(data):
        logger.debug("Found download command with url %s", m.group("url"))
        urls.append(m.group("url"))
        if report_incidents:
            i = incident("dionaea.download.offer")
            i.con = connection
            i.url = m.group("url")
            i.report()

    return urls
Example #14
0
    def download(self, con, host, port, filename, url):
        logger.info("Connecting to %s to download" % host)
        logger.info("    filename -> %s" % filename)

        if 'blksize' in self.options:
            size = self.options['blksize']
            if size < MIN_BLKSIZE or size > MAX_BLKSIZE:
                raise TftpException("Invalid blksize: %d" % size)
        else:
            self.options['blksize'] = DEF_BLKSIZE

        self.filename = filename
        self.port = port
        self.con = con
        self.url = url
        if con != None:
            self.bind(con.local.host, 0)
            self.con.ref()

        self.connect(host,0)
        if con != None:
            i = incident("dionaea.connection.link")
            i.parent = con
            i.child = self
            i.report()
Example #15
0
    def _handle_ABC(self, msg):
        handler_name = msg.method.decode("utf-8").upper()
        # check if Call-ID header exist
        if not msg.header_exist(b"call-id"):
            return

        # Get Call-Id and check if there's already a SipSession
        call_id = msg.headers.get(b"call-id").value

        # ToDo: remove? we don't use it
        # cseq = msg.headers.get(b"cseq").get_raw()

        # Find SipSession and delete it
        if call_id not in g_call_ids or g_call_ids[call_id] is None:
            logger.warn("{!s} request does not match any existing SIP session".format(handler_name))
            icd = incident("dionaea.modules.python.sip.command")
            icd.con = self
            msg_to_icd(msg,d=icd)
            icd.report()
            self.send(msg.create_response(rfc3261.CALL_TRANSACTION_DOSE_NOT_EXIST).dumps())
            return

        try:
            g_call_ids[call_id].handle_msg_in(msg)
        except AuthenticationError:
            logger.warn("Authentication failed for {!s} request".format(handler_name))
Example #16
0
File: http.py Project: jps3/dionaea
    def handle_POST(self):
        """
        Handle the POST method. Send the head and the file. But ignore the POST params.
        Use the bistreams for a better analysis.
        """
        if self.fp_tmp is not None:
            self.fp_tmp.seek(0)
            # at least this information are needed for
            # cgi.FieldStorage() to parse the content
            tmp_environ = {
                'REQUEST_METHOD': 'POST',
                'CONTENT_LENGTH': self.content_length,
                'CONTENT_TYPE': self.content_type
            }
            if sys.version_info[1] >= 8:
                self.request_form = cgi.FieldStorage(
                    fp=self.fp_tmp,
                    environ=tmp_environ,
                    max_num_fields=self.get_max_num_fields)
            else:
                logger.warning(
                    "max_num_fields is only supported with Python >= 3.8")
                self.request_form = cgi.FieldStorage(fp=self.fp_tmp,
                                                     environ=tmp_environ)
            for field_name in self.request_form.keys():
                # dump only files
                if self.request_form[field_name].filename is None:
                    continue

                fp_post = self.request_form[field_name].file

                data = fp_post.read(4096)

                # don't handle empty files
                if len(data) == 0:
                    continue

                fp_tmp = tempfile.NamedTemporaryFile(
                    delete=False,
                    dir=self.download_dir,
                    prefix='http-',
                    suffix=self.download_suffix)
                while data != b'':
                    fp_tmp.write(data)
                    data = fp_post.read(4096)

                icd = incident("dionaea.download.complete")
                icd.path = fp_tmp.name
                icd.con = self
                # We need the url for logging
                icd.url = ""
                fp_tmp.close()
                icd.report()
                os.unlink(fp_tmp.name)

            os.unlink(self.fp_tmp.name)

        x = self.send_head()
        if x:
            self.copyfile(x)
Example #17
0
    def download(self, con, host, port, filename, url):
        logger.info("Connecting to %s to download" % host)
        logger.info("    filename -> %s" % filename)

        if 'blksize' in self.options:
            size = self.options['blksize']
            if size < MIN_BLKSIZE or size > MAX_BLKSIZE:
                raise TftpException("Invalid blksize: %d" % size)
        else:
            self.options['blksize'] = DEF_BLKSIZE

        self.filename = filename
        self.port = port
        self.con = con
        self.url = url
        if con != None:
            self.bind(con.local.host, 0)
            self.con.ref()

        self.connect(host, 0)
        if con != None:
            i = incident("dionaea.connection.link")
            i.parent = con
            i.child = self
            i.report()
Example #18
0
    def handle_io_in(self, data):
        if self.state == self.IDLE:
            p = packets.PPTP_StartControlConnection_Request(data)
            p.show()
            if p.Length == 0:
                logger.warn("Bad PPTP Packet, Length = 0")
                return len(data)

            i = incident("dionaea.modules.python.pptp.connect")
            i.con = self
            logger.debug("pptp remote hostname: %s", p.HostName)
            i.firmware_revision = p.FirmwareRevision
            i.max_channels = p.MaxChannels
            i.protocol_version = p.ProtocolVersion
            i.remote_hostname = p.HostName
            i.vendor_name = p.VendorName
            i.report()
            self.state = self.ESTABLISHED
            r = packets.PPTP_StartControlConnection_Reply()
            r.FirmwareRevision = self.firmware_revision
            r.HostName = self.hostname
            r.VendorName = self.vendor_name
            r.show()
            self.send(r.build())
            return len(data)
        elif self.state == self.ESTABLISHED:
            p = packets.BaseControllMessage(data)
            if p.MessageType == 0x01:
                return self._handle_controll_message(p.ControlMessageType, data)

            logger.warning("Wrong message type %d", p.MessageType)
            return len(data)

        return len(data)
Example #19
0
    def handle_incident_dionaea_modules_python_mwserv_result(self, icd):
        fh = open(icd.path, mode="rb")
        c = fh.read()
        logger.info("mwserv result: {0}".format(c))

        cookie = icd._userdata
        mr = self.cookies[cookie]

        # does backend want us to upload?
        if b'UNKNOWN' in c:
            i = incident("dionaea.upload.request")
            i._url = self.backendurl + 'nepenthes/submit'

            i.sha512 = mr.sha512h
            i.maintainer = self.maintainer
            i.guid = self.guid
            i.secret = self.secret

            i.set('file://data', mr.filepath)

            i.saddr = mr.saddr
            i.sport = mr.sport
            i.daddr = mr.daddr
            i.dport = mr.dport
            i.url = mr.download_url

            i._callback = "dionaea.modules.python.mwserv.uploadresult"
            i._userdata = cookie

            i.report()
        else:
            del self.cookies[cookie]
Example #20
0
 def connection_insert(self, icd, connection_type):
     con = icd.con
     if (con.protocol != 'pcap'):
         cookies = str(uuid.uuid4())
         logger.info(
             "MyCERT Sensor: connection_type: %s, con_protocol: %s" %
             (connection_type, con.protocol))
         i = incident('dionaea.upload.request')
         i._url = self.connection_url
         i.sensorid = self.sensorid
         # i.connection_type = connection_type
         i.protocol = con.protocol
         i.transport = con.transport
         i.hostname = con.remote.hostname
         i.src_ip = con.remote.host
         i.src_port = str(con.remote.port)
         i.dst_ip = con.local.host
         i.dst_port = str(con.local.port)
         i.timestamp = str(
             time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
         i.hash = cookies
         i._callback = "dionaea.modules.python.mycertsensor.connection_result"
         i._userdata = cookies
         self.cookies[cookies] = con
         self.connection[con] = cookies
         i.report()
Example #21
0
    def handle_incident_dionaea_download_complete_unique(self, icd):
        cookie = str(uuid.uuid4())

        i = incident("dionaea.upload.request")
        i._url = self.backendurl + 'nepenthes/submit'

        i.sha512 = sha512file(icd.file)
        i.maintainer = self.maintainer
        i.guid = self.guid
        i.secret = self.secret

        mr = mwserv_report(i.sha512, icd.file)

        if hasattr(icd, 'con'):
            i.saddr = icd.con.remote.host
            i.sport = str(icd.con.remote.port)
            i.daddr = icd.con.local.host
            i.dport = str(icd.con.local.port)
            mr.saddr, mr.sport, mr.daddr, mr.dport = i.saddr, i.sport, i.daddr, i.dport
        if hasattr(icd, 'url'):
            i.url = icd.url
            mr.download_url = icd.url

        i._callback = "dionaea.modules.python.mwserv.result"
        i._userdata = cookie

        self.cookies[cookie] = mr
        i.report()
Example #22
0
 def handle_io_in(self, data):
     fmt = "IIB20s40sB30s30sBBBhHi"
     if len(data) != calcsize(fmt):
         return 0
     values = unpack(fmt, data)
     names = [
         "magic", "id", "type", "genre", "detail", "dist", "link", "tos",
         "fw", "nat", "real", "score", "mflags", "uptime"
     ]
     icd = incident(origin='dionaea.modules.python.p0f')
     for i in range(len(values)):
         s = values[i]
         if type(s) == bytes:
             if s.find(b'\x00'):
                 s = s[:s.find(b'\x00')]
             try:
                 s = s.decode("ascii")
             except UnicodeDecodeError:
                 logger.warning("Unable to decode p0f information %s=%r",
                                i,
                                s,
                                exc_info=True)
             icd.set(names[i], s)
         elif type(s) == int:
             icd.set(names[i], str(s))
     icd.set('con', self.con)
     icd.report()
     self.close()
     return len(data)
Example #23
0
    def processcmd(self, cmd, args):
        logger.debug("cmd '%s'" % cmd)
        l = [i.decode() for i in args]

        i = incident("dionaea.modules.python.ftp.command")
        i.con = self
        i.command = cmd
        i.arguments = l
        i.report()

        cmd = cmd.upper()
        if self.state == self.UNAUTH:
            if cmd != b'USER':
                self.reply("not_logged_in")
                return
            self.ftp_USER(*l)
        elif self.state == self.INAUTH:
            if cmd != b'PASS':
                self.reply("bad_cmd_seq_pass_after_user")
                return
            self.ftp_PASS(*l)
        else:
            method = getattr(self, "ftp_" + cmd.decode(), None)
            if method is not None:
                msg = method(*l)
                if isinstance(msg, str):
                    self.error("Returning messages is deprecated please report so we can fix it")
                    self.sendline(msg)
            else:
                self.reply("cmd_not_implmntd", command=cmd.decode())
Example #24
0
    def _heartbeat(self, events, data):
        logger.info("mwserv _heartbeat")
        i = incident("dionaea.upload.request")
        i._url = self.backendurl + 'heartbeat'
        i.maintainer = self.maintainer
        i.guid = self.guid
        i.secret = self.secret
        i.software = self.software

        i._callback = "dionaea.modules.python.mwserv.heartbeatresult"
        i.report()
Example #25
0
    def get_file_report(self, backlogfile, md5_hash, path, status):
        cookie = str(uuid.uuid4())
        self.cookies[cookie] = vtreport(backlogfile, md5_hash, path, status)

        i = incident("dionaea.upload.request")
        i._url = "https://www.virustotal.com/vtapi/v2/file/report"
        i.resource = md5_hash
        i.apikey = self.apikey
        i._callback = "dionaea.modules.python.virustotal.get_file_report"
        i._userdata = cookie
        i.report()
Example #26
0
    def handle_established(self):
        logger.debug("{!s} handle_established".format(self))

        self.timeouts.idle = 10
        self.timeouts.sustain = 120
        self.processors()

        # fake a connection entry
        i = incident("dionaea.connection.udp.connect")
        i.con = self
        i.report()
Example #27
0
    def scan_file(self, backlogfile, md5_hash, path, status):
        cookie = str(uuid.uuid4())
        self.cookies[cookie] = vtreport(backlogfile, md5_hash, path, status)

        i = incident("dionaea.upload.request")
        i._url = "https://www.virustotal.com/vtapi/v2/file/scan"
        i.apikey = self.apikey
        i.set('file://file', path)
        i._callback = "dionaea.modules.python.virustotal_scan_file"
        i._userdata = cookie
        i.report()
Example #28
0
	def handle_established(self):
		logger.debug("{:s} handle_established".format(self))

		self.timeouts.idle = 10
		self.timeouts.sustain = 120
		self.processors()

		# fake a connection entry
		i = incident("dionaea.connection.udp.connect")
		i.con = self
		i.report()
Example #29
0
    def scan_file(self, backlogfile, md5_hash, path, status):
        cookie = str(uuid.uuid4())
        self.cookies[cookie] = vtreport(backlogfile, md5_hash, path, status)

        i = incident("dionaea.upload.request")
        i._url = "https://www.virustotal.com/vtapi/v2/file/scan"
        i.apikey = self.apikey
        i.set('file://file', path)
        i._callback = "dionaea.modules.python.virustotal_scan_file"
        i._userdata = cookie
        i.report()
Example #30
0
    def get_file_report(self, backlogfile, md5_hash, path, status):
        cookie = str(uuid.uuid4())
        self.cookies[cookie] = vtreport(backlogfile, md5_hash, path, status)

        i = incident("dionaea.upload.request")
        i._url = "https://www.virustotal.com/vtapi/v2/file/report"
        i.resource = md5_hash
        i.apikey = self.apikey
        i._callback = "dionaea.modules.python.virustotal.get_file_report"
        i._userdata = cookie
        i.report()
Example #31
0
    def make_comment(self, backlogfile, md5_hash, path, status):
        cookie = str(uuid.uuid4())
        self.cookies[cookie] = vtreport(backlogfile, md5_hash, path, status)

        i = incident("dionaea.upload.request")
        i._url = "https://www.virustotal.com/vtapi/v2/comments/put"
        i.apikey = self.apikey
        i.resource = md5_hash
        i.comment = "This sample was captured in the wild and uploaded by the dionaea honeypot.\n#honeypot #malware #networkworm"
        i._callback = "dionaea.modules.python.virustotal_make_comment"
        i._userdata = cookie
        i.report()
Example #32
0
    def handle_OPTIONS(self, msg):
        logger.debug("{!s} handle_OPTIONS".format(self))
        icd = incident("dionaea.modules.python.sip.command")
        icd.con = self
        msg_to_icd(msg,d=icd)
        icd.report()

        res = msg.create_response(rfc3261.OK)
        res.headers.append(rfc3261.Header(name="Accept", value="application/sdp"))
        res.headers.append(rfc3261.Header(name="Accept-Language", value="en"))

        self.send(res.dumps())
Example #33
0
    def handle_OPTIONS(self, msg):
        logger.debug("{!s} handle_OPTIONS".format(self))
        icd = incident("dionaea.modules.python.sip.command")
        icd.con = self
        msg_to_icd(msg,d=icd)
        icd.report()

        res = msg.create_response(rfc3261.OK)
        res.headers.append(rfc3261.Header(name="Accept", value="application/sdp"))
        res.headers.append(rfc3261.Header(name="Accept-Language", value="en"))

        self.send(res.dumps())
Example #34
0
    def make_comment(self, backlogfile, md5_hash, path, status):
        cookie = str(uuid.uuid4())
        self.cookies[cookie] = vtreport(backlogfile, md5_hash, path, status)

        i = incident("dionaea.upload.request")
        i._url = "https://www.virustotal.com/vtapi/v2/comments/put"
        i.apikey = self.apikey
        i.resource = md5_hash
        i.comment = "This sample was captured in the wild and uploaded by the dionaea honeypot.\n#honeypot #malware #networkworm"
        i._callback = "dionaea.modules.python.virustotal_make_comment"
        i._userdata = cookie
        i.report()
Example #35
0
    def handle_unknown(self, msg):
        logger.debug("{!s} unknown".format(self))
        logger.warn("Unknown SIP header: {}".format(repr(msg.method)[:128]))

        icd = incident("dionaea.modules.python.sip.command")
        icd.con = self
        msg_to_icd(msg, d=icd)
        icd.report()

        res = msg.create_response(rfc3261.NOT_IMPLEMENTED)
        res.dumps()
        self.send(res.dumps())
Example #36
0
    def handle_unknown(self, msg):
        logger.debug("{!s} unknown".format(self))
        logger.warn("Unknown SIP header: {}".format(repr(msg.method)[:128]))

        icd = incident("dionaea.modules.python.sip.command")
        icd.con = self
        msg_to_icd(msg, d=icd)
        icd.report()

        res = msg.create_response(rfc3261.NOT_IMPLEMENTED)
        res.dumps()
        self.send(res.dumps())
Example #37
0
 def handle_incident_dionaea_download_complete_hash(self, icd):
     logger.info("MyCERT Sensor: handle_incident_dionaea_download_complete_hash")
     i = incident("dionaea.upload.request")
     i._url = self.artifact_url.format(id=self.sensorid, connection_id=str(self.connection[icd.con]))
     i.type = "fileupload"
     i.md5 = icd.md5hash
     i.metadata = json.dumps({
         'url': icd.url,
         'md5': icd.md5hash,
         'timestamp': str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
     })
     i.set('file://' + self.mwsconfig['file_fieldname'], icd.file)
     i.report()
Example #38
0
 def submitArtifact(self, connection_id, jenis, metadata):
     url = self.artifact_url.format(id=self.sensorid, connection_id=connection_id)
     logger.info("MyCERT Sensor: Submit Artifact url=%s, jenis=%s,connection_id=%s" % (url, jenis, connection_id))
     i = incident('dionaea.upload.request')
     i._url = url
     i.type = jenis
     i.metadata = metadata
     i._callback = "dionaea.modules.python.mycertsensor.artifact_result"
     i._userdata = json.dumps({
         'connection_id': connection_id,
         'jenis': jenis,
         'metadata': json.loads(metadata)
     })
     i.report()
Example #39
0
    def makeport(self):
        self.datalistener = FTPData(ftp=self)
        try:
            portrange = g_dionaea.config()["modules"]["python"]["ftp"]["active-ports"]
            (minport, maxport) = portrange.split("-")
            minport = int(minport)
            maxport = int(maxport)
        except:
            minport = 62001
            maxport = 63000

        try:
            # for NAT setups
            host = g_dionaea.config()["modules"]["python"]["ftp"]["active-host"]
            if host == "0.0.0.0":
                host = self.ctrl.local.host
                logger.info("datalisten host %s", host)
            else:
                import socket
                host = socket.gethostbyname(host)
                logger.info("resolved host %s", host)
        except:
            host = self.ctrl.local.host
            logger.info("except datalisten host %s", self.ctrl.local.host)

        # NAT, use a port range which is forwarded to your honeypot
        ports = list(
            filter(
                lambda port: ((port >> 4) & 0xf) != 0,
                range(minport, maxport)
            )
        )
        random.shuffle(ports)
        port = None
        for port in ports:
            self.datalistener.bind(self.ctrl.local.host, port)
            if self.datalistener.listen() == True:
                port = self.datalistener.local.port
                i = incident("dionaea.connection.link")
                i.parent = self.ctrl
                i.child = self.datalistener
                i.report()
                break
        hbytes = host.split(".")
        pbytes = [repr(port // 256), repr(port % 256)]
        bytes = hbytes + pbytes
        port = ",".join(bytes)
        logger.debug("PORT CMD %s", port)
        return port
Example #40
0
 def handle_disconnect(self):
     logger.debug("received %i bytes" % (self._in.accounting.bytes))
     if hasattr(self, 'fileobj') and self.fileobj != None:
         #		print(type(self.file))
         #		print(self.file)
         self.fileobj.close()
         icd = incident("dionaea.download.complete")
         icd.path = self.fileobj.name
         icd.con = self.ftp.con
         icd.url = self.ftp.url
         icd.report()
         self.fileobj.unlink(self.fileobj.name)
         self.ftp.dataconn = None
         self.ftp.datadone()
     return False
Example #41
0
 def handle_disconnect(self):
     logger.debug("received %i bytes", self._in.accounting.bytes)
     if hasattr(self, "fileobj")and self.fileobj is not None:
         # print(type(self.file))
         # print(self.file)
         self.fileobj.close()
         icd = incident("dionaea.download.complete")
         icd.path = self.fileobj.name
         icd.con = self.ftp.con
         icd.url = self.ftp.url
         icd.report()
         self.fileobj.unlink(self.fileobj.name)
         self.ftp.dataconn = None
         self.ftp.datadone()
     return False
Example #42
0
    def makeport(self):
        self.datalistener = ftpdata(ftp=self)
        try:
            portrange = g_dionaea.config(
            )['modules']['python']['ftp']['active-ports']
            (minport, maxport) = portrange.split('-')
            minport = int(minport)
            maxport = int(maxport)
        except:
            minport = 62001
            maxport = 63000

        try:
            # for NAT setups
            host = g_dionaea.config(
            )['modules']['python']['ftp']['active-host']
            if host == '0.0.0.0':
                host = self.ctrl.local.host
                logger.info("datalisten host %s" % host)
            else:
                import socket
                host = socket.gethostbyname(host)
                logger.info("resolved host %s" % host)
        except:
            host = self.ctrl.local.host
            logger.info("except datalisten host %s" % self.ctrl.local.host)

        ports = list(
            filter(lambda port: ((port >> 4) & 0xf) != 0,
                   range(minport, maxport))
        )  # NAT, use a port range which is forwarded to your honeypot
        random.shuffle(ports)
        port = None
        for port in ports:
            self.datalistener.bind(self.ctrl.local.host, port)
            if self.datalistener.listen() == True:
                port = self.datalistener.local.port
                i = incident("dionaea.connection.link")
                i.parent = self.ctrl
                i.child = self.datalistener
                i.report()
                break
        hbytes = host.split('.')
        pbytes = [repr(port // 256), repr(port % 256)]
        bytes = hbytes + pbytes
        port = ','.join(bytes)
        logger.debug("PORT CMD %s" % (port))
        return port
Example #43
0
    def ftp_PASS(self, password):
        if not password:
            self.reply("syntax_error_pass_requires_arg")
            return

        i = incident("dionaea.modules.python.ftp.login")
        i.con = self
        i.username = self.user
        i.password = password
        i.report()

        self.state = self.AUTHED
        if self.user == "anonymous":
            self.reply("guest_logged_in_proceed")
        else:
            self.reply("usr_logged_in_proceed")
Example #44
0
    def ftp_PASS(self, password):
        if not password:
            self.reply("syntax_error_pass_requires_arg")
            return

        i = incident("dionaea.modules.python.ftp.login")
        i.con = self
        i.username = self.user
        i.password = password
        i.report()

        self.state = self.AUTHED
        if self.user == "anonymous":
            self.reply("guest_logged_in_proceed")
        else:
            self.reply("usr_logged_in_proceed")
Example #45
0
    def handle_POST(self):
        """
        Handle the POST method. Send the head and the file. But ignore the POST params.
        Use the bistreams for a better analysis.
        """
        if self.fp_tmp is None:
            self.fp_tmp.seek(0)
            form = cgi.FieldStorage(fp=self.fp_tmp, environ=self.env)
            for field_name in form.keys():
                # dump only files
                if form[field_name].filename is None:
                    continue

                fp_post = form[field_name].file

                data = fp_post.read(4096)

                # don't handle empty files
                if len(data) == 0:
                    continue

                fp_tmp = tempfile.NamedTemporaryFile(
                    delete=False,
                    dir=self.download_dir,
                    prefix='http-',
                    suffix=self.download_suffix
                )
                while data != b'':
                    fp_tmp.write(data)
                    data = fp_post.read(4096)

                icd = incident("dionaea.download.complete")
                icd.path = fp_tmp.name
                icd.con = self
                # We need the url for logging
                icd.url = ""
                fp_tmp.close()
                icd.report()
                os.unlink(fp_tmp.name)

            os.unlink(self.fp_tmp.name)

        x = self.send_head()
        if x:
            self.copyfile(x)
Example #46
0
    def handle_POST(self):
        """
        Handle the POST method. Send the head and the file. But ignore the POST params.
        Use the bistreams for a better analysis.
        """
        if self.fp_tmp is not None:
            self.fp_tmp.seek(0)
            form = cgi.FieldStorage(fp=self.fp_tmp, environ=self.env)
            for field_name in form.keys():
                # dump only files
                if form[field_name].filename is None:
                    continue

                fp_post = form[field_name].file

                data = fp_post.read(4096)

                # don't handle empty files
                if len(data) == 0:
                    continue

                fp_tmp = tempfile.NamedTemporaryFile(
                    delete=False,
                    dir=self.download_dir,
                    prefix='http-',
                    suffix=self.download_suffix
                )
                while data != b'':
                    fp_tmp.write(data)
                    data = fp_post.read(4096)

                icd = incident("dionaea.download.complete")
                icd.path = fp_tmp.name
                icd.con = self
                # We need the url for logging
                icd.url = ""
                fp_tmp.close()
                icd.report()
                os.unlink(fp_tmp.name)

            os.unlink(self.fp_tmp.name)

        x = self.send_head()
        if x:
            self.copyfile(x)
Example #47
0
    def handle_msg_in(self, msg):
        self._timers["idle"].reset()
        self._msg_stack.append(("in", msg))

        icd = incident("dionaea.modules.python.sip.command")
        icd.con = self
        msg_to_icd(msg, d=icd)
        icd.report()

        handler_name = msg.method.decode("utf-8").upper()

        try:
            func = getattr(self, "handle_" + handler_name, None)
        except:
            func = None

        if func is not None and callable(func) == True:
            func(msg)
Example #48
0
    def handle_msg_in(self, msg):
        self._timers["idle"].reset()
        self._msg_stack.append(("in", msg))

        icd = incident("dionaea.modules.python.sip.command")
        icd.con = self
        msg_to_icd(msg,d=icd)
        icd.report()

        handler_name = msg.method.decode("utf-8").upper()

        try:
            func = getattr(self, "handle_" + handler_name, None)
        except:
            func = None

        if func is not None and callable(func) == True:
            func(msg)
Example #49
0
	def __init__(self, proto, call_id, session, invite_message):
		logger.debug("{!s} __init__".format(self))

		logger.debug("SipCall {} session {} ".format(self, session))
		connection.__init__(self, proto)
		# Store incoming information of the remote host

		self.__session = session
		self.__state = SipCall.SESSION_SETUP
		self.__msg = invite_message
		# list of messages
		self._msg_stack = []

		self.__call_id = invite_message.headers.get(b"call-id").value
		self._call_id = call_id
		self._rtp_streams = {}

		self.local.host = self.__session.local.host
		self.local.port = self.__session.local.port

		self.remote.host = self.__session.remote.host
		self.remote.port = self.__session.remote.port

		user = self.__msg.headers.get(b"to").get_raw().uri.user

		self._user = g_sipconfig.get_user_by_username(
			self.__session.personality,
			user
		)

		# fake a connection entry
		i = incident("dionaea.connection.udp.connect")
		i.con = self
		i.report()

		global _SipCall_sustain_timeout

		# Global timers
		self._timers = {
			"idle": pyev.Timer(60.0, 60.0, g_default_loop, self.__handle_timeout_idle),
			"invite_handler": pyev.Timer(5.0, 0.0, g_default_loop, self.__handle_invite),
		}

		self._timers["idle"].start()
Example #50
0
	def handle_INVITE(self, msg):
		logger.debug("{!s} handle_INVITE".format(self))

		global g_sipconfig
		global g_call_ids

		# Read Call-ID field and create new SipCall instance on first INVITE
		# request received (remote host might send more than one because of time
		# outs or because he wants to flood the honeypot)
		#logger.debug("Currently active sessions: {}".format(self._callids))

		if not msg.header_exist(b"call-id"):
			return

		call_id = msg.headers.get(b"call-id").value

		if call_id in g_call_ids and g_call_ids[call_id] == None:
			logger.warn("SIP session with Call-ID {} already exists".format(call_id[:128]))
			# ToDo: error
			return

		# Establish a new SIP Call
		new_call = SipCall(
			self.transport,
			call_id,
			self,
			msg
		)

		# Store session object in sessions dictionary
		g_call_ids[call_id] = new_call

		i = incident("dionaea.connection.link")
		i.parent = self
		i.child = new_call
		i.report()

		try:
			r = new_call.handle_msg_in(msg)
		except AuthenticationError:
			logger.warn("Authentication failed, not creating SIP session")
			new_call.close()
			del new_call
Example #51
0
	def cmd_TFTP(self, args):
		logger.debug("TFTP %s" % (args) )
		if len(args) != 4:
			logger.debug("invalid number of args")
			return "foo","error, invalid number of args"
		if args[0] == '-i' and args[2].lower() == 'get':
			host = args[1]
			file = args[3]
#			logger.debug("TFTP %s %s" % (host, file))
			i = incident("dionaea.download.offer")
			url = 'tftp://' + host + '/' + file
			i.url = url
			if isinstance(self, connection):
				i.con = self
			elif hasattr(self, 'con') and isinstance(self.con, connection):
				i.con = self.con
			i.report()
			return "downloading",None
		return None,None
Example #52
0
	def handle_incident(self, icd):
		logger.debug("do shell")
		con = icd.con
		c = remoteshell()
		i = incident("dionaea.connection.link")
		i.parent = icd.con
		i.child = c
		if icd.origin == "dionaea.service.shell.listen":
			if c.bind(con.local.host,icd.get('port')) == True and c.listen() == True:
				i.report()
			else:
				c.close()
#				con.unref()
		elif icd.origin == "dionaea.service.shell.connect":
			c.bind(con.local.host,0)
			c.connect(icd.get('host'), icd.get('port'))
			i.report()
		else:
			c.close()
Example #53
0
    def handle_incident_dionaea_download_complete_unique(self, icd):
        cookie = str(uuid.uuid4())

        i = incident("dionaea.upload.request")
        i._url = self.backendurl

        i.sha512 = sha512file(icd.file)
        i.md5 = md5file(icd.file)
        i.email = self.email
        i.user = self.user
        i.set('pass', self.passwd)

        mr = submithttp_report(i.sha512, i.md5, icd.file)

        if hasattr(icd, 'con'):
            i.source_host = str(
                struct.unpack('!I', socket.inet_aton(icd.con.remote.host))[0]
            )
            i.source_port = str(icd.con.remote.port)
            i.target_host = str(
                struct.unpack('!I', socket.inet_aton(icd.con.local.host))[0]
            )
            i.target_port = str(icd.con.local.port)
            mr.saddr, mr.sport, mr.daddr, mr.dport = i.source_host, i.source_port, i.target_host, i.target_port
        if hasattr(icd, 'url'):
            i.url = icd.url
            i.trigger = icd.url
            try:
                i.filename = urlparse(icd.url).path.split('/')[-1]
                mr.filename = i.filename
            except:
                pass
            mr.download_url = icd.url

        i.filetype = filetype(icd.file)
        mr.filetype = i.filetype

        i._callback = "dionaea.modules.python.submithttp.result"
        i._userdata = cookie

        self.cookies[cookie] = mr
        i.report()
Example #54
0
 def handle_io_in(self, data):
     fmt = "IIB20s40sB30s30sBBBhHi"
     if len(data) != calcsize(fmt):
         return 0
     values = unpack(fmt, data)
     names=["magic","id","type","genre","detail","dist","link",
            "tos","fw","nat","real","score","mflags","uptime"]
     icd = incident(origin='dionaea.modules.python.p0f')
     for i in range(len(values)):
         s = values[i]
         if type(s) == bytes:
             if s.find(b'\x00'):
                 s = s[:s.find(b'\x00')]
             icd.set(names[i], s)
         elif type(s) == int:
             icd.set(names[i], str(s))
     icd.set('con',self.con)
     icd.report()
     self.close()
     return len(data)
Example #55
0
    def handle_incident_dionaea_download_complete(self, icd):
        url_levels = self.connection_url_levels.get(icd.con)
        if not isinstance(url_levels, dict):
            url_levels = {}
            # Store dict pointer in list, so others can use it
            self.connection_url_levels[icd.con] = url_levels

        next_level = url_levels.get(icd.url, 0) + 1
        if next_level > 1:
            # ToDo: use config value
            return

        fp = open(icd.path, "rb")
        # ToDo: check size
        data = fp.read()
        fp.close()
        urls = None
        # use the url list of the first handler that matches
        for handler in self.handlers:
            urls = handler.run(data)
            if urls is not None:
                break

        if urls is None:
            return

        for url in set(urls):
            if url in url_levels:
                # don't download a file multiple times
                continue

            if len(url_levels) > self.max_subdownloads:
                logger.warning("Max number of subdownloads reached")
                break
            url_levels[url] = next_level
            i = incident("dionaea.download.offer")
            i.con = icd.con
            i.url = url
            i.report()
Example #56
0
    def _report_raw_data(self, data):
        """
        Create temporary file and report incident

        :param bytes data: File data
        """
        fp_tmp = tempfile.NamedTemporaryFile(
            delete=False,
            dir=self.download_dir,
            prefix='mysql-',
            suffix=self.download_suffix
        )

        fp_tmp.write(data)

        icd = incident("dionaea.download.complete")
        icd.path = fp_tmp.name
        icd.con = self
        # We need the url for logging
        icd.url = ""
        fp_tmp.close()
        icd.report()
        os.unlink(fp_tmp.name)