PowerShell小技巧之发送TCP请求

所属分类: 脚本专栏 / PowerShell 阅读数: 483
收藏 0 赞 0 分享

很多时候我们需要通过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入门教程之编写和使用脚本模块实例

这篇文章主要介绍了PowerShell入门教程之编写和使用脚本模块实例,本文讲解了模块、脚本模块、编写脚本模块、模块安装路径、模块文件夹等内容,需要的朋友可以参考下
收藏 0 赞 0 分享

WMI入门教程之什么是WMI?

这篇文章主要介绍了WMI入门教程之什么是WMI?WMI有一组API,我们可以使用VBScript、PowerShell脚本还是利用C#的来访问WMI的类库,需要的朋友可以参考下
收藏 0 赞 0 分享

WMI入门教程之怎么使用WMI?

这篇文章主要介绍了WMI入门教程之怎么使用WMI?本文讲解了在软件中、PowerShell中、.NET中使用WMI的例子,需要的朋友可以参考下
收藏 0 赞 0 分享

WMI入门教程之WMI中的类在哪里?

这篇文章主要介绍了WMI入门教程之WMI中的类在哪里?本文讲解了WMI中类的层次结构、常用WMI类、WMI类查找手册等内容,需要的朋友可以参考下
收藏 0 赞 0 分享

PowerShell小技巧之观察UNC路径

UNC(Universal Naming Convention)通用命名规则,也称通用命名规范、通用命名约定。UNC路径就是类似\\softer这样的形式的网络路径。
收藏 0 赞 0 分享

PowerShell小技巧之True和False的类型转换

这篇文章主要介绍了在PowerShell中将True和False的类型互相转换的几种方法,非常简单实用,有需要的朋友参考下
收藏 0 赞 0 分享

PowerShell小技巧之查找获取注册表路径

这篇文章主要介绍了在PowerShell中使用递归查找获取注册表路径的小技巧,有需要的朋友可以参考下
收藏 0 赞 0 分享

Powershell小技巧之获取字符串的行数

这篇文章主要介绍了Powershell获取字符串的行数的小技巧,只要懂得了它的工作原理就能在多种场合使用。需要的朋友可以参考下
收藏 0 赞 0 分享

Powershell小技巧之查询AD用户

这篇文章主要介绍了Powershell小技巧之查询AD用户,需要的朋友可以参考下
收藏 0 赞 0 分享

Powershell小技巧之查看安装的.Net framework版本信息

本文主要介绍了使用powershell查看安装的.net framework的版本信息,非常简单使用,有需要的朋友参考下
收藏 0 赞 0 分享
查看更多