Update main.ps1

This commit is contained in:
egieb
2025-06-17 11:09:13 +00:00
committed by GitHub
parent 324fd6ef55
commit e4bbbd5cf0
+274 -109
View File
@@ -1,30 +1,24 @@
<# <#
================================================= Beigeworm's Screen Stream over HTTP ========================================================== ================================================= Beigeworm's VNC over HTTP ==========================================================
SYNOPSIS SYNOPSIS
Start up a HTTP server and stream the desktop to a browser window on another device on the network. Start up a HTTP server and stream the desktop to a browser window on another device on LAN with basic mouse and keyboard functionality.
USAGE USAGE
1. Run this script on target computer and note the URL provided 1. Run this script on target computer and note the URL provided
2. on another device on the same network, enter the provided URL in a browser window 2. On another device on the same network, enter the provided URL in a browser window
3. Hold escape key on target for 5 seconds to exit screenshare. 3. Hold escape key on target for 5 seconds to exit screenshare.
4. You mayneed to resize window for mouse calibration!
#> #>
# Hide the powershell console (1 = yes) # Hide the powershell console (1 = yes)
$hide = 1 $hide = 1
# WRITE AS ADMIN!
If (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]'Administrator')) {
Start-Process PowerShell.exe -ArgumentList ("-NoProfile -Ep Bypass -File `"{0}`"" -f $PSCommandPath) -Verb RunAs
Exit
}
[Console]::BackgroundColor = "Black" [Console]::BackgroundColor = "Black"
Clear-Host Clear-Host
[Console]::SetWindowSize(88,30) [Console]::SetWindowSize(88,30)
[Console]::Title = "HTTP Screenshare" [Console]::Title = "VNC over LAN"
Add-Type -AssemblyName System.Windows.Forms Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName PresentationCore,PresentationFramework Add-Type -AssemblyName PresentationCore,PresentationFramework
Add-Type -AssemblyName System.Windows.Forms Add-Type -AssemblyName System.Windows.Forms
@@ -32,77 +26,70 @@ Add-Type -AssemblyName System.Windows.Forms
# Define port number # Define port number
if ($port.length -lt 1){ if ($port.length -lt 1){
Write-Host "Using default port.. (8080)" -ForegroundColor Green
$port = 8080 $port = 8080
} }
Write-Host "Detecting primary network interface." -ForegroundColor DarkGray Add-Type @"
$networkInterfaces = Get-NetAdapter | Where-Object { $_.Status -eq 'Up' -and $_.InterfaceDescription -notmatch 'Virtual' } using System;
$filteredInterfaces = $networkInterfaces | Where-Object { $_.Name -match 'Wi*' -or $_.Name -match 'Eth*'} using System.Runtime.InteropServices;
$primaryInterface = $filteredInterfaces | Select-Object -First 1 public class MouseSimulator {
if ($primaryInterface) { [DllImport("user32.dll", CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)]
if ($primaryInterface.Name -match 'Wi*') { public static extern void mouse_event(long dwFlags, long dx, long dy, long cButtons, long dwExtraInfo);
Write-Output "Wi-Fi is the primary internet connection."
$localIP = Get-NetIPAddress -AddressFamily IPv4 -InterfaceAlias "Wi*" | Select-Object -ExpandProperty IPAddress
} elseif ($primaryInterface.Name -match 'Eth*') {
Write-Output "Ethernet is the primary internet connection."
$localIP = Get-NetIPAddress -AddressFamily IPv4 -InterfaceAlias "Eth*" | Select-Object -ExpandProperty IPAddress
} else {
Write-Output "Unknown primary internet connection."
}
} else {Write-Output "No primary internet connection found."}
New-NetFirewallRule -DisplayName "AllowWebServer" -Direction Inbound -Protocol TCP -LocalPort $port -Action Allow | Out-Null public const int MOUSEEVENTF_LEFTDOWN = 0x02;
$webServer = New-Object System.Net.HttpListener public const int MOUSEEVENTF_LEFTUP = 0x04;
$webServer.Prefixes.Add("http://"+$localIP+":$port/") public const int MOUSEEVENTF_RIGHTDOWN = 0x08;
$webServer.Prefixes.Add("http://localhost:$port/") public const int MOUSEEVENTF_RIGHTUP = 0x10;
$webServer.Start()
Write-Host ("Network Devices Can Reach the server at : http://"+$localIP+":$port")
Write-Host "Press escape key for 5 seconds to exit" -f Cyan
Write-Host "Hiding this window.." -f Yellow
sleep 4
# Code to hide the console on Windows 10 and 11 public static void LeftClick() {
if ($hide -eq 1){ mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
$Async = '[DllImport("user32.dll")] public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);' System.Threading.Thread.Sleep(50);
$Type = Add-Type -MemberDefinition $Async -name Win32ShowWindowAsync -namespace Win32Functions -PassThru mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
$hwnd = (Get-Process -PID $pid).MainWindowHandle
if ($hwnd -ne [System.IntPtr]::Zero) {
$Type::ShowWindowAsync($hwnd, 0)
} }
else {
$Host.UI.RawUI.WindowTitle = 'hideme' public static void RightClick() {
$Proc = (Get-Process | Where-Object { $_.MainWindowTitle -eq 'hideme' }) mouse_event(MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0);
$hwnd = $Proc.MainWindowHandle System.Threading.Thread.Sleep(50);
$Type::ShowWindowAsync($hwnd, 0) mouse_event(MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0);
} }
} }
"@
# Escape to exit key detection # Escape to exit key detection
Add-Type @" Add-Type @"
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
public class Keyboard public class Keyboard
{ {
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern short GetAsyncKeyState(int vKey); public static extern short GetAsyncKeyState(int vKey);
} }
"@ "@
$VK_ESCAPE = 0x1B $VK_ESCAPE = 0x1B
$startTime = $null $startTime = $null
while ($true) {
try {
$context = $webServer.GetContext()
$response = $context.Response
if ($context.Request.RawUrl -eq "/stream") {
$response.ContentType = "multipart/x-mixed-replace; boundary=frame"
$response.Headers.Add("Cache-Control", "no-cache")
$boundary = "--frame"
while ($context.Response.OutputStream.CanWrite) { If (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]'Administrator')) {
Start-Process PowerShell.exe -ArgumentList ("-NoProfile -Ep Bypass -File `"{0}`"" -f $PSCommandPath) -Verb RunAs
Exit
}
function Start-Streaming {
param ($context, $imgWidth, $imgHeight)
$streamRunspace = [runspacefactory]::CreateRunspace()
$streamRunspace.Open()
$streamPowerShell = [powershell]::Create().AddScript({
param ($context, $imgWidth, $imgHeight)
$response = $context.Response
$response.ContentType = "multipart/x-mixed-replace; boundary=frame"
$response.Headers.Add("Cache-Control", "no-cache")
$boundary = "--frame"
try {
while ($response.OutputStream.CanWrite) {
$screen = [System.Windows.Forms.Screen]::PrimaryScreen $screen = [System.Windows.Forms.Screen]::PrimaryScreen
$bitmap = New-Object System.Drawing.Bitmap $screen.Bounds.Width, $screen.Bounds.Height $bitmap = New-Object System.Drawing.Bitmap $screen.Bounds.Width, $screen.Bounds.Height
$graphics = [System.Drawing.Graphics]::FromImage($bitmap) $graphics = [System.Drawing.Graphics]::FromImage($bitmap)
@@ -122,61 +109,239 @@ while ($true) {
$boundaryWriter = [System.Text.Encoding]::ASCII.GetBytes("`r`n") $boundaryWriter = [System.Text.Encoding]::ASCII.GetBytes("`r`n")
$response.OutputStream.Write($boundaryWriter, 0, $boundaryWriter.Length) $response.OutputStream.Write($boundaryWriter, 0, $boundaryWriter.Length)
Start-Sleep -Milliseconds 33 Start-Sleep -Milliseconds 100
# Check for the escape key press to exit
$isEscapePressed = [Keyboard]::GetAsyncKeyState($VK_ESCAPE) -lt 0
if ($isEscapePressed) {
if (-not $startTime) {
$startTime = Get-Date
}
$elapsedTime = (Get-Date) - $startTime
if ($elapsedTime.TotalSeconds -ge 5) {
(New-Object -ComObject Wscript.Shell).Popup("Screenshare Closed.",3,"Information",0x0)
sleep 1
exit
}
} else {
$startTime = $null
}
} }
} else { } catch {
Write-Host "Stream closed: $_"
} finally {
$response.OutputStream.Close()
}
}).AddArgument($context).AddArgument($imgWidth).AddArgument($imgHeight)
$streamPowerShell.Runspace = $streamRunspace
$streamPowerShell.BeginInvoke()
}
$port = 8080
# Get primary network interface and IP
$networkInterfaces = Get-NetAdapter | Where-Object { $_.Status -eq 'Up' -and $_.InterfaceDescription -notmatch 'Virtual' }
$filteredInterfaces = $networkInterfaces | Where-Object { $_.Name -match 'Wi*' -or $_.Name -match 'Eth*'}
$primaryInterface = $filteredInterfaces | Select-Object -First 1
if ($primaryInterface) {
if ($primaryInterface.Name -match 'Wi*') {
$localIP = Get-NetIPAddress -AddressFamily IPv4 -InterfaceAlias "Wi*" | Select-Object -ExpandProperty IPAddress
} elseif ($primaryInterface.Name -match 'Eth*') {
$localIP = Get-NetIPAddress -AddressFamily IPv4 -InterfaceAlias "Eth*" | Select-Object -ExpandProperty IPAddress
}
}
New-NetFirewallRule -DisplayName "AllowWebServer" -Direction Inbound -Protocol TCP -LocalPort $port -Action Allow | Out-Null
$webServer = New-Object System.Net.HttpListener
$webServer.Prefixes.Add("http://$localIP`:$port/")
$webServer.Prefixes.Add("http://localhost`:$port/")
$webServer.Start()
Write-Host "Server started at http://$localIP`:$port" -f Cyan
$screenWidth = [System.Windows.Forms.Screen]::PrimaryScreen.Bounds.Width
$screenHeight = [System.Windows.Forms.Screen]::PrimaryScreen.Bounds.Height
$imgWidth = $screenWidth
$imgHeight = $screenHeight
Write-Host "`nPress escape key for 5 seconds to exit" -f Gray
# Code to hide the console on Windows 10 and 11
if ($hide -eq 1){
Write-Host "Hiding this window.." -f Yellow
sleep 4
$Async = '[DllImport("user32.dll")] public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);'
$Type = Add-Type -MemberDefinition $Async -name Win32ShowWindowAsync -namespace Win32Functions -PassThru
$hwnd = (Get-Process -PID $pid).MainWindowHandle
if ($hwnd -ne [System.IntPtr]::Zero) {
$Type::ShowWindowAsync($hwnd, 0)
}
else {
$Host.UI.RawUI.WindowTitle = 'hideme'
$Proc = (Get-Process | Where-Object { $_.MainWindowTitle -eq 'hideme' })
$hwnd = $Proc.MainWindowHandle
$Type::ShowWindowAsync($hwnd, 0)
}
}
while ($true) {
# Check for the escape key press to exit
$isEscapePressed = [Keyboard]::GetAsyncKeyState($VK_ESCAPE) -lt 0
if ($isEscapePressed) {
if (-not $startTime) {
$startTime = Get-Date
}
$elapsedTime = (Get-Date) - $startTime
if ($elapsedTime.TotalSeconds -ge 5) {
(New-Object -ComObject Wscript.Shell).Popup("Screenshare Closed.",3,"Information",0x0)
sleep 1
exit
}
} else {
$startTime = $null
}
try {
$context = $webServer.GetContext()
$request = $context.Request
$response = $context.Response
if ($request.RawUrl.StartsWith("/stream?")) {
$query = $request.RawUrl -replace "/stream\?", ""
$params = $query -split "&"
$imgWidth = ($params -match "w=").Split("=")[1]
$imgHeight = ($params -match "h=").Split("=")[1]
if (-not $imgHeight -or $imgHeight -eq "0") {
Write-Host "Received imgHeight = 0, defaulting to screen height: $screenHeight"
$imgHeight = $screenHeight
}
Write-Host "Stream started with img size: ${imgWidth}x${imgHeight}"
Start-Streaming -context $context -imgWidth $imgWidth -imgHeight $imgHeight
}
elseif ($request.RawUrl.StartsWith("/keypress")) {
$query = $request.RawUrl -replace "/keypress\?", ""
$params = $query -split "&"
$key = ($params -match "key=").Split("=")[1]
if ($key) {
$decodedKey = [System.Web.HttpUtility]::UrlDecode($key)
switch ($decodedKey) {
"Backspace" { $decodedKey = "{BACKSPACE}" }
"Enter" { $decodedKey = "{ENTER}" }
}
Write-Host "Key Pressed: $decodedKey"
[System.Windows.Forms.SendKeys]::SendWait($decodedKey)
}
$response.StatusCode = 200
$response.Close()
}
elseif ($request.RawUrl.StartsWith("/move")) {
$query = $request.RawUrl -replace "/move\?", ""
$params = $query -split "&"
$moveX = ($params -match "x=").Split("=")[1]
$moveY = ($params -match "y=").Split("=")[1]
if ($moveX -and $moveY -and $imgWidth -and $imgHeight) {
$scaledX = [math]::Round(($moveX / $imgWidth) * $screenWidth)
$scaledY = [math]::Round(($moveY / $imgHeight) * $screenHeight)
Write-Host "Move at Browser: ($moveX, $moveY) -> Adjusted to: ($scaledX, $scaledY)"
[System.Windows.Forms.Cursor]::Position = New-Object System.Drawing.Point($scaledX, $scaledY)
}
$response.StatusCode = 200
$response.Close()
}
elseif ($request.RawUrl.StartsWith("/click")) {
$query = $request.RawUrl -replace "/click\?", ""
$params = $query -split "&"
$clickX = ($params -match "x=").Split("=")[1]
$clickY = ($params -match "y=").Split("=")[1]
if ($clickX -and $clickY -and $imgWidth -and $imgHeight) {
$scaledX = [math]::Round(($clickX / $imgWidth) * $screenWidth)
$scaledY = [math]::Round(($clickY / $imgHeight) * $screenHeight)
Write-Host "Click at Browser: ($clickX, $clickY) -> Adjusted to: ($scaledX, $scaledY)"
[System.Windows.Forms.Cursor]::Position = New-Object System.Drawing.Point($scaledX, $scaledY)
[MouseSimulator]::LeftClick()
}
$response.StatusCode = 200
$response.Close()
}
else {
$response.ContentType = "text/html" $response.ContentType = "text/html"
$html = @" $html = @"
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<title>Streaming Video</title> <title>Remote Desktop</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <script>
<style> function sendMove(event) {
body { let img = document.getElementById("stream");
background-color: black; let rect = img.getBoundingClientRect();
margin: 0; let x = event.clientX - rect.left;
display: flex; let y = event.clientY - rect.top;
justify-content: center; fetch('/move?x=' + x + '&y=' + y);
align-items: center; }
height: 100vh; function updateStreamSize() {
} let img = document.getElementById("stream");
img { let w = img.clientWidth;
width: 90vw; let h = img.clientHeight;
height: auto; img.src = '/stream?w=' + w + '&h=' + h;
max-width: 100%; }
max-height: 100%; function sendClick(event) {
} let img = document.getElementById("stream");
</style> let rect = img.getBoundingClientRect();
let x = event.clientX - rect.left;
let y = event.clientY - rect.top;
fetch('/click?x=' + x + '&y=' + y);
}
function sendKeyPress(event) {
let key = encodeURIComponent(event.key);
fetch('/keypress?key=' + key);
}
window.onload = () => {
setTimeout(() => {
let img = document.getElementById("stream");
img.addEventListener('mousemove', sendMove);
img.addEventListener('keydown', sendKeyPress);
img.src = "/stream";
updateStreamSize();
img.setAttribute("tabindex", "0");
img.focus();
}, 500);
updateStreamSize();
updateStreamSize();
updateStreamSize();
};
window.onresize = updateStreamSize;
</script>
<style>
body { background-color: black; margin: 0; display: flex; justify-content: center; align-items: center; height: 100vh; }
img { min-height: 500px; display: block; width: 90vw; height: auto; max-width: 100%; max-height: 100%; cursor: pointer; }
</style>
</head> </head>
<body> <body>
<img src='/stream' alt='Streaming Video' /> <img id="stream" onclick="sendClick(event)" />
</body> </body>
</html> </html>
"@ "@
$buffer = [System.Text.Encoding]::UTF8.GetBytes($html) $buffer = [System.Text.Encoding]::UTF8.GetBytes($html)
$response.OutputStream.Write($buffer, 0, $buffer.Length) $response.OutputStream.Write($buffer, 0, $buffer.Length)
$response.Close()
} }
$response.Close() }
} catch { catch {
Write-Host "Error encountered: $_" Write-Host "Error encountered: $_"
} }
} }
$webServer.Stop()
$webServer.Stop()