def dotransform(request, response): emailaddr = [] msgfile = request.value lookFor = ['To', 'From'] tmpfolder = request.fields['sniffMyPackets.outputfld'] with open(msgfile, mode='r') as msgfile: reader = msgfile.read() reader = str(reader) for x in lookFor: if x in reader: for s in re.finditer('RCPT TO: <([\w.-]+@[\w.-]+)>', reader): to_addr = s.group(1), 'mail_to' emailaddr.append(to_addr) for t in re.finditer('MAIL FROM: <([\w.-]+@[\w.-]+)>', reader): from_addr = t.group(1), 'mail_from' emailaddr.append(from_addr) for addr, addrfield in emailaddr: e = EmailAddress(addr) e.linklabel = addrfield e += Field('filelocation', request.value, displayname='File Location', matchingrule='loose') e += Field('emailaddr', addrfield, displayname='Header Info') response += e return response
def dotransform(request, response, config): if 'workspace' in request.fields: workspace = request.fields['workspace'] else: workspace = request.value dbcon = db_connect(workspace) contact_list = get_contacts(dbcon) for fullname in contact_list: if fullname[0] is None or fullname[1] is None: pass else: e = Person(fullname[0] + ' ' + fullname[1]) e += Field("workspace", workspace, displayname='Workspace') e += Field("fname", fullname[0], displayname='First Name') e += Field("lname", fullname[1], displayname='Last Name') e += Field("title", fullname[3], displayname='Title') e += Field("location", str(fullname[4]) + ', ' + str(fullname[5]), displayname='Location') e += Label("Title", fullname[3]) e += Label("Location", str(fullname[4]) + ', ' + str(fullname[5])) response += e return response
def dotransform(request, response): pcap = request.value mdns_dump = [] phone_info = [] cmd = 'tshark -r ' + pcap + ' -R "dns.resp.type == 0x0010 && udp.length == 82 && ip.dst == 224.0.0.251" -T fields -e eth.src -e ip.src -e dns.resp.name -e dns.txt -E separator=,' mdns_dump = os.popen(cmd).readlines() for x in mdns_dump: x = x.split(',') phone = x[0], x[1], x[2], x[3] if phone not in phone_info: phone_info.append(phone) for mac, ip, name, model in phone_info: for s in re.finditer('(\S*.\S*)..device', name): e = MobilePhone(s.group(1)) e += Field('mac_addr', mac, displayname='MAC Address', matchingrule='loose') e += Field('ip_addr', ip, displayname='IP Address', matchingrule='loose') for s in re.finditer('model=(\S*)', model): e += Field('model', s.group(1), displayname='Phone Model', matchingrule='loose') response += e return response
def dotransform(request, response, config): try: btc_add = bitcoin_address(request.fields['address']) for trans in btc_add['transactions']: if request.value == trans['transaction_hash']: for address in trans['addresses']: e = BitcoinAddress(address) e += Field("date", trans['date'], displayname='Date') e += Field("trans_uri", trans['transaction_uri'], displayname='Transaction URI') e += Field("recieved_address", request.fields['address'], displayname='Recieved Address') e += Label("Bitcoin Address", address) e += Label("Bitcoin Recieved Address", request.fields['address']) e += Label("Transaction Type", trans['transaction_type']) e += Label("Transaction Hash", trans['transaction_hash']) e += Label("Transaction Date", trans['date']) response += e else: pass return response except Exception as e: raise MaltegoException('An error occured: %s' % e)
def remote_transform(args): entity_type, value = split_validate(args.input, 'entity') fields = {} params = [] for f in args.entity_field: name, value = split_validate(f, 'entity field') fields[name] = Field(name=name, value=value) for p in args.transform_parameter: name, value = split_validate(p, 'transform parameter') params += Field(name=name, value=value) try: r = remote_canari_transform_runner( args.host, args.base_path, args.transform, [_Entity(type=entity_type, value=value, fields=fields)], params, Limits(soft=args.soft_limit, hard=args.hard_limit), args.ssl) if r.status == 200: data = r.read() if args.raw_output: print data else: console_writer(MaltegoMessage.parse(data)) exit(0) print 'ERROR: Received status %d for %s://%s/%s. Are you sure you got the right server?' % ( r.status, 'https' if args.ssl else 'http', args.host, args.transform) except Exception, e: print 'ERROR: %s' % e
def dotransform(request, response): devNull = open('/dev/null', 'w') pcap = request.value file_list = [] try: folder = request.fields['sniffMyPackets.outputfld'] except: return response + UIMessage( 'No output folder defined, run the L0 - Prepare pcap transform') # Use need to change the locations in sniffMyPackets.conf if they are different to the defaults for snort snort_path = config['locations/snort'] snort_conf = config['locations/snort_conf'] snort_folder = folder + '/snort' if not os.path.exists(snort_folder): os.makedirs(snort_folder) cmd = snort_path + ' -c ' + snort_conf + ' -r ' + pcap + ' -l ' + snort_folder + ' -D' subprocess.call(cmd, shell=True, stdout=devNull) file_list = glob.glob(snort_folder + '/*') for x in file_list: e = SnortFile(x) e += Field('pcapsrc', request.value, displayname='Original pcap File', matchingrule='loose') e += Field('sniffMyPackets.outputfld', folder, displayname='Folder Location') e += Field('disclaimer', 'Snort is a registered trademark of Sourcefire, Inc', displayname='Disclaimer') response += e return response
def dotransform(request, response): s_ip = request.value layers = ['IP', 'ARP'] try: pcap = request.fields['pcapsrc'] except: return response + UIMessage('Sorry this isnt a SmP IP Address') mac_list = [] pkts = rdpcap(pcap) for x in pkts: for s in layers: if x.haslayer(s) and s == 'ARP': if x[ARP].psrc == s_ip: mac = x[Ether].src if mac not in mac_list: mac_list.append(mac) if x.haslayer(s) and s == 'IP': if x[IP].src == s_ip: mac = x[Ether].src if mac not in mac_list: mac_list.append(mac) for x in mac_list: e = MacAddress(x) e += Field('pcapsrc', pcap, displayname='Original pcap File') e += Field('ipaddrsrc', s_ip, displayname='Original IP Address') response += e return response
def dotransform(request, response): svc_db = 'sniffMyPackets/resources/databases/utilities.db' pcap = request.fields['pcapsrc'] dport = request.fields['sniffMyPackets.hostdport'] proto = request.fields['proto'] service = [] con = lite.connect(svc_db) with con: cur = con.cursor() cur.execute('SELECT * FROM services WHERE port like ' + "\"" + dport + "\"" + ' AND proto like ' + "\"" + proto + "\"") while True: row = cur.fetchone() if row == None: break if row[0] not in service: service.append(row[0]) for s in service: e = Service(s) e.linklabel = proto + ':' + dport e.linkcolor = 0x0B615E e += Field('pcapsrc', pcap, displayname='Original pcap File') e += Field('id_dport', dport, displayname='Original Destination port') response += e return response
def to_clients(response, output): cat = None for line in output.split('\n'): if not line: continue elif line.startswith(' '): e = None if cat in range(Category.AlternativeTargetInterfaces, Category.OtherAssociations): for ip in ip_matcher.findall(line): e = IPv4Address(ip) e += Field('category', Category.name(cat), displayname='Category') response += e elif cat == Category.OtherAssociations: ip, desc = line.strip().split(' ', 1) e = IPv4Address(ip) e += Label('Additional Info', desc) e += Field('category', Category.name(cat), displayname='Category') response += e elif line.startswith(' '): for id in range(Category.AlternativeTargetInterfaces, Category.OtherAssociations + 1): if Category.name(id) in line: cat = id break
def dotransform(request, response): pcap = request.value pkts = rdpcap(pcap) tcp_srcip = [] udp_srcip = [] convo = [] for p in pkts: if p.haslayer(TCP): tcp_srcip.append(p.getlayer(IP).src) if p.haslayer(IP) and p.haslayer(UDP): udp_srcip.append(p.getlayer(IP).src) for x in tcp_srcip: talker = x, str(tcp_srcip.count(x)), 'tcp' if talker not in convo: convo.append(talker) for y in udp_srcip: talker = y, str(udp_srcip.count(y)), 'udp' if talker not in convo: convo.append(talker) for srcip, count, proto in convo: e = IPv4Address(srcip) e.linkcolor = 0x2314CA e.linklabel = proto e += Field('pcapsrc', pcap, displayname='Original pcap File') e += Field('proto', proto, displayname='Protocol') response += e return response
def passivescan(network, response): nodes = {} debug('Sniffing network traffic for more hosts.') ans = sniff(count=config['scapy/sniffcount'], timeout=config['scapy/snifftimeout']) debug('Analyzing traffic.') for i in ans: src = None dst = None if IP in i: src = i[IP].src dst = i[IP].dst elif ARP in i: src = i[ARP].psrc dst = i[ARP].pdst else: continue if src in network and src not in nodes: nodes[src] = True e = IPv4Address(src, internal=True) e += Field('ethernet.hwaddr', i.src, displayname='Hardware Address') response += e if dst in network and dst not in nodes and i.dst != 'ff:ff:ff:ff:ff:ff': nodes[dst] = True e = IPv4Address(dst, internal=True) e += Field('ethernet.hwaddr', i.dst, displayname='Hardware Address') response += e
def dotransform(request, response): p0f = config['locations/p0f'] pcap = request.value cmd = p0f + ' -s ' + pcap + ' -NUql' p0f_list = [] src_ip = [] p = os.popen(cmd).readlines() for x in p: s_ip = '' s_os = '' for s in re.finditer( '(\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}):\d{1,5} - (\S*.\S*)', x): s_ip = s.group(1) s_os = s.group(2) rec = s_ip, s_os if rec not in p0f_list: p0f_list.append(rec) for s_ip, s_os in p0f_list: if s_os == '': pass else: e = BuiltWithTechnology(s_os) e += Field('source_ip', s_ip, displayname='Source IP', matchingrule='strict') e += Field('pcapsrc', pcap, displayname='Original pcap File') response += e return response
def dotransform(request, response): try: folder = request.fields['sniffMyPackets.outputfld'] except: return response + UIMessage( 'No output folder defined, run the L0 - Prepare pcap transform') tmpfolder = folder + '/files' if not os.path.exists(tmpfolder): os.makedirs(tmpfolder) list_files = [] file_types = [] objects = [] dissector = Dissector() # instance of dissector class dissector.change_dfolder(tmpfolder) pkts = dissector.dissect_pkts(request.value) list_files = glob.glob(tmpfolder + '/*') for i in list_files: if 'stream' not in i: cmd = 'file ' + i x = os.popen(cmd).read() fhash = '' fh = open(i, 'rb') fhash = hashlib.sha1(fh.read()).hexdigest() file_details = x, fhash if file_details not in file_types: file_types.append(file_details) for x, fhash in file_types: for t in re.finditer('^([^:]*)', x): fpath = t.group(1) for s in re.finditer('([^:]*)(\s)', x): ftype = s.group(1) z = fpath, ftype, fhash if z not in objects: objects.append(z) for fpath, ftype, fhash in objects: e = RebuiltFile(fpath) e.ftype = ftype e.fhash = fhash e += Field('pcapsrc', request.value, displayname='Original pcap File', matchingrule='loose') e += Field('sniffMyPackets.outputfld', folder, displayname='Folder Location') e.linklabel = ftype e.linkcolor = 0xFF9900 response += e return response
def dotransform(request, response): # Download GeoIP Database from MaxMinds if not os.path.exists('/opt/geoipdb/geoipdb.dat'): return response + UIMessage('Need local install of MaxMinds Geo IP database, use the download script in resource/external/geoipdownload.sh') gi = pygeoip.GeoIP('/opt/geoipdb/geoipdb.dat') pcap = request.value pkts = rdpcap(pcap) ip_raw = [] ip_geo = [] ip_exclusions = ['192.168.', '172.16.', '10.'] for x in pkts: if x.haslayer(IP): src = x.getlayer(IP).src if src != '0.0.0.0': if src not in ip_raw: ip_raw.append(src) for s in ip_raw: if ip_exclusions[0] in s or ip_exclusions[1] in s or ip_exclusions[2] in s: pass else: rec = gi.record_by_addr(s) city = rec['city'] postcode = rec['postal_code'] country = rec['country_name'] lng = rec['longitude'] lat = rec['latitude'] ccode = rec['country_code'] google_map_url = 'https://maps.google.co.uk/maps?z=20&q=%s,%s' %(lat, lng) geo_ip = s,city, postcode, country, ccode, str(lng), str(lat), google_map_url if geo_ip not in ip_geo: ip_geo.append(geo_ip) for ip, city, postcode, country, ccode, lng, lat, gmap in ip_geo: e = Location(country) e.country = country e.city = city e.linkcolor = 0x2314CA e.linklabel = ip e.areacode = postcode e.longitude = float(lng) e.latitude = float(lat) e.countrycode = ccode e += Field('ipaddress', ip, displayname='IP Address') e += Field('geomapurl', gmap, displayname='Google Map URL') e += Field('pcapsrc', pcap, displayname='Original pcap File') response += e return response
def dotransform(request, response, config): if 'workspace' in request.fields: workspace = request.fields['workspace'] latitude = request.fields['latitude'] longitude = request.fields['longitude'] else: workspace = request.value msg = "Enter Latitude and Longitude" title = "Coordinates to Query for Pushpin" fieldNames = ["Latitude", "Longitude"] fieldValues = [] fieldValues = multenterbox(msg, title, fieldNames) while 1: if fieldValues is None: break errmsg = "" for i in range(len(fieldNames)): if fieldValues[i].strip() == "": errmsg += ('"%s" is a required field.\n\n' % fieldNames[i]) if errmsg == "": break # no problems found fieldValues = multenterbox(errmsg, title, fieldNames, fieldValues) latitude = fieldValues[0] longitude = fieldValues[1] run_pushpin(workspace, latitude, longitude) dbcon = db_connect(request.value) pushpin_list = get_pushpin(dbcon) for pin in pushpin_list: if 'Twitter' == pin[0]: e = TwitterPin(pin[0]) e += Field("workspace", workspace, displayname='Workspace') response += e elif 'Shodan' == pin[0]: e = ShodanPin(pin[0]) e += Field("workspace", workspace, displayname='Workspace') response += e elif 'Picasa' == pin[0]: e = PicasaPin(pin[0]) e += Field("workspace", workspace, displayname='Workspace') response += e elif 'Flickr' == pin[0]: e = FlickrPin(pin[0]) e += Field("workspace", workspace, displayname='Workspace') response += e return response
def dotransform(request, response, config): if 'workspace' in request.fields: workspace = request.fields['workspace'] else: workspace = request.value e = Phrase(request.fields["title"].decode('ascii')) e += Field("workspace", workspace, displayname='Workspace') e += Field("fullname", request.value, displayname='Fullname', matchingrule='loose') response += e return response
def remote_transform(host, transform, input, entity_field, transform_parameter, raw_output, ssl, base_path, soft_limit, hard_limit, verbose): if verbose: set_canari_mode(CanariMode.LocalDebug) entity_type, entity_value = split_validate(input, 'entity') fields = {} params = [] for f in entity_field: name, value = split_validate(f, 'entity field') fields[name] = Field(name=name, value=value) for p in transform_parameter: name, value = split_validate(p, 'transform parameter') params.append(Field(name=name, value=value)) try: r = remote_canari_transform_runner( host, base_path, transform, [_Entity(type=entity_type, value=entity_value, fields=fields)], params, Limits(soft=soft_limit, hard=hard_limit), ssl ) if r.status == 200: data = r.read().decode('utf8') if raw_output: click.echo(data, err=True) exit(0) else: console_writer(MaltegoMessage.parse(data)) exit(0) click.echo('ERROR: Received status %d for %s://%s/%s. Are you sure you got the right server?' % ( r.status, 'https' if ssl else 'http', host, transform ), err=True) if verbose: click.echo(r.read(), err=True) except Exception as e: click.echo('ERROR: %s' % e, err=True) if verbose: traceback.print_exc() exit(-1)
def dotransform(request, response): host = request.value x = db_connect(host) try: cursor = x.cursor() query = "select * from sensors" cursor.execute(query) for (id, ip) in cursor: e = KippoHoneypot('%s' % ip) e += Field('kippodatabase', host, displayname='Kippo Database') e += Field('kipposensorid', ('%s' % id), displayname='Kippo Sensor ID') response += e return response except Exception as e: return response + UIMessage(str(e))
def dotransform(request, response): target = request.value filepath = request.fields['newfolder'] list_files = [] file_details = [] # Create new folder for the extracted files rnd = str(randint(1, 100)) newfolder = filepath + '/' + rnd if not os.path.exists(newfolder): os.makedirs(newfolder) # Check the file extension and if applicable unzip the file to a new folder then store the files if target.endswith(".zip") or target.endswith(".docx"): uzip = zipfile.ZipFile(target) uzip.extractall(newfolder) rootdir = newfolder for root, subFolders, files in os.walk(rootdir): for file in files: list_files.append(os.path.join(root, file)) else: return response + UIMessage('Sorry not the right type of file') # Iterate through the list of files and calculate the SHA1 hash, the filetype for i in list_files: sha1sum = '' fh = open(i, 'rb') sha1sum = hashlib.sha1(fh.read()).hexdigest() cmd = 'file ' + i x = os.popen(cmd).read() for s in re.finditer('([^:]*)(\s)',x): ftype = s.group(1) file_detail = i, newfolder, sha1sum, ftype if file_detail not in file_details: file_details.append(file_detail) # Create the new entity for each file with the details from above for fname, ffolder, fhash, ftype in file_details: e = GenericFile(fname) e += Field('ffolder', ffolder, displayname='File Location') e += Field('fhash', fhash, displayname='SHA1 Hash') e += Field('ftype', ftype, displayname='File Type') e.linklabel = ftype e.linkcolor = 0x75337D response += e return response
def dotransform(request, response): sip = request.value dump = request.fields['dumpfile'] x = parse_netflow(dump) for i in x: srcip = i[4] srcip = srcip.split(':')[0] proto = i[3] if sip in srcip: dip = i[6] dip = dip.split(':')[0] e = IPv4Address(dip) e += Field('dumpfile', dump, displayname='Dump File', matchingrule='loose') # e.linklabel = proto if proto == 'TCP': e.linkcolor = 0xff0000 if proto == 'UDP': e.linkcolor = 0x002bff if proto == 'ICMP': e.linkcolor = 0x2f9a0d response += e else: pass return response
def test_basic_entity_with_dynamic_field_and_explicity_field(self): class TestEntity(Entity): foo = StringEntityField('foo.bar') t = TestEntity('value', foo='random value') t += Field('foo.bar', 1) self.assertEqual(t.foo, 1)
def dotransform(request, response): pcap = request.fields['pcapsrc'] proto = request.fields['proto'] dstip = request.fields['sniffMyPackets.hostdst'] srcip = request.fields['sniffMyPackets.hostsrc'] sport = request.fields['sniffMyPackets.hostsport'] dport = request.fields['sniffMyPackets.hostdport'] folder = request.fields['sniffMyPackets.outputfld'] filename = folder + '/' + str(request.value) + '-' + str(srcip) + '.pcap' # Filter the traffic based on the entity values and save the pcap file with new name sharkit = 'tcpdump -r ' + pcap + ' host ' + srcip + ' and port ' + sport + ' -w ' + filename os.system(sharkit) # Count the number of packets in the file pktcount = '' pkts = rdpcap(filename) pktcount = len(pkts) # Hash the file and return a SHA1 sum sha1sum = '' fh = open(filename, 'rb') sha1sum = hashlib.sha1(fh.read()).hexdigest() e = pcapFile(filename) e.sha1hash = sha1sum e += Field('pktcnt', pktcount, displayname='Number of packets', matchingrule='loose') e.linklabel = '# of pkts:' + str(pktcount) e.linkcolor = 0x669900 response += e return response
def dotransform(request, response): iface = request.value conf.iface = iface subnet = '' network = '' for x in conf.route.routes: if x[3] == iface and x[2] == '0.0.0.0': subnet = x[1] network = x[0] subnet = subnetAddress(subnet) cidr = cidr2subnet(subnet) network = networkAddress(network) ans, uans = arping(network + '/' + str(cidr), verbose=0) for send, rcv in ans: e = IPv4Address(rcv[ARP].psrc) e += Field('ethernet.hwaddr', rcv[Ether].src, displayname='Hardware Address') e.internal = True response += e return response
def dotransform(request, response): interface = request.value conf.iface = interface subnet = '' network = '' cidr = '' arpscan = [] for x in conf.route.routes: if x[3] == interface and x[2] == '0.0.0.0': subnet = x[1] network = x[0] subnet = subnetAddress(subnet) cidr = cidr2subnet(subnet) network = networkAddress(network) ans, uans = arping(str(network) + '/' + str(cidr), verbose=0) for send, rcv in ans: e = IPv4Address(rcv.sprintf("%ARP.psrc%")) e.internal = True e += Field('ethernet.hwaddr', rcv.sprintf("%Ether.src%"), displayname='Hardware Address') response += e return response
def dotransform(request, response, config): msg = 'Enter Search Criteria' title = 'Kippo search for sessions by IP' fieldNames = ["IP"] fieldValues = [] fieldValues = multenterbox(msg, title, fieldNames) if fieldValues[0] != '': s_ip = fieldValues[0] else: return response + UIMessage('You need to type an IP address!!') host = request.value x = db_connect(host) try: cursor = x.cursor() query = ("select * from sessions where ip like %s") cursor.execute(query, (s_ip, )) for (id, starttime, endtime, sensor, ip, termsize, client) in cursor: e = KippoSession('%s' % (id)) e.starttime = ('%s' % (starttime)) e.endtime = ('%s' % (endtime)) e.sensor = ('%s' % (sensor)) e.ipaddr = ('%s' % (ip)) e.termsize = ('%s' % (termsize)) e.client = ('%s' % (client)) e += Field('kippoip', host, displayname='Kippo IP') response += e return response except: return response + UIMessage(x)
def dotransform(request, response): r = Wappalyzer().analyze(request.value) for i in r: e = BuiltWithTechnology(i) e += Field('categories', ', '.join(r[i])) response += e return response
def dotransform(request, response): # Report transform progress progress(50) hash = request.value total = "" try: e = Hash(hash) text = '' resp = urllib2.urlopen( 'https://innocuous.shadowserver.org/api/?query=' + hash).read() start_results = resp.find("{") end_results = resp.find("}") av_results = resp[start_results + 1:end_results].replace('"', '') text += av_results + ',' e += Field('AV Name', text, displayname='AV Name') response += e except IOError: print 'IO Error' # Update progress progress(100) # Return response for visualization return response
def dotransform(request, response, config): try: btc_add = bitcoin_address(request.value) for trans in btc_add['transactions']: if 'Received' in trans['transaction_type']: e = BitcoinTransaction(trans['transaction_hash'], trans_type=trans['transaction_type'], amount=trans['transaction_amount'], trans_uri=trans['transaction_uri'], address=request.value) e += Field("date", trans['date'], displayname='Date') e += Label("Bitcoin Address", request.value) e += Label("Total Amount of Transaction", trans['transaction_amount']) e += Label("Transaction Type", trans['transaction_type']) e += Label("Transaction Date", trans['date']) e.linklabel = 'Received' response += e else: pass return response except Exception as e: raise MaltegoException('An error occured: %s' % e)
def scriptable_transform_runner(transform, value, fields, params, config): global scriptable_api_initialized if not scriptable_api_initialized: scriptable_api_initialized = True def run_transform(self, transform, params=None, config=None): if isinstance(transform, basestring): transform = load_object(transform)() return scriptable_transform_runner(transform, self.value, self.fields, params or [], config or load_config()) Entity.run_transform = run_transform request = MaltegoTransformRequestMessage( parameters={ 'canari.local.arguments': Field(name='canari.local.arguments', value=params) }) request._entities = [to_entity(transform.input_type, value, fields)] msg = transform.do_transform(request, MaltegoTransformResponseMessage(), config) if isinstance(msg, MaltegoTransformResponseMessage): return Response(msg) elif isinstance(msg, basestring): raise MaltegoException(msg) else: raise MaltegoException( 'Could not resolve message type returned by transform.')
def findlocalneighbors(network, response): debug('ARP sweeping %s' % network.netblock) # e = Netblock(network.netblock) # e += Label('CIDR Notation', repr(network)) # e += Label('Network Mask', network.netmask) # e += Label('Number of Hosts', int(~network.netmask) - 1) # response += e ans = arping(repr(network), timeout=config['scapy/sr_timeout'], verbose=config['scapy/sr_verbose'])[0] for i in ans: e = IPv4Address(i[1].psrc) e.internal = True e += Field('ethernet.hwaddr', i[1].hwsrc, displayname='Hardware Address') response += e if len(ans) <= 1: passivescan(network, response) return response