Esempio n. 1
0
def blackhole(txnId, sensorId, attacker):
    global BlackholedRoutes
    global BH_DURATION

    try:
        # do not blackhole items on whitelist
        print "*** kojoney_defend.py : calling hiddenIP() ***"
        if kojoney_hiddenip.hiddenIP(attacker) == True:
            msg = "kojoney_defend.py : blackhole() : warning : attacker " + attacker + " is on hiddenIP() whitelist and must not be blackholed"
            print msg
            syslog.syslog(msg)
            return None

        # blackhole route already exists - issue - should the time be reset to zero ?
        #if BlackholedRoutes.has_key(attacker) == True :
        #    return None

        # get hostname of the attacker
        dnsInfo = ipintellib.ip2name(attacker)
        dnsName = dnsInfo['name']

        # inject the blackhole
        cmd = "/sbin/ip route add blackhole " + attacker
        msg = "Added blackhole (" + BH_DURATION.__str__(
        ) + "s) on " + time.ctime(
        ) + " for " + attacker + " " + dnsName.__str__()
        #print msg
        #syslog.syslog(msg)

        # Update Attacker Database
        srcIP = attacker
        kojoney_attacker_event.generateAttackerEvent(
            txnId, srcIP, None, sensorId, "BHOLE", "DEFEND", None,
            "Attacker blackholed", None, None, None, None, None)

        kojoney_blackhole_idmef.sendBlackholeIDMEF(attacker, "Added blackhole")

        pipe = os.popen(cmd, 'r')
        tweet = "DEFEND," + msg

        #return None	# do not Tweet - not interesting to average punter
        return tweet

    except Exception, e:
        msg = "kojoney_defend.py : blackhole() exception caught = " + ` e `
        syslog.syslog(msg)
        print msg
        return None
