Closed Bug 1824420 (CVE-2023-4052) Opened 1 year ago Closed 1 year ago

Firefox arbitrary file delete vulnerability

Categories

(Toolkit :: Application Update, defect)

defect

Tracking

()

RESOLVED FIXED
116 Branch
Tracking Status
firefox-esr102 --- wontfix
firefox-esr115 116+ fixed
firefox114 --- wontfix
firefox115 --- wontfix
firefox116 + fixed

People

(Reporter: ycdxsb, Assigned: bytesized)

References

Details

(Keywords: csectype-priv-escalation, reporter-external, sec-moderate, Whiteboard: [reporter-external] [client-bounty-form] [verif?] [adv-main116+] [adv-ESR115.1+])

Attachments

(2 files, 1 obsolete file)

Firefox arbitrary file detete vuln

Basic Info

  • Software Name: Firefox for Windows
  • Software Version:111.0.1
  • Test OS System:Windows 21H2 (19044.1826)
  • Vuln Influence:Arbitrary File Delete,Local Privilege Escalation
  • CWE:CWE-1386

Vuln Analyse

After installing Firefox on Windows, a path similar to C:\ProgramData\Mozilla-1de4eec8-1241-4177-a864-e594e8d1fb38\updates\E7CF176E110C211B will be created in the operating system. When an administrator uninstalls Firefox, the uninstall program will recursively delete all files and folders under this path.

  • Problem 1:The permission of directory C:\ProgramData\Mozilla-1de4eec8-1241-4177-a864-e594e8d1fb38\updates\E7CF176E110C211B allow all user in Users group add file and directory in it.
C:\ProgramData\Mozilla-1de4eec8-1241-4177-a864-e594e8d1fb38\updates>icacls E7CF176E110C211B
E7CF176E110C211B BUILTIN\Users:(I)(OI)(CI)(F)
                 BUILTIN\Administrators:(I)(OI)(CI)(F)
                 NT AUTHORITY\SYSTEM:(I)(OI)(CI)(F)
  • Problem 2:On Windows, the recursive deletion feature can be exploited using symbolic links for attacks. For example, by creating a junction link for C:\ProgramData\Mozilla-1de4eec8-1241-4177-a864-e594e8d1fb38\updates\E7CF176E110C211B\poc and other paths, arbitrary file deletion can be achieved.

Proof Of Concept

We can finally get a system shell by trick listing here:https://www.zerodayinitiative.com/blog/2022/3/16/abusing-arbitrary-file-deletes-to-escalate-privilege-and-other-great-tricks.

In this part, we only proof the arbitrary file delete vuln.

  1. an low privilege user attacker create a junction between C:\ProgramData\Mozilla-1de4eec8-1241-4177-a864-e594e8d1fb38\updates\E7CF176E110C211B\poc and C:\Users\admin\Desktop

    mklink /J C:\ProgramData\Mozilla-1de4eec8-1241-4177-a864-e594e8d1fb38\updates\E7CF176E110C211B\poc C:\Users\admin\Desktop
    
  2. admin uninstall firefox

  3. files in C:\Users\admin\Desktop will be deleted.

Hello,
It seems that the poc video is too large. I put the link of it here:https://drive.google.com/file/d/1W_pZDvXFJCvOXxU3_rQDsnHMCM7qMec-/view?usp=share_link
Thanks

Component: Security → Application Update
Product: Firefox → Toolkit
Summary: Firefox arbitrary file detete vuln → Firefox arbitrary file delete vulnerability

I haven't tried to reproduce this yet, but the description of the bug sounds plausible. I'll try to dedicate some time to this when I have some. Hopefully after I'm done with what I'm currently working on.

Severity: -- → S2

In your scenario is Firefox installed by the admin in a privileged location? In the default location we install firefox with limited file permissions, but if you install into a non-standard location we make it world readable. I don't know if that relates to the permissions we use for ProgramData though.

Flags: needinfo?(ycdxsb)

Hello,
In the proof-of-concept video, I demonstrated installing Firefox as an administrator in the default location on a Windows system. It's important to note that all users in the Users group have the ability to add files or directories in the C:\ProgramData\ directory. However, if correct permissions are not set, the default permission inheritance from the C:\ProgramData\ directory is weak.
Thanks

Flags: needinfo?(ycdxsb)
Assignee: nobody → bytesized

Thought I'd give a status update on the direction that I plan on going here. I was originally hoping to use UAC::ExecCodeSegment to execute the deletion with lower privileges. But this won't actually help if the installer was run with elevated privileges in the first place (rather than elevating with a UAC prompt). I suspect that this is probably pretty common in enterprise environments, which is sort of the worst place to have this kind of problem. So I'm scrapping that idea.

