Repository navigation
Expand file tree
/
Copy pathapekit.py
More file actions
125 lines (113 loc) · 4.8 KB
/
Copy pathapekit.py
File metadata and controls
125 lines (113 loc) · 4.8 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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
"""
Top Level Pipeline Module
EC521 Cyber Security Project
Copyright 2015 Luke Sorenson
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import fnmatch
import os
import subprocess
from datetime import datetime
from backend.model_interface import ModelInterface
from vulns.vuln_lib_checker import VulnLibChecker
from vulns.keySearch import keySearch
from vulns.httpschecker import httpschecker
from vulns.commentchecker import commentchecker
# from charting.charting import chart_vulns
class Pipeline(object):
"""
Top level module for apekit, which reads the list of downloaded apps,
decompiles them into java files, reads in the java files and runs the
lines through a variety of security modules to look for common
vulnerabilities. These vulnerabilities are then aggregated in a
database so that we can compute statistics.
"""
def __init__(self):
self.counter = 0
def run(self):
"""
Runs the pipeline on the apps from the sqlite db.
"""
print ("="*80)
print "{:<40}{:>40}".format("DECOMPILATION STARTED", str(datetime.now()))
print ("="*80)
failed_to_decompile_count = 0
mi = ModelInterface.get_instance()
num_apps = mi.get_num_apps()
for i in xrange(1, num_apps + 1):
app = mi.get_app_for_id(i)
if not app:
print "Failed to get app for id: " + str(i)
continue
dir_name = "decompiled/" + app.app_id
if not os.path.isdir(dir_name):
try:
subprocess.check_output("python androguard/androdd.py -i " +
app.apk_local + " -o " + dir_name + " -l " +
app.app_id + "*", shell=True)
except:
print "App " + app.app_id + " could not be decompiled"
failed_to_decompile_count += 1
continue
files = self.get_java_files_in_dir(dir_name)
for path_to_file in files:
self.analyze_file_for_vulns(app, path_to_file)
print "{:>5}/{:<5} ".format(i, num_apps) + app.app_id
print "Failed to decompile " + str(failed_to_decompile_count) + " apps"
print ("="*80)
print "{:<40}{:>40}".format("DECOMPILATION COMPLETED", str(datetime.now()))
print ("="*80)
# def chart_vulns(self):
# mi = ModelInterface.get_instance()
# num_apps = mi.get_num_apps()
# chart_vulns(mi.get_vulnerabilities_and_descriptions(), num_apps)
@staticmethod
def analyze_file_for_vulns(app, path_to_file):
mi = ModelInterface.get_instance()
vln = VulnLibChecker.get_instance()
with open(path_to_file) as f:
line_counter = 1
for line in f:
line = line.rstrip()
# Call the vulnerability analysis modules here.
if len(line) > 0:
# Check for potentially vulnerable library.
ids = vln.vulnCheck(line)
for vuln_id in ids:
mi.add_vulnerability_for_app(
app, vuln_id, path_to_file, line_counter, line)
# Check for secure keys.
is_key = keySearch(line)
if is_key[0]:
mi.add_vulnerability_for_app(app, 10,
path_to_file, line_counter, line)
# Check for http instead of https.
if httpschecker(line):
mi.add_vulnerability_for_app(app, 11,
path_to_file, line_counter, line)
if commentchecker(line):
mi.add_vulnerability_for_app(app, 12,
path_to_file, line_counter, line)
line_counter += 1
@staticmethod
def get_java_files_in_dir(directory):
"""
Returns a list of all java file paths in a directory.
"""
matches = []
for root, dirnames, filenames in os.walk(directory):
for filename in fnmatch.filter(filenames, '*.java'):
matches.append(os.path.join(root, filename))
return matches
if __name__ == "__main__":
pipeline = Pipeline()
pipeline.run()
# pipeline.chart_vulns()