Esempio n. 2
0
def processGlastopf(txnId, sensorId, line):

    asMsg = ""

    try:
        print "-------------\nprocessGlastopf() : line read is " + line
        dstIP = "192.168.1.62"  # bug - not portable
        request = "No URL found"
        apacheCLF = "None"

        logEntry = line  # keep a copy since we are going to modify line

        # Normalise Mail attacks
        line = line.replace("ail attack found", "ail attack from")

        # Looks like a duplication bug so ignore the 'Unknown' variant
        if "Unknown POST attack" in line:
            return None

        # ATTACK : Successful attack
        if line.find("attack from") != -1 or line.find(
                "Mail attack found from") != -1:
            print "WebApp attack detected : " + line
            apacheCLF = fakeApacheCLF(line)  # fake an Apache CLF record
            fields = line.split(" - ")
            #print fields
            msg = ' '.join(fields[3:])
            #msg = ' '.join(fields[3:]).rstrip("?")		# does glastopf add trailing ? / ??
            msg = "WEB_X," + msg
            msg = msg.replace(" with request: ", " req=")
            #msg = msg.replace("found from","from")		# normalise MAIL versus "other" attacks
            msg = msg.replace(
                "Mail", "Webmail")  # normalise MAIL versus "other" attacks

            msg = msg.replace(
                "/", "|"
            )  # fool Twitter into not using t.co URL shortening and ensure users cannot click on malware links

            a = re.findall("(GET|POST|Unknown POST|Mail) attack from", line)
            if len(a) > 0:
                attackType = "WebApp " + a[0].upper(
                ) + "-based RFI attack"  # upper() used to convert Mail to MAIL
            else:
                attackType = "Unknown WebApp attack"

            ips = re.findall("from (\d+\.\d+\.\d+\.\d+)", line)
            if len(ips) > 0:
                srcIP = ips[0]
                if "request" in line:
                    request = line.split("request: ")[1]
                print "Successful WebApp attack : AttackType=" + attackType + " srcIP=" + srcIP + " URLrequest=" + request

            if "unknown" in line.lower():
                completion = "failed"
            else:
                completion = "succeeded"

            kojoney_glastopf_idmef.sendWebAppIDMEF(attackType, request, "http",
                                                   "18080", completion, srcIP,
                                                   dstIP, apacheCLF, srcIP,
                                                   logEntry)
            kojoney_attacker_event.generateAttackerEvent(
                txnId, srcIP, None, sensorId, "ATTACKING", "GLASTOPF", None,
                attackType, None, None, None, apacheCLF, None)

            return msg

        # File retrieved
        if line.find("successfully opened") != -1:
            #apacheCLF=fakeApacheCLF(line)					# fake an Apache CLF record
            fields = line.split(" - ")
            #print fields
            msg = ' '.join(fields[3:])
            msg = "WEB_OPEN," + msg
            urls = re.findall("(\S+) successfully opened", line)
            if len(urls) > 0:
                url = urls[0]
                domain = kojoney_idmef_common.extractDomain(url)
                if domain != None:
                    dnsInfo = ipintellib.ip2name(domain)
                    dstIP = dnsInfo['name']
                else:
                    dstIP = "0.0.0.0"  # error
                # IDMEF the honeypot to drop-site flow
                kojoney_glastopf_idmef.sendWebAppURLIDMEF(
                    "WebApp URL opened", url, "http", "192.168.1.62", dstIP,
                    "80", "succeeded", "None", dstIP, logEntry)

            msg = msg.replace(
                "/", "|"
            )  # fool Twitter into not using t.co URL shortening and ensure users cannot click on malware links

            return msg

        # Googledorks data written to mySQL database - not interesting enough to Tweet
        #if line.find("written into local database") != -1 :
        #    fields = line.split(" - ")
        #    #print fields
        #    msg = ' '.join(fields[3:])
        #    msg = "WEB_GOOGLEDORK," + msg
        #    return msg

        # File saved to disk
        if line.find("written to disk") != -1 and line.find("File ") != -1:
            fields = line.split(" - ")
            #print fields
            msg = ' '.join(fields[3:])
            msg = msg.replace("File", "Previously unseen PHP malware file")
            msg = "WEB_WRITE," + msg
            fileMD5 = fields[3].split(" ")[1]
            kojoney_glastopf_idmef.sendWebAppFile(
                "File retrieved from remote server", fileMD5, logEntry)
            return msg

        # Scan - i.e. unsuccessful attack
        if line.find("No attack found") != -1:
            apacheCLF = fakeApacheCLF(line)  # fake an Apache CLF record
            #print "scan"
            ip = kojoney_funcs.findFirstIP(line)
            if ip != None:
                #print "IP found = " + ip
                # WHOIS information
                #asInfo = rch_asn_funcs.ip2asn(ip)
                asInfo = ipintellib.ip2asn(ip)
                asNum = asInfo['as']  # AS123
                asRegisteredCode = asInfo[
                    'registeredCode']  # Short-form e.g.ARCOR
                asMsg = asRegisteredCode + " (" + asNum + ")"
                #print asMsg

            fields = line.split(" - ")
            #print fields
            msg = ' '.join(fields[3:])
            if line.find("http"
                         ) != -1:  # attacker is trying to test if I am a proxy
                msg = msg.replace("No attack found from",
                                  "WEB_PRX,Request from")
                attackType = "WebApp proxy scan"
            else:  # LOC = local
                msg = msg.replace("No attack found from", "WEB_SCN,Scan from")
                attackType = "WebApp scan"
            msg = msg.replace(" with request: ", " req=")
            msg = msg.rstrip()
            # remove any trailing characters
            #msg = msg + " ISP=" + asMsg
            kojoney_afterglow.visWebScan(msg)

            msg = msg.replace(
                "/", "|"
            )  # fool Twitter into not using t.co URL shortening and ensure users cannot click on malware links

            ips = re.findall("from (\d+\.\d+\.\d+\.\d+)", line)
            if len(ips) > 0:
                srcIP = ips[0]
                request = line.split("request: ")[1]
                #print attackType + " : srcIP : " + srcIP + " request : " + request
                # go for two events ?
                if attackType == "WebApp proxy scan":
                    kojoney_glastopf_idmef.sendWebAppURLIDMEF(
                        "WebApp proxy scan Request", request, "http", srcIP,
                        "192.168.1.62", "18080", "failed", apacheCLF, srcIP,
                        logEntry)  # inbound
                    kojoney_attacker_event.generateAttackerEvent(
                        txnId, srcIP, None, sensorId, "SCANNING", "GLASTOPF",
                        None, "WebApp proxy scan Request", None, None, None,
                        apacheCLF, None)
                    domain = kojoney_idmef_common.extractDomain(request)
                    if domain != None:
                        dnsInfo = ipintellib.ip2name(domain)
                        dstIP = dnsInfo['name']
                    else:
                        dstIP = "0.0.0.0"  # error
                    kojoney_glastopf_idmef.sendWebAppURLIDMEF(
                        "WebApp proxy scan Retrieval", request, "http",
                        "192.168.1.62", dstIP, "80", "failed", apacheCLF,
                        dstIP, logEntry)  # outbound
                    kojoney_attacker_event.generateAttackerEvent(
                        txnId, srcIP, None, sensorId, "SCANNING", "GLASTOPF",
                        None, "WebApp proxy scan Retrieval", None, None, None,
                        apacheCLF, None)
                else:
                    kojoney_glastopf_idmef.sendWebAppURLIDMEF(
                        attackType, request, "http", srcIP, "192.168.1.62",
                        "18080", "failed", apacheCLF, srcIP,
                        logEntry)  # inbound
                    kojoney_attacker_event.generateAttackerEvent(
                        txnId, srcIP, None, sensorId, "SCANNING", "GLASTOPF",
                        None, "WebApp scan", None, None, None, apacheCLF, None)
            return msg

        return None

    except Exception, e:
        msg = "kojoney_glastopf_parse.py : processGlastopf() : " + ` e ` + " line=" + line
        print msg
        syslog.syslog(msg)