I've considered a number of other ideas, none of which I'm entirely happy with. But I think that we can pretty easily enumerate all the files that we want to delete. Which should allow us to delete them all by path, and then attempt to remove the directories containing them non-recursively. I believe that this should effectively sidestep the issue here.

Gah, I'm no longer so sure about that idea. The backgroundupdate directory contains some not very well-defined file names

I wrote a document of what I believe are the available solutions here. Since this is security sensitive, the document is currently restricted to my team. If you would like access, let me know. Hopefully we will have a decision on how we want to move forward here shortly.

Alright, I have a solution that I am going to attempt to go forward with that involves creating a separate binary that attempts to reinvoke itself as the least privileged user possible. I'm hoping to combine this approach with manually implementing a recursive deletion method that will attempt to prevent itself from being tricked into deleting files that it doesn't intend to.

Yu Chendong: you appear to have filed this bug using our bug bounty form, but it does not have the sec-bounty? flag that form should have added. Did you remove that flag when you filed the bug, or is our form broken?

Flags: needinfo?(ycdxsb)

Hello,
I submit this issue by a security bug form from bug bounty program site. I am not sure why there is no sec-bounty flag.
Thanks.

Flags: needinfo?(ycdxsb)
Group: firefox-core-security → core-security-release
Status: UNCONFIRMED → RESOLVED
Closed: 1 year ago
Resolution: --- → FIXED
Target Milestone: --- → 116 Branch

I'm going to assume that given the severity of this bug and the risk associated, we probably don't want to attempt to backport this to ESR102 so late in its lifecycle (but please confirm that!). We probably do want to get this onto ESR115, however.

Flags: needinfo?(bytesized)

It's not immediately clear how we should port this over to Thunderbird.

For the first two modified files, I can find equivalent files for TB, and it seems possible to merge those changes. For the additional files in browser, we don't seem to have them in TB, and I don't know if we need to add them.

Rob, do you understand how to handle this, should we experiment, or do we need help from bytesized?

Blocks: 1840887

