Skip to content

Instantly share code, notes, and snippets.

@HarmJ0y
Last active September 12, 2022 01:55
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save HarmJ0y/d8be3dc870c77f583d43 to your computer and use it in GitHub Desktop.
Save HarmJ0y/d8be3dc870c77f583d43 to your computer and use it in GitHub Desktop.
Host a single binary file without needing administrative privileges
Function Invoke-HostFile {
<#
.SYNOPSIS
Hosts a base64 string representation of a binary file or a given
$FilePath on the specified $Port. Any HTTP request to the given
host/port will return the binary data of the specified file.
.PARAMETER Base64File
Base64 string of a binary file.
.PARAMETER FilePath
Path of local file to host.
.PARAMETER Port
Port to host the file on, defaults to 8000.
.PARAMETER ServerSleep
Time (in seconds) to sleep before killing the webserver.
.PARAMETER FireWallRule
Switch. Add/remove a local firewall rule (needs local admin).
.EXAMPLE
Invoke-HostFile -Base64File "UEs..." -Port 80
Host the base64 encoded file on port 80.
.EXAMPLE
Invoke-HostFile -FilePath file.exe -Port 8000 -FireWallRule
Host the specified local file encoded file on port 8000, adding/removing
a local firewall rule.
#>
param (
[String]
$Base64File,
[ValidateScript({Test-Path -Path $_ })]
[String]
$FilePath,
[Int]
$Port = 8000,
[Int]
$ServerSleep = 60,
[Switch]
$FireWallRule
)
begin {
# add a temporary firewall rule if specified
if($FireWallRule) {
if (!([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
Write-Output "[!] Warning: user is not an administrator, firewall rule can't be added"
throw "[!] Warning: user is not an administrator, firewall rule can't be added"
}
Write-Output "[*] Setting inbound firewall rule for port: $Port"
$FW = New-Object -ComObject hnetcfg.fwpolicy2
$Rule = New-Object -ComObject HNetCfg.FWRule
$Rule.Name = "Updater32"
$Rule.Protocol = 6
$Rule.LocalPorts = $Port
$Rule.Direction = 1
$Rule.Enabled = $true
$Rule.Grouping = "@firewallapi.dll,-23255"
$Rule.Profiles = 7
$Rule.Action = 1
$Rule.EdgeTraversal=$false
$FW.Rules.Add($Rule)
}
if(!$Base64File) {
[byte[]] $FileBytes = [System.IO.File]::ReadAllBytes($FilePath)
$Base64File = [System.Convert]::ToBase64String($FileBytes)
Write-Output "[*] Hosting file: $FilePath"
}
else {
Write-Output "[*] Using base64 string file for hosting"
}
$WebserverScriptblock = {
param($Port, $Base64File)
[byte[]] $FileBytes = [System.Convert]::FromBase64String($Base64File)
try {
$EndPoint = New-Object System.Net.IPEndPoint([IPAddress]::any, $Port)
$Listener = New-Object System.Net.Sockets.TcpListener $EndPoint
$Listener.Start()
# block until a TCP connection is received
$Data = $Listener.AcceptTcpClient()
# Write-Output "[*] Connection from: $($Data.Client.RemoteEndPoint)"
$Stream = $Data.GetStream()
$Stream.Write($FileBytes,0,$FileBytes.length)
$Stream.Close()
$Listener.Stop()
}
catch [exception] {
# Write-Output "[!] Exception: $_"
}
}
}
process {
Write-Output "[*] Starting hosting on port: $Port"
# start hosting the webserver
$Null = Start-Job -Name "WebServer" -Scriptblock $WebserverScriptblock -ArgumentList $Port,$Base64File
Start-Sleep -Seconds $ServerSleep
# kill the webserver off
Write-Output "[*] Killing off server"
Get-Job -Name "WebServer" | Stop-Job
Write-Output "[*] Server killed"
}
end {
if($FireWallRule) {
# remove the firewall rule if specified
if($FireWallRule){
Write-Verbose "[*] Removing inbound firewall rule"
Write-Output "[*] Removing inbound firewall rule"
$FW.rules.Remove("Updater32")
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment