PowerShell小技巧之发送TCP请求
很多时候我们需要通过Socket发送特定的TCP请求给服务器的特定端口来实现探测服务器的指定端口所开启的服务。很多语言都有相应的方法实现上述需求,当然,PowerShell也不例外,比如我们要发送一个简单的http请求到指定的web服务器:
GET/HTTP/1.1
Host:cn.bing.com
这里我们想请求微软必应的中文首页,如果需要通过PowerShell向cn.bing.com服务器发送get请求,就需要创建一个System.Net.Sockets.TcpClient对象,向指定的服务器和端口发送请求。
具体代码如下:
=====文件名:Send-TcpRequest.ps1===== ######################################## #Send-TcpRequest.ps1 ##SendaTCPrequesttoaremotecomputer,andreturntheresponse. ##Ifyoudonotsupplyinputtothisscript(viaeitherthepipeline,orthe ##-InputObjectparameter,)thescriptoperatesininteractivemode. ## ##Example: ## ##$http=@" ##GET/HTTP/1.1 ##Host:cn.bing.com ##`n`n ##"@ ## ##$http|.\Send-TcpRequestcn.bing.com 80 ######################################## param( [string]$remoteHost="localhost", [int]$port=80, [switch]$UseSSL, [string]$inputObject, [int]$commandDelay=100 )
[string]$output=""
##Storetheinputintoanarraythatwecanscanover.Iftherewasnoinput, ##thenwewillbeininteractivemode. $currentInput=$inputObject if(-not$currentInput) { $SCRIPT:currentInput=@($input) } $scriptedMode=[bool]$currentInput
functionMain { ##Openthesocket,andconnecttothecomputeronthespecifiedport if(-not$scriptedMode) { write-host"Connectingto$remoteHostonport$port" }
trap{Write-Error"Couldnotconnecttoremotecomputer:$_";exit} $socket=new-objectSystem.Net.Sockets.TcpClient($remoteHost,$port)
if(-not$scriptedMode) { write-host"Connected.Press^Dfollowedby[ENTER]toexit.`n" }
$stream=$socket.GetStream()
if($UseSSL) { $sslStream=New-ObjectSystem.Net.Security.SslStream$stream,$false $sslStream.AuthenticateAsClient($remoteHost) $stream=$sslStream }
$writer=new-objectSystem.IO.StreamWriter$stream
while($true) { ##Receivetheoutputthathasbufferedsofar $SCRIPT:output+=GetOutput
##Ifwe'reinscriptedmode,sendthecommands, ##receivetheoutput,andexit. if($scriptedMode) { foreach($linein$currentInput) { $writer.WriteLine($line) $writer.Flush() Start-Sleep-m$commandDelay $SCRIPT:output+=GetOutput }
break } ##Ifwe'reininteractivemode,writethebuffered ##output,andrespondtoinput. else { if($output) { foreach($linein$output.Split("`n")) { write-host$line } $SCRIPT:output="" }
##Readtheuser'scommand,quittingiftheyhit^D $command=read-host if($command-eq([char]4)){break;}
##Otherwise,Writetheircommandtotheremotehost $writer.WriteLine($command) $writer.Flush() } }
##Closethestreams $writer.Close() $stream.Close()
##Ifwe'reinscriptedmode,returntheoutput if($scriptedMode) { $output } }
##Readoutputfromaremotehost functionGetOutput { ##Createabuffertoreceivetheresponse $buffer=new-objectSystem.Byte[]1024 $encoding=new-objectSystem.Text.AsciiEncoding
$outputBuffer="" $foundMore=$false
##Readallthedataavailablefromthestream,writingittothe ##outputbufferwhendone. do { ##Allowdatatobufferforabit start-sleep-m1000
##Readwhatdataisavailable $foundmore=$false $stream.ReadTimeout=1000
do { try { $read=$stream.Read($buffer,0,1024)
if($read-gt0) { $foundmore=$true $outputBuffer+=($encoding.GetString($buffer,0,$read)) } }catch{$foundMore=$false;$read=0} }while($read-gt0) }while($foundmore)
$outputBuffer } .Main 该脚本使用方法如下: $http=@"
GET/HTTP/1.1 Host:cn.bing.com `n`n "@ $http|.\Send-TcpRequestcn.bing.com80