(In reply to Ryan VanderMeulen [:RyanVM] from comment #13)

I'm going to assume that given the severity of this bug and the risk associated, we probably don't want to attempt to backport this to ESR102 so late in its lifecycle (but please confirm that!).

Agreed. I don't think that's necessary.

We probably do want to get this onto ESR115, however.

Yes, I want to make sure this makes it to ESR115. I'm a little confused about the timing of this. Will this need to be marked for ESR uplift to make it into 115?

Flags: needinfo?(bytesized) → needinfo?(ryanvm)

I've set the flags so it's on the radar for next cycle (i.e. 115.1esr shipping alongside Fx116). You can request approval now or wait a bit if you want.

Flags: needinfo?(ryanvm)

I want to do some quick manual testing on the Nightly installer and then I'll request approval.

Comment on attachment 9341189 [details]
Bug 1824420 - r=nalexander!

ESR Uplift Approval Request

  • If this is not a sec:{high,crit} bug, please state case for ESR consideration: This vulnerability seems most risky for ESR users. Most enterprise users use ESR. The most common time that the installer would be run regularly is an enterprise environment. And that is also the most likely case for an attacker to be interested in a targeted Elevation of Privilege attack.
  • User impact if declined: ESR user would be more vulnerable to an Elevation of Privilege attack from an attacker with local access.
  • Fix Landed on Version: 116
  • Risk to taking this patch: Low
  • Why is the change risky/not risky? (and alternatives if risky): Only affects the installer and uninstaller. Failure of code is non-critical. The installer and uninstaller will succeed even if the new code fails.
Attachment #9341189 - Flags: approval-mozilla-esr115?

Comment on attachment 9341189 [details]
Bug 1824420 - r=nalexander!

Approved for 115.1esr

Attachment #9341189 - Flags: approval-mozilla-esr115? → approval-mozilla-esr115+
Flags: qe-verify+
QA Whiteboard: [qa-triaged]

I'm trying to verify that this bug is fixed on 115esr and latest Firefox 116 beta but for me for every build I use all the files will be deleted from Desktop in this case. I assume I did something wrong with the privileges of the non admin user or something else but not sure.
Here are the steps I used:

  1. Made a standard user that has the following permissions: Read&Execute, List folder contents, Read, Write for ProgramData from the admin user.
  2. Installed Firefox, 115.0.2esr in this case https://archive.mozilla.org/pub/firefox/candidates/115.0.2esr-candidates/build1/win64/en-US/Firefox%20Setup%20115.0.2esr.exe from the admin user.
  3. Switched to the standard user (Signed out of the admin user)
  4. From standard user I executed in CMD the following command mklink /J C:\ProgramData\Mozilla-1de4eec8-1241-4177-a864-e594e8d1fb38\updates\E7CF176E110C211B\poc C:\Users\admin\Desktop. (replaced the updates file and the path to admin user)
  5. Checked inside the updates folder that the poc symbolic link was made and that it points to Desktop from Admin account.
  6. Opened Control Panel and uninstalled Firefox (when requested for an admin account to uninstall I provided the credential for the Admin account)
  7. I checked the symbolic link and there were no more files in Desktop from admin user.
  8. I switched to the admin account and I confirmed that the Desktop was clean.

Could you please help in determining if I used the correct steps here? Thanks

Flags: needinfo?(bytesized)

Ideally the thing that we would be testing against is that the (un)installer won't delete a directory that is exclusively owned by TrustedIntaller. But the steps that you gave should work fine if you use two separate administrator users, let's call them admin1 and admin2. Then make a file on the desktop as admin2 and don't use that user's account or credentials again until step 8 where you check if the file was deleted. Anything else should be done as admin1.

I believe that the problem that you are having is that you are testing that the (un)installer doesn't have access to C:\Users\admin\Desktop, but then you are running the uninstaller with that same admin's credentials. So even after de-escalating privileges, the (un)installer probably still has access to the admin's files.

Flags: needinfo?(bytesized)

(In reply to Robin Steuber (they/them) [:bytesized] from comment #22)

Ideally the thing that we would be testing against is that the (un)installer won't delete a directory that is exclusively owned by TrustedIntaller. But the steps that you gave should work fine if you use two separate administrator users, let's call them admin1 and admin2. Then make a file on the desktop as admin2 and don't use that user's account or credentials again until step 8 where you check if the file was deleted. Anything else should be done as admin1.

I believe that the problem that you are having is that you are testing that the (un)installer doesn't have access to C:\Users\admin\Desktop, but then you are running the uninstaller with that same admin's credentials. So even after de-escalating privileges, the (un)installer probably still has access to the admin's files.

Thanks for your reply, I did try again with two admin users as you said (called them admin1 and admin2) and followed the steps from comment 21 but with no success.
I also tried to install Firefox, created symlink and uninstalled Firefox from admin2, I only accessed admin1 to give sharing access to Desktop for admin2 and to see if the files were deleted after uninstallation and unfortunately they were with 116.0b5. Both admin have full access control, I also made sure that I can have access to desktop of admin1 from admin2 via the symlink created. Not sure what I am doing wrong. Would you mind verifying this with latest Beta and 115esr?

Flags: needinfo?(bytesized)

(In reply to Bogdan Maris, Desktop QA from comment #23)

I also made sure that I can have access to desktop of admin1 from admin2 via the symlink created. Not sure what I am doing wrong.

This is confusing to me and I'm suspicious that this is the reason that verifying this wasn't working. Though the link should correctly point to admin1's desktop, admin2 shouldn't actually be able to access it without elevation. No unelevated user should be able to just access another user's files. Though perhaps this could be one of those implicit elevation things that Explorer sometimes does.

Would you mind verifying this with latest Beta and 115esr?

I just tested with Beta and ESR 115 as downloaded from here. I could verify the fix in Beta, but not in ESR 115. This sort of seems expected to me since this was approved for uplift to ESR 115.1, but the newest available ESR is ESR 115.0.2.

Flags: needinfo?(bytesized)

Since Bogdan is currently on PTO I picked this verification up and the same results reported as Bogdan.

  • winver 21H2 PRO version
  • admin1 - administrator account(local account)
  • admin2 - administrator account(local account)
  • user - standard account(local account)

Tested with 117.0a1 (2023-07-16) and Beta 116.0b6 creating symlinks from admin2 and user to 2 desktop folders(folder1 and folder2) on admin1 and the results is both folders get deleted on uninstall triggered from admin1. Robin, did you use local user accounts or Microsoft accounts for your verification?

Flags: needinfo?(bytesized)

Hmm. I discovered that the way that I was creating my junctions caused them to be malformed in a way that (apparently) the new version of the installer wouldn't delete but the old version would. Now that I am creating them correctly, I can reproduce this problem. I'm not entirely sure whether this means that the vulnerability still exists or not. I'll investigate more tomorrow.

Well. I have made a number of interesting discoveries.

One is Bug 1844179. I'd rather leave the details in that bug so that they don't become public when/if this bug does (I'm not actually 100% sure it needs to be marked as a security bug, but I am going to assume that it does until told otherwise). But suffice to say it is related to the unexpected testing results in the past few comments.

Another is that, as things stand, this patch does not prevent following the proof of concept steps originally provided. But there are a couple of mitigating factors that are relevant here:

  1. When I run the uninstaller, it doesn't run as TrustedInstaller or even SYSTEM, it runs as my login user in an elevated context. An administrator, even in an elevated context, does not have the permissions necessary to delete a directory that only has permissions granted to TrustedInstaller. I checked this to be sure.
  2. The more I thought about this, the more I realized that I don't actually understand the proposed exploit as well as I thought that I did. I was thinking that you would make a directory junction from the update directory pointing to C:\Config.Msi (the vulnerable directory mentioned in the original link in the bug description). But this doesn't actually do what we want because, in order to perform the described exploit, the attacker needs to remove the directory itself, not just its contents, in order to be able to fill it with evil without escalating privileges. I guess you could point the directory junction instead at the parent directory (C:\), but if you have the privileges necessary to remove C:\Config.Msi, you are also going to have the necessary privileges to remove large parts of C:\Windows, which is going to have some pretty serious consequences for performing the later stages of any exploit.

All of which is to say that I don't think that there is actually any way to use this bug to perform an escalation of privileges.
@Yu Chendong - Am I missing something here? How can a privilege escalation actually be performed here without running into the two problems I mentioned above?

If there is no escalation of privilege here, I contemplated backing this patch out, but I actually do think that it's valuable. If, for some reason, you did run the uninstaller as TrustedInstaller or SYSTEM, this should successfully drop a certain amount of those privileges and prevent deletion of some especially highly privileged things that really should not be deleted.
And, additionally, this patch has the potential to become substantially more valuable if Bug 1844179 or Bug 1828503 is fixed.

Flags: needinfo?(bytesized) → needinfo?(ycdxsb)

Hello,
You are right, arbitrary file deletion through junction point is the original impact of this vulnerability. With the privilege of uninstaller process, attacker can delete important files (e.g. files under C:\Windows or files under C:\Users\admin) in Windows system.
Thanks

Flags: needinfo?(ycdxsb)

(In reply to Yu Chendong from comment #28)

Hello,
You are right, arbitrary file deletion through junction point is the original impact of this vulnerability. With the privilege of uninstaller process, attacker can delete important files (e.g. files under C:\Windows or files under C:\Users\admin) in Windows system.
Thanks

The files in C:\Windows are owned by TrustedInstaller, not the Administrator group, so they are not vulnerable here.


Since this bug is now being used as the place to handle potential escalation of privilege, work to handle interacting with the update directory in a safer way, generally, will be done in another bug. Since the escalation of privileges is only possible if the (un)installer is run by TrustedInstaller, I'm not actually entirely sure how to test this patch, since it's not clear to me how to just run something as TrustedInstaller. But I still think it's valuable to keep the patch as it should theoretically work and, as mentioned in Comment 27, it will be more valuable if other bugs get fixed.

Yes, the trick in https://www.zerodayinitiative.com/blog/2022/3/16/abusing-arbitrary-file-deletes-to-escalate-privilege-and-other-great-tricks is a way to eop. As you mentioned, it not work in this issue because it only delete files under C:\Config.msi. There are also other tricks, like https://secret.club/2020/04/23/directory-deletion-shell.html.

I agree that having the original fix is better than not having it, but I'm uncertain what can be actually verified in this bug.

Flags: needinfo?(bytesized)

I'm not sure either. I tried getting the uninstaller to run as TrustedInstaller, but didn't end up having much luck.

Flags: needinfo?(bytesized)

Thanks Robin! Removing the qe+ for the time being. Please reaply as need arise.

Flags: qe-verify+
Whiteboard: [reporter-external] [client-bounty-form] [verif?] → [reporter-external] [client-bounty-form] [verif?] [adv-main116+] [adv-ESR115.1+]
Attached file advisory.txt (obsolete) —

Hello,
Could you please change Yu Chendong to my hacker name : ycdxsb?
Thanks

Attached file advisory.txt
Attachment #9345938 - Attachment is obsolete: true
Flags: sec-bounty?
Flags: sec-bounty? → sec-bounty+
See Also: → 1864758
Group: core-security-release
Alias: CVE-2023-4052
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: