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
## send a tcp request to a remote computer, and return the response.
## if you do not supply input to this script (via either the pipeline, or the
## -inputobject parameter,) the script operates in interactive mode.
##
## example:
##
## $http = @"
## get / http/1.1
## host:cn.bing.com
## `n`n
## "@
##
## $http | .\send-tcprequest cn.bing.com 80
########################################
param(
[string] $remotehost = "localhost",
[int] $port = 80,
[switch] $usessl,
[string] $inputobject,
[int] $commanddelay = 100
)
[string] $output = ""
## store the input into an array that we can scan over. if there was no input,
## then we will be in interactive mode.
$currentinput = $inputobject
if(-not $currentinput)
{
$script:currentinput = @($input)
}
$scriptedmode = [bool] $currentinput
function main
{
## open the socket, and connect to the computer on the specified port
if(-not $scriptedmode)
{
write-host "connecting to $remotehost on port $port"
}
trap { write-error "could not connect to remote computer: $_"; exit }
$socket = new-object system.net.sockets.tcpclient($remotehost, $port)
if(-not $scriptedmode)
{
write-host "connected. press ^d followed by [enter] to exit.`n"
}
$stream = $socket.getstream()
if($usessl)
{
$sslstream = new-object system.net.security.sslstream $stream,$false
$sslstream.authenticateasclient($remotehost)
$stream = $sslstream
}
$writer = new-object system.io.streamwriter $stream
while($true)
{
## receive the output that has buffered so far
$script:output += getoutput
## if we're in scripted mode, send the commands,
## receive the output, and exit.
if($scriptedmode)
{
foreach($line in $currentinput)
{
$writer.writeline($line)
$writer.flush()
start-sleep -m $commanddelay
$script:output += getoutput
}
break
}
## if we're in interactive mode, write the buffered
## output, and respond to input.
else
{
if($output)
{
foreach($line in $output.split("`n"))
{
write-host $line
}
$script:output = ""
}
## read the user's command, quitting if they hit ^d
$command = read-host
if($command -eq ([char] 4)) { break; }
## otherwise, write their command to the remote host
$writer.writeline($command)
$writer.flush()
}
}
## close the streams
$writer.close()
$stream.close()
## if we're in scripted mode, return the output
if($scriptedmode)
{
$output
}
}
## read output from a remote host
function getoutput
{
## create a buffer to receive the response
$buffer = new-object system.byte[] 1024
$encoding = new-object system.text.asciiencoding
$outputbuffer = ""
$foundmore = $false
## read all the data available from the stream, writing it to the
## output buffer when done.
do
{
## allow data to buffer for a bit
start-sleep -m 1000
## read what data is available
$foundmore = $false
$stream.readtimeout = 1000
do
{
try
{
$read = $stream.read($buffer, 0, 1024)
if($read -gt 0)
{
$foundmore = $true
$outputbuffer += ($encoding.getstring($buffer, 0, $read))
}
} catch { $foundmore = $false; $read = 0 }
} while($read -gt 0)
} while($foundmore)
$outputbuffer
}
. main
该脚本使用方法如下:
$http = @"
get / http/1.1
host:cn.bing.com
`n`n
"@
$http | .\send-tcprequest cn.bing.com 80
执行效果如图所示:
需要说明的是,由于页面返回的内容太长了,这里至少是将返回的内容缓存在一个变量里,并只输出了变量的头10行。
有了这个脚本,我们就可以向指定的web服务器发送特定的请求,来实现模拟登陆和操作的功能了。
推荐阅读
-
Powershell小技巧之使用WMI查询插上的U盘
-
Powershell小技巧之系统运行时间
-
Powershell小技巧之使用Copy-Item添加程序到开机启动
-
Powershell小技巧之使用-F方法带入数据
-
Powershell小技巧之使用WMI测试服务响应
-
Powershell小技巧之播放WAV声音
-
Powershell小技巧之使用Jint引擎在PowerShell中执行Javascript函数
-
Powershell小技巧之通过EventLog查看近期电脑开机和关机时间
-
Powershell小技巧之使用Get-ChildItem得到指定扩展名文件
-
PowerShell小技巧之启动远程桌面连接