Esempio n. 3
0
def processKippo(txnId,sensorId,line):

    try :
        line=line.strip("\n")
        print "############################################"
        print "processKippo() : line received from Honeypot : " + line
        addInfo1 = None
        addInfo2 = None
                
        # log succeeded attempted passwords to a file            
        if line.find("login attempt") != -1 and line.find("succeeded") != -1 :
            pat = '\d+\.\d+\.\d+\.\d+'
            attacker = re.findall(pat,line)
            if len(attacker) == 1 :
                srcIP = attacker[0]
            else :
                srcIP = "0.0.0.0"    
            geoIP = ipintellib.geo_ip(srcIP)
            countryCode = geoIP['countryCode'].__str__()
            
            fields = line.split(" ")
            #print fields
            a = fields[8]		# e.g. [root/123456]
            a = a.lstrip("[")
            a = a.rstrip("]")
            username = a.split('/')[0]
            password = a.split('/')[1]
            
            #print "login OK : credentials = " + username + " " + password
            msg = srcIP + ":" + countryCode + "," + username + ":" + password + ",succeeded" + ",kippo"
            print msg
            
            # Fake auth.log entry for use by OSSEC :-
            # Accepted password for crouchr from 192.168.1.73 port 46366 ssh2
            tstamp = time.ctime()
            fields = tstamp.split(" ")
            print "kojoney_kippo_parse.py : fields=" + fields.__str__()
            
            tstamp = fields[1] + " " + fields[2] + " " + fields[3]
            fakeAuthLogMsg = tstamp + " mars sshd[12345]: Accepted password for " + username + " from " + srcIP + " port 12345 ssh2"
            print "kojoney_kippo_parse.py : fakeAuthLogMsg : " + fakeAuthLogMsg
            fp = open("/home/var/log/kippo_auth.log",'a')
            print >> fp, fakeAuthLogMsg
            fp.close()
            
            # Send event to SIEM
            kojoney_kippo_idmef.sendSshIDMEF(srcIP,"192.168.1.64","2222",username,password,True,line)

            # Send to syslog to be picked up by logstash
            #sdata = {}
            #sdata['username'] = username
            #sdata['password'] = password
            #sdata['ip']       = srcIP.__str__()
            #sdata['phase']    = "GAINED_ACCESS"
            #syslog.openlog("kojoney_kippo")
            #syslog.syslog(json.dumps(sdata))   

            # Update attacker database
            addInfo1 = username
            addInfo2 = password
            kojoney_attacker_event.generateAttackerEvent(txnId,srcIP,None,sensorId,"GAINED_ACCESS","KIPPO",None,"Successful login",None,None,None,addInfo1,addInfo2)

            fp = open("/home/var/secviz/failedCredentialsViz.csv",'a')
            print >> fp, msg
            fp.close()
            
        # log failed attempted passwords to a file            
        if line.find("login attempt") != -1 and line.find("failed") != -1 :
            pat = '\d+\.\d+\.\d+\.\d+'
            attacker = re.findall(pat,line)
            if len(attacker) == 1 :
                srcIP = attacker[0]
            else :
                srcIP = "0.0.0.0"    
            geoIP = ipintellib.geo_ip(srcIP)
            countryCode = geoIP['countryCode']
            
            fields = line.split(" ")
            #print fields
            a = fields[8]		# e.g. [root/123456]
            a = a.lstrip("[")
            a = a.rstrip("]")
            username = a.split('/')[0]
            password = a.split('/')[1]
            if len(password) == 0 :
                password = "******"
                
            #print "login FAIL : credentials = " + username + " " + password
            msg = srcIP + ":" + countryCode + "," + username + ":" + password + ",failed" + ",kippo" + "," + time.ctime()
            print msg

            # Fake FAILED auth.log entry for use by Ossec :-
            # Failed password for user crouchr from 192.168.1.73 port 46366 ssh2
            tstamp = time.ctime()
            fields = tstamp.split(" ")
            tstamp = fields[1] + " " + fields[2] + " " + fields[3]
            fakeAuthLogMsg = tstamp + " mars sshd[12345]: Failed password for user " + username + " from " + srcIP + " port 12345 ssh2"
            fakeAuthLogMsg = fakeAuthLogMsg.replace("2013 ","")
            print "fakeAuthLogMsg : " + fakeAuthLogMsg
            # Update clone of auth.log so OSSEC standard SSH rules can be used           
            fp = open("/home/var/log/kippo_auth.log",'a')
            print >> fp, fakeAuthLogMsg
            fp.close()
            
            # Send event to SIEM
            kojoney_kippo_idmef.sendSshIDMEF(srcIP,"192.168.1.64","2222",username,password,False,line)

            # Send to syslog to be picked up by logstash
            #sdata = {}
            #sdata['username'] = username
            #sdata['password'] = password
            #sdata['ip']       = srcIP.__str__()
            #sdata['phase']    = "ATTACKING"
            #syslog.openlog("kojoney_kippo")
            #syslog.syslog(json.dumps(sdata))   
            
            # Update attacker database
            addInfo1 = username
            addInfo2 = password
            kojoney_attacker_event.generateAttackerEvent(txnId,srcIP,None,sensorId,"ATTACKING","KIPPO",None,"Failed login attempt",None,None,None,addInfo1,addInfo2)

            fp = open("/home/var/secviz/failedCredentialsViz.csv",'a')
            print >> fp, msg
            fp.close()
        
        # Also add INPUT - i.e. if user performs a passwd
        # Received unhandled keyID => attacker is a human
        if (line.find("Opening TTY log") == -1 and line.find("CMD:") == -1 and  line.find("Received unhandled keyID") == -1) :         # can't find the interesting entries so return 
            return None
        
        # Human keystrokes (backspace etc.) detected ?
        if  "Received unhandled keyID" in line :
            ip = re.findall("(\d+\.\d+\.\d+\.\d+)",line)
            if len(ip) > 0 :
                srcIP = ip[0]
            else:
                srcIP = "0.0.0.0"    
            kojoney_attacker_event.generateAttackerEvent(txnId,srcIP,None,sensorId,"HUMAN_ACTIVITY","KIPPO",None,"Attacker is a human",None,None,None,addInfo1,addInfo2)
            return None
                
        #print "processKippo() : candidate syslog read from Honeypot : " + line
                                                                                 
        fields = line.split()
        #print fields
        
        uid = "0"		# Kippo only supports a root account
        a = fields[9].rstrip(']')
        srcip = a.split(',')[2]
        #print "Attacker IP : " + srcip

        # INT = intrusion
        if line.find("Opening TTY log") != -1:
            tweet = "KIPPO_INT," + "login from " + srcip + " to be logged in " + fields[13] 
        else:
            cmd = ' '.join(fields[11:])
            #cmd = 'rch testing - ignore'
            print "kojoney_kippo_parse.py : cmd=[" + cmd.__str__() + "]"
        
            ip = re.findall("(\d+\.\d+\.\d+\.\d+)",line)
            if len(ip) > 0 :
                srcIP = ip[0]
            else:
                srcIP = "0.0.0.0"    
            geoIP = ipintellib.geo_ip(srcIP)
            countryCode = geoIP['countryCode'].__str__()
            
            #print "kojoney_kippo_parse.py : Attacker " + srcIP + " from " + countryCode + " typed : " + cmd
            
            # fake the correct shell prompt
            if uid == "0" :
                prompt = "#"
            else:
                prompt = "$"
            #tweet = "--,KIPPO,UID:" + uid + " {sshd} " + prompt + " " + cmd	# fake the GeoIP of src (unknown)
            tweet = "KIPPO,UID:" + uid + " {sshd} " + prompt + " " + cmd	# fake the GeoIP of src (unknown)
            
            kojoney_kippo_idmef.sendSshCmdIDMEF(srcIP,"192.168.1.64","2222",uid,prompt + " " + cmd,line)
            
            # Log all commands to a file
            msg = time.ctime() + "," + srcIP + "," + countryCode.__str__() + "," + cmd
            fpCmds = open("/home/var/log/kippo-all-cmds.csv","a")
            print >> fpCmds,msg
            fpCmds.close()
            
            # Update Attacker Database
            addInfo1 = cmd
            addInfo2 = None
            if "wget " in cmd.lower() :			# Use trailing space to force an argument to have been supplied for wget etc.
                kojoney_attacker_event.generateAttackerEvent(txnId,srcIP,None,sensorId,"MAINTAIN_ACCESS","KIPPO",None,"Attacker attempted to retrieve malware",None,None,None,addInfo1,addInfo2)
            elif "apt-get install " in cmd.lower():	# Use trailing space to force an argument to have been supplied for wget etc.
                kojoney_attacker_event.generateAttackerEvent(txnId,srcIP,None,sensorId,"MAINTAIN_ACCESS","KIPPO",None,"Attacker attempted to install software",None,None,None,addInfo1,addInfo2)
            elif "chmod " in cmd.lower() or "tar " in cmd.lower():	# Use trailing space to force an argument to have been supplied for wget etc.
                kojoney_attacker_event.generateAttackerEvent(txnId,srcIP,None,sensorId,"MAINTAIN_ACCESS","KIPPO",None,"Attacker attempted to install software",None,None,None,addInfo1,addInfo2)
            elif "perl " in cmd.lower() or "sh " in cmd.lower() or "python " in cmd.lower() or "./" in cmd.lower():	# Use trailing space to force an argument to have been supplied for wget etc.
                kojoney_attacker_event.generateAttackerEvent(txnId,srcIP,None,sensorId,"MAINTAIN_ACCESS","KIPPO",None,"Attacker attempted to execute software",None,None,None,addInfo1,addInfo2)
            elif "rm " in cmd.lower() :			# Use trailing space to force an argument to have been supplied for wget etc.
                kojoney_attacker_event.generateAttackerEvent(txnId,srcIP,None,sensorId,"COVER_TRACKS","KIPPO",None,"Attacker attempted to delete file",None,None,None,addInfo1,addInfo2)
            elif "passwd" in cmd.lower() :		
                kojoney_attacker_event.generateAttackerEvent(txnId,srcIP,None,sensorId,"COVER_TRACKS","KIPPO",None,"Attacker attempted to modify password",None,None,None,addInfo1,addInfo2)
            elif "adduser" in cmd.lower() :		
                kojoney_attacker_event.generateAttackerEvent(txnId,srcIP,None,sensorId,"COVER_TRACKS","KIPPO",None,"Attacker attempted to add user",None,None,None,addInfo1,addInfo2)
            elif "apt-get remove " in cmd.lower():	# Use trailing space to force an argument to have been supplied for wget etc.
                kojoney_attacker_event.generateAttackerEvent(txnId,srcIP,None,sensorId,"COVER_TRACKS","KIPPO",None,"Attacker attempted to uninstall software",None,None,None,addInfo1,addInfo2)
            elif "reboot" in cmd.lower():		# Use trailing space to force an argument to have been supplied for wget etc.
                kojoney_attacker_event.generateAttackerEvent(txnId,srcIP,None,sensorId,"COVER_TRACKS","KIPPO",None,"Attacker attempted to reboot node",None,None,None,addInfo1,addInfo2)
            elif "shutdown " in cmd.lower():		# Use trailing space to force an argument to have been supplied for wget etc.
                kojoney_attacker_event.generateAttackerEvent(txnId,srcIP,None,sensorId,"COVER_TRACKS","KIPPO",None,"Attacker attempted to shutdown node",None,None,None,addInfo1,addInfo2)
                
        print "processKippo() : tweet=" + tweet 
        return tweet
    
    except Exception,e:
        syslog.syslog("kojoney_tweet.py : processKippo() exception caught = " + `e` + " line=" + line)
