p3nt4 / Invoke-SocksProxy

Socks proxy, and reverse socks server using powershell.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Failed to receive SOCKS5 connect request ack

manasmbellani opened this issue · comments

I am using Windows 7 machine to run powershell.exe. The Win 7 machine does have Internet access as well so it can connect out on the internet.

screen shot 2017-12-16 at 11 11 50 am

On the win7 client where socks proxy is running, I can see the connection from the kali machine from which the curl session above was run.

screen shot 2017-12-16 at 11 13 38 am

I have attached a Wireshark capture as well between kali (192.168.56.101) and win7 (192.168.56.102) where socks proxy is running.
Invoke-SocksProxy.wiresharkcap.pcapng.zip

commented

Will investigate on Monday. In the meantime, you can try other clients. Proxychains should work. Or eventually socks4 with curl.

commented

image
Cant reproduce that issue sorry. Are you sure your windows host is connected to the internet and can resolve google.com?
If your host is using a corporate proxy, this wont work natively.

commented

I identified a few issues on windows 7. Corrected some of them.

Can you try again? Please Include -i to see if the protocol headers are received.

Hi @p3nt4

I am seeing the connections on the attacker side simply hanging indefinitely. I have the two machines - kali (192.168.56.102) and win7 (192.168.56.101)- both in a host-only adapter network connection in Virtualbox.

The hanging response is same whether I use -x socks5://: OR --socks5-hostname :.
screen shot 2017-12-19 at 12 41 20 am

Even Proxychains just hangs...

screen shot 2017-12-19 at 9 24 19 am

commented

Ok, let's debug it:

Add:

$_ | Out-File "Error.log" -Append

In the catch of the socks connection manager block.

And please give me the output of the error. (In the "Error.log file")

Hey @p3nt4

So, I have done as you requested, and there was nothing written to the error log. So I have added extra Debug messages to see what is happening throughout the script. The modified script is below.

The output is shown below that is displayed within 'Normal.log' - so it appears that the output is trapped within the while loop.
screen shot 2017-12-19 at 11 59 48 pm

