Disassembler

- Artificial Intelligence is no match for natural stupidity.
Registrace | Přihlášení

Miniaturní socket server v PowerShellu

04
únor
2017

Je tomu už téměř rok, co jsem potřeboval malou nenáročnou utilitku pro AIX, která by si sedla na mnou zvolený TCP port a já tak s její pomocí mohl zjistit, zda jsem schopný se na socket připojit, i pokud sedím za devatero firewally, devatero proxynami a devatero NATy. Dnes se mi přihodilo, že jsem něco podobného potřeboval odladit na Windows Serverech. A světe div se, ani pro ně neexistuje slušná a nenáročná náhrada netcatu.

Ťuk ťuk. Kdo tam?


Abych čtenáře nemystifikoval příliš, prozradím, že netcat, stejně jako nmap, existují i ve formě zkompilovaných binárek pro Windows, ale na Windows Server 2012 R2 se mi tvrdošíjně odmítaly spustit. Stejně jako v případě perlu na AIXu, i zde mě v zápětí napadlo zkusit přemluvit nativní systémové funkce, a s pomocí zaklínadel ve formě skriptovacího jazyka je zřetězit tak, aby dělaly, co zrovna potřebuju. PowerShell, který je od dob Windows Server 2008 ve standardní výbavě operačního systému, se k takovému kousku výborně hodí, protože umožňuje vypůjčit si potřebné objekty z .NET knihoven. Podotýkám, že účelem kódu bylo co nejméně se nadřít a vyrobit jej co nejpodobněji jako dříve publikovanou perlovskou variantu, takže k nějakému mistrovskému dílu má hodně daleko. Například neřeší žádné timeouty a metoda AcceptTcpClient() blokuje vlákno, takže skript je potřeba ukončit násilím. Případně se také dá použít metoda Pending() a napsat okolo ní vlastní polling. $endpoint = New-Object System.Net.IPEndPoint ([System.Net.IPAddress]::Parse("192.168.12.34"), 12345) $server = New-Object System.Net.Sockets.TcpListener $endpoint $server.Start() Write-Host "Server started on $endpoint" While ($client = $server.AcceptTcpClient()) { Write-Host "Connection received from $($client.Client.RemoteEndPoint)" $writer = New-Object System.IO.StreamWriter $client.GetStream() $writer.Write("Welcome to {0}", $endpoint); $writer.Flush() $client.Close() } Pro ještě menší dřinu je možno v definici endpointu použít [System.Net.IPAddress]::All, které systém donutí naslouchat na všech síťových rozhraních, což ovšem nemusí být vždy žádoucí.