Esempio n. 4
0
def processTelnetd(txnId, sensorId, line):

    try:
        addInfo1 = None
        addInfo2 = None

        line = line.rstrip('\n')
        #print line.rstrip('\n')

        if "echo Failed login from" not in line and "echo Successful login from" not in line and "echo Command ran from" not in line:
            return None

        #print "--------------------"
        print "processTelnetd() : " + line

        username = ""

        if "Failed" in line:
            success = False
        else:
            success = True

        ips = re.findall("(\d+\.\d+\.\d+\.\d+)", line)
        if len(ips) > 0:
            srcIP = ips[0]
        else:
            srcIP = "0.0.0.0"
        #print "srcIP = " + srcIP

        geoIP = ipintellib.geo_ip(srcIP)
        countryCode = geoIP['countryCode'].__str__()

        c = re.findall("with (\S+)\:(\S+) ", line)
        if len(c) > 0:
            username = c[0][0]
            password = c[0][1]
            #print c.__str__()
            #print "username : "******"password : "******"login" in line:
            kojoney_telnetd_idmef.sendTelnetIDMEF(srcIP, "192.168.1.69",
                                                  "10023", username, password,
                                                  success, line)

            # Update attacker database
            addInfo1 = username
            addInfo2 = password
            if success == True:
                kojoney_attacker_event.generateAttackerEvent(
                    txnId, srcIP, None, sensorId, "GAINED_ACCESS", "TELNETD",
                    None, "Successful login", None, None, None, addInfo1,
                    addInfo2)
            else:
                kojoney_attacker_event.generateAttackerEvent(
                    txnId, srcIP, None, sensorId, "ATTACKING", "TELNETD", None,
                    "Failed login attempt", None, None, None, addInfo1,
                    addInfo2)
        elif "Command" in line:  # attacker entered a command
            c = re.findall("with (\S+)\:(\S+)\: (\S+)", line)
            if len(c) > 0:
                #username = c[0][0]
                #password = c[0][1]
                cmd = c[0][2]
                print "telnet command : [" + cmd + "]"
                addInfo1 = cmd
                addInfo2 = None
                kojoney_attacker_event.generateAttackerEvent(
                    txnId, srcIP, None, sensorId, "MAINTAIN_ACCESS", "TELNETD",
                    None, "Attacker entered command", None, None, None,
                    addInfo1, addInfo2)
        return None

    except Exception, e:
        msg = "processTelnetd() : exception : " + e.__str__()
        print msg
        syslog.syslog(msg)
