-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstatic_final.py
More file actions
98 lines (87 loc) · 3.25 KB
/
Copy pathstatic_final.py
File metadata and controls
98 lines (87 loc) · 3.25 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
#!/usr/bin/env python3
import os
import ast
# Starter Script for Automated Static Code Analysis Tool
# Scenario: You are a junior penetration tester at a manufacturing facility.
# Your mission is to identify vulnerabilities in the facility's software.
# Vulnerabilities to target:
# - Use of unsafe functions (e.g., eval, exec)
# - (Additional patterns can be added as you refine the script)
def collect_source_files(directory, extension=".py"):
"""
Recursively collects all source code files with a given extension from the specified directory.
"""
source_files = []
for root, _, files in os.walk(directory):
for file in files:
if file.endswith(extension):
source_files.append(os.path.join(root, file))
return source_files
def parse_source_code(file_path):
"""
Parses the source code file and returns its Abstract Syntax Tree (AST).
"""
with open(file_path, "r", encoding="utf-8") as file:
source = file.read()
try:
tree = ast.parse(source, filename=file_path)
return tree
except SyntaxError as e:
print(f"Syntax error in {file_path}: {e}")
return None
# Define vulnerability patterns (for example, unsafe functions)
unsafe_functions = ["eval", "exec", "pickle.loads"]
def is_vulnerable_function(node):
"""
Checks if the function call node uses any unsafe functions.
"""
if isinstance(node, ast.Call):
# Retrieve the function name if possible
func_name = ""
if isinstance(node.func, ast.Name):
func_name = node.func.id
elif isinstance(node.func, ast.Attribute):
# Reconstruct dotted names like "pickle.loads" instead of just "loads"
if isinstance(node.func.value, ast.Name):
func_name = f"{node.func.value.id}.{node.func.attr}"
else:
func_name = node.func.attr
if func_name in unsafe_functions:
return True, func_name
return False, None
def analyze_ast(tree, file_path):
"""
Analyzes the AST of a source file for potential vulnerabilities.
Returns a list of found issues.
"""
issues = []
for node in ast.walk(tree):
vulnerable, func_name = is_vulnerable_function(node)
if vulnerable:
issue = {
"file": file_path,
"line": getattr(node, 'lineno', 'unknown'),
"issue": f"Use of unsafe function '{func_name}'"
}
issues.append(issue)
return issues
def main(directory):
"""
Main function to perform static code analysis on all source files in the given directory.
"""
all_issues = []
source_files = collect_source_files(directory)
for file in source_files:
tree = parse_source_code(file)
if tree:
issues = analyze_ast(tree, file)
all_issues.extend(issues)
if all_issues:
print("Vulnerabilities found:")
for issue in all_issues:
print(f"File: {issue['file']}, Line: {issue['line']}, Issue: {issue['issue']}")
else:
print("No vulnerabilities found.")
if __name__ == "__main__":
# Replace 'your_source_code_directory' with the path to the directory you want to analyze.
main("your_source_code_directory")