added hash based scanning, yara scanning, and heuristics scanning
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
__pycache__
|
||||
venv
|
||||
4
src/console.py
Normal file
4
src/console.py
Normal file
@@ -0,0 +1,4 @@
|
||||
from rich.console import Console
|
||||
|
||||
|
||||
console = Console()
|
||||
3
src/detections/__init__.py
Normal file
3
src/detections/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from .hash import Hash
|
||||
from .yara import Yara
|
||||
from .heuristics import Heuristics
|
||||
6
src/detections/detection.py
Normal file
6
src/detections/detection.py
Normal file
@@ -0,0 +1,6 @@
|
||||
class Detection:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def run(self, contents: bytes, file) -> bool:
|
||||
pass
|
||||
23
src/detections/hash.py
Normal file
23
src/detections/hash.py
Normal file
@@ -0,0 +1,23 @@
|
||||
from .detection import Detection
|
||||
|
||||
import hashlib
|
||||
|
||||
|
||||
hashes = {
|
||||
"test virus": {
|
||||
"md5": "e74af7e29983d1c1d1b6fa11c9e6ea9a",
|
||||
"sha1": "e66c4bc68cc58313baf227843df85911f23ae202",
|
||||
"sha256": "fcd2db21ad4eb03b77405235381b87ddd2d29150cfc273db520b3f852702c8e4"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Hash(Detection):
|
||||
def run(self, content: bytes, _) -> bool:
|
||||
md5, sha1, sha256 = hashlib.md5(content).hexdigest(), hashlib.sha1(content).hexdigest(), hashlib.sha256(content).hexdigest()
|
||||
|
||||
for virus_name, virus_hashes in hashes.items():
|
||||
if virus_hashes["md5"] == md5 or virus_hashes["sha1"] == sha1 or virus_hashes["sha256"] == sha256:
|
||||
return True
|
||||
|
||||
return False
|
||||
45
src/detections/heuristics.py
Normal file
45
src/detections/heuristics.py
Normal file
@@ -0,0 +1,45 @@
|
||||
from .detection import Detection
|
||||
|
||||
from elftools.elf.elffile import ELFFile
|
||||
|
||||
|
||||
class Heuristics(Detection):
|
||||
THRESHOLD = 3
|
||||
|
||||
def run(self, contents: bytes, file):
|
||||
elf = ELFFile(file)
|
||||
|
||||
scary = {
|
||||
"Process spawning": {
|
||||
"exec": 2,
|
||||
"execv": 2,
|
||||
"execve": 2,
|
||||
"execvp": 2,
|
||||
"system": 2,
|
||||
"popen": 2,
|
||||
"fork": 2,
|
||||
"vfork": 2,
|
||||
"clone": 2,
|
||||
},
|
||||
|
||||
"Tracing": {
|
||||
"ptrace": 1
|
||||
},
|
||||
|
||||
"Networking": {
|
||||
"connect": 1,
|
||||
"socket": 1,
|
||||
}
|
||||
}
|
||||
|
||||
score = 0
|
||||
dynsym = elf.get_section_by_name(".dynsym")
|
||||
if dynsym:
|
||||
for sym in dynsym.iter_symbols():
|
||||
for reason, scary_names in scary.items():
|
||||
if sym.name in scary_names.keys():
|
||||
score += scary_names[sym.name]
|
||||
|
||||
print(score)
|
||||
|
||||
return score >= self.THRESHOLD
|
||||
13
src/detections/yara.py
Normal file
13
src/detections/yara.py
Normal file
@@ -0,0 +1,13 @@
|
||||
from .detection import Detection
|
||||
|
||||
import yara
|
||||
import os
|
||||
|
||||
|
||||
class Yara(Detection):
|
||||
def run(self, contents: bytes, _) -> bool:
|
||||
rules = yara.compile(os.path.realpath(os.path.join(__file__, "../../yara_rules.yara")))
|
||||
|
||||
matches = rules.match(data=contents)
|
||||
|
||||
return len(matches) > 0
|
||||
5
src/main.py
Normal file
5
src/main.py
Normal file
@@ -0,0 +1,5 @@
|
||||
from scanner import Scanner
|
||||
|
||||
|
||||
scanner = Scanner()
|
||||
scanner.scan_file("a.out")
|
||||
36
src/scanner.py
Normal file
36
src/scanner.py
Normal file
@@ -0,0 +1,36 @@
|
||||
from detections import *
|
||||
from console import console
|
||||
|
||||
from rich.table import Table
|
||||
from time import time
|
||||
|
||||
|
||||
class Scanner:
|
||||
def __init__(self):
|
||||
self.detections = {
|
||||
"Hash Detection": Hash(),
|
||||
"Yara Pattern Matching": Yara(),
|
||||
"Heuristics": Heuristics()
|
||||
}
|
||||
|
||||
def scan_file(self, file_path: str):
|
||||
with console.status(f"Scanning {file_path}...") as status:
|
||||
f = open(file_path, "rb")
|
||||
contents = f.read()
|
||||
|
||||
|
||||
table = Table("Scan", "Match")
|
||||
|
||||
for name, detection in self.detections.items():
|
||||
start_time = time()
|
||||
console.print(f"[d]Running {name}..", end='\r')
|
||||
|
||||
match = detection.run(contents, f)
|
||||
table.add_row(name, "[bold orange1]⚠️ Match" if match else "[bold green]✅ Clean")
|
||||
|
||||
console.print(f"Running {name}.. [d]({round(time()-start_time, 3)}s)", highlight=False)
|
||||
|
||||
f.close()
|
||||
|
||||
print()
|
||||
console.print(table)
|
||||
12
src/yara_rules.yara
Normal file
12
src/yara_rules.yara
Normal file
@@ -0,0 +1,12 @@
|
||||
rule test_virus {
|
||||
meta:
|
||||
author = "Azure"
|
||||
description = "A test virus that isn't actually dangerous but in theory is really naughty."
|
||||
|
||||
strings:
|
||||
$a = "virus"
|
||||
|
||||
condition:
|
||||
any of them
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user