Esempio n. 5
0
def processHoneytrap(txnId, sensorId, line):

    try:
        line = line.rstrip("\n")
        print "processHoneytrap() : line read is " + line

        # Only interested in certain events
        #if line.find("Connection from ") == -1 and line.find(" attack string from ") == -1 :
        if line.find(" attack string from "
                     ) == -1:  # only interested if attacker sends data
            return None

        # Where is the attack coming from ?
        fields = re.findall("(\d+\.\d+\.\d+\.\d+)\:(\d+)", line)
        if len(fields) > 0:
            srcip = fields[0][0]
            srcPort = fields[0][1]
        else:
            srcip = "None"
            srcPort = "None"

        #print "srcIP   = " + srcip
        #print "srcPort = " + srcPort

        fields = re.findall("(\d+) bytes attack string from", line)
        if len(fields) > 0:
            bytes = fields[0]
        else:
            bytes = "0"
        #print "bytes = " + bytes

        fields = re.findall("(\d+)\/tcp", line)
        if len(fields) > 0:
            dport = fields[0]
        else:
            dport = "None"
        #print "dport = " + dport

        dstip = "192.168.1.60"  # bug -> hard-coded dst IP

        # Not interested in events originating from LAN
        print "*** kojoney_honeytrap_parse.py : calling hiddenIP() ***"
        if kojoney_hiddenip.hiddenIP(srcip) == True:
            return None

        p0fDict = kojoney_p0f_lib.getp0f(srcip, dstip, dport)
        if p0fDict != None:
            p0f = " p0f=" + p0fDict['genre_short'] + " hops=" + p0fDict[
                'hops'] + " up=" + p0fDict['uptime']
        else:
            p0f = ""

        tweet = "HTRAP," + srcip + ":" + srcPort + " -> " + dstip + ":" + dport + " [bytes=" + bytes + p0f + "]"  # bug -> hard-coded dest IP !!!
        print tweet

        geoIP = ipintellib.geo_ip(srcip)
        countryCode = geoIP['countryCode'].__str__()
        kojoney_honeytrap_idmef.sendHoneytrapIDMEF(srcip, dstip, dport, p0f,
                                                   line)

        # Update Attacker Database
        addInfo1 = "proto=TCP:dPort=" + dport.__str__(
        ) + ":" + "bytes=" + bytes.__str__()
        addInfo2 = None
        attackerIP = srcip
        kojoney_attacker_event.generateAttackerEvent(
            txnId, attackerIP, p0fDict, sensorId, "SCANNING", "HONEYTRAP",
            None, "Established incoming connection", None, None, None,
            addInfo1, addInfo2)

        # Replace destination IP with text
        tweet = kojoney_snort_funcs.snortTwittifyLite(tweet)

        return None  # no need to Tweet now we have SIEM
        #return tweet

    except Exception, e:
        msg = "kojoney_honeytrap_parse.py : processHoneytrap() : " + ` e ` + " line=" + line
        print msg
        syslog.syslog(msg)
        return None
