From d1d4462f5661e0d15176375ec297b3c59d0896c3 Mon Sep 17 00:00:00 2001 From: Louis Burda Date: Thu, 24 Jun 2021 19:34:08 +0200 Subject: add more havocs to test stl parsing --- checker/src/checker.py | 105 +++++++++++++++++++++++++++++++------------ checker/src/requirements.txt | 24 +--------- 2 files changed, 78 insertions(+), 51 deletions(-) (limited to 'checker') diff --git a/checker/src/checker.py b/checker/src/checker.py index 69c9084..ebe3b8e 100644 --- a/checker/src/checker.py +++ b/checker/src/checker.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 from enochecker import BaseChecker, BrokenServiceException, EnoException, run from enochecker.utils import SimpleSocket, assert_equals, assert_in -import os, random, string, struct, subprocess, logging, selectors, time, socket +import math, os, random, string, struct, subprocess, logging, selectors, time, socket import numpy as np logging.getLogger("faker").setLevel(logging.WARNING) @@ -28,16 +28,18 @@ signal.signal(signal.SIGALRM, handler) evil_file = b""" solid test\xff -facet normal 0 0 1.0 - outer loop - vertex 1 0 0 - vertex 1 1 0 - vertex 0 1 0 - endloop - endfacet -endsolid + facet normal 0 0 1.0 + outer loop + vertex 1 0 0 + vertex 1 1 0 + vertex 0 1 0 + endloop + endfacet +endsolid test\xff """ +generic_alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmopqrstuvwxyz0123456789-+.!" + def ensure_bytes(v): if type(v) == bytes: return v @@ -52,7 +54,7 @@ class STLDoctorChecker(BaseChecker): flag_variants = 2 noise_variants = 2 - havoc_variants = 4 + havoc_variants = 8 exploit_variants = 2 prompt = b"$ " @@ -71,9 +73,8 @@ class STLDoctorChecker(BaseChecker): def fakeid(self): fake = Faker(["en_US"]) - allowed = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmopqrstuvwxyz0123456789-+.!" - idstr = "".join([c for c in fake.name().replace(' ','') if c in allowed][:12]).ljust(10, '.') - idstr += "".join([rand.choice(allowed) for i in range(8)]) + idstr = "".join([c for c in fake.name().replace(' ','') if c in generic_alphabet][:12]).ljust(10, '.') + idstr += "".join([rand.choice(generic_alphabet) for i in range(8)]) return idstr def havocid(self): @@ -110,34 +111,46 @@ class STLDoctorChecker(BaseChecker): def reverse_hash(self, hashstr): return subprocess.check_output([os.getenv("REVHASH_PATH"), hashstr])[:-1] - def genfile_ascii(self, solidname): + def genfile_ascii(self, solidname, malformed=False): solidname = ensure_bytes(solidname) + randchoice = rand.randint(0,2) if len(solidname) != 0: content = b"solid " + solidname + b"\n" else: content = b"solid\n" facet_count = rand.randint(4, 30) + indent = b" " * rand.randint(1, 4) for fi in range(facet_count): - content += b"facet normal " + if malformed and randchoice == 0: # malformed by wrong keyword + content += indent * 1 + b"facet nornal " + else: + content += indent * 1 + b"facet normal " vs = [[rand.random() for i in range(3)] for k in range(3)] norm = np.cross(np.subtract(vs[1], vs[0]), np.subtract(vs[2],vs[0])) norm = norm / np.linalg.norm(norm) content += " ".join([f"{v:.2f}" for v in norm]).encode() + b"\n" - content += b"outer loop\n" + if malformed and randchoice == 1: # malformed wrong keyword case + content += indent * 2 + b"outer lOop\n" + else: + content += indent * 2 + b"outer loop\n" for i in range(3): - content += b"vertex " + " ".join([f"{v:.2f}" for v in vs[i]]).encode() + b"\n" - content += b"endloop\n" - content += b"endfacet\n" - if solidname != b"": - content += b"endsolid " + solidname + b"\n" + content += indent * 3 + b"vertex " + " ".join([f"{v:.2f}" for v in vs[i]]).encode() + b"\n" + content += indent * 2 + b"endloop\n" + content += indent + b"endfacet\n" + if malformed and randchoice == 2: + content += b"" # malformed since no endsolid else: - content += b"endsolid\n" + if solidname != b"": + content += b"endsolid " + solidname + b"\n" + else: + content += b"endsolid\n" return content - def genfile_bin(self, solidname): + def genfile_bin(self, solidname, malformed=False): solidname = ensure_bytes(solidname) + randchoice = rand.randint(0, 3) if len(solidname) > 78: raise EnoException("Solidname to embed in header is larger than header itself") @@ -146,23 +159,36 @@ class STLDoctorChecker(BaseChecker): else: content = b"#" + b"\x00" * 79 facet_count = rand.randint(4, 30) - content += struct.pack(" None if self.variant_id == 0: conn = self.openconn() @@ -337,6 +379,14 @@ class STLDoctorChecker(BaseChecker): self.havoc_upload('ascii', True) elif self.variant_id == 3: self.havoc_upload('bin', True) + elif self.variant_id == 4: + self.malformed_upload('ascii') + elif self.variant_id == 5: + self.malformed_upload('bin') + elif self.variant_id == 6: + self.malformed_upload('garbage') + elif self.variant_id == 7: + self.malformed_upload('garbage-tiny') else: raise EnoException(f"Invalid havoc variant ({self.variant_id}) provided") @@ -372,7 +422,6 @@ class STLDoctorChecker(BaseChecker): raise BrokenServiceException("Download size is not a valid integer") resp += conn.recvn(size) resp += conn.recvuntil("? ") - self.debug(resp) found = self.search_flag_bytes(resp) if found is not None or i == len(filelist) - 1: break diff --git a/checker/src/requirements.txt b/checker/src/requirements.txt index 38a6e0b..42539e3 100644 --- a/checker/src/requirements.txt +++ b/checker/src/requirements.txt @@ -1,28 +1,6 @@ -certifi==2020.12.5 -chardet==4.0.0 -click==7.1.2 -dnspython==1.16.0 -# enochecker==0.4.2 -# git+https://github.com/enowars/enochecker@37981175f3125bd552c3c351494186fe9ce35e0b + git+https://github.com/Sinitax/enochecker@f04cab0fd57fbc927809e88c97a1dd37579089ee -enochecker-cli==0.7.0 -enochecker-core==0.10.0 eventlet==0.30.2 -Flask==1.1.2 -greenlet==1.0.0 gunicorn==20.1.0 -idna==2.10 -itsdangerous==1.1.0 -Jinja2==2.11.3 -jsons==1.4.2 -MarkupSafe==1.1.1 -pycryptodome==3.10.1 -pymongo==3.11.3 -requests==2.25.1 -six==1.15.0 -typish==1.9.2 -urllib3==1.26.5 -Werkzeug==1.0.1 numpy==1.20.1 Faker==8.1.4 -pwntools==4.5.0 -- cgit v1.2.3-71-gd317