`<#
.SYNOPSIS

Powershell Socks5 Proxy

Author: p3nt4 (https://twitter.com/xP3nt4)
License: MIT

.DESCRIPTION

Creates a Socks proxy using powershell.

Supports both Socks4 and Socks5 connections.

This is only a subset of the Socks 4 and 5 protocols: It does not support authentication, It does not support UDP or bind requests.

New features will be implemented in the future. PRs are welcome.

.EXAMPLE

Create a Socks proxy on port 1234:
Invoke-SocksProxy -bindPort 1234

Create a simple tcp port forward:
Invoke-PortFwd -bindPort 33389 -destHost 127.0.0.1 -destPort 3389

#>

[ScriptBlock]$TcpConnectionMgr = {
param($vars)
$srvConnection=$vars.srvConnection
$cliConnection=$vars.cliConnection
$Script = {
param($vars)
$vars.inStream.CopyToAsync($vars.outStream)
}
$cliStream = $cliConnection.GetStream()
$srvStream = $srvConnection.GetStream()
$vars2 = [PSCustomObject]@{"inStream"=$cliStream;"outStream"=$srvStream}
$PS = [PowerShell]::Create()
$PS.AddScript($Script).AddArgument($vars2) | Out-Null
[System.IAsyncResult]$AsyncJobResult = $null

$vars3 = [PSCustomObject]@{"inStream"=$srvStream;"outStream"=$cliStream}
$PS2 = [PowerShell]::Create()
$PS2.AddScript($Script).AddArgument($vars3) | Out-Null
[System.IAsyncResult]$AsyncJobResult2 = $null

try
{
    $AsyncJobResult = $PS.BeginInvoke()
    $AsyncJobResult2 = $PS2.BeginInvoke()
    while($cliConnection.Connected -and $srvConnection.Connected){
        sleep -m 100;
    }
}
catch {
}
finally {
    if ($cliConnection -ne $null) {
        $cliConnection.Close()
        $cliConnection.Dispose()
        $cliConnection = $null
    }
    if ($srvConnection -ne $null) {
        $srvConnection.Close()
        $srvConnection.Dispose()
        $srvConnection = $null
    }
    if ($PS -ne $null -and $AsyncJobResult -ne $null) {
        $PS.EndInvoke($AsyncJobResult) | Out-Null
        $PS.Dispose()
    }
    if ($PS2 -ne $null -and $AsyncJobResult2 -ne $null) {
        $PS2.EndInvoke($AsyncJobResult2) | Out-Null
        $PS2.Dispose()
    }
}

}

[ScriptBlock]$SocksConnectionMgr = {
param($vars)
function Get-IpAddress{
param($ip)
IF ($ip -as [ipaddress]){
return $ip
}else{
$ip2 = [System.Net.Dns]::GetHostAddresses($ip)[0].IPAddressToString;
}
return $ip2
}
$client=$vars.cliConnection
$TcpConnectionMgr=$vars.TcpConnectionMgr
$buffer = New-Object System.Byte[] 32
try
{
"Entering SocksConnectionMgr Try Block" | Out-File "Normal.log" -Append
$cliStream = $client.GetStream()
$cliStream.Read($buffer,0,2) | Out-Null
$socksVer=$buffer[0]
if ($socksVer -eq 5){
"Entering First If Statement Block" | Out-File "Normal.log" -Append
$cliStream.Read($buffer,2,$buffer[1]) | Out-Null
for ($i=2; $i -le $buffer[1]+1; $i++) {
if ($buffer[$i] -eq 0) {break}
}
if ($buffer[$i] -ne 0){
$buffer[1]=255
$cliStream.Write($buffer,0,2)
}else{
$buffer[1]=0
$cliStream.Write($buffer,0,2)
}
$cliStream.Read($buffer,0,4) | Out-Null
$cmd = $buffer[1]
$atyp = $buffer[3]
if($cmd -ne 1){
$buffer[1] = 7
$cliStream.Write($buffer,0,2)
throw "Not a connect"
}
"Middle" | Out-File "Normal.log" -Append
if($atyp -eq 1){
$ipv4 = New-Object System.Byte[] 4
$cliStream.Read($ipv4,0,4) | Out-Null
$ipAddress = New-Object System.Net.IPAddress(,$ipv4)
$hostName = $ipAddress.ToString()
}elseif($atyp -eq 3){
$cliStream.Read($buffer,4,1) | Out-Null
$hostBuff = New-Object System.Byte[] $buffer[4]
$cliStream.Read($hostBuff,0,$buffer[4]) | Out-Null
$hostName = [System.Text.Encoding]::ASCII.GetString($hostBuff)
}
else{
$buffer[1] = 8
$cliStream.Write($buffer,0,2)
throw "Not a valid destination address"
}
$cliStream.Read($buffer,4,2) | Out-Null
$destPort = $buffer[4]256 + $buffer[5]
$destHost = Get-IpAddress($hostName)
if($destHost -eq $null){
$buffer[1]=4
$cliStream.Write($buffer,0,2)
throw "Cant resolve destination address"
}
"[
] Destination Host $destHost"| Out-File "Normal.log" -Append
$tmpServ = New-Object System.Net.Sockets.TcpClient($destHost, $destPort)
"[] Destination Host $destHost connected on $destPort, with tmpSrv $tmpServ"| Out-File "Normal.log" -Append
if($tmpServ.Connected){
$buffer[1]=0
$buffer[3]=1
$buffer[4]=0
$buffer[5]=0
$cliStream.Write($buffer,0,10)
$cliStream.Flush()
$vars = [PSCustomObject]@{"cliConnection"=$client;"srvConnection"= $tmpServ}
$PS3 = [PowerShell]::Create()
"[
] Creating TCP Conection Manager"| Out-File "Normal.log" -Append
$PS3.AddScript($TcpConnectionMgr).AddArgument($vars) | Out-Null
"[] TCP Conection Manager created"| Out-File "Normal.log" -Append
[System.IAsyncResult]$AsyncJobResult3 = $null
$AsyncJobResult3 = $PS3.BeginInvoke()
"[
] AsyncJobResult3 invoked"| Out-File "Normal.log" -Append
while($client.Connected -and $tmpServ.Connected){
"[] Looping and waiting"| Out-File "Normal.log" -Append
sleep -m 100;
}
"[
] Completed Async Script"| Out-File "Normal.log" -Append
}
"Middle2" | Out-File "Normal.log" -Append
else{
$buffer[1]=4
$cliStream.Write($buffer,0,2)
throw "Cant connect to host"
}
}elseif($socksVer -eq 4){
"Else If statement" | Out-File "Normal.log" -Append
$cmd = $buffer[1]
if($cmd -ne 1){
$buffer[0] = 0
$buffer[1] = 91
$cliStream.Write($buffer,0,2)
throw "Not a connect"
}
$cliStream.Read($buffer,2,2) | Out-Null
$destPort = $buffer[2]*256 + $buffer[3]
$ipv4 = New-Object System.Byte[] 4
$cliStream.Read($ipv4,0,4) | Out-Null
$destHost = New-Object System.Net.IPAddress(,$ipv4)
$buffer[0]=1
while ($buffer[0] -ne 0){
$cliStream.Read($buffer,0,1)
}
$tmpServ = New-Object System.Net.Sockets.TcpClient($destHost, $destPort)
if($tmpServ.Connected){
"Sub-If statement" | Out-File "Normal.log" -Append
$buffer[0]=0
$buffer[1]=90
$buffer[2]=0
$buffer[3]=0
$cliStream.Write($buffer,0,8)
$cliStream.Flush()
$vars = [PSCustomObject]@{"cliConnection"=$client;"srvConnection"= $tmpServ}
$PS3 = [PowerShell]::Create()
$PS3.AddScript($TcpConnectionMgr).AddArgument($vars) | Out-Null
[System.IAsyncResult]$AsyncJobResult3 = $null
$AsyncJobResult3 = $PS3.BeginInvoke()
while($client.Connected -and $tmpServ.Connected){
sleep -m 100;
}
}
"Hi" | Out-File "Normal.log" -Append
}else{
throw "Unknown socks version"
}
}
catch {
$_ | Out-File "Error.log" -Append
}
finally {
if ($client -ne $null) {
$client.Close()
$client.Dispose()
$client = $null
}
if ($PS3 -ne $null -and $AsyncJobResult3 -ne $null) {
$PS3.EndInvoke($AsyncJobResult3) | Out-Null
$PS3.Dispose()
}
}
}

function Invoke-SocksProxy{
param (

        [String]$bindIP = "0.0.0.0",

        [Int]$bindPort = 1080

 )
try{
    $listener = new-object System.Net.Sockets.TcpListener([System.Net.IPAddress]::Parse($bindIP), $bindPort)
    $listener.start()
    write-host "Listening on port $bindPort..."
    while($true){
        $client = $listener.AcceptTcpClient()
        Write-Host "New Connection from " $client.Client.RemoteEndPoint
        $vars = [PSCustomObject]@{"cliConnection"=$client;"TcpConnectionMgr"=$TcpConnectionMgr}
        $PS3 = [PowerShell]::Create()
        $PS3.AddScript($SocksConnectionMgr).AddArgument($vars) | Out-Null
        [System.IAsyncResult]$AsyncJobResult3 = $null
        $AsyncJobResult3 = $PS3.BeginInvoke()
    }
 }
catch{
    write-host $_.Exception.Message
}
finally{
    write-host "Server closed."
    if ($listener -ne $null) {
              $listener.Stop()
       }
    if ($client -ne $null) {
        $client.Close()
        $client.Dispose()
        $client = $null
    }
    if ($PS3 -ne $null -and $AsyncJobResult3 -ne $null) {
        $PS3.EndInvoke($AsyncJobResult3) | Out-Null
        $PS3.Dispose()
    }
}

}

function Invoke-PortFwd{
param (

        [String]$destHost,

        [Int]$destPort,

        [String]$bindIP = "0.0.0.0",

        [Int]$bindPort

 )
$destIp = Get-IpAddress $destHost
$listener = new-object System.Net.Sockets.TcpListener([System.Net.IPAddress]::Parse($bindIP), $bindPort)
$listener.start()
write-host "Listening on port $bindPort..."
while($true){
    $client = $listener.AcceptTcpClient()
    Write-Host "New Connection"
    $serv = New-Object System.Net.Sockets.TcpClient($destIp, $destPort)
    $vars = [PSCustomObject]@{"cliConnection"=$client;"srvConnection"= $serv}
    $PS3 = [PowerShell]::Create()
    $PS3.AddScript($TcpConnectionMgr).AddArgument($vars) | Out-Null
    [System.IAsyncResult]$AsyncJobResult3 = $null
    $AsyncJobResult3 = $PS3.BeginInvoke()
}
if ($listener -ne $null) {
          $listener.Stop()
   }
if ($PS3 -ne $null -and $AsyncJobResult3 -ne $null) {
    $PS3.EndInvoke($AsyncJobResult3) | Out-Null
    $PS3.Dispose()
}
write-host "Connection closed."

}

function Get-IpAddress{
param($ip)
IF ($ip -as [ipaddress]){
return $ip
}else{
$ip2 = [System.Net.Dns]::GetHostAddresses($ip)[0].IPAddressToString;
Write-Host "$ip resolved to $ip2"
}
return $ip2
}
export-modulemember -function Invoke-SocksProxy
export-modulemember -function Invoke-PortFwd
`

commented

What version of .Net are you using?
Also, can you please reattach a traffic capture? From the windows box if possible.
Does the client receive the response at all? Maybe the proxy just fails to close the connection.
Did you make it work on windows 10?