Skip to content

Commit ef4a73a

Browse files
committed
Adding files
1 parent e77e2cb commit ef4a73a

File tree

321 files changed

+13009
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

321 files changed

+13009
-0
lines changed

ch04/code/domain_suffixes.txt

+1,381
Large diffs are not rendered by default.

ch04/code/install-requirements.sh

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
sudo apt install python-pygraphviz
2+
sudo apt install icoutils
3+
sudo pip install -r requirements.txt

ch04/code/listing-4-1.py

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/usr/bin/python
2+
import networkx
3+
4+
# Instantiate a network with no nodes and no edges.
5+
network = networkx.Graph()
6+
7+
nodes = ["hello","world",1,2,3]
8+
for node in nodes:
9+
network.add_node(node)
10+
network.add_edge("hello","world")
11+
network.add_edge(1,2)
12+
network.add_edge(1,3)
13+
network.add_node(1,myattribute="foo")
14+
network.node[1]["myattribute"] = "foo"
15+
print network.node[1]["myattribute"] # prints "foo"
16+
network.add_edge("node1","node2",myattribute="attribute of an edge")
17+
network.get_edge_data("node1","node2")["myattribute"] = "attribute of an edge"
18+
network.get_edge_data("node1","node2")["myattribute"] = 321
19+
print network.get_edge_data("node1","node2")["myattribute"] # prints 321

ch04/code/listing-4-12.py

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#!/usr/bin/python
2+
3+
import pefile
4+
import sys
5+
import argparse
6+
import os
7+
import pprint
8+
import logging
9+
import networkx
10+
import collections
11+
import tempfile
12+
from networkx.drawing.nx_agraph import write_dot
13+
from networkx.algorithms import bipartite
14+
15+
# Use argparse to parse any command line arguments
16+
17+
args = argparse.ArgumentParser("Visualize shared image relationships between a directory of malware samples")
18+
args.add_argument("target_path",help="directory with malware samples")
19+
args.add_argument("output_file",help="file to write DOT file to")
20+
args.add_argument("malware_projection",help="file to write DOT file to")
21+
args.add_argument("resource_projection",help="file to write DOT file to")
22+
args = args.parse_args()
23+
network = networkx.Graph()
24+
25+
class ExtractImages():
26+
def __init__(self,target_binary):
27+
self.target_binary = target_binary
28+
self.image_basedir = None
29+
self.images = []
30+
31+
def work(self):
32+
self.image_basedir = tempfile.mkdtemp()
33+
icondir = os.path.join(self.image_basedir,"icons")
34+
bitmapdir = os.path.join(self.image_basedir,"bitmaps")
35+
raw_resources = os.path.join(self.image_basedir,"raw")
36+
for directory in [icondir,bitmapdir,raw_resources]:
37+
os.mkdir(directory)
38+
rawcmd = "wrestool -x {0} -o {1} 2> /dev/null".format(self.target_binary,raw_resources)
39+
bmpcmd = "mv {0}/*.bmp {1} 2> /dev/null".format(raw_resources,bitmapdir)
40+
icocmd = "icotool -x {0}/*.ico -o {1} 2> /dev/null".format(raw_resources,icondir)
41+
for cmd in [rawcmd,bmpcmd,icocmd]:
42+
try:
43+
os.system(cmd)
44+
except Exception,msg:
45+
pass
46+
for dirname in [icondir,bitmapdir]:
47+
for path in os.listdir(dirname):
48+
logging.info(path)
49+
path = os.path.join(dirname,path)
50+
imagehash = hash(open(path).read())
51+
if path.endswith(".png"):
52+
self.images.append((path,imagehash))
53+
if path.endswith(".bmp"):
54+
self.images.append((path,imagehash))
55+
56+
def cleanup(self):
57+
os.system("rm -rf {0}".format(self.image_basedir))
58+
59+
# search the target directory for PE files to extract images from
60+
image_objects = []
61+
for root,dirs,files in os.walk(args.target_path):
62+
for path in files:
63+
# try to parse the path to see if it's a valid PE file
64+
65+
try:
66+
pe = pefile.PE(os.path.join(root,path))
67+
except pefile.PEFormatError:
68+
continue
69+
fullpath = os.path.join(root,path)
70+
images = ExtractImages(fullpath)
71+
images.work()
72+
image_objects.append(images)
73+
74+
# create the network by linking malware samples to their images
75+
for path, image_hash in images.images:
76+
# set the image attribute on the image nodes to tell GraphViz to render images within these nodes
77+
if not image_hash in network:
78+
network.add_node(image_hash,image=path,label='',type='image')
79+
node_name = path.split("/")[-1]
80+
network.add_node(node_name,type="malware")
81+
network.add_edge(node_name,image_hash)
82+
83+
# write the bipartite network, then do the two projections and write them
84+
write_dot(network, args.output_file)
85+
malware = set(n for n,d in network.nodes(data=True) if d['type']=='malware')
86+
resource = set(network) - malware
87+
malware_network = bipartite.projected_graph(network, malware)
88+
resource_network = bipartite.projected_graph(network, resource)
89+
90+
write_dot(malware_network,args.malware_projection)
91+
write_dot(resource_network,args.resource_projection)

