Example #1
0
 def test_whois(self):
     o = WhoisEntry()
     o.dnssec = UNICODE_STR
     o2 = round_trip(o)
Example #2
0
    def __create_whois_object(self, domain):
        """ Creates a CybOX WHOISObjectType object """
        if not domain:
            return None

        if(self.__verbose_output):
            sys.stderr.write("** creating Whois object for: %s\n" % domain)

        if self.http_whois:
            record = self.__get_whois_record_http(domain)
        else:
            record = self.__get_whois_record(domain)

        if not record:
            return None

        whois = WhoisEntry()

        record['status'] = ['OK' if status == 'ACTIVE' else status for status in record['status']]

        #Only build registrar info objects if we have the relevant info
        if (record['registrar'] or record['whois_server'] or
                    record['registrar_address'] or record['referral_url'] or
                    record['registrar_contacts']):
            registrar = WhoisRegistrar()
            registrar.name = String(record.get('registrar'))
            registrar.address = String(record.get('registrar_address'))
            registrar.whois_server = URI(record.get('whois_server'))
            registrar.referral_url = URI(record.get('referral_url'))

            contacts = WhoisContacts()
            for email in record['registrar_contacts']:
                contact = WhoisContact()
                contact.contact_type = 'ADMIN'
                contact.name = String(record.get('registrar'))
                contact.email_address = EmailAddress(email)

                contacts.append(contact)
            registrar.contacts = contacts

            whois.registrar_info = registrar

        whois.domain_name = self.__create_domain_name_object(record.get('domain_name'))

        nservers = WhoisNameservers()
        for url in record.get('name_servers', []):
            nservers.append(self.__create_url_object(url))
        if nservers:
            whois.nameservers = nservers

        status = WhoisStatuses()
        for s in record.get('status', []):
            status.append(WhoisStatus(s))
        if status:
            whois.status = status

        whois.updated_date = DateTime(record.get('updated_date'))
        whois.creation_date = DateTime(record.get('creation_date'))
        whois.expiration_date = DateTime(record.get('expiration_date'))

        return whois
 def test_whois(self):
     o = WhoisEntry()
     o.dnssec = UNICODE_STR
     o2 = round_trip(o)
