Source code for tests.default_http
from .test import *
from bs4 import BeautifulSoup
import urllib.request
import urllib.error
import http
import ssl
import re
import hashlib
[docs]class DefaultStylesheetTest(Test):
name = "Default Website Stylesheet Test"
description = "Test unchanged website stylesheet"
karma_value = 30
doc_file = 'default_stylesheet.html'
[docs] def run(self):
"""Check if content matches known content"""
default_hashes = {
'1118635ac91417296e67cd0f3e6f9927e5f502e328b92bb3888b3b789a49a257': "glastopf"
}
css = self.target_honeypot.get_websites_css()
if not css:
self.set_result(TestResult.NOT_APPLICABLE, "No stylesheet found")
for style in css:
if isinstance(style, bytes):
hash_obj = hashlib.sha256(style)
else:
hash_obj = hashlib.sha256(style.encode())
digest = hash_obj.hexdigest()
if digest in default_hashes:
self.set_result(TestResult.WARNING, "Default stylesheet used for", default_hashes[digest])
if self.result == TestResult.UNKNOWN:
self.set_result(TestResult.OK, "No default stylesheet matched")
[docs]class DefaultWebsiteTest(Test):
name = "Default Website Test"
description = "Test unchanged website content"
karma_value = 60
doc_file = 'default_website.html'
[docs] def run(self):
"""Check if webpage has a known hash"""
# TODO conpot has current time, hash everything except that?
# TODO use bs4 and test partial hashes for such cases
default_hashes = {
'c59e04f46e25c454e65544c236abd9d71705cc4e5c4b4b7dc3ff83fec0e9402f': "shockpot",
'd405fe3c5b902342565cbf5523bb44a78c6bfb15b38a40c81a5f7bf4d8eb7838': "honeything",
'351190a71ddca564e471600c3d403fd8042e6888c8c6abe9cdfe536cef005e82': "dionaea",
'576137c8755b80c0751baa18c8306465fa02c641c683caf8b6d19469a5b96b86': "amun"
}
sites = self.target_honeypot.get_websites()
if not sites:
self.set_result(TestResult.NOT_APPLICABLE, "No website found")
for content in sites:
if isinstance(content, bytes):
hash_obj = hashlib.sha256(content)
else:
hash_obj = hashlib.sha256(content.encode())
digest = hash_obj.hexdigest()
if digest in default_hashes:
self.set_result(TestResult.WARNING, "Default website used for", default_hashes[digest])
if self.result == TestResult.UNKNOWN:
self.set_result(TestResult.OK, "No default website matched")
[docs]class DefaultGlastopfWebsiteTest(Test):
name = "Default Glastopf Website Content Test"
description = "Test unchanged source for website content"
karma_value = 60
doc_file = 'default_glastopf_site.html'
[docs] def run(self):
"""Check if content matches known content"""
try:
try:
request = urllib.request.urlopen('http://www.gutenberg.org/files/42671/42671.txt', timeout=10)
except:
request = urllib.request.urlopen('http://www.gutenberg.org/files/42671/42671.txt', timeout=10)
book = request.read().decode(request.headers.get_content_charset())
except urllib.error.URLError:
self.set_result(TestResult.UNKNOWN, 'failed to download gutenberg.org book content')
return
sites = self.target_honeypot.get_websites()
if not sites:
self.set_result(TestResult.NOT_APPLICABLE, "No website found")
for content in sites:
soup = BeautifulSoup(content, 'html.parser')
article = soup.find('p')
article = str(article)
article = re.sub('</*p>', '', article)
article = re.sub('<a.*?/a>', '---search---', article)
items = article.split('---search---')
total_items = len(items)
matched_items = 0
for item in items:
if len(item) > 15 and item.strip(' ') in book:
matched_items += 1
# if more than 20 percent of the content is found
if matched_items > 0.2 * total_items:
self.set_result(TestResult.WARNING, "Default Glastopf content source was used")
else:
self.set_result(TestResult.OK, "No default content found")
[docs]class CertificateValidationTest(Test):
name = "Certificate Validation Test"
description = "Check validity of SSL certificates"
karma_value = 20
doc_file = 'invalid_certificate.html'
[docs] def run(self):
"""Check validity of SSL certificates"""
# FIXME NMAP does not report https correctly when using -oX
# target_ports = self.target_honeypot.get_service_ports('https', 'tcp')
# target_ports += self.target_honeypot.get_service_ports('ssl/http', 'tcp')
target_ports = []
if self.target_honeypot.has_tcp(443):
target_ports += [443]
if not target_ports:
self.set_result(TestResult.NOT_APPLICABLE, "Port 443 not open")
return
for port in target_ports:
conn = http.client.HTTPSConnection(self.target_honeypot.ip, port=port, timeout=5)
try:
conn.request('GET', '/')
except ssl.SSLError as e:
if e.reason == "CERTIFICATE_VERIFY_FAILED":
self.set_result(TestResult.WARNING, "Certificate invalid for", self.target_honeypot.ip, ":", port)
else:
self.set_result(TestResult.WARNING, "Other certificate error:", e.reason,
"for", self.target_honeypot.ip, ":", port)
return
except Exception as e:
self.set_result(TestResult.WARNING, "Connection failed with exception ", e)
return
self.set_result(TestResult.OK, "Certificates Valid")