def emit(self, record): """ Rewrite each record before it is printed to the console. """ formatted = record if record.levelname == "WARNING": formatted.msg = color(record.msg, 33) # yellow if record.levelname == "ERROR" or record.levelname == "CRITICAL": formatted.msg = color(record.msg, 31) # red else: formatted.msg = record.msg logging.StreamHandler.emit(self, record)
def run(self): # run as long as we did not send an interrupt while not Analyzer.stoprequest.is_set(): try: # wait for a new packet #log.debug("Waiting for a new packet to analyze.") my_packet = self.q.get(block=True, timeout=0.5) if my_packet: #log.debug("Took new packet from queue.") if my_packet.has_layer("tcp"): # First Packet (SYN) if my_packet["tcp"].is_syn_packet(): log.debug(color("New TCP Stream (%d) detected (SYN).",36), self.identifier) # Create and init a new stream self.create_stream(my_packet) else: # Append new packets to existing streams self.append_to_stream(my_packet) # print my_packet except Queue.Empty: continue
def run(self): while not TimerClass.stoprequest.is_set(): TimerClass.stoprequest.wait(5) log.info("%s/%s read (%.2f%%)." % (Sniffer.packet_count, Sniffer.total_count, round( (Sniffer.packet_count / float(Sniffer.total_count)) * 100.0, 2))) log.info(color("Done.", 32))
def statistical_analysis2(self, stream, first_span=STREAM_TIMING_THRESHOLD): ''' Try to identify transparent proxies using statistical analysis. ''' start_time = stream.first_timestamp end_time = stream[-1].timestamp # take time stamp from the last packet in stream log.debug("2) =========================") log.debug("Threshold: (%s%%/%s%%)", (first_span*100), (100.0-first_span*100)) #log.debug("Start time: %s", str(start_time)) #log.debug("End time: %s", str(end_time)) # Download time download_time = end_time - start_time #log.debug("Download time: %s.", str(download_time)) #log.debug("File size: %s", str(stream.file_size)) # 90 percent of download time: first_time_span = float(download_time) * first_span second_time_span = float(download_time) * (1.0 - first_span) log.debug("First part: %.2f", first_time_span) log.debug("Second part: %.2f", second_time_span) packet_number_first = 0 packet_number_second = 0 # Count packets according to threshold # Skip first packet (get request) for elem in stream[1:]: packet_time = elem.timestamp - start_time if packet_time < first_time_span: packet_number_first = packet_number_first + 1 else: packet_number_second = packet_number_second + 1 log.debug("Total packet count: %d", len(stream)) percentage_first_part = float(packet_number_first) / float(len(stream)) * 100.0 percentage_second_part = float(packet_number_second) / float(len(stream)) * 100.0 log.debug("Packet count - first part: %d (%.2f%%)", packet_number_first, percentage_first_part) log.debug("Packet count - second part: %d (%.2f%%)", packet_number_second, percentage_second_part) detected = "No" #if percentage_first_part < 2% of all packets: if percentage_first_part < 1.00: # First part: 90% of time --> There have to be more packages log.critical(color("Network anomaly detected! Download '%s' might be infected.",1), stream.file_name) syslog.syslog(syslog.LOG_CRIT, "Network anomaly detected! Download {0} might be infected.".format(stream.file_name)) stream.proxy_detected = True detected = "Yes" else: log.debug("No proxy detected.") stream.proxy_detected = False log.debug("============================")
def run(self): while not Hasher.stoprequest.is_set(): try: url, hash_val = self.q.get(block=True, timeout=0.5) remote_hashes = [] for server in self.servers: if url and hash_val: if ".exe" in url or ".zip" in url or "tar.gz" in url: log.debug("Requesting remote check ('%s')", server["label"]) params = urllib.urlencode({'user': server["user"], 'p': server["password"], 'url': url}) headers = {"Content-type": "application/x-www-form-urlencoded","Accept": "text/plain"} conn = httplib.HTTPSConnection(server["address"]) conn.request(server["type"], server["path"], params, headers) response = conn.getresponse() # print response.status, response.reason data = response.read() conn.close() if "invalid" in data: log.error("Could not obtain remote hash.") else: remote_hashes.append(data.split()[0]) # Compare hash values log.info("Remote hashes:") count = 0 for val in remote_hashes: log.info(" |--- %s", val) if hash_val in val: pass # log.info("File is not infected.") else: count = count + 1 if count == 0: log.debug("File is not infected.") else: log.critical(color("File is most probably infected. Hash sum mismatch (%d/%d) & proxy detected!",1),count,len(remote_hashes)) syslog.syslog(syslog.LOG_CRIT, "File is most probably infected. Hash sum mismatch & proxy detected!") except Queue.Empty: continue
def plot_packets_over_time_interval(self, stream, interval): ''' Plot packet count * time (in time interval). ''' t = datetime.fromtimestamp(stream.first_timestamp).strftime('%Y-%m-%d_%H-%M-%S') with open(os.path.join(APP_ROOT,"log","tcpstream-" + str(stream.identifier) + "-" + "int" + str(interval) + "-" + t + ".dat"), 'w+') as file: file.write("# TCP stream data\n") file.write("# Time\tCount\n") start_time = stream.first_timestamp time_delta = 0 count = 0 file.write(str(time_delta) + "\t" + str(count) + "\n") for elem in stream: if elem.timestamp - (start_time + time_delta) < interval: count = count + 1 else: time_delta = time_delta + interval file.write(str(time_delta) + "\t" + str(count) + "\n") count = 1 file.write(str(time_delta + 1) + "\t" + str(count) + "\n") file.write("# Total: " + str(len(stream)) + "\n") log.info(color("File 'tcpstream-" + str(stream.identifier) + "-"+ "int" + str(interval) + "-" + t + ".dat' created.", 34))
def plot_packets_over_time(self,stream): ''' Plot packet count * time. ''' t = datetime.fromtimestamp(stream.first_timestamp).strftime('%Y-%m-%d_%H-%M-%S') with open(os.path.join(APP_ROOT,"log",'tcpstream-' + str(stream.identifier) + '-' + t + '.dat'), 'w+') as file: file.write("# TCP stream data\n") file.write("# Time\tSize\tCount\n") count = 0 # local packet counter for elem in stream: count = count + 1 tcp_data_len = elem["tcp"].get_data_size(elem["ip"].total_length) # Ignore ACK packets for now if elem["tcp"].flag_ack == 1 and tcp_data_len == 0: continue # log.debug("Time: %s, Size: %d", elem.timestamp-stream.first_timestamp, tcp_data_len) file.write(str(elem.timestamp-stream.first_timestamp) + "\t" + str(tcp_data_len) + "\t" + str(count) + "\n") file.write(str(elem.timestamp-stream.first_timestamp) + "\t" + str(tcp_data_len) + "\t" + str(count) + "\n") log.info(color("File 'tcpstream-" + str(stream.identifier) + '-' + t + ".dat' created.", 34))
def plot_packets_over_time_interval(self, stream, interval): ''' Plot packet count * time (in time interval). ''' t = datetime.fromtimestamp(stream.first_timestamp).strftime('%Y-%m-%d_%H-%M-%S') with open(os.path.join(ETHERSNIFF_ROOT,"log","tcpstream-" + str(stream.identifier) + "-" + "int" + str(interval) + "-" + t + ".dat"), 'w+') as file: file.write("# TCP stream data\n") file.write("# Time\tCount\n") start_time = stream.first_timestamp time_delta = 0 count = 0 file.write(str(time_delta) + "\t" + str(count) + "\n") for elem in stream: if elem.timestamp - (start_time + time_delta) < interval: count = count + 1 else: time_delta = time_delta + interval file.write(str(time_delta) + "\t" + str(count) + "\n") count = 1 file.write(str(time_delta + 1) + "\t" + str(count) + "\n") file.write("# Total: " + str(len(stream)) + "\n") log.info(color("File 'tcpstream-" + str(stream.identifier) + "-"+ "int" + str(interval) + "-" + t + ".dat' created.", 34))
def plot_packets_over_time(self,stream): ''' Plot packet count * time. ''' t = datetime.fromtimestamp(stream.first_timestamp).strftime('%Y-%m-%d_%H-%M-%S') with open(os.path.join(ETHERSNIFF_ROOT,"log",'tcpstream-' + str(stream.identifier) + '-' + t + '.dat'), 'w+') as file: file.write("# TCP stream data\n") file.write("# Time\tSize\tCount\n") count = 0 # local packet counter for elem in stream: count = count + 1 tcp_data_len = elem["tcp"].get_data_size(elem["ip"].total_length) # Ignore ACK packets for now if elem["tcp"].flag_ack == 1 and tcp_data_len == 0: continue # log.debug("Time: %s, Size: %d", elem.timestamp-stream.first_timestamp, tcp_data_len) file.write(str(elem.timestamp-stream.first_timestamp) + "\t" + str(tcp_data_len) + "\t" + str(count) + "\n") file.write(str(elem.timestamp-stream.first_timestamp) + "\t" + str(tcp_data_len) + "\t" + str(count) + "\n") log.info(color("File 'tcpstream-" + str(stream.identifier) + '-' + t + ".dat' created.", 34))
log.debug("Parsing baseline file.") baseline_packets = extract_packets(args.baseline) # Init sniffer baseline_sniff = Sniffer(sniff_sock=None, packet_data=baseline_packets, protocols=args.protocols, ip=args.ip) baseline_analyze = MetaAnalyzer(baseline=True, session_id=None, tag=args.tag) analysis_session = baseline_analyze.session_id if args.ignore: baseline_analyze.filter_qnames = args.ignore.split(",") baseline_analyze.start() log.info(color("Sniffing baseline packets.", 36)) # Wait for packets while True: try: # Receive packets according to filter rules my_packet = baseline_sniff.sniff() if my_packet: # Analyze packets baseline_analyze.add_packet(my_packet) continue if len(baseline_sniff.packet_data) == 0: log.info("Finished baseline sniffing.") break except Exception as e:
def statistical_analysis3(self, stream, packet_amount=0.01, multiplicator=3.5): ''' Try to identify transparent proxies using statistical analysis. ''' log.debug("Alg 2) =========================") log.debug("Total packet count: %d", len(stream)) # In order to calculate variance and standard deviation we need more than 2 packets (because we take the first one out) if len(stream) > 2: start_time = stream.first_timestamp end_time = stream[-1].timestamp # take time stamp from the last packet in stream # Download time download_time = end_time - start_time # Calculate time interval between first and second packet delta_one = stream[1].timestamp - stream[0].timestamp # Calculate every time interval and write it to list (inter packet time) log.debug("Calculating inter packet time.") deltas = [] # For performance reasons we just focus on the 1000 packets border = -1 if len(stream) > 1000: border = 1000 log.debug("Too much packets.") # Calculate the other time intervals for elem in stream[2:border]: # find previous packet prev = stream[stream.index(elem)-1] deltas.append(elem.timestamp - prev.timestamp) log.debug("Analyzing %d time intervals.", len(deltas)+1) # +1 for delta_one #log.debug(deltas) log.debug("Sorting packets.") # Sort time values (descending) deltas.sort(reverse=True) #log.debug([delta_one] + deltas) detected = "No" log.debug("Packet analysis:") # Calculate a specified amount of biggest packets biggest_packets = int(round(len(deltas) * packet_amount)) log.debug("First %d%%: %s", (packet_amount*100), biggest_packets) # Amount is too small if biggest_packets < 200: # Stream itself is too small #log.debug("Packet amount too small.") if len(deltas) < 20: # Set amount = stream length biggest_packets = len(deltas) log.debug("Stream too small. Analyzing all packet delays (%d+1).", len(deltas)) elif len(deltas) < 200: log.debug("Stream too small. Analyzing 20%% of all packet delays (%d+1).", len(deltas)*0.2) biggest_packets = int(round(len(deltas) * 0.2)) elif len(deltas) < 500: log.debug("Stream too small. Analyzing 10%% of all packet delays (%d+1).", len(deltas)*0.1) biggest_packets = int(round(len(deltas) * 0.1)) elif len(deltas) < 2000: biggest_packets = int(round(len(deltas) * (packet_amount*2))) log.debug("Analyzing the first %d packet delays.", biggest_packets) else: # Set minimium packets to 50 biggest_packets = 50 log.debug("Analyzing the first 50 packet delays.") big_packets = deltas[:biggest_packets] if biggest_packets >= 2: avg_with = statistics.mean([delta_one] + big_packets[:-1]) avg_without = statistics.mean(big_packets) var_with = statistics.variance([delta_one] + big_packets[:-1]) var_without = statistics.variance(big_packets) sdev_with = statistics.pstdev([delta_one] + big_packets[:-1]) sdev_without = statistics.pstdev(big_packets) log.debug("Delta_1: %s", delta_one) log.debug("Vals: %d", len(deltas)) #log.debug(deltas[:biggest_packets]) #log.debug([delta_one] + deltas[:biggest_packets-1]) log.debug("AVG: %s", avg_with) log.debug("AVG -first: %s", avg_without) log.debug("Threshold: %s", avg_without * 2.0) log.debug("variance: %s", var_with) log.debug("variance -first: %s", var_without) log.debug("standard deviation: %s", sdev_with) log.debug("standard deviation -first: %s", sdev_without) # Normalize biggest packets log.debug("Normalizing.") #log.debug("Overall AVG: %s", statistics.mean(deltas)) threshold = avg_without + avg_without log.debug("Internal threshold: %s", threshold) tmp = [] for val in big_packets: if val > threshold: tmp.append(val) for val in tmp: log.debug("Removing %s", val) big_packets.remove(val) #log.debug(big_packets) avg_with = statistics.mean([delta_one] + big_packets[:-1]) avg_without = statistics.mean(big_packets) log.debug("New avg: %s", avg_with) log.debug("New avg -first: %s", avg_without) log.debug("New Threshold: %s", avg_without * multiplicator) if (avg_without * multiplicator) < avg_with: log.critical(color("Network anomaly detected! Download '%s' might be infected.",1), stream.file_name) syslog.syslog(syslog.LOG_CRIT, "Network anomaly! Download {0} might be infected.".format(stream.file_name)) detected = "Yes" stream.proxy_detected = True else: log.error("Dataset to small. Can not calculate variance.") else: log.debug("Not enough packets. Skipping this test.") log.debug("============================")
def logo(): """Cuckoo asciiarts. @return: asciiarts array. """ logos = [] logos.append(""" }$$$$$$$$$$$$$$$$$$$$$$$$$$^ $$$$$,$$$$$$$$$$$$$$$$$$$$$$$$ $$$$$ $$$ $$$$$$$$$$$$$$$$$$$$$$ $$$ $$$$$$$$$$$$$$$$$$$$$$ $$$ B$ $$$$$$$$$$$$$$$$$$$$ $$ $$$ $$$$$$*$$$$ $$$$$$$ $$ $$$$$$$ ;$$$$$$$$$$$ $$$$ -$$$$$ $$$$$$ $$ $$$$$# $$$$$$ $$$$ $$$ . ]$$$$ $$$$ $$ $$$$ $$$$ $ $$$ $$$ $ u$$ $$ $@ $$ $$' $ $$$ $$$ $$$ $ _ Ql $ $$$ $$$ $$ $$$$ $$$ ' $$$ $ $$$$ $$ $$ $$. $$ .$$ $$ $$ $ $$ $$ $ $$$ $ $ $$$ $ $$ $$ $ $ <$$ $$$ $$$ $ $$$! B$$$ $ $$$$ $$$ $$. $ $$ $$$ $$$ $$$ $$$ $$$$ $$$ $$ $$$ ;$$.$ $$$$$ $$$$$ $$$$ $$$ $$ $ $$ X$$$$$( $$$$$$ $$ $ $$ $ $ $$ $$$$$$ $$$$ $$$$$$ $$ $ $ $ $$ $$$$$$$$$$$$$$$$$$$$$$$$$$ $ $ $ .$$$ $$$$$$$$$$$$$$$$$$ $$$ $ ' $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ k *$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $$$$$$ $ $$$$$$$$$$$$$$$$$$$$v $$$$$ $$%$ $ $ $ $$$$$ $$$$ $$ $ $$$ $$$ $ $$$$ $$$mmmm$mm$mm$mmmmm$$mm$$$ $$%$$%$%%$%%%%%%$%%%$%$$ $$$$$$$$$$$$$$$$$$$$. $$$$$$$$$$$$$$$$$$$ $$$$$$$$$$$$$$$$ $$$$$$$$$$$$ $$$$$$ $ """) logos.append(""" $$r[[a "X[# ($ $Z[[[[[I & q[& $[[[[[[[[ (f h" [[[% $t[[[[[[[[[ h -Ou[a [[[[[[[|# } h kZhf a$ $[[[[[[1 > pp" b ZW #> $ [[[[[[( >hn nZZm> $[[[[[z ( [[[[[C I $ $[[[[[ wZZZZdo#8n h$ $[[[[r nZm##wZZZZZZZZZbo&WW&d $[[[[a -ZZZZZZZZZZZZZZZZZZZZO $[[[[p ZZZZZZZZZZZZZZZZZZZa O Z[[[Z CaOOOOOOmoZZZZZZZZ* $[[[[ %OOOOOOOOOkZZZZZh $ Q[[[# "OOOOOOOOOZZZq O $1[[[- %OOOOOOO%Zh [[[[ "MOOOoI 8 Z[[[h IO&dZf >Zw&%ZZM %rkZZZoaQrz IbMb&$z $q#b[[[[[[" zzCzM $ $[[[[[[[[& pzzbw $ [[[[[[[[#-C nn --> p [[[[uU[O n n$ $ |[[[[[[ h ( a[[[[[[- n h $ $ow$$[[[[[[X n" h - oZZZ$[[[[[[[Q q $kZ@$[[[[[[[[[# -q[[ $ X[[[[[[[[[[[[[[[[[[[h $ $([[[[[[[[[[[[[[%$ $- $ X[[[[[[[[[X$ $ q[[[[[u$ p a[[[$ $ $ " ( $ ($ """) logos.append(""" $$$$$$$$$ $$$$$$$$$$ $$ $$; $$ >$$ $$ $$ $$ ;$$ $ ; $$$$$$$$$ $$ $$ f$ $ $ $$$$ $$$$ $ $$$$$ $$$$$ $$$$ $$ $$ $$$ f$ $ $ $$ $, $ $$ $ $> $$ $ $$ $$ $$; f$ $ $ $$ $ $ $$ $$ $ $+ $$ $$$$$$$$ $$$$ $ $ $$$$ $$$$ $ $$$$$$ $$$ $$$$$$ $ """) print(color(random.choice(logos), random.randrange(31, 37))) print print(" PD_update") print(" From liebesu") print(" https://github.com/liebesu/PD_update") print(" www.polydata.com.cn") print(" Copyright (c) 2010-2015") print sys.stdout.flush()
def logo(): """Malice asciiarts. @return: asciiarts array. """ logos = [] logos.append(""" ███▄ ▄███▓ ▄▄▄ ██▓ ██▓ ▄████▄ ▓█████ ▓██▒▀█▀ ██▒▒████▄ ▓██▒ ▓██▒▒██▀ ▀█ ▓█ ▀ ▓██ ▓██░▒██ ▀█▄ ▒██░ ▒██▒▒▓█ ▄ ▒███ ▒██ ▒██ ░██▄▄▄▄██ ▒██░ ░██░▒▓▓▄ ▄██▒▒▓█ ▄ ▒██▒ ░██▒ ▓█ ▓██▒░██████▒░██░▒ ▓███▀ ░░▒████▒ ░ ▒░ ░ ░ ▒▒ ▓▒█░░ ▒░▓ ░░▓ ░ ░▒ ▒ ░░░ ▒░ ░ ░ ░ ░ ▒ ▒▒ ░░ ░ ▒ ░ ▒ ░ ░ ▒ ░ ░ ░ ░ ░ ░ ▒ ░ ░ ▒ ░░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ """) logos.append(""" __ __ _ _ | \/ | __ _| (_) ___ ___ | |\/| |/ _` | | |/ __/ _ \\ | | | | (_| | | | (_| __/ |_| |_|\__,_|_|_|\___\___| """) logos.append(""" _/ _/ _/ _/ _/_/ _/_/ _/_/_/ _/ _/_/_/ _/_/ _/ _/ _/ _/ _/ _/ _/ _/ _/_/_/_/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/_/_/ _/ _/ _/_/_/ _/_/_/ """) logos.append(""" _____ ___| _|__ ____ ____ ____ ______ ______ | \ / | || \ | | | || ___|| ___| | \/ | || \ | |_ | || |__ | ___| |__/\__/|__|_||__|\__\|______||____||______||______| |_____| """) logos.append(""" ______________________________________________________________ /~~\__/~~\__/~~~~~~\__/~~\_______/~~~~\__/~~~~~~\__/~~~~~~~~\_ /~~~\/~~~\_/~~\__/~~\_/~~\________/~~\__/~~\__/~~\_/~~\_______ /~~~~~~~~\_/~~~~~~~~\_/~~\________/~~\__/~~\_______/~~~~~~\___ /~~\__/~~\_/~~\__/~~\_/~~\________/~~\__/~~\__/~~\_/~~\_______ /~~\__/~~\_/~~\__/~~\_/~~~~~~~~\_/~~~~\__/~~~~~~\__/~~~~~~~~\_ ______________________________________________________________""") logos.append(""" ======================================== = ===== ========= =================== = === ========= =================== = = = ========= =================== = == == === === == === ==== == = ===== == = == ====== = == = = = ===== ===== == == == ===== = = ===== === == == == ===== ==== = ===== == = == == == = == = = = ===== === == == === ==== == ========================================""") logos.append(""" __ __ __ _ _ ______ | V |/ \| | | |/ _/ __| | \_/ | /\ | |_| | \_| _| |_| |_|_||_|___|_|\__/___|""") logos.append(""" e e 888 ,e, d8b d8b ,"Y88b 888 " e88'888 ,e e, e Y8b Y8b "8" 888 888 888 d888 '8 d88 88b d8b Y8b Y8b ,ee 888 888 888 Y888 , 888 , d888b Y8b Y8b "88 888 888 888 "88,e8' "YeeP" """) logos.append(""" ____ ____ ____ ____ ____ ____ ||M |||a |||l |||i |||c |||e || ||__|||__|||__|||__|||__|||__|| |/__\|/__\|/__\|/__\|/__\|/__\|""") logos.append(""" _____ ______ ________ ___ ___ ________ _______ |\ _ \ _ \|\ __ \|\ \ |\ \|\ ____\|\ ____\\ \ \ \\ \\__\ \ \ \ \|\ \ \ \ \ \ \ \ \___|\ \\ \__/ \ \ \|__| \ \ \ __ \ \ \ \ \ \ \ \ \ \ _\\ \ \ \ \ \ \ \ \ \ \ \ \____\ \ \ \ \____\ \ \____ \ \__\ \ \__\ \__\ \__\ \_______\ \__\ \_______\ \______\\ \|__| \|__|\|__|\|__|\|_______|\|__|\|_______|\|______|""") logos.append(""" .-----------------. | Malice? | | OH NOES! |\\ '-.__.-' '-----------------' \\ /oo |--.--,--,--. \\_.-'._i__i__i_.' \"\"\"\"\"\"\"\"\"""") logos.append(""" • ▌ ▄ ·. ▄▄▄· ▄▄▌ ▪ ▄▄· ▄▄▄ . ·██ ▐███▪▐█ ▀█ ██• ██ ▐█ ▌▪▀▄.▀· ▐█ ▌▐▌▐█·▄█▀▀█ ██▪ ▐█·██ ▄▄▐▀▀▪▄ ██ ██▌▐█▌▐█ ▪▐▌▐█▌▐▌▐█▌▐███▌▐█▄▄▌ ▀▀ █▪▀▀▀ ▀ ▀ .▀▀▀ ▀▀▀·▀▀▀ ▀▀▀ """) logos.append(""" ___ ___ ___ ___ ___ ___ /\__\ /\ \ /\__\ /\ \ /\ \ /\ \\ /::L_L_ /::\ \ /:/ / _\:\ \ /::\ \ /::\ \\ /:/L:\__\ /::\:\__\ /:/__/ /\/::\__\ /:/\:\__\ /::\:\__\\ \/_/:/ / \/\::/ / \:\ \ \::/\/__/ \:\ \/__/ \:\:\/ / /:/ / /:/ / \:\__\ \:\__\ \:\__\ \:\/ / \/__/ \/__/ \/__/ \/__/ \/__/ \/__/ """) logos.append(""" ___ ___ _ _ | \/ | | (_) | . . | __ _| |_ ___ ___ | |\/| |/ _` | | |/ __/ _ \\ | | | | (_| | | | (_| __/ \_| |_/\__,_|_|_|\___\___|""") logos.append(""" __ __ __ __ / \ / | / |/ | $$ \ /$$ | ______ $$ |$$/ _______ ______ $$$ \ /$$$ | / \ $$ |/ | / | / \\ $$$$ /$$$$ | $$$$$$ |$$ |$$ |/$$$$$$$/ /$$$$$$ | $$ $$ $$/$$ | / $$ |$$ |$$ |$$ | $$ $$ | $$ |$$$/ $$ |/$$$$$$$ |$$ |$$ |$$ \_____ $$$$$$$$/ $$ | $/ $$ |$$ $$ |$$ |$$ |$$ |$$ | $$/ $$/ $$$$$$$/ $$/ $$/ $$$$$$$/ $$$$$$$/ """) logos.append(""" `7MMM. ,MMF' db `7MMF' `7MMF' .g8""'bgd'`7MM""'YMM MMMb dPMM ;MM: MM MM .dP' `M MM `7 M YM ,M MM ,V^MM. MM MM dM' ` MM d M Mb M' MM ,M `MM MM MM MM MMmmMM M YM.P' MM AbmmmqMA MM , MM MM. MM Y , M `YM' MM A' VML MM ,M MM `Mb. ,' MM ,M .JML. `' .JMML..AMA. .AMMA..JMMmmmmMMM .JMML. `"bmmmd' .JMMmmmmMMM""") print(color(random.choice(logos), random.randrange(31, 37))) print print(" Malice %s" % yellow(MALICE_VERSION)) print(" https://github.com/blacktop/malice") print(" Copyright (c) 2013-2014") print sys.stdout.flush()
def append_to_stream(self, my_packet): self.old_streams = [] # mark closed streams for deletion for stream in self.tcp_streams: if stream.is_equal(my_packet["ip"].src_addr, my_packet["ip"].dest_addr, my_packet["tcp"].src_port, my_packet["tcp"].dest_port): # First, add packet to stream stream.add_packet(my_packet) # We are just interested in file downloads if "GET" in my_packet["tcp"].data[0:4]: # Search for file endings (improvement needed!) if '.exe ' in my_packet["tcp"].data or '.zip ' in my_packet["tcp"].data or '.tar.gz' in my_packet["tcp"].data: # To Do: Identify end of download (http ok 200 packet) log.debug("Found GET and file download.") # Extract domain name domain = '<empty>' request = my_packet["tcp"].data.split('\r\n') for r in request: if 'Host' in r: domain = r.split(' ')[1] if domain == '<empty>': # we were not able to extract the domain name # try to use the host ip instead stream.file_url = "http://" + my_packet["ip"].dest_addr \ + ":" + str(my_packet["tcp"].dest_port) \ + my_packet["tcp"].data.split(' ')[1] else: # we extracted the domain name stream.file_url = "http://" + domain + my_packet["tcp"].data.split(' ')[1] log.debug("URL: %s", stream.file_url) stream.file_name = my_packet["tcp"].data.split(' ')[1].split('/')[-1] log.debug("File: %s", stream.file_name) stream.contains_download = True #print my_packet["tcp"] #print my_packet["tcp"].data elif "Content-Length" in my_packet["tcp"].data or "content-length" in my_packet["tcp"].data: if stream.contains_download == True: log.debug("Stream contains download.") http_data = my_packet["tcp"].data.split() if "Content-Length:" in http_data: stream.file_size = http_data[http_data.index("Content-Length:")+1] elif "content-length:" in http_data: stream.file_size = http_data[http_data.index("content-length:")+1] # Calculate file size #stream.file_size = stream.file_size + my_packet["tcp"].get_data_size(my_packet["ip"].total_length) #log.debug("TCP DATA SIZE: %d", stream.file_size) # Connection closing elif my_packet["tcp"].is_closing_packet(): stream.conn_close = stream.conn_close + 1 if stream.conn_close == 1: log.debug("TCP stream %d: Closing detected (first FIN,ACK).", stream.identifier) elif stream.conn_close > 1: log.debug("TCP stream %d: Closing detected (second FIN,ACK).", stream.identifier) #log.debug("Added packet to TCP stream %d.", stream.identifier) # Find final 'ack' elif my_packet["tcp"].is_final_closing_packet(): if stream.conn_close > 1: # (fin, ack) was seen twice log.debug(color(color("TCP stream %d: Last packet detected (ACK).", 36), 2), stream.identifier) if stream.contains_download == True: # Plot log.info(color("Identified file download in TCP stream %d.", 31), stream.identifier) try: if self.plot: self.plot_packets_over_time(stream) self.plot_packets_over_time_interval(stream,1) # Remove SYN/ACK/FIN+ACK and unimportant http packets self.prepare_stream(stream) # Latest analysis approach self.statistical_analysis3(stream,0.05,3.5) except IOError: log.warning("I was not able to create the plot file.") # Calculate hash sum if proxy detected # (-> We can't differ between 'good' or 'bad' proxy servers) if stream.proxy_detected == True: sha256_hash = self.stream_hash(stream) log.info("Local hash:") log.info(" |--- %s", sha256_hash) if self.hasher.active == True: self.hasher.add_file_check(stream.file_url, sha256_hash) if self.extract: self.extract_files(stream) else: log.info("No anomaly detected.") # drop closed stream data to save memory self.old_streams.append(stream) # Check whether or not the stream is active self.check_stream(stream) # Delete all finished streams not containing any download self.cleanup_streams()
def statistical_analysis(self, stream, first_span=STREAM_TIMING_THRESHOLD): ''' Try to identify transparent proxies using statistical analysis. ''' start_time = stream.first_timestamp end_time = stream[-1].timestamp # take time stamp from the last packet in stream log.debug("Alg 1a) =========================") log.debug("Threshold: (%s%%/%s%%)", (first_span*100), (100.0-first_span*100)) log.debug("Start time: %s", str(start_time)) log.debug("End time: %s", str(end_time)) # Download time download_time = end_time - start_time log.debug("Download time: %s.", str(download_time)) log.debug("File size: %s", str(stream.file_size)) # 90 percent of download time: first_time_span = float(download_time) * first_span second_time_span = float(download_time) * (1.0 - STREAM_TIMING_THRESHOLD) log.debug("First part: %.2f", first_time_span) log.debug("Second part: %.2f", second_time_span) packet_number_first = 0 packet_number_second = 0 # Count packets according to threshold # Skip first packet (get request) for elem in stream[1:]: packet_time = elem.timestamp - start_time if packet_time < first_time_span: packet_number_first = packet_number_first + 1 else: packet_number_second = packet_number_second + 1 log.debug("Total packet count: %d", len(stream)) percentage_first_part = float(packet_number_first) / float(len(stream)) * 100.0 percentage_second_part = float(packet_number_second) / float(len(stream)) * 100.0 log.debug("Packet count - first part: %d (%.2f%%)", packet_number_first, percentage_first_part) log.debug("Packet count - second part: %d (%.2f%%)", packet_number_second, percentage_second_part) # Filename log_file = os.path.join(APP_ROOT,"log","statistical-analysis" + ".dat") # Date t = datetime.fromtimestamp(stream.first_timestamp).strftime('%Y-%m-%d_%H-%M-%S') # Check for an existing file if not os.path.isfile(log_file): with open(log_file, 'w+') as f: tmp = "# Statistical analysis - %s\n" % t f.write(tmp) #f.write("# Date\tFile\tSize\tDownload time\tT1\tT2\tPackets\t#P/LT1\t#P/RT1\t%P/LT1\t%P/RT1\n") f.write('{:20s}\t'.format("# Date") +'{:15s}\t'.format("File") +'{:>10s}\t'.format("Size (MB)") +'{:>6s}\t'.format("DLtime") +'{:>5s}\t'.format("T1") +'{:>5s}\t'.format("T2") +'{:>8s}\t'.format("#Packets") +'{:>8s}\t'.format("#P/LT1") +'{:>8s}\t'.format("#P/RT1") +'{:>6s}\t'.format("%P/LT1") +'{:>6s}\t'.format("%P/RT1") +'{:>3s}\n'.format("Detected") ) detected = "No" #if percentage_first_part < (STREAM_PACKET_THRESHOLD * 100.0): if percentage_first_part < percentage_second_part: # First part: 90% of time --> There have to be more packages log.critical(color("Network anomaly detected! Download '%s' might be infected.",1), stream.file_name) syslog.syslog(syslog.LOG_CRIT, "Network anomaly detected! Download {0} might be infected.".format(stream.file_name)) stream.proxy_detected = True detected = "Yes" with open(os.path.join(APP_ROOT,"log","statistical-analysis" + ".dat"), 'a') as file: if self.comment: file.write("\n### {0} ### \n".format(self.comment)) self.comment = None file.write('{:20s}\t'.format(t) +'{:15s}\t'.format(stream.file_name) +'{:10.3f}\t'.format(int(stream.file_size)/1024.0/1024.0) +'{:6.2f}\t'.format(download_time) +'{:5.2f}\t'.format(STREAM_TIMING_THRESHOLD * 100.0) +'{:5.2f}\t'.format(STREAM_PACKET_THRESHOLD * 100.0) +'{:8d}\t'.format(len(stream)) +'{:8d}\t'.format(packet_number_first) +'{:8d}\t'.format(packet_number_second) +'{:6.2f}\t'.format(percentage_first_part) +'{:6.2f}\t'.format(percentage_second_part) +'{:3s}\n'.format(detected) ) log.debug("============================")
def statistical_analysis(self, stream, first_span=STREAM_TIMING_THRESHOLD): ''' Try to identify transparent proxies using statistical analysis. ''' start_time = stream.first_timestamp end_time = stream[-1].timestamp # take time stamp from the last packet in stream log.debug("Alg 1a) =========================") log.debug("Threshold: (%s%%/%s%%)", (first_span*100), (100.0-first_span*100)) log.debug("Start time: %s", str(start_time)) log.debug("End time: %s", str(end_time)) # Download time download_time = end_time - start_time log.debug("Download time: %s.", str(download_time)) log.debug("File size: %s", str(stream.file_size)) # 90 percent of download time: first_time_span = float(download_time) * first_span second_time_span = float(download_time) * (1.0 - STREAM_TIMING_THRESHOLD) log.debug("First part: %.2f", first_time_span) log.debug("Second part: %.2f", second_time_span) packet_number_first = 0 packet_number_second = 0 # Count packets according to threshold # Skip first packet (get request) for elem in stream[1:]: packet_time = elem.timestamp - start_time if packet_time < first_time_span: packet_number_first = packet_number_first + 1 else: packet_number_second = packet_number_second + 1 log.debug("Total packet count: %d", len(stream)) percentage_first_part = float(packet_number_first) / float(len(stream)) * 100.0 percentage_second_part = float(packet_number_second) / float(len(stream)) * 100.0 log.debug("Packet count - first part: %d (%.2f%%)", packet_number_first, percentage_first_part) log.debug("Packet count - second part: %d (%.2f%%)", packet_number_second, percentage_second_part) # Filename log_file = os.path.join(ETHERSNIFF_ROOT,"log","statistical-analysis" + ".dat") # Date t = datetime.fromtimestamp(stream.first_timestamp).strftime('%Y-%m-%d_%H-%M-%S') # Check for an existing file if not os.path.isfile(log_file): with open(log_file, 'w+') as f: tmp = "# Statistical analysis - %s\n" % t f.write(tmp) #f.write("# Date\tFile\tSize\tDownload time\tT1\tT2\tPackets\t#P/LT1\t#P/RT1\t%P/LT1\t%P/RT1\n") f.write('{:20s}\t'.format("# Date") +'{:15s}\t'.format("File") +'{:>10s}\t'.format("Size (MB)") +'{:>6s}\t'.format("DLtime") +'{:>5s}\t'.format("T1") +'{:>5s}\t'.format("T2") +'{:>8s}\t'.format("#Packets") +'{:>8s}\t'.format("#P/LT1") +'{:>8s}\t'.format("#P/RT1") +'{:>6s}\t'.format("%P/LT1") +'{:>6s}\t'.format("%P/RT1") +'{:>3s}\n'.format("Detected") ) detected = "No" #if percentage_first_part < (STREAM_PACKET_THRESHOLD * 100.0): if percentage_first_part < percentage_second_part: # First part: 90% of time --> There have to be more packages log.critical(color("Network anomaly detected! Download '%s' might be infected.",1), stream.file_name) syslog.syslog(syslog.LOG_CRIT, "Network anomaly detected! Download {0} might be infected.".format(stream.file_name)) stream.proxy_detected = True detected = "Yes" with open(os.path.join(ETHERSNIFF_ROOT,"log","statistical-analysis" + ".dat"), 'a') as file: if self.comment: file.write("\n### {0} ### \n".format(self.comment)) self.comment = None file.write('{:20s}\t'.format(t) +'{:15s}\t'.format(stream.file_name) +'{:10.3f}\t'.format(int(stream.file_size)/1024.0/1024.0) +'{:6.2f}\t'.format(download_time) +'{:5.2f}\t'.format(STREAM_TIMING_THRESHOLD * 100.0) +'{:5.2f}\t'.format(STREAM_PACKET_THRESHOLD * 100.0) +'{:8d}\t'.format(len(stream)) +'{:8d}\t'.format(packet_number_first) +'{:8d}\t'.format(packet_number_second) +'{:6.2f}\t'.format(percentage_first_part) +'{:6.2f}\t'.format(percentage_second_part) +'{:3s}\n'.format(detected) ) log.debug("============================")
def logo(): """Malice asciiarts. @return: asciiarts array. """ logos = [] logos.append( """ ███▄ ▄███▓ ▄▄▄ ██▓ ██▓ ▄████▄ ▓█████ ▓██▒▀█▀ ██▒▒████▄ ▓██▒ ▓██▒▒██▀ ▀█ ▓█ ▀ ▓██ ▓██░▒██ ▀█▄ ▒██░ ▒██▒▒▓█ ▄ ▒███ ▒██ ▒██ ░██▄▄▄▄██ ▒██░ ░██░▒▓▓▄ ▄██▒▒▓█ ▄ ▒██▒ ░██▒ ▓█ ▓██▒░██████▒░██░▒ ▓███▀ ░░▒████▒ ░ ▒░ ░ ░ ▒▒ ▓▒█░░ ▒░▓ ░░▓ ░ ░▒ ▒ ░░░ ▒░ ░ ░ ░ ░ ▒ ▒▒ ░░ ░ ▒ ░ ▒ ░ ░ ▒ ░ ░ ░ ░ ░ ░ ▒ ░ ░ ▒ ░░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ """ ) logos.append( """ __ __ _ _ | \/ | __ _| (_) ___ ___ | |\/| |/ _` | | |/ __/ _ \\ | | | | (_| | | | (_| __/ |_| |_|\__,_|_|_|\___\___| """ ) logos.append( """ _/ _/ _/ _/ _/_/ _/_/ _/_/_/ _/ _/_/_/ _/_/ _/ _/ _/ _/ _/ _/ _/ _/ _/_/_/_/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/_/_/ _/ _/ _/_/_/ _/_/_/ """ ) logos.append( """ _____ ___| _|__ ____ ____ ____ ______ ______ | \ / | || \ | | | || ___|| ___| | \/ | || \ | |_ | || |__ | ___| |__/\__/|__|_||__|\__\|______||____||______||______| |_____| """ ) logos.append( """ ______________________________________________________________ /~~\__/~~\__/~~~~~~\__/~~\_______/~~~~\__/~~~~~~\__/~~~~~~~~\_ /~~~\/~~~\_/~~\__/~~\_/~~\________/~~\__/~~\__/~~\_/~~\_______ /~~~~~~~~\_/~~~~~~~~\_/~~\________/~~\__/~~\_______/~~~~~~\___ /~~\__/~~\_/~~\__/~~\_/~~\________/~~\__/~~\__/~~\_/~~\_______ /~~\__/~~\_/~~\__/~~\_/~~~~~~~~\_/~~~~\__/~~~~~~\__/~~~~~~~~\_ ______________________________________________________________""" ) logos.append( """ ======================================== = ===== ========= =================== = === ========= =================== = = = ========= =================== = == == === === == === ==== == = ===== == = == ====== = == = = = ===== ===== == == == ===== = = ===== === == == == ===== ==== = ===== == = == == == = == = = = ===== === == == === ==== == ========================================""" ) logos.append( """ __ __ __ _ _ ______ | V |/ \| | | |/ _/ __| | \_/ | /\ | |_| | \_| _| |_| |_|_||_|___|_|\__/___|""" ) logos.append( """ e e 888 ,e, d8b d8b ,"Y88b 888 " e88'888 ,e e, e Y8b Y8b "8" 888 888 888 d888 '8 d88 88b d8b Y8b Y8b ,ee 888 888 888 Y888 , 888 , d888b Y8b Y8b "88 888 888 888 "88,e8' "YeeP" """ ) logos.append( """ ____ ____ ____ ____ ____ ____ ||M |||a |||l |||i |||c |||e || ||__|||__|||__|||__|||__|||__|| |/__\|/__\|/__\|/__\|/__\|/__\|""" ) logos.append( """ _____ ______ ________ ___ ___ ________ _______ |\ _ \ _ \|\ __ \|\ \ |\ \|\ ____\|\ ____\\ \ \ \\ \\__\ \ \ \ \|\ \ \ \ \ \ \ \ \___|\ \\ \__/ \ \ \|__| \ \ \ __ \ \ \ \ \ \ \ \ \ \ _\\ \ \ \ \ \ \ \ \ \ \ \ \____\ \ \ \ \____\ \ \____ \ \__\ \ \__\ \__\ \__\ \_______\ \__\ \_______\ \______\\ \|__| \|__|\|__|\|__|\|_______|\|__|\|_______|\|______|""" ) logos.append( """ .-----------------. | Malice? | | OH NOES! |\\ '-.__.-' '-----------------' \\ /oo |--.--,--,--. \\_.-'._i__i__i_.' \"\"\"\"\"\"\"\"\"""" ) logos.append( """ • ▌ ▄ ·. ▄▄▄· ▄▄▌ ▪ ▄▄· ▄▄▄ . ·██ ▐███▪▐█ ▀█ ██• ██ ▐█ ▌▪▀▄.▀· ▐█ ▌▐▌▐█·▄█▀▀█ ██▪ ▐█·██ ▄▄▐▀▀▪▄ ██ ██▌▐█▌▐█ ▪▐▌▐█▌▐▌▐█▌▐███▌▐█▄▄▌ ▀▀ █▪▀▀▀ ▀ ▀ .▀▀▀ ▀▀▀·▀▀▀ ▀▀▀ """ ) logos.append( """ ___ ___ ___ ___ ___ ___ /\__\ /\ \ /\__\ /\ \ /\ \ /\ \\ /::L_L_ /::\ \ /:/ / _\:\ \ /::\ \ /::\ \\ /:/L:\__\ /::\:\__\ /:/__/ /\/::\__\ /:/\:\__\ /::\:\__\\ \/_/:/ / \/\::/ / \:\ \ \::/\/__/ \:\ \/__/ \:\:\/ / /:/ / /:/ / \:\__\ \:\__\ \:\__\ \:\/ / \/__/ \/__/ \/__/ \/__/ \/__/ \/__/ """ ) logos.append( """ ___ ___ _ _ | \/ | | (_) | . . | __ _| |_ ___ ___ | |\/| |/ _` | | |/ __/ _ \\ | | | | (_| | | | (_| __/ \_| |_/\__,_|_|_|\___\___|""" ) logos.append( """ __ __ __ __ / \ / | / |/ | $$ \ /$$ | ______ $$ |$$/ _______ ______ $$$ \ /$$$ | / \ $$ |/ | / | / \\ $$$$ /$$$$ | $$$$$$ |$$ |$$ |/$$$$$$$/ /$$$$$$ | $$ $$ $$/$$ | / $$ |$$ |$$ |$$ | $$ $$ | $$ |$$$/ $$ |/$$$$$$$ |$$ |$$ |$$ \_____ $$$$$$$$/ $$ | $/ $$ |$$ $$ |$$ |$$ |$$ |$$ | $$/ $$/ $$$$$$$/ $$/ $$/ $$$$$$$/ $$$$$$$/ """ ) logos.append( """ `7MMM. ,MMF' db `7MMF' `7MMF' .g8""'bgd'`7MM""'YMM MMMb dPMM ;MM: MM MM .dP' `M MM `7 M YM ,M MM ,V^MM. MM MM dM' ` MM d M Mb M' MM ,M `MM MM MM MM MMmmMM M YM.P' MM AbmmmqMA MM , MM MM. MM Y , M `YM' MM A' VML MM ,M MM `Mb. ,' MM ,M .JML. `' .JMML..AMA. .AMMA..JMMmmmmMMM .JMML. `"bmmmd' .JMMmmmmMMM""" ) print(color(random.choice(logos), random.randrange(31, 37))) print print(" Malice %s" % yellow(MALICE_VERSION)) print(" https://github.com/blacktop/malice") print(" Copyright (c) 2013-2014") print sys.stdout.flush()