Advisories

Juniper Junos OS validate package mgd_package_real() command injection

CVE ID

CVE-2021-0219

Tested Versions

  • Junos OS 20.1R1.11

Product URL(s)

  • https://www.juniper.net/

Description of the vulnerability

The command injection vulnerability exists in the validation of the installed package. Upon successfully exploiting this vulnerability, an attacker with low privilege can execute a command with root privilege in the system.

Technical Details

The Vulnerability

To validate a package on host before installing, user run command request system software add validate-on-host <host> <package-path> in cli console. First, when run this command, function mgd_package_real() in /usr/lib/dd/libjunos-actions-impl.so will be called:

  v63 = ddl_get_value_length(a1, "package-name", 0);
  v197 = "package-name";
  v191 = (char *)ddl_get_value_string(
                   (int)a1,
                   (int)"package-name",
                   0,
                   ((unsigned int)&v177 - ((v63 + 3) & 0xFFFFFFFC)) & 0xFFFFFFF0,
                   v63);
    ...
    v164 = ddl_get_value_length(a1, "validate-on-host", 0);
    v181 = "validate-on-host";
    v180 = (const char *)ddl_get_value_string(
                           (int)a1,
                           (int)"validate-on-host",
                           0,
                           ((unsigned int)&v177 - ((v164 + 3) & 0xFFFFFFFC)) & 0xFFFFFFF0,
                           v164);
    ...
    if ( v180 )
    {
      ddl_build_remove_arg((int)a1, (int)v181);
      ...
      if ( sub_1967E0((int)v180, (int)a1, (int)v165, 0, v191) )
        return v40;
    }

The function sub_1967E0 will be called with the 5th args as a path to package file. In sub_1967E0 function:

int __usercall sub_1967E0@<eax>(int a1@<edx>, int a2@<ecx>, int a3, int a4, char *file) {
  ...
  if ( stat(file, (struct stat *)&s2) == -1 )
  {
    v18 = (int *)__error(v10);
    strerror(*v18);
    js_error("Invalid install package : %s");
    v9 = "Failed to extract JUNOS version from install package : %s";
    goto LABEL_8;
  }
  memset(dest, 0, 0x400u);
  snprintf(&command, 0x800u, "%s -xzOf %s --fast-read +COMMENT", "/usr/bin/tar", file);
  v11 = popen(&command, "r");
  ...

This function only checks if the package file exists, without using the validate path function. Therefore, it leads to command injection vulnerability.

The exploitation

To successfully exploit this vulnerability, attackers must have user access with maintenance privilege (to execute request software add ... command).

PoC

Timeline

  • 2020-06-12 Reported to Vendor, Vendor acknowledged on same day
  • 2021-01-12 Vendor patched the vulnerability

Credit

Discovered by Hoàng Thạch Nguyễn (d4rkn3ss)