PowerShell/Polaris

polaris endpoint not accessible out side of client machine

mazad01 opened this issue · 14 comments

Polaris Bug Report

Description of the bug

polaris endpoint not accessible out side of client machine. i get the following error trying to access it outside of the machine:

Bad Request - Invalid Hostname
HTTP Error 400. The request hostname is invalid.

Expected behavior

Hello world should be the return, as it is the return on the client machine

Hi @mazad01, on the current version in PowerShell gallery you would have to be running as admin for it to be listening for external requests.

In #175 we added support for binding to a specific hostname and port which means you can listen on external interfaces without running as admin although it will error out if you have not reserved the url for powershell.exe ahead of time.

Hi, I am running Polaris in an admin context of ps_ise

Can you give any more detail on your environment to help us reproduce?

Sure:

  • I'm using a vanilla build of Windows Server 2016 Standard (10.0.14393)
  • PSVersion: 5.1.14393.2636
  • Using the latest polaris version
  • Windows Firewall is completely turned off
  • Running the following in an Administrator instance of Powershell_ISE
New-PolarisGetRoute -Path "/helloworld" -Scriptblock {
    $Response.Send('Hello World!');
}

Start-Polaris

On the local machine, i can visit that endpoint through I.E (NOTE: it does not work via invoke-restmethod on the local machine. I'll open a separate issue for that later)

On a remote machine, I cant hit the endpoint. However, a netstat on the polaris box shows that the remote machine initiated a connection that is on TIME_WAIT

Hmm... odd.

So let's say your $Env:Computername is MyPC01 and you are running the above script and then going to another PC and running:

Invoke-RestMethod "http://MyPC01:8080/helloworld"

results in no response. Correct?

After running the sample script you gave there can you check the output of the following command:

(Get-Polaris).Listener

The Prefixes property should be {http://+:8080/}

yes thats correct. and prefixes property is empty:

PS C:\WINDOWS\system32> (Get-Polaris).Listener


AuthenticationSchemeSelectorDelegate : 
ExtendedProtectionSelectorDelegate   : 
AuthenticationSchemes                : Anonymous
ExtendedProtectionPolicy             : ProtectionScenario=TransportSelected; PolicyEnforcement=Never; CustomChannelBinding=<null>; ServiceNames=<null>
DefaultServiceNames                  : {HTTP/localhost, HTTP/mypc01.ad.com}
Realm                                : 
TimeoutManager                       : 
IsListening                          : False
IgnoreWriteExceptions                : True
UnsafeConnectionNtlmAuthentication   : False
Prefixes                             : 


Get-Polaris command:

PS C:\WINDOWS\system32> Get-Polaris


Port              : 8080
RouteMiddleWare   : {}
ScriptblockRoutes : {[/helloworld, System.Collections.Generic.Dictionary`2[System.String,System.Management.Automation.ScriptBlock]]}
GetLogsString     : PolarisLogs
ClassDefinitions  : 
UriPrefix         : http://localhost:8080/
ContextHandler    : System.AsyncCallback

This is the statement we're using to detect if you're an admin on the box:

[System.Environment]::OSVersion.Platform -ne [System.PlatformID]::Win32NT -or
            ([System.Environment]::OSVersion.Platform -eq [System.PlatformID]::Win32NT -and
                ([System.Security.Principal.WindowsPrincipal]::new([System.Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator))

It should evaluate to true

Then it will run essentially the following code if you want to try it just plain vanilla and see if you're getting any error

$ListenerPrefix = "Http"
$Listener = [System.Net.HttpListener]::new()
$Listener.Prefixes.Add("http://+:8080/")

The first statement does evaluate to true. and i reran my code, and see this under prefixes:

Prefixes                             : {http://localhost:8080/}

question is how do i get the hostname added to the listener attribute of get-polaris? i tried running the command above, and same local host prefix

alright i manually modified this line with the actual hostname of the machine

$this.UriPrefix = $ListenerPrefix + '://' + $HostName + ':' + $this.Port + '/'

and i see it in (get-polaris).listener. i was also able to access it through the remote machine. question now becomes how does that attr get populated?

it seems -hostname is required in start-polaris, that might be it

Ah yeah that could be it. Did you install from the Github repo or from PowerShell gallery?

github repo

Okay gotcha, yeah we haven't updated the docs yet since the last gallery release. We just merged in a change for that. Sorry I completely missed asking that.

# Respond to all names on the designated port
Start-Polaris -Hostname "+"

# Listen on all unreserved names
Start-Polaris -Hostname "*"

# Listen on the computername of the PC
Start-Polaris -Hostname $Env:Computername

# Listen on a specific IP address
Start-Polaris -Hostname "10.0.0.24"

# Listen for requests to a specific URL
Start-Polaris -Hostname "myawesomesite.mydomain.com"

*Note: Anything other than "localhost" which is the default will either require running as admin or pre-registering the prefix for use with a specific user by running netsh as admin.

netsh http add urlacl url=http://+:1233/ user=Chris-PC\Chris

Awesome, thanks for the help!