def DNSRequestObj(dnsinfo): networkconnection = NetworkConnection() networkconnection.layer3_protocol = "IPv4" networkconnection.layer4_protocol = "UDP" networkconnection.layer7_protocol = "DNS" ssocketaddress = SocketAddress() sport = Port() sport.port_value = dnsinfo[1] sport.layer4_protocol = "UDP" ssocketaddress.port = sport networkconnection.source_socket_address = ssocketaddress dsocketaddress = SocketAddress() dsocketaddress.ip_address = dnsinfo[2] dport = Port() dport.port_value = dnsinfo[3] dport.layer4_protocol = "UDP" dsocketaddress.port = dport networkconnection.destination_socket_address = dsocketaddress layer7connections = Layer7Connections() dqr = DNSQuery() indicator = Indicator() dnsques = DNSQuestion() dnsques.qname = dnsinfo[4] dnsques.qtype = translateType(dnsinfo[5]) dqr.question = dnsques indicator.title = "DNS Request" indicator.description = ( "An indicator containing information about a DNS Request") layer7connections.dns_query = dqr networkconnection.layer7_connections = layer7connections indicator.set_produced_time(utils.dates.now()) indicator.add_object(networkconnection) return indicator
def TCPConnectionEstablishedObj(tcpinfo): networkconnection = NetworkConnection() networkconnection.layer3_protocol = "IPv4" networkconnection.layer4_protocol = "TCP" if tcpinfo[0] != VMIP: # incoming connection networkconnection.destination_tcp_state = "ESTABLISHED" ssocketaddress = SocketAddress() ssocketaddress.ip_address = tcpinfo[0] sport = Port() sport.port_value = tcpinfo[2] sport.layer4_protocol = "TCP" ssocketaddress.port = sport networkconnection.source_socket_address = ssocketaddress elif tcpinfo[1] != VMIP: # outgoing connection networkconnection.source_tcp_state = "ESTABLISHED" dsocketaddress = SocketAddress() dsocketaddress.ip_address = tcpinfo[1] dport = Port() dport.port_value = tcpinfo[3] dport.layer4_protocol = "TCP" dsocketaddress.port = dport networkconnection.destination_socket_address = dsocketaddress indicator = Indicator() indicator.title = "TCP Connection Established" indicator.description = ( "An indicator containing information about a successful TCP hand shake" ) indicator.set_produced_time(utils.dates.now()) indicator.add_object(networkconnection) return indicator
def UDPRequestObj(udpinfo): u = NetworkConnection() u.layer3_protocol = "IPv4" u.layer4_protocol = "UDP" ssocketaddress = SocketAddress() if udpinfo[3] != VMIP: ssocketaddress.ip_address = udpinfo[3] sport = Port() sport.port_value = udpinfo[0] sport.layer4_protocol = "UDP" ssocketaddress.port = sport u.source_socket_address = ssocketaddress dsocketaddress = SocketAddress() if udpinfo[2] != VMIP: dsocketaddress.ip_address = udpinfo[2] dport = Port() dport.port_value = udpinfo[1] dport.layer4_protocol = "UDP" dsocketaddress.port = dport u.destination_socket_address = dsocketaddress indicator = Indicator() indicator.title = "UDP connection" indicator.description = ( "An indicator containing information about a UDP connection") indicator.set_produced_time(utils.dates.now()) indicator.add_object(u) return indicator
def SSHObj(SSH): networkconnection = NetworkConnection() networkconnection.layer3_protocol = "IPv4" networkconnection.layer4_protocol = "TCP" networkconnection.layer7_protocol = "SSH" if SSH[0] != VMIP and SSH[4] == 1 and SSH[5] == 0: # incoming connection ssocketaddress = SocketAddress() ssocketaddress.ip_address = SSH[0] sport = Port() sport.port_value = SSH[1] sport.layer4_protocol = "TCP" ssocketaddress.port = sport networkconnection.source_socket_address = ssocketaddress elif SSH[2] != VMIP and SSH[4] == 1 and SSH[5] == 0: # outgoing connection dsocketaddress = SocketAddress() dsocketaddress.ip_address = SSH[2] dport = Port() dport.port_value = SSH[3] dport.layer4_protocol = "TCP" dsocketaddress.port = dport networkconnection.destination_socket_address = dsocketaddress indicator = Indicator() if SSH[6] != '': indicator.title = "SSH Request with pulic key" indicator.description = ("SSH public key: " + SSH[6]) else: indicator.title = "SSH Request" indicator.description = ( "An indicator containing information about a SSH request") indicator.set_produced_time(utils.dates.now()) indicator.add_object(networkconnection) return indicator
def generateIPObservable(indicator, attribute): indicator.add_indicator_type("IP Watchlist") address_object = resolveIPType(attribute["value"], attribute["type"]) address_object.parent.id_ = cybox.utils.idgen.__generator.namespace.prefix + ":AddressObject-" + attribute[ "uuid"] if ("|" in attribute["value"]): port = attribute["value"].split('|')[1] address_observable = Observable(address_object) address_observable.id_ = cybox.utils.idgen.__generator.namespace.prefix + ":Address-" + attribute[ "uuid"] port_object = Port() port_object.port_value = attribute["value"].split('|')[1] port_object.port_value.condition = "Equals" port_object.parent.id_ = cybox.utils.idgen.__generator.namespace.prefix + ":PortObject-" + attribute[ "uuid"] port_observable = Observable(port_object) port_observable.id_ = cybox.utils.idgen.__generator.namespace.prefix + ":Port-" + attribute[ "uuid"] compositeObject = ObservableComposition( observables=[address_observable, port_observable]) compositeObject.operator = "AND" observable = Observable( id_=cybox.utils.idgen.__generator.namespace.prefix + ":ObservableComposition-" + attribute["uuid"]) observable.observable_composition = compositeObject return observable else: return address_object
def generatePortObservable(indicator, attribute): port_object = Port() port_object.port_value = attribute["value"] port_object.port_value.condition = "Equals" port_object.parent.id_ = cybox.utils.idgen.__generator.namespace.prefix + ":PortObject-" + attribute[ "uuid"] return port_object
def cybox_object_http(obj): http_session = HTTPSession() hh = HTTPRequestResponse() hc = HTTPClientRequest() if obj.client_request.message_body: hm = HTTPMessage() hm.lenght = len(obj.client_request.message_body) hm.message_body = String(obj.client_request.message_body) hc.http_message_body = hm rh = HTTPRequestHeader() if obj.client_request.raw_header: rh.raw_header = String(obj.client_request.raw_header) hhf = HTTPRequestHeaderFields() hhf.user_agent = String(obj.client_request.user_agent) host_field = HostField() host_field.domain_name = URI(value=obj.client_request.domain_name) port = Port() port.port_value = PositiveInteger(obj.client_request.port.port) host_field.port = port hhf.host = host_field rh.parsed_header = hhf hc.http_request_header = rh hl = HTTPRequestLine() hl.http_method = String(obj.client_request.request_method) hl.version = String(obj.client_request.request_version) hl.value = String(obj.client_request.request_uri) hc.http_request_line = hl hh.http_client_request = hc http_session.http_request_response = [hh] return http_session
def add_host(host_info): uri_port = host_info.split(":") hf = HostField() if len(uri_port) > 1: port = Port() port.port_value = uri_port[1] hf.port = port hf.domain_name = URI(uri_port[0], URI.TYPE_DOMAIN) return hf
def convert_address_ref(obj20, direction): # TODO: ref could be to a domain-name sa = None add_property = direction + "_ref" port_property = direction + "_port" if add_property in obj20: if obj20[add_property] in _STIX1X_OBJS: sa = SocketAddress() address_obj = _STIX1X_OBJS[obj20[add_property]] sa.ip_address = address_obj if port_property in obj20: if not sa: sa = SocketAddress() sa.port = Port() sa.port.port_value = obj20[port_property] return sa
def convert_address_ref(obj2x, direction, obs2x_id): sa = None add_property = direction + "_ref" port_property = direction + "_port" if add_property in obj2x: if obj2x[add_property] in _STIX1X_OBJS: sa = SocketAddress() obj = _STIX1X_OBJS[obj2x[add_property]] if isinstance(obj, Address): sa.ip_address = obj elif isinstance(obj, DomainName): sa.hostname = Hostname() sa.hostname.hostname_value = obj.value else: warn("%s is not an index found in %s", 306, obj2x[add_property], obs2x_id) if port_property in obj2x: if not sa: sa = SocketAddress() sa.port = Port() sa.port.port_value = obj2x[port_property] return sa
def generate_ip_observable(self, indicator, attribute): indicator.add_indicator_type("IP Watchlist") address_object = self.resolve_ip_type(attribute.type, attribute.value) address_object.parent.id_ = "{}:AddressObject-{}".format(self.namespace_prefix, attribute.uuid) if '|' in attribute.value: port = attribute.value.split('|')[1] address_observable = Observable(address_object) address_observable.id_ = "{}:Address-{}".format(self.namespace_prefix, attribute.uuid) port_object = Port() port_object.port_value = port port_object.port_value.condition = "Equals" port_object.parent.id_ = "{}:PortObject-{}".format(self.namespace_prefix, attribute.uuid) port_observable = Observable(port_object) port_observable.id_ = "{}:Port-{}".format(self.namespace_prefix, attribute.uuid) compositeObject = ObservableComposition(observables=[address_observable, port_observable]) compositeObject.operator = "AND" observable = Observable(id_ = "{}:ObservableComposition-{}".format(self.namespace_prefix, attribute.uuid)) observable.observable_composition = compositeObject return observable else: return address_object
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 = [] ### Parsing IP Address for sAddr in data[sKey]['attrib']['ipAddrList']: if len(sAddr) > 0: objAddr = Address() objAddr.is_destination = True objAddr.address_value = sAddr #objAddr.address_value.operator = 'Equals' objAddr.address_value.condition = 'Equals' if isIPv4(sAddr): objAddr.category = 'ipv4-addr' elif isIPv6(sAddr): objAddr.category = 'ipv6-addr' else: continue obsAddr = Observable(objAddr) objAddr = None obsAddr.sighting_count = 1 obsAddr.title = 'IP: ' + sAddr sDscrpt = 'IPv4' + ': ' + sAddr + " | " sDscrpt += "isDestination: True | " obsAddr.description = "<![CDATA[" + sDscrpt + "]]>" listOBS.append(obsAddr) obsAddr = None ### Parsing Port Number sPort = data[sKey]['attrib']['ipPort'] if len(sPort) > 0: objPort = Port() objPort.port_value = int(sPort) objPort.port_value.condition = 'Equals' sProtocol = data[sKey]['attrib']['ipProt'] if len(sProtocol) > 0: objPort.layer4_protocol = sProtocol.upper() obsPort = Observable(objPort) objPort = None obsPort.sighting_count = 1 obsPort.title = 'Port: ' + sPort sDscrpt = 'PortNumber' + ': ' + sPort + " | " sDscrpt += "Protocol: " + sProtocol.upper() + " | " obsPort.description = "<![CDATA[" + sDscrpt + "]]>" listOBS.append(obsPort) ### Add Generated observable to Indicator objIndicator.add_indicator_type("IP Watchlist") objIndicator.observable_composition_operator = 'OR' objIndicator.observables = listOBS from stix.extensions.test_mechanism.snort_test_mechanism import SnortTestMechanism from stix.common import InformationSource, Identity testMech = SnortTestMechanism() testMech.rules = [data[sKey]['attrib']['rule']] testMech.efficacy = "Unknown" infoSrc = InformationSource(identity=Identity(name=srcObj.Domain)) infoSrc.add_contributing_source("http://www.shadowserver.org") infoSrc.add_contributing_source("https://spyeyetracker.abuse.ch") infoSrc.add_contributing_source("https://palevotracker.abuse.ch") infoSrc.add_contributing_source("https://zeustracker.abuse.ch") testMech.producer = infoSrc lstRef = data[sKey]['attrib']['reference'].split('|') testMech.producer.references = lstRef objIndicator.test_mechanisms = [testMech] #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']) ### Title / Description Generator objIndicator.set_received_time(data[sKey]['dateDL']) sTitle = "sid:" + data[sKey]['attrib']['sid'] + " | " sTitle += data[sKey]['attrib']['msg'] + " | " sTitle += "rev:" + data[sKey]['attrib']['rev'] objIndicator.title = sTitle sDscrpt = "SNORT Rule by Emergingthreats | " + data[sKey]['attrib'][ 'rule'] objIndicator.description = "<![CDATA[" + sDscrpt + "]]>" #Parse TTP objMalware = MalwareInstance() nameList = data[sKey]['attrib']['flowbits'] if len(nameList) > 0: nameList = nameList.split("|") for sName in nameList: sName = sName.split(",")[1] objMalware.add_name(sName) #objMalware.add_type("Remote Access Trojan") objMalware.short_description = data[sKey]['attrib']['msg'] ttpTitle = data[sKey]['attrib']['classtype'] + " | " + data[sKey][ 'attrib']['msg'] objTTP = TTP(title=ttpTitle) objTTP.behavior = Behavior() objTTP.behavior.add_malware_instance(objMalware) objIndicator.add_indicated_ttp(objTTP) #objIndicator.add_indicated_ttp(TTP(idref=objTTP.id_)) #stix_package.add_ttp(objTTP) 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) tlp = TLPMarkingStructure() tlp.color = "WHITE" marking_specification.marking_structures.append(tlp) marking_specification.controlled_structure = "//node()" objTOU = TermsOfUseMarkingStructure() sTOU = open('tou.txt').read() objTOU.terms_of_use = sProducer + " | " + sTOU marking_specification.marking_structures.append(objTOU) 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)
def home(request): """ Name: home Desc: Main GUI view """ # Forms:Job,target and relay creation create_job_form = CreateJob(request=request, prefix="create_job") create_target_form = CreateTarget(request=request, prefix="create_target") create_relay_form = CreateRelay(request=request, prefix="create_relay") if request.method == "POST": # Remove a relay if "delete_relay_id" in request.POST: try: Relay.objects.get(pk=request.POST["delete_relay_id"]).delete() except ObjectDoesNotExist, e: pass # Create new relay if "create_relay-name" in request.POST: # Actuator creation create_relay_form = CreateRelay(request.POST, request=request, prefix="create_relay") if create_relay_form.is_valid(): host = create_relay_form.save() host.save() # TODO - Call a sync here # Job Creations if "create_job-raw_message" in request.POST: new_job = Job(capability=Capability.objects.get( pk=request.POST["create_job-capability"]), target=Target.objects.get( pk=request.POST["create_job-target"]), raw_message="Pending", status=JobStatus.objects.get(status="Pending"), created_by=request.user) new_job.save() # Now we have a pk - update the id command = json.loads(request.POST["create_job-raw_message"]) command["modifiers"]["command-ref"] = new_job.id logger.info("Job Created\n%s" % json.dumps(command)) new_job.raw_message = json.dumps(command, sort_keys=True, indent=4).replace( "\t", u'\xa0\xa0\xa0\xa0\xa0') new_job.save() # Target Creations namespace_url = getattr(settings, "NAMESPACE_URL", None) namespace_id = getattr(settings, "NAMESPACE_ID", None) set_id_namespace(Namespace(namespace_url, namespace_id)) if "create_target-cybox_type" in request.POST: cybox_type = CybOXType.objects.get( pk=request.POST["create_target-cybox_type"]) if cybox_type.identifier == "cybox:NetworkConnectionObjectType": obs = NetworkConnection() # Source sock = SocketAddress() sock.ip_address = request.POST["create_target-source_address"] sock.ip_address.category = "ipv4-addr" sock.ip_address.condition = "Equals" sport = Port() sport.port_value = int( request.POST["create_target-source_port"]) sock.port = sport obs.source_socket_address = sock # Dest sock = SocketAddress() sock.ip_address = request.POST[ "create_target-destination_address"] sock.ip_address.category = "ipv4-addr" sock.ip_address.condition = "Equals" dport = Port() dport.port_value = int( request.POST["create_target-destination_port"]) sock.port = dport obs.destination_socket_address = sock name = "Network Connection %s:%s -> %s:%s (%s)" % ( request.POST["create_target-source_address"], request.POST["create_target-source_port"], request.POST["create_target-destination_address"], request.POST["create_target-destination_port"], request.POST["create_target-protocol"]) raw_message = Observable(item=obs, title=name).to_json() elif cybox_type.identifier == "cybox:AddressObjectType": name = "Address %s " % (request.POST["create_target-address"]) raw_message = Observable(item=Address( address_value=request.POST["create_target-address"], category=Address.CAT_IPV4), title=name).to_json() elif cybox_type.identifier == "cybox:URIObjectType": name = "URI %s " % (request.POST["create_target-uri"]) obs = URI() obs.value = request.POST["create_target-uri"] obs.type_ = URI.TYPE_URL obs.condition = "Equals" raw_message = Observable(item=obs, title=name).to_json() elif cybox_type.identifier == "cybox:EmailMessageObjectType": name = "Email %s " % ( request.POST["create_target-email_subject"]) obs = EmailMessage() obs.raw_body = request.POST["create_target-email_message"] obs.header = EmailHeader() obs.header.subject = request.POST[ "create_target-email_subject"] obs.header.subject.condition = "StartsWith" obs.header.to = request.POST["create_target-email_to"] obs.header.from_ = request.POST["create_target-email_from"] raw_message = Observable(item=obs, title=name).to_json() else: # Should never reach here raw_message = {} name = "Undefined Object" create_target_form = CreateTarget(request.POST, request=request, prefix="create_target") if create_target_form.is_valid(): target = create_target_form.save(commit=False) target.name = name target.raw_message = raw_message target.save()
def make_cybox_object(type_, name=None, value=None): """ Converts type_, name, and value to a CybOX object instance. :param type_: The object type. :type type_: str :param name: The object name. :type name: str :param value: The object value. :type value: str :returns: CybOX object """ if type_ == "Account": acct = Account() acct.description = value return acct elif type_ == "Address": return Address(category=name, address_value=value) elif type_ == "Email Message": e = EmailMessage() e.raw_body = value return e elif type_ == "API": api = API() api.description = value return api elif type_ == "Artifact": if name == "Data Region": atype = Artifact.TYPE_GENERIC elif name == 'FileSystem Fragment': atype = Artifact.TYPE_FILE_SYSTEM elif name == 'Memory Region': atype = Artifact.TYPE_MEMORY else: raise UnsupportedCybOXObjectTypeError(type_, name) return Artifact(value, atype) elif type_ == "Code": obj = Code() obj.code_segment = value obj.type = name return obj elif type_ == "Disk": disk = Disk() disk.disk_name = type_ disk.type = name return disk elif type_ == "Disk Partition": disk = DiskPartition() disk.device_name = type_ disk.type = name return disk elif type_ == "DNS Query": r = URI() r.value = value dq = DNSQuestion() dq.qname = r d = DNSQuery() d.question = dq return d elif type_ == "DNS Record": # DNS Record indicators in CRITs are just a free form text box, there # is no good way to map them into the attributes of a DNSRecord cybox # object. So just stuff it in the description until someone tells me # otherwise. d = StructuredText(value=value) dr = DNSRecord() dr.description = d return dr elif type_ == "GUI Dialogbox": obj = GUIDialogbox() obj.box_text = value return obj elif type_ == "GUI Window": obj = GUIWindow() obj.window_display_name = value return obj elif type_ == "HTTP Request Header Fields" and name and name == "User-Agent": # TODO/NOTE: HTTPRequestHeaderFields has a ton of fields for info. # we should revisit this as UI is reworked or CybOX is improved. obj = HTTPRequestHeaderFields() obj.user_agent = value return obj elif type_ == "Library": obj = Library() obj.name = value obj.type = name return obj elif type_ == "Memory": obj = Memory() obj.memory_source = value return obj elif type_ == "Mutex": m = Mutex() m.named = True m.name = String(value) return m elif type_ == "Network Connection": obj = NetworkConnection() obj.layer7_protocol = value return obj elif type_ == "Pipe": p = Pipe() p.named = True p.name = String(value) return p elif type_ == "Port": p = Port() try: p.port_value = PositiveInteger(value) except ValueError: # XXX: Raise a better exception... raise UnsupportedCybOXObjectTypeError(type_, name) return p elif type_ == "Process": p = Process() p.name = String(value) return p elif type_ == "String": c = Custom() c.custom_name = "crits:String" c.description = ("This is a generic string used as the value of an " "Indicator or Object within CRITs.") c.custom_properties = CustomProperties() p1 = Property() p1.name = "value" p1.description = "Generic String" p1.value = value c.custom_properties.append(p1) return c elif type_ == "System": s = System() s.hostname = String(value) return s elif type_ == "URI": r = URI() r.type_ = name r.value = value return r elif type_ == "User Account": obj = UserAccount() obj.username = value return obj elif type_ == "Volume": obj = Volume() obj.name = value return obj elif type_ == "Win Driver": w = WinDriver() w.driver_name = String(value) return w elif type_ == "Win Event Log": obj = WinEventLog() obj.log = value return obj elif type_ == "Win Event": w = WinEvent() w.name = String(value) return w elif type_ == "Win Handle": obj = WinHandle() obj.type_ = name obj.object_address = value return obj elif type_ == "Win Kernel Hook": obj = WinKernelHook() obj.description = value return obj elif type_ == "Win Mailslot": obj = WinMailslot() obj.name = value return obj elif type_ == "Win Network Share": obj = WinNetworkShare() obj.local_path = value return obj elif type_ == "Win Process": obj = WinProcess() obj.window_title = value return obj elif type_ == "Win Registry Key": obj = WinRegistryKey() obj.key = value return obj elif type_ == "Win Service": obj = WinService() obj.service_name = value return obj elif type_ == "Win System": obj = WinSystem() obj.product_name = value return obj elif type_ == "Win Task": obj = WinTask() obj.name = value return obj elif type_ == "Win User Account": obj = WinUser() obj.security_id = value return obj elif type_ == "Win Volume": obj = WinVolume() obj.drive_letter = value return obj elif type_ == "X509 Certificate": obj = X509Certificate() obj.raw_certificate = value return obj """ The following are types that are listed in the 'Indicator Type' box of the 'New Indicator' dialog in CRITs. These types, unlike those handled above, cannot be written to or read from CybOX at this point. The reason for the type being omitted is written as a comment inline. This can (and should) be revisited as new versions of CybOX are released. NOTE: You will have to update the corresponding make_crits_object function with handling for the reverse direction. In the mean time, these types will raise unsupported errors. """ #elif type_ == "Device": # No CybOX API #elif type_ == "DNS Cache": # No CybOX API #elif type_ == "GUI": # revisit when CRITs supports width & height specification #elif type_ == "HTTP Session": # No good mapping between CybOX/CRITs #elif type_ == "Linux Package": # No CybOX API #elif type_ == "Network Packet": # No good mapping between CybOX/CRITs #elif type_ == "Network Route Entry": # No CybOX API #elif type_ == "Network Route": # No CybOX API #elif type_ == "Network Subnet": # No CybOX API #elif type_ == "Semaphore": # No CybOX API #elif type_ == "Socket": # No good mapping between CybOX/CRITs #elif type_ == "UNIX File": # No CybOX API #elif type_ == "UNIX Network Route Entry": # No CybOX API #elif type_ == "UNIX Pipe": # No CybOX API #elif type_ == "UNIX Process": # No CybOX API #elif type_ == "UNIX User Account": # No CybOX API #elif type_ == "UNIX Volume": # No CybOX API #elif type_ == "User Session": # No CybOX API #elif type_ == "Whois": # No good mapping between CybOX/CRITs #elif type_ == "Win Computer Account": # No CybOX API #elif type_ == "Win Critical Section": # No CybOX API #elif type_ == "Win Executable File": # No good mapping between CybOX/CRITs #elif type_ == "Win File": # No good mapping between CybOX/CRITs #elif type_ == "Win Kernel": # No CybOX API #elif type_ == "Win Mutex": # No good mapping between CybOX/CRITs #elif type_ == "Win Network Route Entry": # No CybOX API #elif type_ == "Win Pipe": # No good mapping between CybOX/CRITs #elif type_ == "Win Prefetch": # No CybOX API #elif type_ == "Win Semaphore": # No CybOX API #elif type_ == "Win System Restore": # No CybOX API #elif type_ == "Win Thread": # No good mapping between CybOX/CRITs #elif type_ == "Win Waitable Timer": # No CybOX API raise UnsupportedCybOXObjectTypeError(type_, name)
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() # if 'indicator' in data[sKey]['meta']['IDs']: # objIndicator.id_ = data[sKey]['meta']['IDs'].key # else: # data[sKey]['meta']['IDs'].update({objIndicator.id_:'indicator'}) listOBS = [] ### Parsing IP Address sAddr = data[sKey]['attrib']['IP Address'] if sAddr: objAddr = Address() objAddr.is_source = True objAddr.address_value = sAddr objAddr.address_value.condition = 'Equals' if isIPv4(sAddr): objAddr.category = 'ipv4-addr' elif isIPv6(sAddr): objAddr.category = 'ipv6-addr' else: continue obsAddr = Observable(objAddr) # if 'address"' in data[sKey]['meta']['IDs']: # obsAddr.id_ = data[sKey]['meta']['IDs'].key # else: # data[sKey]['meta']['IDs'].update({objIndicator.id_:'address'}) objAddr = None obsAddr.sighting_count = 1 obsAddr.title = 'IP: ' + sAddr sDscrpt = 'IPv4' + ': ' + sAddr + " | " sDscrpt += "isSource: True | " obsAddr.description = "<![CDATA[" + sDscrpt + "]]>" listOBS.append(obsAddr) obsAddr = None objIndicator.add_indicator_type("IP Watchlist") ### Parsing Domain sDomain = data[sKey]['attrib']['Hostname'] if sDomain: objDomain = DomainName() objDomain.value = sDomain objDomain.value.condition = 'Equals' if isFQDN(sDomain): objDomain.type = 'FQDN' elif isTLD(sDomain): objDomain.type = 'TLD' else: continue obsDomain = Observable(objDomain) # if 'domain' in data[sKey]['meta']['IDs']: # obsDomain.id_ = data[sKey]['meta']['IDs'].key # else: # data[sKey]['meta']['IDs'].update({obsDomain.id_:'domain'}) objDomain = None obsDomain.sighting_count = 1 obsDomain.title = 'Domain: ' + sDomain sDscrpt = 'Domain: ' + sDomain + " | " sDscrpt += "isFQDN: True | " obsDomain.description = "<![CDATA[" + sDscrpt + "]]>" listOBS.append(obsDomain) obsDomain = None objIndicator.add_indicator_type("Domain Watchlist") ### Parsing Port Number sPortList = data[sKey]['attrib']['Ports'] for item in sPortList: if sPortList[item]: objPort = Port() sPort = sPortList[item] objPort.port_value = int(sPort) objPort.port_value.condition = 'Equals' objPort.layer4_protocol = 'TCP' obsPort = Observable(objPort) objPort = None obsPort.sighting_count = 1 obsPort.title = 'Port: ' + str(sPort) sDscrpt = 'PortNumber: ' + str(sPort) + " | " sDscrpt += "Protocol: TCP | " obsPort.description = "<![CDATA[" + sDscrpt + "]]>" listOBS.append(obsPort) ### Add Generated observable to Indicator objIndicator.observable_composition_operator = 'OR' objIndicator.observables = listOBS #Parsing Producer infoSrc = InformationSource(identity=Identity(name=srcObj.Domain)) #infoSrc.add_contributing_source(data[sKey]['attrib']['ref']) objIndicator.producer = infoSrc # if data[sKey]['attrib']['lstDateVF']: # objIndicator.set_produced_time(data[sKey]['attrib']['lstDateVF'][0]); objIndicator.set_received_time(data[sKey]['meta']['dateDL']) ### Generate Indicator Title based on availbe data lstContainng = [] lstIs = [] sTitle = ' This' if data[sKey]['attrib']['Hostname']: sTitle += ' domain ' + data[sKey]['attrib']['Hostname'] else: sTitle += ' ipAddress ' + sKey sTitle += ' has been identified as a TOR network "Exit Point" router' objIndicator.title = sTitle ### Generate Indicator Description based on availbe data sDscrpt = ' torstatus.blutmagie.de has identified this' if data[sKey]['attrib']['Hostname']: sDscrpt += ' domain ' + data[sKey]['attrib']['Hostname'] else: sDscrpt += ' ipAddress ' + sKey # sDscrpt += ' with a router name of "' + data[sKey]['attrib']['Router Name'] + '"' # if data[sKey]['attrib']['Ports']['ORPort']: # sDscrpt += ' using ORPort: ' + str(data[sKey]['attrib']['Ports']['ORPort']) # if data[sKey]['attrib']['Ports']['DirPort']: # sDscrpt += ' and DirPort: ' + str(data[sKey]['attrib']['Ports']['DirPort']) sDscrpt += ' as a TOR network "Exit Point" router' if data[sKey]['attrib']['Country Code']: sCntry_code = data[sKey]['attrib']['Country Code'] if sCntry_code in dictCC2CN: sCntry_name = dictCC2CN[sCntry_code] sDscrpt += ', which appears to be located in ' + sCntry_name sDscrpt += '. \n\n RawData: ' + str(data[sKey]['attrib']) objIndicator.description = "<![CDATA[" + sDscrpt + "]]>" #Parse TTP # objMalware = MalwareInstance() # objMalware.add_type("Remote Access Trojan") # ttpTitle = data[sKey]['attrib']['type'] # objTTP = TTP(title=ttpTitle) # objTTP.behavior = Behavior() # objTTP.behavior.add_malware_instance(objMalware) # objIndicator.add_indicated_ttp(objTTP) #objIndicator.add_indicated_ttp(TTP(idref=objTTP.id_)) #stix_package.add_ttp(objTTP) 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) tlp = TLPMarkingStructure() tlp.color = "WHITE" marking_specification.marking_structures.append(tlp) marking_specification.controlled_structure = "//node()" objTOU = TermsOfUseMarkingStructure() sTOU = open('tou.txt').read() objTOU.terms_of_use = srcObj.Domain + " | " + sTOU marking_specification.marking_structures.append(objTOU) 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) # locDataFile = 'db_' + srcObj.fileName.split('.')[0] + '.json' # sndFile_Dict2JSON(data,locDataFile); # data = None return (stix_package)
def make_cybox_object(type_, value=None): """ Converts type_, name, and value to a CybOX object instance. :param type_: The object type. :type type_: str :param value: The object value. :type value: str :returns: CybOX object """ if type_ == IndicatorTypes.USER_ID: acct = Account() acct.description = value return acct elif type_ in IPTypes.values(): if type_ == IPTypes.IPV4_ADDRESS: name = 'ipv4-addr' elif type_ == IPTypes.IPV6_ADDRESS: name = 'ipv6-addr' elif type_ == IPTypes.IPV4_SUBNET: name = 'ipv4-net' elif type_ == IPTypes.IPV6_SUBNET: name = 'ipv6-net' return Address(category=name, address_value=value) elif type_ == IndicatorTypes.API_KEY: api = API() api.description = value return api elif type_ == IndicatorTypes.DOMAIN: obj = DomainName() obj.value = value elif type_ == IndicatorTypes.USER_AGENT: obj = HTTPRequestHeaderFields() obj.user_agent = value return obj elif type_ == IndicatorTypes.MUTEX: m = Mutex() m.named = True m.name = String(value) return m elif type_ in (IndicatorTypes.SOURCE_PORT, IndicatorTypes.DEST_PORT): p = Port() try: p.port_value = PositiveInteger(value) except ValueError: # XXX: Raise a better exception... raise UnsupportedCybOXObjectTypeError(type_, name) return p elif type_ == IndicatorTypes.PROCESS_NAME: p = Process() p.name = String(value) return p elif type_ == IndicatorTypes.URI: r = URI() r.type_ = 'URL' r.value = value return r elif type_ in (IndicatorTypes.REGISTRY_KEY, IndicatorTypes.REG_KEY_CREATED, IndicatorTypes.REG_KEY_DELETED, IndicatorTypes.REG_KEY_ENUMERATED, IndicatorTypes.REG_KEY_MONITORED, IndicatorTypes.REG_KEY_OPENED): obj = WinRegistryKey() obj.key = value return obj """ The following are types that are listed in the 'Indicator Type' box of the 'New Indicator' dialog in CRITs. These types, unlike those handled above, cannot be written to or read from CybOX at this point. The reason for the type being omitted is written as a comment inline. This can (and should) be revisited as new versions of CybOX are released. NOTE: You will have to update the corresponding make_crits_object function with handling for the reverse direction. In the mean time, these types will raise unsupported errors. """ #elif type_ == "Device": # No CybOX API #elif type_ == "DNS Cache": # No CybOX API #elif type_ == "GUI": # revisit when CRITs supports width & height specification #elif type_ == "HTTP Session": # No good mapping between CybOX/CRITs #elif type_ == "Linux Package": # No CybOX API #elif type_ == "Network Packet": # No good mapping between CybOX/CRITs #elif type_ == "Network Route Entry": # No CybOX API #elif type_ == "Network Route": # No CybOX API #elif type_ == "Network Subnet": # No CybOX API #elif type_ == "Semaphore": # No CybOX API #elif type_ == "Socket": # No good mapping between CybOX/CRITs #elif type_ == "UNIX File": # No CybOX API #elif type_ == "UNIX Network Route Entry": # No CybOX API #elif type_ == "UNIX Pipe": # No CybOX API #elif type_ == "UNIX Process": # No CybOX API #elif type_ == "UNIX User Account": # No CybOX API #elif type_ == "UNIX Volume": # No CybOX API #elif type_ == "User Session": # No CybOX API #elif type_ == "Whois": # No good mapping between CybOX/CRITs #elif type_ == "Win Computer Account": # No CybOX API #elif type_ == "Win Critical Section": # No CybOX API #elif type_ == "Win Executable File": # No good mapping between CybOX/CRITs #elif type_ == "Win File": # No good mapping between CybOX/CRITs #elif type_ == "Win Kernel": # No CybOX API #elif type_ == "Win Mutex": # No good mapping between CybOX/CRITs #elif type_ == "Win Network Route Entry": # No CybOX API #elif type_ == "Win Pipe": # No good mapping between CybOX/CRITs #elif type_ == "Win Prefetch": # No CybOX API #elif type_ == "Win Semaphore": # No CybOX API #elif type_ == "Win System Restore": # No CybOX API #elif type_ == "Win Thread": # No good mapping between CybOX/CRITs #elif type_ == "Win Waitable Timer": # No CybOX API raise UnsupportedCybOXObjectTypeError(type_, name)
def generate_port_observable(self, indicator, attribute): port_object = Port() port_object.port_value = attribute.value port_object.port_value.condition = "Equals" port_object.parent.id_ = "{}:PortObject-{}".format(self.namespace_prefix, attribute.uuid) return port_object
def create_port(prtvalue): prt = Port() prt.port_value = prtvalue return prt
def FTPObj(ftp): networkconnection = NetworkConnection() networkconnection.layer3_protocol = "IPv4" networkconnection.layer4_protocol = "TCP" networkconnection.layer7_protocol = "FTP" indicator = Indicator() if ftp[4] == '220': if ftp[0] != VMIP: # incoming connection ssocketaddress = SocketAddress() ssocketaddress.ip_address = ftp[0] sport = Port() sport.port_value = ftp[1] sport.layer4_protocol = "TCP" ssocketaddress.port = sport networkconnection.source_socket_address = ssocketaddress elif ftp[2] != VMIP: # outgoing connection dsocketaddress = SocketAddress() dsocketaddress.ip_address = ftp[2] dport = Port() dport.port_value = ftp[3] dport.layer4_protocol = "TCP" dsocketaddress.port = dport networkconnection.destination_socket_address = dsocketaddress indicator.title = "FTP" indicator.description = ("Service ready for new user: "******"TCP" ssocketaddress.port = sport networkconnection.source_socket_address = ssocketaddress elif ftp[2] != VMIP: # outgoing connection dsocketaddress = SocketAddress() dsocketaddress.ip_address = ftp[2] dport = Port() dport.port_value = ftp[3] dport.layer4_protocol = "TCP" dsocketaddress.port = dport networkconnection.destination_socket_address = dsocketaddress indicator.title = "FTP" indicator.description = ("User logged in") indicator.set_produced_time(utils.dates.now()) indicator.add_object(networkconnection) return indicator elif ftp[4] == '250': if ftp[0] != VMIP: # incoming connection ssocketaddress = SocketAddress() ssocketaddress.ip_address = ftp[0] sport = Port() sport.port_value = ftp[1] sport.layer4_protocol = "TCP" ssocketaddress.port = sport networkconnection.source_socket_address = ssocketaddress elif ftp[2] != VMIP: # outgoing connection dsocketaddress = SocketAddress() dsocketaddress.ip_address = ftp[2] dport = Port() dport.port_value = ftp[3] dport.layer4_protocol = "TCP" dsocketaddress.port = dport networkconnection.destination_socket_address = dsocketaddress indicator.title = "FTP" indicator.description = ("Requested file action okay, completed.") indicator.set_produced_time(utils.dates.now()) indicator.add_object(networkconnection) return indicator elif ftp[5] == "USER": if ftp[0] != VMIP: # incoming connection ssocketaddress = SocketAddress() ssocketaddress.ip_address = ftp[0] sport = Port() sport.port_value = ftp[1] sport.layer4_protocol = "TCP" ssocketaddress.port = sport networkconnection.source_socket_address = ssocketaddress elif ftp[2] != VMIP: # outgoing connection dsocketaddress = SocketAddress() dsocketaddress.ip_address = ftp[2] dport = Port() dport.port_value = ftp[3] dport.layer4_protocol = "TCP" dsocketaddress.port = dport networkconnection.destination_socket_address = dsocketaddress indicator.title = "FTP" indicator.description = ("Requested username: "******"PASS": if ftp[0] != VMIP: # incoming connection ssocketaddress = SocketAddress() ssocketaddress.ip_address = ftp[0] sport = Port() sport.port_value = ftp[1] sport.layer4_protocol = "TCP" ssocketaddress.port = sport networkconnection.source_socket_address = ssocketaddress elif ftp[2] != VMIP: # outgoing connection dsocketaddress = SocketAddress() dsocketaddress.ip_address = ftp[2] dport = Port() dport.port_value = ftp[3] dport.layer4_protocol = "TCP" dsocketaddress.port = dport networkconnection.destination_socket_address = dsocketaddress indicator.title = "FTP" indicator.description = ("Requested Password: "******"STOR": if ftp[0] != VMIP: # incoming connection ssocketaddress = SocketAddress() ssocketaddress.ip_address = ftp[0] sport = Port() sport.port_value = ftp[1] sport.layer4_protocol = "TCP" ssocketaddress.port = sport networkconnection.source_socket_address = ssocketaddress elif ftp[2] != VMIP: # outgoing connection dsocketaddress = SocketAddress() dsocketaddress.ip_address = ftp[2] dport = Port() dport.port_value = ftp[3] dport.layer4_protocol = "TCP" dsocketaddress.port = dport networkconnection.destination_socket_address = dsocketaddress indicator.title = "FTP" indicator.description = ("Upload file to server: " + ftp[6]) indicator.set_produced_time(utils.dates.now()) indicator.add_object(networkconnection) return indicator elif ftp[5] == "RETR": if ftp[0] != VMIP: # incoming connection ssocketaddress = SocketAddress() ssocketaddress.ip_address = ftp[0] sport = Port() sport.port_value = ftp[1] sport.layer4_protocol = "TCP" ssocketaddress.port = sport networkconnection.source_socket_address = ssocketaddress elif ftp[2] != VMIP: # outgoing connection dsocketaddress = SocketAddress() dsocketaddress.ip_address = ftp[2] dport = Port() dport.port_value = ftp[3] dport.layer4_protocol = "TCP" dsocketaddress.port = dport networkconnection.destination_socket_address = dsocketaddress indicator.title = "FTP" indicator.description = ("Retrieve a copy of the file: " + ftp[6]) indicator.set_produced_time(utils.dates.now()) indicator.add_object(networkconnection) return indicator
def HTTPFullObj(http): httprequestline = HTTPRequestLine() httprequestline.http_method = http[0] httprequestline.value = http[1] httprequestline.version = http[2] hostfield = HostField() h = URI() h.value = str(http[14]) hostfield.domain_name = h port = Port() port.port_value = http[3] hostfield.port = port httprequestheaderfields = HTTPRequestHeaderFields() if http[4] != '': httprequestheaderfields.accept = http[4] if http[5] != '': httprequestheaderfields.accept_language = http[5] if http[6] != '': httprequestheaderfields.accept_encoding = http[6] if http[7] != '': httprequestheaderfields.authorization = http[7] if http[8] != '': httprequestheaderfields.cache_control = http[8] if http[9] != '': httprequestheaderfields.connection = http[9] if http[10] != '': httprequestheaderfields.cookie = http[10] if http[11] != '': httprequestheaderfields.content_length = http[11] # integer if http[12] != '': httprequestheaderfields.content_type = http[12] if http[13] != '': httprequestheaderfields.date = http[13] # datetime if http[14] != '': httprequestheaderfields.host = hostfield if http[15] != '': httprequestheaderfields.proxy_authorization = http[15] httprequestheader = HTTPRequestHeader() httprequestheader.parsed_header = httprequestheaderfields httpclientrequest = HTTPClientRequest() httpclientrequest.http_request_line = httprequestline httpclientrequest.http_request_header = httprequestheader http_request_response = HTTPRequestResponse() http_request_response.http_client_request = httpclientrequest httpsession = HTTPSession() httpsession.http_request_response = http_request_response layer7connections = Layer7Connections() layer7connections.http_session = httpsession networkconnection = NetworkConnection() networkconnection.layer3_protocol = "IPv4" networkconnection.layer4_protocol = "TCP" networkconnection.layer7_protocol = "HTTP" networkconnection.layer7_connections = layer7connections indicator = Indicator() indicator.title = "HTTP request" indicator.description = ( "An indicator containing information about a HTTP request") indicator.set_produced_time(utils.dates.now()) indicator.add_object(networkconnection) return indicator