forked from aroulin/binary-analysis
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathshared_hostnames_analysis.py
More file actions
executable file
·86 lines (67 loc) · 2.81 KB
/
shared_hostnames_analysis.py
File metadata and controls
executable file
·86 lines (67 loc) · 2.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#!/usr/bin/python2.7
import argparse
import collections
import networkx
import os
import pefile
import pprint
import re
import sys
from networkx.algorithms import bipartite
from networkx.drawing.nx_agraph import write_dot
from os import popen
def find_hostnames(string):
possible_hostnames = re.findall(
r'(?:[a-zA-Z0-9](?:[a-zA-Z0-9\-]{,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}',
string)
valid_hostname = filter(
lambda hostname: hostname.split(".")[-1].lower() in valid_hostname_suffixes,
possible_hostnames)
return valid_hostname
args = argparse.ArgumentParser(description="Visualize shared hostnames"
" between a directory of malware samples")
args.add_argument("target_path", help="directory with malware samples")
args.add_argument("output_file", help="file to write DOT file to")
args.add_argument("malware_projection", help="file to write DOT file to")
args.add_argument("resource_projection", help="file to write DOT file to")
args.add_argument("graph_tool", help="tool to draw graphs to png (fpd, sfdp, neato)", default="fdp", nargs='?')
args = args.parse_args()
network = networkx.Graph()
valid_hostname_suffixes = map(
lambda string: string.strip(), open("domain_suffixes.txt")
)
valid_hostname_suffixes = set(valid_hostname_suffixes)
for root, dirs, files in os.walk(args.target_path):
for path in files:
try:
per = pefile.PE(os.path.join(root, path))
except pefile.PEFormatError:
continue
fullpath = os.path.join(root, path)
strings = popen("strings '{0}'".format(fullpath)).read()
hostnames = find_hostnames(strings)
if len(hostnames):
network.add_node(path, label=path[:32], color='black', penwidth=5, bipartite=0)
for hostname in hostnames:
network.add_node(hostname, label=hostname, color='blue', penwidth=10, bipartite=1)
network.add_edge(hostname, path, penwidth=2)
if hostnames:
print "Extracted hostnames from: ", path
pprint.pprint(hostnames)
write_dot(network, args.output_file)
malware = set(n for n,d in network.nodes(data=True) if d['bipartite'] == 0)
hostname = set(network) - malware
malware_network = bipartite.projected_graph(network, malware)
hostname_network = bipartite.projected_graph(network, hostname)
write_dot(malware_network, args.malware_projection)
write_dot(hostname_network, args.resource_projection)
toolname = args.graph_tool
popen("'{0}' '{1}' -Goverlap=false -Gsplines=true -T png -o '{1}'.png".format(
toolname, args.output_file
))
popen("'{0}' '{1}' -Goverlap=false -Gsplines=true -T png -o '{1}'.png".format(
toolname, args.malware_projection
))
popen("'{0}' '{1}' -Goverlap=false -Gsplines=true -T png -o '{1}'.png".format(
toolname, args.resource_projection
))