mirror of
https://github.com/BenjiTrapp/MostShittyAV
synced 2026-06-06 15:24:25 +00:00
203 lines
8.2 KiB
Nim
203 lines
8.2 KiB
Nim
import os, times, strformat, strutils
|
|
|
|
type
|
|
IAntimalwareProvider* = ref object of RootObj
|
|
name*: string
|
|
|
|
proc scan*(self: IAntimalwareProvider, filePath: string): bool =
|
|
discard
|
|
|
|
type
|
|
LoggingAntimalwareProvider* = ref object of IAntimalwareProvider
|
|
|
|
|
|
proc log(msg: string) =
|
|
let timestamp = now().format("yyyy-MM-dd HH:mm:ss")
|
|
echo fmt"[{timestamp}] {msg}"
|
|
|
|
###########################################################################
|
|
# Example ASCII signatures (checked lowercase) #
|
|
###########################################################################
|
|
const
|
|
signatures = [
|
|
"malware",
|
|
"virus",
|
|
"trojan",
|
|
"evil_payload",
|
|
"dropper",
|
|
"ransomware",
|
|
"payload.exe"
|
|
]
|
|
|
|
proc toLowerAsciiByte(b: byte): byte =
|
|
if b >= 0x41 and b <= 0x5A:
|
|
return b + 0x20.byte
|
|
else:
|
|
return b
|
|
|
|
proc containsSignatureBytes(content: seq[byte]): bool =
|
|
if content.len == 0:
|
|
return false
|
|
var lower = newString(content.len)
|
|
for i, b in content:
|
|
lower[i] = chr(toLowerAsciiByte(b))
|
|
for sig in signatures:
|
|
if lower.find(sig.toLowerAscii()) >= 0:
|
|
return true
|
|
return false
|
|
|
|
proc nonPrintableRatioBytes(content: seq[byte]): float =
|
|
if content.len == 0:
|
|
return 0.0
|
|
var nonPrintable = 0
|
|
for b in content:
|
|
if b < 9 or (b > 13 and b < 32) or b > 126:
|
|
inc(nonPrintable)
|
|
return nonPrintable.float / content.len.float
|
|
|
|
proc fileExtLower(path: string): string =
|
|
let idx = path.rfind('.')
|
|
if idx >= 0:
|
|
return path[idx .. ^1].toLowerAscii()
|
|
else:
|
|
return ""
|
|
|
|
proc isSuspiciousExtension(ext: string): bool =
|
|
const suspicious = [".exe", ".dll", ".bat", ".cmd", ".sh", ".ps1", ".scr", ".js", ".vbs", ".jar", ".lnk"]
|
|
return ext in suspicious
|
|
|
|
# Implement the scan method provided by IAntimalwareProvider
|
|
proc scan*(self: LoggingAntimalwareProvider, filePath: string): bool =
|
|
log("AMSI: Starting scan for file: " & filePath)
|
|
|
|
if not fileExists(filePath):
|
|
log("AMSI: Scan aborted - File not found: " & filePath)
|
|
return false
|
|
|
|
var content: seq[byte] = @[]
|
|
try:
|
|
log("AMSI: Reading file content...")
|
|
var f = open(filePath, fmRead)
|
|
let size = getFileSize(filePath)
|
|
setLen(content, size)
|
|
var buf: array[1024, byte]
|
|
var readSoFar = 0
|
|
while readSoFar < size:
|
|
let toRead = min(size - readSoFar, buf.len)
|
|
let n = f.readBuffer(addr buf[0], toRead)
|
|
for i in 0..<n:
|
|
content[readSoFar + i] = buf[i]
|
|
readSoFar += n
|
|
f.close()
|
|
log(fmt"AMSI: File successfully read ({size} bytes)")
|
|
except OSError as e:
|
|
log("AMSI: Error reading file: " & e.msg)
|
|
return false
|
|
|
|
#########################################################################################
|
|
# Welcome to the MostShitty Heuristic Based Scan Engine #
|
|
# This is a simple simulation of an antimalware scan using basic heuristics. #
|
|
# It checks for known signatures, suspicious file extensions, and analyzes byte content.#
|
|
# It is NOT a real antimalware solution and is intended for educational purposes only. #
|
|
#########################################################################################
|
|
# CHALLENGE: #
|
|
# ---------- #
|
|
# Can you bypass the engine? How far can you go? Try to run Malware samples or #
|
|
# abuse this code to the max and see if it gets detected! #
|
|
#########################################################################################
|
|
|
|
type
|
|
ScanEngine = object
|
|
content: seq[byte]
|
|
filePath: string
|
|
ext: string
|
|
|
|
proc signatureScan(self: ScanEngine): bool =
|
|
log("AMSI: Checking for known malware signatures...")
|
|
if containsSignatureBytes(self.content):
|
|
log("AMSI: \e[31mThreat detected - Signature found in " & self.filePath & "\e[0m")
|
|
return false
|
|
else:
|
|
log("AMSI: No known signatures found.")
|
|
return true
|
|
|
|
proc extensionHeuristic(self: ScanEngine): bool =
|
|
log("AMSI: Checking file extension: " & self.ext)
|
|
if isSuspiciousExtension(self.ext):
|
|
log("AMSI: \e[33mWarning - Suspicious file extension detected: " & self.ext & "\e[0m")
|
|
return false
|
|
else:
|
|
log("AMSI: File extension considered benign.")
|
|
return true
|
|
|
|
proc nonPrintableRatioCheck(self: ScanEngine): bool =
|
|
log("AMSI: Analyzing ratio of non-printable bytes...")
|
|
let ratio = nonPrintableRatioBytes(self.content)
|
|
log(fmt"AMSI: Non-printable bytes: {ratio:.3f} (Threshold: 0.40)")
|
|
if self.content.len >= 64 and ratio > 0.40:
|
|
log("AMSI: \e[31mThreat detected - High ratio of non-printable bytes (possibly packed/obfuscated)\e[0m")
|
|
return false
|
|
else:
|
|
log("AMSI: Ratio of non-printable bytes is unremarkable.")
|
|
return true
|
|
|
|
proc smallExecutableCheck(self: ScanEngine): bool =
|
|
log("AMSI: Checking for very small executable/script files...")
|
|
if self.content.len < 32 and isSuspiciousExtension(self.ext):
|
|
log("AMSI: \e[31m Threat detected - Very small executable/script file\e[0m")
|
|
return false
|
|
else:
|
|
log("AMSI: File size within expected range.")
|
|
return true
|
|
|
|
#########################################################################################
|
|
# Now run the scan engine with the loaded content #
|
|
#########################################################################################
|
|
let engine = ScanEngine(content: content, filePath: filePath, ext: fileExtLower(filePath))
|
|
|
|
if not engine.signatureScan():
|
|
return false
|
|
|
|
discard engine.extensionHeuristic() # Only logs, doesn't block
|
|
|
|
if not engine.nonPrintableRatioCheck():
|
|
return false
|
|
|
|
if not engine.smallExecutableCheck():
|
|
return false
|
|
|
|
log("AMSI: \e[32mScan complete - No threats found in " & filePath & "\e[0m")
|
|
return true
|
|
|
|
when isMainModule:
|
|
let provider = LoggingAntimalwareProvider(name: "MostShittyAVScanner")
|
|
echo """
|
|
888b d888 888 .d8888b. 888 d8b 888 888 d8888 888 888
|
|
8888b d8888 888 d88P Y88b 888 Y8P 888 888 d88888 888 888
|
|
88888b.d88888 888 Y88b. 888 888 888 d88P888 888 888
|
|
888Y88888P888 .d88b. .d8888b 888888 "Y888b. 88888b. 888 888888 888888 888 888 d88P 888 Y88b d88P
|
|
888 Y888P 888 d88""88b 88K 888 "Y88b. 888 "88b 888 888 888 888 888 d88P 888 Y88b d88P
|
|
888 Y8P 888 888 888 "Y8888b. 888 "888 888 888 888 888 888 888 888 d88P 888 Y88o88P
|
|
888 " 888 Y88..88P X88 Y88b. Y88b d88P 888 888 888 Y88b. Y88b. Y88b 888 d8888888888 Y888P
|
|
888 888 "Y88P" 88888P' "Y888 "Y8888P" 888 888 888 "Y888 "Y888 "Y88888 d88P 888 Y8P
|
|
888
|
|
Y8b d88P
|
|
"Y88P"
|
|
"""
|
|
echo "MostShittyAVScanner - AMSI Raccoon Lab - Nim Antimalware Simulator"
|
|
echo "=================================================================="
|
|
echo ""
|
|
|
|
if paramCount() == 0:
|
|
|
|
echo "Usage: nim c -r nim_antimalware_sim.nim <file1> [file2 ...]"
|
|
echo "Run ./create_test_files.nim to generate test files."
|
|
echo "Example: nim c -r nim_antimalware_sim.nim testfile.txt infected.txt"
|
|
else:
|
|
for i in 1..paramCount():
|
|
let fp = paramStr(i)
|
|
let ok = provider.scan(fp)
|
|
let verdict = if ok: "\e[32mBENIGN\e[0m" else: "\e[31mMALICIOUS\e[0m"
|
|
echo "--------------------------------------------"
|
|
echo "\e[34mResult for ", fp, ": ", verdict, "\e[0m"
|
|
echo "" |