ch04/code/listing-4-3.py

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#!/usr/bin/python
2+
import networkx
3+
from networkx.drawing.nx_agraph import write_dot
4+
5+
# instantiate a network, add some nodes, and connect them
6+
nodes = ["hello","world",1,2,3]
7+
network = networkx.Graph()
8+
for node in nodes:
9+
network.add_node(node)
10+
network.add_edge("hello","world")
11+
write_dot(network, "network.dot")
12+

ch04/code/listing-4-4.py

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/usr/bin/python
2+
3+
import networkx
4+
from networkx.drawing.nx_agraph import write_dot
5+
6+
g = networkx.Graph()
7+
g.add_node(1)
8+
g.add_node(2)
9+
g.add_edge(1,2,penwidth=10) # make the edge extra wide
10+
write_dot(g,'network.dot')
11+
12+
13+

ch04/code/listing-4-5.py

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/usr/bin/python
2+
3+
import networkx
4+
from networkx.drawing.nx_agraph import write_dot
5+
6+
g = networkx.Graph()
7+
g.add_node(1,color="blue") # make the node outline blue
8+
g.add_node(2,color="pink") # make the node outline pink
9+
g.add_edge(1,2,color="red") # make the edge red
10+
write_dot(g,'network.dot')
11+
12+
13+

ch04/code/listing-4-6.py

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/usr/bin/python
2+
3+
import networkx
4+
from networkx.drawing.nx_agraph import write_dot
5+
6+
g = networkx.Graph()
7+
g.add_node(1,shape='diamond')
8+
g.add_node(2,shape='egg')
9+
g.add_edge(1,2)
10+
11+
write_dot(g,'network.dot')
12+
13+

ch04/code/listing-4-7.py

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/usr/bin/python
2+
3+
import networkx
4+
from networkx.drawing.nx_agraph import write_dot
5+
6+
g = networkx.Graph()
7+
g.add_node(1,label="first node")
8+
g.add_node(2,label="second node")
9+
g.add_edge(1,2,label="link between first and second node")
10+
11+
write_dot(g,'network.dot')
12+
13+