Esempio n. 6
0
def processOssecSyslog(txnId, sensorId, line):
    try:
        srcIP = None
        srcPort = None
        dstIP = None
        dstPort = None
        user = None
        rule = None
        level = None
        ruleMsg = None
        sid = None
        priority = None
        addInfo1 = None
        addInfo2 = None

        line = line.rstrip("\n")
        #if "IDS" not in line:
        #    return

        #print "------------------"
        print line

        rule = re.findall("Rule\: (\d+)", line)
        if len(rule) > 0:
            rule = rule[0]
            #print "OSSEC Rule     : " + rule.__str__()

        if "Rule:" in line:
            ruleMsg = line.split("Rule: " + rule + " - ")[1]
            ruleMsg = ruleMsg.split(";")[0]
            ruleMsg = ruleMsg.rstrip(".")
            #print "OSSEC RuleMsg  : [" + ruleMsg.__str__() + "]"

        # level is a <str>
        level = re.findall("Alert Level\: (\d+)", line)
        if len(level) > 0:
            level = level[0]
            #print "OSSEC Level    : " + level
            addInfo1 = "LEVEL=" + level.__str__()

        if "Location:" in line:
            location = line.split("Location: ")[1]
            location = location.split(";")[0]
            #print "OSSEC Location : [" + location.__str__() + "]"

        if "user:"******"user: "******";")[0]
            #print "OSSEC User     : [" + user.__str__() + "]"

        if "srcip:" in line:
            ips = re.findall("srcip\: (\d+\.\d+\.\d+\.\d+)", line)
            if len(ips) > 0:
                srcIP = ips[0]
                #print "OSSEC srcIP    : " + srcIP.__str__()

        if "dstip:" in line:
            ips = re.findall("dstip\: (\d+\.\d+\.\d+\.\d+)", line)
            if len(ips) > 0:
                dstIP = ips[0]
                #print "OSSEC dstIP    : " + dstIP.__str__()

        # -------- SPECIFIC RULES ----------
        if ("IDS event" in ruleMsg
                or "First time this IDS alert is generated" in ruleMsg):
            # and ("{UDP}" in line or "{TCP}" in line) :
            #print "Snort-specific decoding"
            if ("{TCP}" in line or "{UDP}" in line):
                ips = re.findall(
                    "(\d+\.\d+\.\d+\.\d+)\:(\d+) -> (\d+\.\d+\.\d+\.\d+)\:(\d+)",
                    line)
                #print ips.__str__()
                srcPort = ips[0][1]
                dstPort = ips[0][3]

            #elif ("{TCP}" in line or "{UDP}" in line):
            #    ips = re.findall("(\d+\.\d+\.\d+\.\d+)\:(\d+) -> (\d+\.\d+\.\d+\.\d+)\:(\d+)",line)
            #    #print ips.__str__()
            #    srcPort = ips[0][1]
            #    dstPort = ips[0][3]

            sid = re.findall("\[(\d+)\:(\d+)\:\d+\]", line)
            if len(sid) > 0:
                #print "IDS sid=" + sid.__str__()
                sid = sid[0][0] + ":" + sid[0][1]
                msg = "kojoney_ossec_parse.py : parsed Snort SID " + sid.__str__(
                ) + " from " + line
                #addInfo1 = sid.__str__()
                #print msg

            # Snort Message
            snortMsg = line.replace("]: ", "")
            snortMsg = snortMsg.split(']')[1]
            snortMsg = snortMsg.split('[')[0]
            snortMsg = snortMsg.lstrip(" ")
            snortMsg = snortMsg.rstrip(" ")
            #print "snortMsg=(" + snortMsg + ")"

            # Classification - this is not in every Snort message
            if "Classification" in line:
                classification = line.split("Classification: ")[1]
                classification = classification.split("]")[0]
                classification = classification.replace(" ", "_")
                classification = classification.upper()
            else:
                classification = "UNCLASSIFIED"
            #print "classification=(" + classification + ")"

            priority = re.findall("Priority\: (\d+)", line)
            if len(priority) > 0:
                priority = priority[0]
                msg = "kojoney_ossec_parse.py : Snort Priority=" + priority
                addInfo2 = snortMsg + ":" + "PRI=" + priority.__str__(
                ) + ":" + "CL=" + classification + ":" + "SID=" + sid.__str__(
                )
                #print msg

        # Update Attacker Database
        #print "kojoney_ossec_parse : priority=" + priority.__str__()

        if (priority != None
                and int(priority) == 1) or "ATTACK" in line.upper():  # Snort
            kojoney_attacker_event.generateAttackerEvent(
                txnId, srcIP, None, sensorId, "ATTACKING", "OSSEC", rule,
                ruleMsg, None, None, None, addInfo1, addInfo2)
        elif priority != None and int(priority) == 2:  # Snort
            kojoney_attacker_event.generateAttackerEvent(
                txnId, srcIP, None, sensorId, "SCANNING", "OSSEC", rule,
                ruleMsg, None, None, None, addInfo1, addInfo2)
        elif priority != None and int(priority) == 3:  # Snort
            kojoney_attacker_event.generateAttackerEvent(
                txnId, srcIP, None, sensorId, "PROBING", "OSSEC", rule,
                ruleMsg, None, None, None, addInfo1, addInfo2)
        elif int(level) < 12:
            #print "OSSEC : generic classification"
            kojoney_attacker_event.generateAttackerEvent(
                txnId, srcIP, None, sensorId, "ATTACKING", "OSSEC", rule,
                ruleMsg, None, None, None, addInfo1, addInfo2)
        else:
            kojoney_attacker_event.generateAttackerEvent(
                txnId, srcIP, None, sensorId, "GAINED_ACCESS", "OSSEC", rule,
                ruleMsg, None, None, None, addInfo1, addInfo2)

        # ---------- IDMEF ----------
        attackerIP = srcIP
        #print "Combined log entry is : " + line + ":" + line2 + ":" + line3 + ":" + line4 + ":" + line5 + ":" + line6
        #msg = "srcIP=" + srcIP + " attackerIP=" + attackerIP + " rule=" + rule + " level=" + level + " msg=" + message
        #print msg

        client = PreludeEasy.ClientEasy("blackrain")
        client.Start()

        # Create the IDMEF message
        idmef = PreludeEasy.IDMEF()

        # Sensor
        fieldsSet = kojoney_idmef_common.setIDMEFcommon(
            idmef, "Honeypot", sensorId, srcIP, dstIP, None, attackerIP, line)

        # Classification
        idmef.Set("alert.classification.ident", rule)  # ident = OSSEC Rule

        text = "OSSEC " + rule + " : " + ruleMsg
        if sid != None:
            text = text + " [" + sid.__str__() + "]"
        #print text
        idmef.Set("alert.classification.text", text)

        # Source
        if srcIP != None:
            idmef.Set("alert.source(0).node.address(0).address", srcIP)
            idmef.Set("alert.source(0).service.ip_version", 4)

        if srcPort != None:
            idmef.Set("alert.source(0).service.port", dstPort)

        # Target(s)
        if dstIP != None:
            idmef.Set("alert.target(0).node.address(0).address", dstIP)
            idmef.Set("alert.target(0).service.ip_version", 4)

        if dstPort != None:
            idmef.Set("alert.target(0).service.port", dstPort)

        # Targetted User
        if user != None:
            idmef.Set("alert.target(0).user.category", "application")
            idmef.Set("alert.target(0).user.user_id(0).type", "target-user")
            idmef.Set("alert.target(0).user.user_id(0).name", user)

        # Severity is based on OSSEC Level
        if int(level) >= 12:
            severity = "high"
        elif int(level) >= 7 and int(level) < 12:
            severity = "medium"
        else:
            severity = "low"
        #print "severity : " + severity
        idmef.Set("alert.assessment.impact.severity", severity)

        #idmef.Set("alert.source(0).process.name","OSSEC")

        # Additional Data
        fieldsOffset = fieldsSet
        #print "fieldsOffset = " + fieldsOffset.__str__()
        #idmef.Set("alert.additional_data(" + fieldsOffset.__str__() + ").type", "string")
        #idmef.Set("alert.additional_data(" + fieldsOffset.__str__() + ").meaning", "OSSEC Rule")
        #idmef.Set("alert.additional_data(" + fieldsOffset.__str__() + ").data", rule)

        #fieldsOffset = fieldsOffset + 1
        msg = "Level " + level
        #print msg
        #idmef.Set("alert.additional_data(" + fieldsOffset.__str__() + ").type", "string")
        idmef.Set(
            "alert.additional_data(" + fieldsOffset.__str__() + ").meaning",
            "OSSEC Level")
        idmef.Set("alert.additional_data(" + fieldsOffset.__str__() + ").data",
                  msg)

        fieldsOffset = fieldsOffset + 1
        #idmef.Set("alert.additional_data(" + fieldsOffset.__str__() + ").type", "string")
        idmef.Set(
            "alert.additional_data(" + fieldsOffset.__str__() + ").meaning",
            "OSSEC Log Location")
        idmef.Set("alert.additional_data(" + fieldsOffset.__str__() + ").data",
                  location)

        client.SendIDMEF(idmef)

        return None

    except Exception, e:
        msg = "processOssecSyslog() : exception : " + e.__str__(
        ) + " line=" + line + "]"
        print msg
        syslog.syslog(msg)
