Update main.ps1

This commit is contained in:
egieb
2025-06-17 11:09:13 +00:00
committed by GitHub
parent 324fd6ef55
commit e4bbbd5cf0

View File

@@ -1,30 +1,24 @@
<#
================================================= Beigeworm's Screen Stream over HTTP ==========================================================
================================================= Beigeworm's VNC over HTTP ==========================================================
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
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.
4. You mayneed to resize window for mouse calibration!
#>
# Hide the powershell console (1 = yes)
$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"
Clear-Host
[Console]::SetWindowSize(88,30)
[Console]::Title = "HTTP Screenshare"
[Console]::Title = "VNC over LAN"
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName PresentationCore,PresentationFramework
Add-Type -AssemblyName System.Windows.Forms
@@ -32,77 +26,70 @@ Add-Type -AssemblyName System.Windows.Forms
# Define port number
if ($port.length -lt 1){
Write-Host "Using default port.. (8080)" -ForegroundColor Green
$port = 8080
}
Write-Host "Detecting primary network interface." -ForegroundColor DarkGray
$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*') {
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."}
Add-Type @"
using System;
using System.Runtime.InteropServices;
public class MouseSimulator {
[DllImport("user32.dll", CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)]
public static extern void mouse_event(long dwFlags, long dx, long dy, long cButtons, long dwExtraInfo);
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 ("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
public const int MOUSEEVENTF_LEFTDOWN = 0x02;
public const int MOUSEEVENTF_LEFTUP = 0x04;
public const int MOUSEEVENTF_RIGHTDOWN = 0x08;
public const int MOUSEEVENTF_RIGHTUP = 0x10;
# Code to hide the console on Windows 10 and 11
if ($hide -eq 1){
$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)
public static void LeftClick() {
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
System.Threading.Thread.Sleep(50);
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
}
else {
$Host.UI.RawUI.WindowTitle = 'hideme'
$Proc = (Get-Process | Where-Object { $_.MainWindowTitle -eq 'hideme' })
$hwnd = $Proc.MainWindowHandle
$Type::ShowWindowAsync($hwnd, 0)
public static void RightClick() {
mouse_event(MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0);
System.Threading.Thread.Sleep(50);
mouse_event(MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0);
}
}
"@
# Escape to exit key detection
Add-Type @"
using System;
using System.Runtime.InteropServices;
public class Keyboard
{
[DllImport("user32.dll")]
public static extern short GetAsyncKeyState(int vKey);
}
"@
$VK_ESCAPE = 0x1B
Add-Type @"
using System;
using System.Runtime.InteropServices;
public class Keyboard
{
[DllImport("user32.dll")]
public static extern short GetAsyncKeyState(int vKey);
}
"@
$VK_ESCAPE = 0x1B
$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
$bitmap = New-Object System.Drawing.Bitmap $screen.Bounds.Width, $screen.Bounds.Height
$graphics = [System.Drawing.Graphics]::FromImage($bitmap)
@@ -122,61 +109,239 @@ while ($true) {
$boundaryWriter = [System.Text.Encoding]::ASCII.GetBytes("`r`n")
$response.OutputStream.Write($boundaryWriter, 0, $boundaryWriter.Length)
Start-Sleep -Milliseconds 33
# 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
}
Start-Sleep -Milliseconds 100
}
} 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"
$html = @"
<!DOCTYPE html>
<html>
<head>
<title>Streaming Video</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body {
background-color: black;
margin: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
img {
width: 90vw;
height: auto;
max-width: 100%;
max-height: 100%;
}
</style>
<title>Remote Desktop</title>
<script>
function sendMove(event) {
let img = document.getElementById("stream");
let rect = img.getBoundingClientRect();
let x = event.clientX - rect.left;
let y = event.clientY - rect.top;
fetch('/move?x=' + x + '&y=' + y);
}
function updateStreamSize() {
let img = document.getElementById("stream");
let w = img.clientWidth;
let h = img.clientHeight;
img.src = '/stream?w=' + w + '&h=' + h;
}
function sendClick(event) {
let img = document.getElementById("stream");
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>
<body>
<img src='/stream' alt='Streaming Video' />
<img id="stream" onclick="sendClick(event)" />
</body>
</html>
"@
$buffer = [System.Text.Encoding]::UTF8.GetBytes($html)
$response.OutputStream.Write($buffer, 0, $buffer.Length)
$response.Close()
}
$response.Close()
} catch {
}
catch {
Write-Host "Error encountered: $_"
}
}
$webServer.Stop()
$webServer.Stop()