4

This is similar to " how create medium integrity level process from low integrity level process? ", but I'm coming from a slightly different angle. (And that isn't answered anyway.) :)

If a file is saved as low integrity (typically from a low integrity app such as a browser) then it is marked with a Low Integrity Mandatory Label. (This label can also be applied with icacls /setintegritylevel low.) If such a file is executed, it becomes a low integrity process, understandably.

Is there some way to elevate (via consent UI) this process back to medium integrity? It's possible to go to high integrity if the app is marked with a requiresAdministrator manifest, or if it calls ShellExecute with the runas verb, but obviously this requires admin permissions as well. Going to medium integrity doesn't require admin permissions and it still unlocks a lot of permissions unavailable to low integrity processes.

Obviously any mechanism to do so should require the user consent UI (it should be impossible to do it silently, otherwise what's the point?), but how can that be invoked?

The only discussion on this topic that I've found involves having an originally-medium-integrity process of your own and spinning off the low-integrity process from it; this permits elevation by communication back to the medium-integrity process and getting it to launch whatever. But this doesn't help when it's the OS itself that initially starts the process with low integrity.

Community
  • 1
  • 1
Miral
  • 12,637
  • 4
  • 53
  • 93
  • A process becomes a `Low` integrity if it has the *Low Mandatory Integrity Level* label (`S-1-16-4096`). i'm looking at the MSDN code now where you duplicate your current token, and add the `LowIL` sid. Presumably creating a medium integrity level process is similarly easy - adding a *Medium Integrity Level* label (`S-1-16-8192`). – Ian Boyd Mar 05 '12 at 01:20
  • Nevermind, that doesn't work. The call to `SetTokenInformation`, attempting to add the higher integrity label fails with `1314 - A required privilege is not held by the client.` – Ian Boyd Mar 05 '12 at 03:41
  • @Miral: have you been able to reproduce this problem? – Harry Johnston Mar 08 '12 at 03:55
  • @HarryJohnston: I haven't been able to reproduce a file being saved as low integrity from IE9, no (that idea was based on a user report, but may have been caused by something else). I *have* reproduced the case I mention above where a file marked as low integrity via unspecified-means-not-relevant-to-the-question will run as a low integrity process and be unable to elevate itself to medium, only to high. Which seems weird. I accept that consent UI must be required for this elevation, I'm just surprised there doesn't seem to be a standard broker for it as with high integrity. – Miral Mar 12 '12 at 07:12
  • @Miral: I think the bottom line is that files aren't supposed to be marked as low integrity without a good reason. The proper solution is not for the executable to be able to ask a non-privileged user for permission to elevate itself back up to medium, but to identify and correct the problem that caused it to be marked as low integrity in the first place. – Harry Johnston Mar 12 '12 at 20:28
  • (Note that the user can remove the low integrity mark by copying the file.) – Harry Johnston Mar 12 '12 at 20:30

2 Answers2

1

I have never seen or heard of a way to get a user's consent to elevate a process from low to medium integrity. I would say you are out of luck.

Please also see this blog article for reference: Internet Explorer in Protected Mode – How the Low Integrity Environment Gets Created

Helge Klein
  • 8,829
  • 8
  • 51
  • 71
  • I hope not. Reportedly IE9 has a habit of marking downloaded files as low integrity... – Miral Dec 01 '11 at 00:12
  • @Miral: do you have a reliable source for that? It certainly doesn't do that normally, and if it does sometimes happen, I doubt it is intentional. If you're worried about it, your best bet might be to test to see if you're running in low integrity, and if so, pop up a dialog explaining the situation to the user. – Harry Johnston Dec 01 '11 at 03:33
  • @Miral: Another possible workaround would be to make the download a zip file, the extraction should remove the low integrity label. – Harry Johnston Dec 01 '11 at 03:49
  • @Miral: I updated my answer with a link to an article discussing related matters. – Helge Klein Dec 01 '11 at 08:51
  • @HarryJohnston Miral's thinking of the so-called *"Mark of the web"*; the thing that you get rid of by clicking the `Unblock` button in a file's properties dialog. The integrity level is not touched. – Ian Boyd Mar 05 '12 at 00:52
  • @IanBoyd: Actually no, I wasn't; I know that's separate. The idea about IE9 being the culprit was based on an (evidently incorrect) user report; I'm not sure what ended up giving it the low integrity label (virus scanner, maybe?) but it undoubtedly did happen and caused problems as a result. But that doesn't invalidate the question. – Miral Mar 12 '12 at 07:19
1

You will have to do what Internet Explorer (and Chrome) do. The browser tabs themselves are separate processes running at Low Mandatory Integrity Level. But there is still a Medium level parent process.

The client processes communicate back to the "parent" process though named pipes, asking the parent to perform some action. Since the parent is medium, it can launch something at medium.


Update: Here's an example of how you cannot create a medium integrity process from a low integrity process:

void CreateLowProcess(String szProcessName; String IntegritySid)
{
    hToken: THandle;
    hNewToken: THandle;
    szIntegritySid: WideString;
    pIntegritySid: PSID;
    TIL: TOKEN_MANDATORY_LABEL;
    ProcInfo: PROCESS_INFORMATION;
    startupInfo: TStartupInfo;

    const int SE_GROUP_INTEGRITY = 0x00000020;
    const int TokenIntegrityLevel = 25;

    const String SLowIntegritySid = "S-1-16-4096";
    const String SMediumIntegritySid = "S-1-16-8192";
    const String SHighIntegritySid = "S-1-16-12288";
    const String SSystemIntegritySid = "S-1-16-16384";

    /*
        Designing Applications to Run at a Low Integrity Level
        http://msdn.microsoft.com/en-us/library/bb625960.aspx
    */

    // Low integrity SID
    if IntegritySid == ""
       IntegritySid = SMediumIntegritySid;

    pIntegritySid = null;

    ZeroMemory(@startupInfo, sizeof(startupInfo));


    if (!OpenProcessToken(GetCurrentProcess(), 
          TOKEN_DUPLICATE or TOKEN_ADJUST_DEFAULT or TOKEN_QUERY or TOKEN_ASSIGN_PRIMARY, 
          ref hToken))
    RaiseLastWin32Error;
    try
        if (not DuplicateTokenEx(hToken, 0, nil, SecurityImpersonation, TokenPrimary, {var}hNewToken)) then
            RaiseLastWin32Error;
        try
            if (not ConvertStringSidToSidW(PWideChar(szIntegritySid), {var}pIntegritySid)) then
                RaiseLastWin32Error;
            try
                TIL._Label.Attributes := SE_GROUP_INTEGRITY;
                TIL._Label.Sid := pIntegritySid;

                // Set the process integrity level
                if (not SetTokenInformation(hNewToken, TTokenInformationClass(TokenIntegrityLevel), @TIL,
                        sizeof(TOKEN_MANDATORY_LABEL) + GetLengthSid(pIntegritySid))) then
                    RaiseLastWin32Error;

                //Create the new process at Low integrity
                Result := CreateProcessAsUserW(
                        hNewToken,
                        nil,
                        PWideChar(szProcessName),
                        nil, //ProcessAttributes
                        nil, //ThreadAttributes
                        False, //bInheritHandles
                        0, //dwCreationFlags
                        nil, //lpEnvironment
                        nil, //lpCurrentDirectory
                        startupInfo,
                        ProcInfo);
            finally
                LocalFree(Cardinal(pIntegritySid));
            end;
        finally
            CloseHandle(hNewToken);
        end;
    finally
        CloseHandle(hToken);
    end;
end;

And i give up transcoding the rest from pascal to C#. It can't be done anyway, that's the answer.

Ian Boyd
  • 246,734
  • 253
  • 869
  • 1,219
  • I specifically stated that this is an unacceptable answer. The only running process was initially started at low integrity by Explorer. There is no medium integrity process to talk to. – Miral Mar 06 '12 at 23:39
  • Sorry, i was confusing two questions - one where the person wanted to know how to start a medium integrity process from a low integrity process, and then yours. Either way, i tried it: and you can't. Welcome or not it is the answer. – Ian Boyd Mar 07 '12 at 00:42
  • 1
    I'm very happy that a low integrity process cannot elevate its own token to medium integrity. Otherwise there wouldn't be any point to having the low integrity concept. What I'm asking about is how to invoke a standard OS-provided brokerage process to do the elevation via consent UI, as you can to get to high integrity. Maybe there isn't any such thing. But if not that would seem to be a bug in Windows. – Miral Mar 12 '12 at 07:16
  • 1
    There is no consent UI in Windows designed to ask the user if they want to "elevate" out of low to medium. The only standard UI provided by Windows is to elevate to administrator. An example would be Internet Explorer, which doesn't even have a consent dialog - it has it's own "Open", "Save As", "Cancel". And in my opinion Windows should not have a Low->Medium elevation dialog; it would be too easily confused with the UAC consent dialog. – Ian Boyd Mar 12 '12 at 15:10