Esempio n. 7
0
def processArgus(txnId,sensorId,line):
    
    try :
        addInfo1 = None
        addInfo2 = None
        
        line = line.rstrip("\n")
        print "processArgus() : line read is " + line
        
        # Ignore file headers
        if line.find("StartTime") != -1 :
            return None

        protocols = re.findall("icmp|tcp|udp",line)
        if len(protocols) > 0 :
            protocol = protocols[0].upper()
        else:
            protocol = "OTHER"    
        #print "protocol = " + protocol

        fields = line.split()
        #print fields
        state = fields[-1]
        
        if state == "s" and protocol == "TCP" :		# SYN scanning
            return None
   
        if state == "sS" and protocol == "TCP" :	# SYN scanning - honeypot has responded with SYN/ACK
            return None

        if state == "sSR" and protocol == "TCP" :	# SYN scanning - honeypot has responded with SYN/ACK and then session is RESET
            return None
   
        bytes = fields[-2]
        pkts  = fields[-3]
        dir   = fields[-5]
        
        if int(bytes) >= 1024 or int(pkts) >= 32 :
            size = "Long "
        else :
            size = ""    
                
        #print "state = " + state
                
        # Where is the scan coming from ?
        ips = re.findall("(\d+\.\d+\.\d+\.\d+)\.(\d+)",line)
        if len(ips) > 0 :
            #print ips
            srcip = ips[0][0]
            sport = ips[0][1]
            dstip = ips[1][0]
            dport = ips[1][1]
        else:
            #print "Can't locate all fields for a flow, so return"
            return None
              
        #print srcip + " -> " + dstip
        
        # Not interested in scan from LAN - includes syslog bursts from ADSL router etc false positives
        #if srcip.find("192.168.1.") != -1 :
        #    return None
        print "*** kojoney_argus_parse.py : calling hiddenIP() ***"         
        if kojoney_hiddenip.hiddenIP(srcip) == True :
            return None
                    
        # Not interested in false alerts from Google DNS
        #if srcip.find("8.8.8.8") != -1 :
        #    return None

        #msg = line[16:] 	   	# skip timestamp
        #msg = msg.replace(":","")
        #msg = msg.replace("mode ","")
        #msg = msg.replace("port scan", "portscan")	# less ambigious when grepping for

        p0fDict = kojoney_p0f_lib.getp0f(srcip,dstip,dport)
        
        # How to solve this more pythonically ???
        #print p0fDict.__str__()
        if p0fDict.__str__() != "None":
            #p0f = " p0f=" + p0fDict['genre_short'] + " hops=" + p0fDict['hops'] + " link=" + p0fDict['link'] + " up=" + p0fDict['uptime']
            p0f = " p0f=" + p0fDict['genre_short'] + " hops=" + p0fDict['hops'] + " up=" + p0fDict['uptime']
            p0fOS = p0fDict['genre_short']
            p0fHops = p0fDict['hops']
        else:
            p0f = ""            
            p0fOS   = "Unknown"
            p0fHops = "Unknown"

        if "192.168.1." in srcip and "192.168.1." in dstip :
            FLOW_TYPE = "AFLOW"
        elif dir == "->" and srcip.find("192.168.1.") >= 0 :	# bug : make this a generic function
            FLOW_TYPE = "AFLOW_OUT"
        elif dir == "->" and srcip.find("192.168.1.") < 0 :
            FLOW_TYPE = "AFLOW_IN"
        else:
            FLOW_TYPE = "AFLOW"        
        print "FLOW_TYPE : " + FLOW_TYPE
            
        msg = srcip + ":" + sport + " " + dir + " " + dstip + ":" + dport + " state=" + state + " pkts=" + pkts + " bytes=" + bytes + p0f
        tweet = FLOW_TYPE + "," + msg	
        
        # Replace destination IP with text
        tweet = kojoney_snort_funcs.snortTwittifyLite(tweet)
        
        # construct return list of tweets
        tweets = []
        tweets.append(tweet)
        
        # Send event to Prelude
        kojoney_argus_idmef.sendArgusIDMEF(srcip,dstip,dport,protocol,dir,state,pkts,bytes,p0fOS,p0fHops,FLOW_TYPE)
 
        # Update Attacker Database        
        attackerIP  = srcip
        phase       = "SCANNING"
        eventSource = "ARGUS"
        eventId     = None
        eventDesc   = FLOW_TYPE
        MD5         = None
        virusVendor = None
        virusName   = None
        addInfo1    = "state=" + state + ":" + "proto=" + protocol + ":" + "dPort=" + dport.__str__() + ":" + "bytes=" + bytes.__str__() + ":" + "pkts=" + pkts.__str__()
        
        # Treat outbound flows as accessing malware download site etc : TCP for HTTP/SSH and UDP for TFTP
        if (protocol == "TCP" or protocol == "UDP") and FLOW_TYPE == "AFLOW_OUT" :
            phase    = "MAINTAIN_ACCESS"
            addInfo2 = "destIP=" + dstip
        elif int(pkts) < 3 :		# downgrade to scan if number of packets is low - may need to tune this value
            phase    = "PROBING"    
            addInfo2 = "<3 pkts"
            
        # Update TSOM calculations    
        kojoney_attacker_event.generateAttackerEvent(txnId,attackerIP,p0fDict,sensorId,phase,eventSource,eventId,eventDesc,MD5,virusVendor,virusName,addInfo1,addInfo2)
        
        #Tweet if flow initiated by honeypot - this is interesting
        if phase == "MAINTAIN_ACCESS":
            return tweets
        else:    
            return None        

    except Exception,e:
        syslog.syslog("kojoney_argus_parse.py : processArgus() : " + `e` + " line=" + line)
        print "processArgus() : exception : " + e.__str__()
        return None