ch04/code/listing-4-8.py

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#!/usr/bin/python
2+
3+
import pefile
4+
import sys
5+
import argparse
6+
import os
7+
import pprint
8+
import networkx
9+
import re
10+
from networkx.drawing.nx_agraph import write_dot
11+
import collections
12+
from networkx.algorithms import bipartite
13+
14+
args = argparse.ArgumentParser("Visualize shared hostnames between a directory of malware samples")
15+
args.add_argument("target_path",help="directory with malware samples")
16+
args.add_argument("output_file",help="file to write DOT file to")
17+
args.add_argument("malware_projection",help="file to write DOT file to")
18+
args.add_argument("hostname_projection",help="file to write DOT file to")
19+
args = args.parse_args()
20+
network = networkx.Graph()
21+
22+
valid_hostname_suffixes = map(lambda string: string.strip(), open("domain_suffixes.txt"))
23+
valid_hostname_suffixes = set(valid_hostname_suffixes)
24+
def find_hostnames(string):
25+
possible_hostnames = re.findall(r'(?:[a-zA-Z0-9](?:[a-zA-Z0-9\-]{,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}', string)
26+
valid_hostnames = filter(
27+
lambda hostname: hostname.split(".")[-1].lower() in valid_hostname_suffixes,
28+
possible_hostnames
29+
)
30+
return valid_hostnames
31+
32+
# search the target directory for valid Windows PE executable files
33+
for root,dirs,files in os.walk(args.target_path):
34+
for path in files:
35+
# try opening the file with pefile to see if it's really a PE file
36+
try:
37+
pe = pefile.PE(os.path.join(root,path))
38+
except pefile.PEFormatError:
39+
continue
40+
fullpath = os.path.join(root,path)
41+
# extract printable strings from the target sample
42+
strings = os.popen("strings '{0}'".format(fullpath)).read()
43+
44+
# use the search_doc function in the included reg module to find hostnames
45+
hostnames = find_hostnames(strings)
46+
if len(hostnames):
47+
# add the nodes and edges for the bipartite network
48+
network.add_node(path,label=path[:32],color='black',penwidth=5,bipartite=0)
49+
for hostname in hostnames:
50+
network.add_node(hostname,label=hostname,color='blue',
51+
penwidth=10,bipartite=1)
52+
network.add_edge(hostname,path,penwidth=2)
53+
if hostnames:
54+
print "Extracted hostnames from:",path
55+
pprint.pprint(hostnames)
56+
# write the dot file to disk
57+
write_dot(network, args.output_file)
58+
malware = set(n for n,d in network.nodes(data=True) if d['bipartite']==0)
59+
hostname = set(network)-malware
60+
61+
# use NetworkX's bipartite network projection function to produce the malware
62+
# and hostname projections
63+
malware_network = bipartite.projected_graph(network, malware)
64+
hostname_network = bipartite.projected_graph(network, hostname)
65+
66+
# write the projected networks to disk as specified by the user
67+
write_dot(malware_network,args.malware_projection)
68+
write_dot(hostname_network,args.hostname_projection)

ch04/code/network.dot

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
strict graph {
2+
world -- hello;
3+
2;
4+
3;
5+
1;
6+
}

ch04/code/requirements.txt

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Requirements automatically generated by pigar.
2+
# https://github.com/Damnever/pigar
3+
4+
networkx == 2.0
5+
pydot == 1.2.4
6+
Murmur == 0.1.3
7+
pefile == 2017.11.5
8+
matplotlib == 2.0.0

ch04/code/run-listing-4-12.sh

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
python listing-4-12.py ../data full_network.dot malware_network.dot image_network.dot

ch04/code/run-listing-4-8.sh

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
python listing-4-8.py ../data/APT1_MALWARE_FAMILIES/ network.dot malware.dot hostname.dot
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
The AURIGA malware family shares a large amount of functionality with the BANGAT backdoor. The malware family contains functionality for keystroke logging, creating and killing processes, performing file system and registry modifications, spawning interactive command shells, performing process injection, logging off the current user or shutting down the local machine. The AURIGA malware contains a driver component which is used to inject the malware DLL into other processes. This driver can also perform process and IP connection hiding. The malware family will create a copy of cmd.exe to perform its C2 activity, and replace the "Microsoft corp" strings in the cmd.exe binary with different values. The malware family typically maintains persistence through installing itself as a service

0 commit comments

Comments
 (0)