def adptr_dict2STIX(srcObj, data):
    sTxt = "Called... "
    sndMSG(sTxt, 'INFO', 'adptr_dict2STIX()')
    stixObj = None

    ### Input Check
    if srcObj == None or data == None:
        #TODO: Needs error msg: Missing srcData Object
        return (False)

    ### Generate NameSpace id tags
    STIX_NAMESPACE = {"http://hailataxii.com": "opensource"}
    OBS_NAMESPACE = Namespace("http://hailataxii.com", "opensource")
    stix_set_id_namespace(STIX_NAMESPACE)
    obs_set_id_namespace(OBS_NAMESPACE)

    ### Building STIX Wrapper
    stix_package = STIXPackage()
    objIndicator = Indicator()

    ### Bulid Object Data
    for sKey in data:
        objIndicator = Indicator()
        listOBS = []

        oObsSrcData = genObsSrcData(srcObj, data[sKey])

        ### Parsing IP Address
        sAddr = sKey
        if len(sAddr) > 0:
            objAddr = Address()
            objAddr.is_source = True
            objAddr.address_value = sAddr
            objAddr.address_value.condition = 'InclusiveBetween'

            objAddr.category = 'ipv4-net'

            obsAddr = Observable(objAddr)
            objAddr = None
            obsAddr.sighting_count = int(data[sKey]['attrib']['Attacks'])
            oObsSrcData.sighting_count = int(data[sKey]['attrib']['Attacks'])
            obsAddr.observable_source.append(oObsSrcData)

            sTitle = 'NETWORK_range: ' + sAddr
            obsAddr.title = sTitle
            sDscpt = 'ipv4-net' + ': ' + sAddr + " | "
            sDscpt += "is_source: True | "
            sDscpt += "Attack_Count: " + data[sKey]['attrib']['Attacks'] + " | "
            sDscpt += "Attack_DateRange: " + data[sKey]['attrib'][
                'dateRange'] + " | "
            obsAddr.description = sDscpt
            listOBS.append(obsAddr)
            obsAddr = None

        ### Parsing Registrar Information
        if data[sKey]['attrib']['email']:
            objEmail = EmailAddress()
            objEmail.address_value = data[sKey]['attrib']['email']
            objEmail.address_value.condition = 'Equals'
            objEmail.category = 'e-mail'

            objWhoisReg = WhoisRegistrar()
            if len(data[sKey]['attrib']['Name']) > 1:
                objWhoisReg.name = data[sKey]['attrib']['Name']
            objWhoisReg.email_address = objEmail
            objEmail = None

            objWhois = WhoisEntry()
            objWhois.registrar_info = objWhoisReg

            obsWhois = Observable(objWhois)
            #print obsWhois.id_
            objWhois = None
            obsWhois.sighting_count = 1

            sTitle = 'REGISTRAR_email: ' + data[sKey]['attrib']['email']
            if len(data[sKey]['attrib']['Name']) > 0:
                sTitle += " | REGISTRAR_name: " + data[sKey]['attrib'][
                    'Name'] + " | "
            obsWhois.title = sTitle
            obsWhois.description = sTitle
            listOBS.append(obsWhois)
            obsWhois = None

        sDscrpt = None
        sCntry_code = None
        sCntry_name = None
        sRgstra_email = None
        sRgstra_name = None

        if len(data[sKey]['attrib']['Country']) > 0:
            sCntry_code = data[sKey]['attrib']['Country']
            if sCntry_code in dictCC2CN:
                sCntry_name = dictCC2CN[sCntry_code]

        if 'email' in data[sKey]['attrib']:
            sRgstra_email = data[sKey]['attrib']['email']

        if len(data[sKey]['attrib']['Name']) > 0:
            sRgstra_name = data[sKey]['attrib']['Name']

        sDscrpt = "This IP block appears to have "
        if sCntry_code:
            sDscrpt += "originated in " + sCntry_code
            if sCntry_name:
                sDscrpt += "(" + sCntry_name + ")"
        if sCntry_code and (sRgstra_email or sRgstra_name):
            sDscrpt += " and is "
        if sRgstra_email:
            sDscrpt += "register to " + sRgstra_email
        if sRgstra_email and sRgstra_name:
            sDscrpt += " of " + sRgstra_name
        elif sRgstra_name:
            sDscrpt += "register to " + sRgstra_name
        sDscrpt += "."

        if sCntry_code or sRgstra_email or sRgstra_name:
            objIndicator.description = "<![CDATA[" + sDscrpt + "]]>"

        objIndicator.title = sAddr.replace('##comma##',
                                           ' - ') + " | " + srcObj.pkgTitle

        ### Add Generated observable to Indicator
        objIndicator.add_indicator_type("IP Watchlist")
        objIndicator.observable_composition_operator = 'OR'
        objIndicator.observables = listOBS

        #Parsing Producer
        sProducer = srcObj.Domain
        if len(sProducer) > 0:
            objIndicator.set_producer_identity(sProducer)

        objIndicator.set_produced_time(data[sKey]['attrib']['dateVF'])
        objIndicator.set_received_time(data[sKey]['dateDL'])

        stix_package.add_indicator(objIndicator)
        objIndicator = None

    ### STIX Package Meta Data
    stix_header = STIXHeader()
    stix_header.title = srcObj.pkgTitle
    stix_header.description = "<![CDATA[" + srcObj.pkgDscrpt + "]]>"

    ### Understanding markings http://stixproject.github.io/idioms/features/data-markings/
    marking_specification = MarkingSpecification()

    classLevel = SimpleMarkingStructure()
    classLevel.statement = "Unclassified (Public)"
    marking_specification.marking_structures.append(classLevel)

    objTOU = TermsOfUseMarkingStructure()
    #sTOU = open('tou.txt').read()
    objTOU.terms_of_use = sProducer + " | " + srcObj.srcTOU
    marking_specification.marking_structures.append(objTOU)

    tlp = TLPMarkingStructure()
    tlp.color = "WHITE"
    marking_specification.marking_structures.append(tlp)
    marking_specification.controlled_structure = "//node()"

    handling = Marking()
    handling.add_marking(marking_specification)
    stix_header.handling = handling

    stix_package.stix_header = stix_header
    stix_header = None

    ### Generate STIX XML File
    locSTIXFile = 'STIX_' + srcObj.fileName.split('.')[0] + '.xml'
    sndFile(stix_package.to_xml(), locSTIXFile)

    return (stix_package)