Esempio n. 8
0
def processIplog(txnId,sensorId,line):
    
    try :
        #print "processIplog() : line read is " + line

        # Only interested in scan and flood (start and end) events
        if line.find(" expired for ") == -1 and line.find(" scan detected ") == -1 and line.find(" scan/flood detected ") == -1 :
            return None
        
        # Where is the scan coming from ?
        srcip = re.findall("\d+\.\d+\.\d+\.\d+",line)
        if len(srcip) > 0 :
            srcip = srcip[0]
        else:
            srcip = "None"    
        #print srcip
        
        # Not interested in scan from LAN - includes syslog bursts from ADSL router etc false positives
        if srcip.find("192.168.1.") != -1 :
            return None

        # Not interested in false alerts from Google DNS
        if srcip.find("8.8.8.8") != -1 :
            return None
        
        if  "SYN scan detected" in line :
            scanType = "SYN scan"
        elif "TCP port scan detected" in line :
            scanType = "TCP scan"
        elif "UDP: scan/flood detected" in line :
            scanType = "UDP scan"
        else:
            scanType = "Port scan"	# generic - this value should never be used    
        
        # bug - single port was targetted               
        ports = re.findall("\[port (\d+)\]",line)
        if len(ports) > 0:
            port = ports[0]
        else :
            port = "-1"
        
        msg = line[16:] 	   			# skip timestamp
        msg = msg.replace(":","")
        msg = msg.replace("mode ","")
        msg = msg.replace("port scan", "portscan")	# less ambigious when grepping for
        tweet = "IPLOG," + msg	
        
        # Update Prelude SIEM
        kojoney_iplog_idmef.portScanIDMEF(srcip,scanType,port,line)
        
        # Update Attacker Database
        addInfo1 = None
        addInfo2 = None
        kojoney_attacker_event.generateAttackerEvent(txnId,srcip,None,sensorId,"PSCAN","IPLOG",None,scanType,None,None,None,addInfo1,addInfo2)
                
        # active response against certain ports - but not Microsoft ones
        ACTIVEPORTLIST = ['22','23','25'] # list of ports to add blackholes for 
        if line.find(" scan detected ") == -1 and line.find(" scan/flood detected ") == -1 :
            return None
        else :
            if port in ACTIVEPORTLIST:
                bh_tweet = kojoney_defend.blackhole(txnId,sensorId,srcip)       
                #if bh_tweet == None:
                #    return None
            else:
                bh_tweet = None
                            
        # construct return list of tweets
        tweets = []
        tweets.append(tweet)
        if bh_tweet != None:
            tweets.append(bh_tweet)
        
        return tweets

    except Exception,e:
        msg = "kojoney_iplog_parse.py : processIplog() : " + `e` + " line=" + line
        print msg
        syslog.syslog(msg)
        return None