Share via

NtCreateToken example for creating elevated token without user password

Bala Smart 51 Reputation points
2021-06-15T11:17:06.337+00:00

Hi,

I need elevated token for user, So i can achieve this by using NtCreateToken undocumented API. I'm not able to find any examples to call NtCreateToken.

If anybody knowing usage of [NtCreateToken][1], help me!!!!!!
Developer technologies | C++
Developer technologies | C++

A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.


3 answers

Sort by: Most helpful
  1. 杨 承浩睿 0 Reputation points
    2025-08-24T13:14:52.8766667+00:00

    #include <Windows.h>#include <winternl.h>

    #include <sddl.h>

    #include <iostream>

    #include <vector>

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

    // 来自 ntdll.dll 的 NtCreateToken 声明

    extern "C" NTSTATUS NTAPI NtCreateToken(

    PHANDLE TokenHandle,
    
    ACCESS_MASK DesiredAccess,
    
    POBJECT_ATTRIBUTES ObjectAttributes,
    
    TOKEN_TYPE TokenType,
    
    PLUID AuthenticationId,
    
    PLARGE_INTEGER ExpirationTime,
    
    PTOKEN_USER TokenUser,
    
    PTOKEN_GROUPS TokenGroups,
    
    PTOKEN_PRIVILEGES TokenPrivileges,
    
    PTOKEN_OWNER Owner,
    
    PTOKEN_PRIMARY_GROUP PrimaryGroup,
    
    PTOKEN_DEFAULT_DACL DefaultDacl,
    
    PTOKEN_SOURCE TokenSource
    ```);
    
    // 启用指定特权
    
    BOOL EnablePrivilege(LPCWSTR privName) {
    
    

    HANDLE hToken;

    TOKEN_PRIVILEGES tp;

    LUID luid;

    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))

    return FALSE;
    

    if (!LookupPrivilegeValue(NULL, privName, &luid)) {

    CloseHandle(hToken);
    
    return FALSE;
    

    }

    tp.PrivilegeCount = 1;

    tp.Privileges[0].Luid = luid;

    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

    AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);

    CloseHandle(hToken);

    return (GetLastError() == ERROR_SUCCESS);

    
    int wmain() {
    
    

    // 1️⃣ 启用创建令牌的特权

    if (!EnablePrivilege(L"SeCreateTokenPrivilege")) {

    std::wcout << L"[-] 无法启用 SeCreateTokenPrivilege\n";
    
    return 1;
    

    }

    // 2️⃣ 基本对象属性

    OBJECT_ATTRIBUTES objAttr = {};

    objAttr.Length = sizeof(objAttr);

    // 3️⃣ 身份标识符(可自定义)

    LUID authId = { 999, 0 };

    // 4️⃣ 令牌过期时间(-1 = 永不过期)

    LARGE_INTEGER expTime;

    expTime.QuadPart = -1;

    // 5️⃣ 主用户 SID(SYSTEM)

    PSID pUserSid = NULL;

    ConvertStringSidToSid(L"S-1-5-18", &pUserSid); // Local System

    TOKEN_USER tokenUser = {};

    tokenUser.User.Sid = pUserSid;

    tokenUser.User.Attributes = 0;

    // 6️⃣ 用户组(这里示例只加 Administrators)

    std::vector<SID_AND_ATTRIBUTES> groups(1);

    ConvertStringSidToSid(L"S-1-5-32-544", &groups[0].Sid); // Administrators

    groups[0].Attributes = SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;

    TOKEN_GROUPS tokenGroups = { (DWORD)groups.size(), groups.data() };

    // 7️⃣ 特权(开启 Debug 权限)

    LUID luid;

    LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid);

    TOKEN_PRIVILEGES tokenPrivs = {};

    tokenPrivs.PrivilegeCount = 1;

    tokenPrivs.Privileges[0].Luid = luid;

    tokenPrivs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

    // 8️⃣ Token Owner

    TOKEN_OWNER tokenOwner = { pUserSid };

    // 9️⃣ Primary Group

    TOKEN_PRIMARY_GROUP primaryGroup = { pUserSid };

    // 🔟 Default DACL(默认访问控制表)

    TOKEN_DEFAULT_DACL defaultDacl = {};

    defaultDacl.DefaultDacl = NULL; // 无默认 DACL

    // 1️⃣1️⃣ Token 来源信息

    TOKEN_SOURCE tokenSource = { "CppTok" };

    AllocateLocallyUniqueId(&tokenSource.SourceIdentifier);

    // 1️⃣2️⃣ 创建令牌

    HANDLE hToken = NULL;

    NTSTATUS status = NtCreateToken(

    &hToken,
    
    TOKEN_ALL_ACCESS,
    
    &objAttr,
    
    TokenPrimary,
    
    &authId,
    
    &expTime,
    
    &tokenUser,
    
    &tokenGroups,
    
    &tokenPrivs,
    
    &tokenOwner,
    
    &primaryGroup,
    
    &defaultDacl,
    
    &tokenSource
    

    );

    if (status == STATUS_SUCCESS) {

    std::wcout << L"[+] 成功创建令牌\n";
    
    // 1️⃣3️⃣ 使用令牌启动 cmd.exe
    
    STARTUPINFO si = { sizeof(si) };
    
    PROCESS_INFORMATION pi;
    
    if (CreateProcessAsUser(hToken, NULL, (LPWSTR)L"C:\\Windows\\System32\\cmd.exe",
    
        NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
    
        std::wcout << L"[+] 已使用新令牌启动进程\n";
    
        CloseHandle(pi.hProcess);
    
        CloseHandle(pi.hThread);
    
    } else {
    
        std::wcout << L"[-] CreateProcessAsUser 失败,错误码:" << GetLastError() << L"\n";
    
    }
    
    CloseHandle(hToken);
    

    } else {

    std::wcout << L"[-] NtCreateToken 失败,状态码:0x" << std::hex << status << L"\n";
    

    }

    LocalFree(pUserSid);

    return 0;

    Was this answer helpful?

    0 comments No comments

  2. RLWA32 52,561 Reputation points
    2021-06-17T22:29:36.047+00:00

    Well, it can be done. Here's a standard user - Bozo with an elevated Administrator command prompt running.

    106630-ntcreatetoken.png

    Was this answer helpful?


  3. Castorix31 91,871 Reputation points
    2021-06-15T14:04:54.96+00:00

    You can find samples from Google, like
    SeCreateTokenPrivilege.cpp
    But I get STATUS_PRIVILEGE_NOT_HELD as Admin on Windows 10
    (cannot enable SE_CREATE_TOKEN_NAME privilege)

    Was this answer helpful?


Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.