Example #5
0
def main():

    # get args
    parser = argparse.ArgumentParser ( description = "Parse a given CSV from Shadowserver and output STIX XML to stdout"
    , formatter_class=argparse.ArgumentDefaultsHelpFormatter )

    parser.add_argument("--infile","-f", help="input CSV with bot data", default = "bots.csv")

    args = parser.parse_args()


    # setup stix document
    stix_package = STIXPackage()
    stix_header = STIXHeader()
    stix_header.title = "Bot Server IP addresses"
    stix_header.description = "IP addresses connecting to bot control servers at a given port"
    stix_header.add_package_intent ("Indicators - Watchlist")

    # add marking
    mark = Marking()
    markspec = MarkingSpecification()
    markstruct = SimpleMarkingStructure()
    markstruct.statement = "Usage of this information, including integration into security mechanisms implies agreement with the Shadowserver Terms of Service  available at  https://www.shadowserver.org/wiki/pmwiki.php/Shadowserver/TermsOfService"
    markspec.marking_structures.append(markstruct)
    mark.add_marking(markspec)

    stix_header.handling = mark

    # include author info
    stix_header.information_source = InformationSource()
    stix_header.information_source.time = Time()
    stix_header.information_source.time.produced_time  =datetime.now(tzutc())
    stix_header.information_source.tools = ToolInformationList()
    stix_header.information_source.tools.append("ShadowBotnetIP-STIXParser")
    stix_header.information_source.identity = Identity()
    stix_header.information_source.identity.name = "MITRE STIX Team"
    stix_header.information_source.add_role(VocabString("Format Transformer"))

    src = InformationSource()
    src.description = "https://www.shadowserver.org/wiki/pmwiki.php/Services/Botnet-CCIP"
    srcident = Identity()
    srcident.name = "shadowserver.org"
    src.identity = srcident
    src.add_role(VocabString("Originating Publisher"))
    stix_header.information_source.add_contributing_source(src)

    stix_package.stix_header = stix_header

    # add TTP for overall indicators
    bot_ttp = TTP()
    bot_ttp.title = 'Botnet C2'
    bot_ttp.resources = Resource()
    bot_ttp.resources.infrastructure = Infrastructure()
    bot_ttp.resources.infrastructure.title = 'Botnet C2'

    stix_package.add_ttp(bot_ttp)

    # read input data
    fd = open (args.infile, "rb") 
    infile = csv.DictReader(fd)

    for row in infile:
    # split indicators out, may be 1..n with positional storage, same port and channel, inconsistent delims
        domain = row['Domain'].split()
        country = row['Country'].split()
        region = row['Region'].split('|')
        state = row['State'].split('|')
        asn = row['ASN'].split()
        asname = row['AS Name'].split()
        asdesc = row['AS Description'].split('|')

        index = 0
        for ip in row['IP Address'].split():
            indicator = Indicator()
            indicator.title = "IP indicator for " + row['Channel'] 
            indicator.description = "Bot connecting to control server"


            # point to overall TTP
            indicator.add_indicated_ttp(TTP(idref=bot_ttp.id_))

            # add our IP and port
            sock = SocketAddress()
            sock.ip_address = ip

            # add sighting
            sight = Sighting()
            sight.timestamp = ""
            obs = Observable(item=sock.ip_address)
            obsref = Observable(idref=obs.id_)
            sight.related_observables.append(obsref)
            indicator.sightings.append(sight)

            stix_package.add_observable(obs)

            # add pattern for indicator
            sock_pattern = SocketAddress()
            sock_pattern.ip_address = ip
            port = Port()
            port.port_value = row['Port']
            sock_pattern.port = port

            sock_pattern.ip_address.condition= "Equals"
            sock_pattern.port.port_value.condition= "Equals"

            indicator.add_object(sock_pattern)
            stix_package.add_indicator(indicator)
            
            # add domain
            domain_obj = DomainName()
            domain_obj.value = domain[index]
            domain_obj.add_related(sock.ip_address,"Resolved_To", inline=False)

            stix_package.add_observable(domain_obj)

            # add whois obs
            whois_obj = WhoisEntry()
            registrar = WhoisRegistrar()
            registrar.name = asname[index] 
            registrar.address = state[index] + region[index] + country[index]

            whois_obj.registrar_info = registrar 
            whois_obj.add_related(sock.ip_address,"Characterizes", inline=False)

            stix_package.add_observable(whois_obj)
            
            # add ASN obj
            asn_obj = AutonomousSystem()
            asn_obj.name = asname[index] 
            asn_obj.number = asn[index]
            asn_obj.handle = "AS" + str(asn[index])
            asn_obj.add_related(sock.ip_address,"Contains", inline=False)

            stix_package.add_observable(asn_obj)

            # iterate 
            index = index + 1

    print stix_package.to_xml()