GShield
unknown
powershell
2 days ago
10 kB
2
No Index
# GShield.ps1
# Author: Gorstak
#Requires -RunAsAdministrator
# Self-contained AV - copies to ProgramData\GShield and installs as service
param([string]$Path='C:\', [int]$IntervalMinutes=60)
# ==================== CONFIG ====================
$ServiceName = 'GShield'
$InstallDir = "$env:ProgramData\GShield"
$LogDir = "$InstallDir\logs"
$QuarDir = "$InstallDir\quarantine"
$YaraDir = "$InstallDir\yara"
$RulesDir = "$InstallDir\rules"
$LogFile = "$LogDir\service.log"
$Cache = "$InstallDir\av.csv"
$HashCache = "$InstallDir\hashes.csv"
$ScriptName = 'Antivirus.ps1'
$ScriptPath = "$InstallDir\$ScriptName"
$YaraUrl = "https://github.com/VirusTotal/yara/releases/download/v4.5.5/yara-4.5.5-2368-win64.zip"
$YaraHash = "2cc0b3388039629653b2ef581ab2553670f021a88c9b0fe1d0e35151317399f3"
$RulesUrl = "https://github.com/Yara-Rules/rules/archive/refs/heads/master.zip"
$Ext = '*.exe','*.msi','*.dll','*.ocx','*.winmd','*.ps1','*.vbs','*.js','*.bat','*.cmd','*.scr'
$Exclusions = @(
"$env:ProgramFiles", "$env:ProgramFiles(x86)", "$env:windir",
"$InstallDir", "C:\Windows\System32", "C:\Windows\SysWOW64"
)
$SuspiciousAPIs = 'VirtualAlloc|WriteProcessMemory|CreateRemoteThread|NtUnmapViewOfSection|ReadProcessMemory|OpenProcess|VirtualProtect|LoadLibrary|GetProcAddress|WinExec|CreateProcess|ShellExecute|URLDownloadToFile|InternetOpen'
# ===============================================
# Logging function for service mode (no console)
function Write-Log {
param([string]$Message, [string]$Level = 'INFO')
$timestamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
$logEntry = "$timestamp [$Level] $Message"
$logEntry | Add-Content $LogFile -Force -ErrorAction SilentlyContinue
}
# Self-installation: copy to ProgramData and create service
function Install-Self {
# Create directory structure
@($InstallDir, $LogDir, $QuarDir, $YaraDir, $RulesDir) | ForEach-Object {
if (!(Test-Path $_)) { New-Item $_ -ItemType Directory -Force | Out-Null }
}
# Copy script to install location if not already there
$currentScript = $PSCommandPath
if ($currentScript -ne $ScriptPath) {
Write-Host "Installing GShield AV to $InstallDir..." -ForegroundColor Cyan
Copy-Item $currentScript $ScriptPath -Force
Write-Host "Copied script to $ScriptPath" -ForegroundColor Green
}
# Check if service exists
$svc = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if (!$svc) {
Write-Host "Creating Windows service $ServiceName..." -ForegroundColor Cyan
$binPath = "powershell.exe -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$ScriptPath`" -Path `"$Path`" -IntervalMinutes $IntervalMinutes"
$scArgs = "create $ServiceName binPath= `"$binPath`" start= auto DisplayName= `"GShield Antivirus`""
$proc = Start-Process sc.exe -ArgumentList $scArgs -Wait -PassThru -WindowStyle Hidden
if ($proc.ExitCode -eq 0) {
Write-Host "Service created successfully" -ForegroundColor Green
Start-Service $ServiceName -ErrorAction SilentlyContinue
Write-Host "GShield AV service started!" -ForegroundColor Green
Write-Host "Logs: $LogFile" -ForegroundColor Gray
Write-Host "Quarantine: $QuarDir" -ForegroundColor Gray
exit 0
} else {
Write-Host "Failed to create service (exit code: $($proc.ExitCode))" -ForegroundColor Red
exit 1
}
} else {
Write-Host "Service $ServiceName already exists" -ForegroundColor Yellow
$svcStatus = $svc.Status
Write-Host "Current status: $svcStatus" -ForegroundColor Gray
if ($svcStatus -ne 'Running') {
Start-Service $ServiceName
Write-Host "Service started" -ForegroundColor Green
}
}
}
# Run self-install if not running from install directory
if ($PSCommandPath -ne $ScriptPath) {
Install-Self
}
# Helper functions
function Get-SHA256 { param($file); (Get-FileHash $file -Algorithm SHA256).Hash }
function Test-Excluded { param($p); $Exclusions | Where-Object { $p -like "$_*" } }
function Ensure-Setup {
# Ensure all dirs exist
@($LogDir, $QuarDir, $YaraDir, $RulesDir) | ForEach-Object {
if (!(Test-Path $_)) { New-Item $_ -ItemType Directory -Force | Out-Null }
}
$yaraExe = (Get-ChildItem $YaraDir -Filter yara64.exe -EA 0 | Select -First 1).FullName
if (!$yaraExe) {
Write-Log "Downloading YARA..."
$z = "$env:TEMP\yara.zip"
try {
Invoke-WebRequest $YaraUrl -OutFile $z -UseBasicParsing
if ((Get-SHA256 $z) -ne $YaraHash) {
Write-Log "YARA hash mismatch!" "ERROR"
Remove-Item $z -Force
return
}
Expand-Archive $z -DestinationPath $YaraDir -Force
# Move yara64.exe to root of yara dir
Get-ChildItem $YaraDir -Recurse -Filter yara64.exe | Select -First 1 | ForEach-Object {
Copy-Item $_.FullName "$YaraDir\yara64.exe" -Force
}
Remove-Item $z -Force
Write-Log "YARA installed"
} catch {
Write-Log "Failed to download YARA: $_" "ERROR"
}
}
if (!(Test-Path "$RulesDir\index.yar")) {
Write-Log "Downloading YARA rules..."
$z = "$env:TEMP\rules.zip"
try {
Invoke-WebRequest $RulesUrl -OutFile $z -UseBasicParsing
Expand-Archive $z -DestinationPath $env:TEMP -Force
# Find extracted folder and move rules
$extracted = Get-ChildItem $env:TEMP -Directory | Where-Object { $_.Name -like 'rules-*' } | Select -First 1
if ($extracted) {
Copy-Item "$($extracted.FullName)\*" $RulesDir -Recurse -Force
Remove-Item $extracted.FullName -Recurse -Force
}
Remove-Item $z -Force
Write-Log "YARA rules installed"
} catch {
Write-Log "Failed to download rules: $_" "ERROR"
}
}
}
# AMSI Wrapper
Add-Type -TypeDefinition @'
using System;using System.Runtime.InteropServices;
public class Amsi{[DllImport("amsi.dll")]public static extern int AmsiInitialize(string a,out IntPtr c);[DllImport("amsi.dll")]public static extern int AmsiScanString(IntPtr c,string s,string n,string sess,out IntPtr r);[DllImport("amsi.dll")]public static extern void AmsiUninitialize(IntPtr c);
public static int Scan(string s){IntPtr ctx,rs;int hr=AmsiInitialize("GShield",out ctx);if(hr!=0)return 0;AmsiScanString(ctx,s,"", "",out rs);int res=(int)rs;AmsiUninitialize(ctx);return res;}}
'@
function Test-Amsi { param([string]$c); if(!$c) {return 0}; return [Amsi]::Scan($c) -ge 1 }
function Get-Entropy { param([byte[]]$b)
if(!$b.Length) {return 0}
$f=@{}; foreach($c in $b){$f[$c]++}
$e=0; foreach($c in $f.Keys){$p=$f[$c]/$b.Length; $e-=$p*([Math]::Log($p)/[Math]::Log(2))}
return $e
}
function Test-Heuristic {
param([string]$path)
$warn = @()
$ext = [IO.Path]::GetExtension($path).ToLower()
try {
$b = [IO.File]::ReadAllBytes($path)
if ((Get-Entropy $b) -gt 7.2) { $warn += "high-entropy" }
if ($ext -in '.exe','.dll') {
$str = [Text.Encoding]::ASCII.GetString($b)
if ($str -match $SuspiciousAPIs) { $warn += "susp-api" }
}
if ($ext -in '.ps1','.vbs','.js','.bat') {
$c = Get-Content $path -Raw -EA 0
if ($c -match '[A-Za-z0-9+/]{80,}={0,2}') { $warn += "b64" }
if ($c -match 'IEX|Invoke-Expression|FromBase64String|DownloadString|Hidden') { $warn += "obf" }
}
} catch {}
return ($warn -join ',')
}
function Invoke-Scan {
param([string]$p)
$yaraExe = (Get-ChildItem $YaraDir -Filter yara64.exe -EA 0 | Select -First 1).FullName
Get-ChildItem $p -Recurse -Include $Ext -EA 0 | Where-Object { !(Test-Excluded $_.FullName) } | ForEach-Object {
$f = $_
try {
$h = (Get-FileHash $f.FullName -A SHA1).Hash
$heur = Test-Heuristic $f.FullName
if ($heur -match "high-entropy|susp-api|obf") {
Write-Log "QUARANTINED: $($f.FullName) [$heur]" "ALERT"
Move-Item $f.FullName "$QuarDir\$($f.Name)" -Force -EA 0
}
if ($f.Extension -in '.ps1','.vbs','.js' -and (Test-Amsi (Get-Content $f.FullName -Raw))) {
Write-Log "QUARANTINED (AMSI): $($f.FullName)" "ALERT"
Move-Item $f.FullName "$QuarDir\$($f.Name)" -Force -EA 0
}
if ($yaraExe) {
$y = & $yaraExe -r "$RulesDir" $f.FullName 2>$null
if ($y) {
Write-Log "QUARANTINED (YARA): $($f.FullName) - $y" "ALERT"
Move-Item $f.FullName "$QuarDir\$($f.Name)" -Force -EA 0
}
}
} catch {}
}
Write-Log "Scan completed: $p"
}
# Service startup
Write-Log "GShield AV starting - PID: $PID"
Write-Log "Install dir: $InstallDir"
Write-Log "Log file: $LogFile"
Write-Log "Quarantine: $QuarDir"
Ensure-Setup
if ($IntervalMinutes -le 0) {
Invoke-Scan $Path
exit
}
Write-Log "Real-time protection enabled"
# Real-time Process Guard
Register-WmiEvent -Query "SELECT * FROM Win32_ProcessStartTrace" -SourceIdentifier "ProcGuard" -Action {
$e = $Event.SourceEventArgs.NewEvent
$procId = $e.ProcessID
try {
$proc = Get-CimInstance Win32_Process -Filter "ProcessId=$procId"
$procPath = $proc.ExecutablePath
if (!$procPath -or (Test-Excluded $procPath)) { return }
$heur = Test-Heuristic $procPath
if ($heur -match "high-entropy|susp-api|obf") {
Stop-Process -Id $procId -Force -EA 0
Write-Log "BLOCKED: $procPath [$heur]" "ALERT"
}
} catch {}
} | Out-Null
# Main service loop
while ($true) {
Write-Log "Periodic scan starting: $Path"
Invoke-Scan $Path
Start-Sleep -Seconds ($IntervalMinutes * 60)
}
Editor is loading...
Leave a Comment