-
Notifications
You must be signed in to change notification settings - Fork 1
/
pentest.py
125 lines (96 loc) · 4.77 KB
/
pentest.py
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
import json
import time
import requests
start_pentest = time.perf_counter()
swagger_url = "http://localhost:5000/swagger/v1/swagger.json"
url_token_roles = "http://localhost:5000/dev/test-roles"
request_token = requests.get(url_token_roles)
data_tokens = request_token.json()
# Print ALL Roles
print(f"All Roles detected ({len(data_tokens)}):")
for role in data_tokens:
print(role['roleName'])
# Pentest
print("\nPentest: \n")
get_all_url_swagger = requests.get(swagger_url)
data_swagger = get_all_url_swagger.json()
# Save all paths from swagger
paths = []
for path in data_swagger['paths']:
paths.append({
'path': path,
'method': list(data_swagger['paths'][path].keys())[0]
})
# Print all paths
print(f"All Paths detected ({len(paths)}) : ")
# Save all resulsts
results = {}
with open("./pentest/result.txt", "w", encoding="utf-8") as f:
f.write("Pentest script developed by Mercure to test the API\n\n")
# Test all paths
for path in paths:
print(f"\nTesting Path: {path['path']} with Method: {path['method']}")
f.write("\nTesting Path: " + path['path'])
results[path['path']] = {
'method': path['method'],
'result': []
}
for token in data_tokens:
print("\t Role role testing: " + token['roleName'])
f.write("\nRole role testing: " + token['roleName'] + "\n")
headers = {
'Authorization': token['token']
}
start_request = time.perf_counter()
if path['method'] == 'get':
res = requests.get("http://localhost:5000" +
path['path'], headers=headers)
elif path['method'] == 'post':
res = requests.post("http://localhost:5000" +
path['path'], headers=headers)
elif path['method'] == 'put':
res = requests.put("http://localhost:5000" +
path['path'], headers=headers)
elif path['method'] == 'delete':
res = requests.delete(
"http://localhost:5000" + path['path'], headers=headers)
else:
print("Method not supported")
request_time = time.perf_counter() - start_request
results[path['path']]['result'].append({
'roleName': token['roleName'],
'response_code': res.status_code,
'response_time': request_time * 1000
})
print("\t\t Response code : " + str(res.status_code))
print("\t\t Response time : {0:.0f}ms".format(
request_time * 1000))
print("\t\t Can access : " + ("🟩" if res.status_code == 200 else "🟥"))
f.write("\t\t Response code : " + str(res.status_code) + "\n")
f.write("\t\t Response time : {0:.0f}ms".format(
request_time * 1000) + "\n")
f.write("\t\t Can access : " +
("🟩" if res.status_code == 200 else ("🟧" if res.status_code == 400 else "🟥")) + "\n")
end_pentest = time.perf_counter() - start_pentest
print("\n\nPentest finished in {0:.0f}ms".format(end_pentest * 1000))
f.write("\n\nPentest finished in {0:.0f}ms".format(end_pentest * 1000))
# Close file
f.close()
# save results in a json file
with open("./pentest/results.json", "w", encoding="utf-8") as f:
f.write(json.dumps(results, indent=4))
f.close()
# Print les résultats dans un tableau lisible
print("Generating markdown file")
with open("./pentest/RESULT_PENTEST.md", "w", encoding="utf-8") as f:
f.write("# Pentest script developed by Mercure to test the API\n\n")
f.write(
"\n🟩 = Success without param\n\n🟧 = Need param to be tested *(this script can't for now request with params needed)* \n\n🟥 = No chance\n\n\n\n")
f.write("|Path | " + " | ".join([token['roleName']
for token in data_tokens]) + "|\n")
f.write("|---|" + "---|" * len(data_tokens) + "\n")
for result in results:
f.write("|"+result + " | " + " | ".join(["<table><thead><tr><th>W</th><th>R</th></tr></thead><tbody><tr><td>" + ("🟩" if res['response_code'] == 200 and results[result]['method'] == "post" else ("🟧" if res['response_code'] == 400 and results[result]['method'] == "post" else "🟥")) +
"</td><td>" + ("🟩" if res['response_code'] !=
401 and results[result]['method'] == "get" else ("🟧" if res['response_code'] == 400 or res['response_code'] == 500 and results[result]['method'] == "get" else "🟥")) + "</td></tr></tbody></table>" for res in results[result]['result']]) + "|\n")
f.close()