2023-01-14 18:09:37 +01:00
|
|
|
import os
|
|
|
|
import json
|
|
|
|
import re
|
|
|
|
from flagging import scoring
|
|
|
|
|
|
|
|
onionReport = os.getenv("ONIONSCAN_REPORT")
|
2023-01-15 19:13:59 +01:00
|
|
|
httpHeaders = os.getenv("HTTP_HEADERS")
|
|
|
|
|
|
|
|
onionFlag = 1
|
|
|
|
httpFlag = 1
|
|
|
|
|
|
|
|
securityHeaders = {
|
|
|
|
"X-Frame-Options":"DENY",
|
|
|
|
"X-XSS-Protection":0,
|
|
|
|
"X-Content-Type-Options":"nosniff",
|
|
|
|
"Referrer-Policy":"strict-origin-when-cross-origin",
|
|
|
|
"Content-Type":"text/html; charset=UTF-8",
|
|
|
|
"Set-Cookie":"HttpOnly; Secure; SameSite=Strict",
|
|
|
|
"Strict-Transport-Security":"max-age=63072000; includeSubDomains; preload",
|
|
|
|
"Content-Security-Policy":"default-src 'none'; script-src 'self'; connect-src 'self'; img-src 'self'; style-src 'self'; frame-ancestors 'self'; form-action 'self'",
|
|
|
|
"Cross-Origin-Opener-Policy":"same-origin",
|
|
|
|
"Cross-Origin-Embedder-Policy":"require-corp",
|
|
|
|
"Cross-Origin-Resource-Policy":"same-site",
|
|
|
|
"Permissions-Policy":"microphone=(); geolocation=(); interest-cohort=()",
|
|
|
|
"X-DNS-Prefetch-Control":"off",
|
|
|
|
}
|
|
|
|
|
|
|
|
badHeaders = [
|
|
|
|
"Access-Control-Allow-Origin",
|
|
|
|
"Expect-CT",
|
|
|
|
"X-Powered-By",
|
|
|
|
"X-AspNet-Version",
|
|
|
|
"X-AspNetMvc-Version",
|
|
|
|
"Public-Key-Pins",
|
|
|
|
"Server",
|
|
|
|
"ETag"
|
|
|
|
]
|
|
|
|
|
|
|
|
print("Analysis started with base score at 100")
|
|
|
|
print("")
|
2023-01-14 18:09:37 +01:00
|
|
|
|
|
|
|
if len(onionReport) == 0:
|
2023-01-15 19:13:59 +01:00
|
|
|
print("OnionScan report not found, skipping...")
|
|
|
|
onionFlag = 0
|
|
|
|
|
|
|
|
if onionFlag == 1:
|
|
|
|
onionReport = json.loads(onionReport)
|
|
|
|
|
|
|
|
print("OnionScan analysis:")
|
|
|
|
baseScore = 100
|
|
|
|
|
|
|
|
hiddenService = onionReport['hiddenService']
|
|
|
|
print("\t Hidden service address:", hiddenService)
|
|
|
|
if hiddenService == " http://ciadotgov4sjwlzihbbgxnqg3xiyrg7so2r2o3lt5wz5ypk4sxyjstad.onion":
|
|
|
|
baseScore = 0
|
|
|
|
print("\t Score goes down, now:", baseScore)
|
|
|
|
print("\t This hidden service is likely owned by CIA.")
|
|
|
|
scoring(baseScore)
|
|
|
|
exit()
|
|
|
|
|
|
|
|
ssh = onionReport['sshDetected']
|
|
|
|
print("\t SSH?", ssh)
|
|
|
|
if ssh:
|
|
|
|
baseScore = baseScore * 0.67
|
|
|
|
print("\t Score goes down, now:", baseScore)
|
|
|
|
print("\t SSH key:", onionReport['sshKey'])
|
|
|
|
|
2023-01-14 18:09:37 +01:00
|
|
|
ftp = onionReport['ftpDetected']
|
2023-01-15 19:13:59 +01:00
|
|
|
print("\t FTP?", ftp)
|
|
|
|
if ftp:
|
|
|
|
baseScore = baseScore * 0.67
|
|
|
|
print("\t Score goes down, now:", baseScore)
|
|
|
|
print("\t FTP fingerprint:", onionReport['ftpFingerprint'])
|
|
|
|
print("\t FTP banner:", onionReport['ftpBanner'])
|
|
|
|
ftp = onionReport['ftpDetected']
|
|
|
|
|
|
|
|
smtp = onionReport['smtpDetected']
|
|
|
|
print("\t SMTP?", smtp)
|
|
|
|
if smtp:
|
|
|
|
baseScore = baseScore * 0.67
|
|
|
|
print("\t Score goes down, now:", baseScore)
|
|
|
|
print("\t SMTP fingerprint:", onionReport['smtpFingerprint'])
|
|
|
|
print("\t SMTP banner:", onionReport['smtpBanner'])
|
|
|
|
|
|
|
|
bitcoin = onionReport['bitcoinDetected']
|
|
|
|
print("\t Bitcoin?", bitcoin)
|
|
|
|
if bitcoin:
|
|
|
|
baseScore = baseScore * 0.81
|
|
|
|
print("\t Score goes down, now:", baseScore)
|
|
|
|
bitcoinInfo = onionReport['bitcoinServices']['bitcoin']
|
|
|
|
print("\t Bitcoin user agent:", bitcoinInfo['userAgent'])
|
|
|
|
print("\t Bitcoin version:", bitcoinInfo['protocolVersion'])
|
|
|
|
print("\t Bitcoin onion peers:", bitcoinInfo['onionPeers'])
|
|
|
|
|
|
|
|
idReport = onionReport['identifierReport']
|
|
|
|
|
|
|
|
privateKey = idReport['privateKeyDetected']
|
|
|
|
print("\t Private key found?", privateKey)
|
|
|
|
if privateKey:
|
|
|
|
baseScore = baseScore * 0.63
|
|
|
|
print("\t Score goes down, now:", baseScore)
|
|
|
|
|
|
|
|
apacheStatus = idReport['foundApacheModStatus']
|
|
|
|
print("\t Apache status found?", apacheStatus)
|
|
|
|
if apacheStatus:
|
|
|
|
baseScore = baseScore * 0.87
|
|
|
|
print("\t Score goes down, now:", baseScore)
|
2023-01-14 18:09:37 +01:00
|
|
|
|
2023-01-15 19:13:59 +01:00
|
|
|
ipAddress = idReport['ipAddresses']
|
|
|
|
print("\t IP address leakage?", ipAddress)
|
|
|
|
if ipAddress:
|
|
|
|
baseScore = baseScore * 0.55
|
|
|
|
print("\t Score goes down, now:", baseScore)
|
|
|
|
|
|
|
|
emailAddress = idReport['emailAddresses']
|
|
|
|
print("\t Email address found?", emailAddress)
|
|
|
|
if emailAddress:
|
2023-01-14 18:09:37 +01:00
|
|
|
baseScore = baseScore * 0.959
|
2023-01-15 19:13:59 +01:00
|
|
|
print("\t Score goes down, now:", baseScore)
|
|
|
|
|
|
|
|
analyticsId = idReport['analyticsIDs']
|
|
|
|
print("\t Analytics tags?", analyticsId)
|
|
|
|
if analyticsId:
|
|
|
|
baseScore = baseScore * 0.6
|
|
|
|
print("\t Score goes down, now:", baseScore)
|
|
|
|
|
|
|
|
risks = onionReport['simpleReport']['risks']
|
|
|
|
if not risks:
|
|
|
|
print("\t No risk detected.")
|
|
|
|
print("")
|
|
|
|
else:
|
|
|
|
print("\t OnionScan detected risks:\n")
|
|
|
|
for r in risks:
|
|
|
|
t = r['title']
|
|
|
|
print("\t Name:", t)
|
|
|
|
s = r['severity']
|
|
|
|
print("\t Severity:", s)
|
|
|
|
if s == "info":
|
|
|
|
baseScore = baseScore * 0.999
|
|
|
|
print("\t Score goes down, now:", baseScore)
|
|
|
|
if s == "low":
|
|
|
|
baseScore = baseScore * 0.959
|
|
|
|
print("\t Score goes down, now:", baseScore)
|
|
|
|
if s == "medium":
|
|
|
|
baseScore = baseScore * 0.939
|
|
|
|
print("\t Score goes down, now:", baseScore)
|
|
|
|
if s == "high":
|
|
|
|
baseScore = baseScore * 0.87
|
|
|
|
print("\t Score goes down, now:", baseScore)
|
|
|
|
if s == "critical":
|
|
|
|
baseScore = baseScore * 0.77
|
|
|
|
print("\t Score goes down, now:", baseScore)
|
|
|
|
print("")
|
|
|
|
|
|
|
|
if len(httpHeaders) == 0:
|
|
|
|
print("HTTP Headers not found, skipping...")
|
|
|
|
httpFlag = 0
|
|
|
|
|
|
|
|
if httpFlag == 1:
|
|
|
|
httpHeaders = json.loads(httpHeaders)
|
|
|
|
print("HTTP headers analysis:")
|
|
|
|
for badHeader in badHeaders:
|
|
|
|
if badHeader in httpHeaders:
|
|
|
|
baseScore = baseScore * 0.993
|
|
|
|
print("\t Found", badHeader, "in HTTP headers.")
|
|
|
|
print("\t Score goes down, now:", baseScore)
|
|
|
|
|
|
|
|
for secureHeader in securityHeaders:
|
|
|
|
if secureHeader in httpHeaders:
|
|
|
|
if securityHeaders[secureHeader] != httpHeaders[secureHeader]:
|
|
|
|
baseScore = baseScore * 0.987
|
|
|
|
print("\t", secureHeader, "is present, but have diffrent value than expected.")
|
|
|
|
print("\t Present value:", httpHeaders[secureHeader])
|
|
|
|
print("\t Expected value:", securityHeaders[secureHeader])
|
|
|
|
print("\t Score goes down, now:", baseScore)
|
|
|
|
else:
|
|
|
|
print("\t", secureHeader, "is present and set correctly.")
|
|
|
|
else:
|
|
|
|
baseScore = baseScore * 0.983
|
|
|
|
print("\t",secureHeader, "not found.")
|
|
|
|
print("\t Score goes down, now:", baseScore)
|
|
|
|
|
|
|
|
if "Expect-CT" in httpHeaders:
|
|
|
|
baseScore = baseScore * 0.983
|
|
|
|
print("\t This site is using Expect-CT header, it is recommended to not use it.")
|
|
|
|
print("\t Check https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Expect-CT for details.")
|
|
|
|
print("\t Score goes down, now:", baseScore)
|
|
|
|
|
|
|
|
if "Access-Control-Allow-Origin" in httpHeaders:
|
|
|
|
baseScore = baseScore * 0.989
|
|
|
|
print("\t This site is using Access-Control-Allow-Origin header, which allows to relax SOP.")
|
|
|
|
print("\t Score goes down, now:", baseScore)
|
|
|
|
|
|
|
|
|
|
|
|
if onionFlag or httpFlag:
|
|
|
|
scoring(baseScore)
|
2023-01-14 18:09:37 +01:00
|
|
|
|
|
|
|
print("Analysis ended.")
|