|
本人菜鸟,大神飘过
背景:有个软件需要在驱动里找一个具有system权限的svchost,借它做点非常正规的事情.此处省略一万字.
本着从贵站也学习也奉贤的原则.开始如下:
首先想到了之前写过用户层的,先发出代码.
'SECURITY_MANDATORY_UNTRUSTED_RID = $00000000; -0
'SECURITY_MANDATORY_LOW_RID = $00001000; -4096
'SECURITY_MANDATORY_MEDIUM_RID = $00002000; -8192 普通用户权限
'SECURITY_MANDATORY_HIGH_RID = $00003000; -12288 管理员权限
'SECURITY_MANDATORY_SYSTEM_RID = $00004000; -16384 system权限
'SECURITY_MANDATORY_PROTECTED_PROCESS_RID = $00005000;-20480
Option Explicit
Private Declare Function GetCurrentProcess Lib "kernel32" () As Long
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function OpenProcessToken Lib "advapi32.dll" (ByVal ProcessHandle As Long, ByVal DesiredAccess As Long, TokenHandle As Long) As Long
Private Declare Function GetTokenInformation Lib "advapi32.dll" (ByVal TokenHandle As Long, ByRef TokenInformationClass As TOKEN_INFORMATION_CLASS, ByRef TokenInformation As Any, ByVal TokenInformationLength As Long, ByRef ReturnLength As Long) As Long
Private Declare Function GetSidSubAuthorityCount Lib "advapi32.dll" (ByVal pSid As Long) As Long
Private Declare Function GetSidSubAuthority Lib "advapi32.dll" (ByVal pSid As Long, ByVal nSubAuthority As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Type SID_AND_ATTRIBUTES
SID As Long
Attributes As Long
End Type
Private Type TOKEN_MANDATORY_LABEL
Label As SID_AND_ATTRIBUTES
End Type
Private Enum TOKEN_INFORMATION_CLASS
TokenUser = 1
TokenGroups
TokenPrivileges
TokenOwner
TokenPrimaryGroup
TokenDefaultDacl
TokenSource
tokenType
TokenImpersonationLevel
TokenStatistics
TokenRestrictedSids
TokenSessionId
TokenGroupsAndPrivileges
TokenSessionReference
TokenSandBoxInert
TokenAuditPolicy
TokenOrigin
TokenElevationType
TokenLinkedToken
TokenElevation
TokenHasRestrictions
TokenAccessInformation
TokenVirtualizationAllowed
TokenVirtualizationEnabled
TokenIntegrityLevel
TokenUIAccess
TokenMandatoryPolicy
TokenLogonSid
TokenIsAppContainer
TokenCapabilities
TokenAppContainerSid
TokenAppContainerNumber
TokenUserClaimAttributes
TokenDeviceClaimAttributes
TokenRestrictedUserClaimAttributes
TokenRestrictedDeviceClaimAttributes
TokenDeviceGroups
TokenRestrictedDeviceGroups
TokenSecurityAttributes
TokenIsRestricted
MaxTokenInfoClass
End Enum
Private Const TOKEN_QUERY = &H8
Private Const TOKEN_QUERY_SOURCE = &H10
Public Function GetIntegrityLevel() As Long
Dim hProcess As Long
Dim hToken As Long
Dim dwSize As Long
Dim pUser As TOKEN_MANDATORY_LABEL
Dim psaCount As Long
Dim SubAuthority As Long
Dim lRet As Long
Dim lpBuffer() As Long
hProcess = GetCurrentProcess()
If hProcess Then
Call OpenProcessToken(hProcess, TOKEN_QUERY Or TOKEN_QUERY_SOURCE, hToken)
If hToken Then
Call GetTokenInformation(hToken, ByVal TokenIntegrityLevel, ByVal 0&, 0, dwSize)
If dwSize Then
ReDim lpBuffer(dwSize) As Long
lRet = GetTokenInformation(hToken, ByVal TokenIntegrityLevel, lpBuffer(0), dwSize, dwSize)
If lRet Then
Call CopyMemory(pUser, lpBuffer(0), LenB(pUser))
psaCount = GetSidSubAuthorityCount(pUser.Label.SID)
If psaCount Then
CopyMemory SubAuthority, ByVal psaCount, 4
SubAuthority = SubAuthority - 1
lRet = GetSidSubAuthority(pUser.Label.SID, SubAuthority)
If lRet Then
CopyMemory GetIntegrityLevel, ByVal lRet, 4
End If
End If
End If
Erase lpBuffer()
End If
CloseHandle hToken
End If
End If
End Function
再来c++版
#include<windows.h>
#ifndef _TOKEN_MANDATORY_LABEL
typedef struct _TOKEN_MANDATORY_LABEL {
SID_AND_ATTRIBUTES Label;
} TOKEN_MANDATORY_LABEL, *PTOKEN_MANDATORY_LABEL;
#endif
#ifndef TokenIntegrityLevel
#define TokenIntegrityLevel 0x19
#endif
DWORD GetIntegrityLevel()
{
HANDLE hProcess = NULL, hToken = NULL;
DWORD dwSize = 0, dwRet = 0;
PTOKEN_MANDATORY_LABEL pTokenInfo = NULL;
hProcess = GetCurrentProcess();
if (hProcess != NULL)
{
OpenProcessToken(hProcess, TOKEN_QUERY | TOKEN_QUERY_SOURCE, &hToken);
if (hToken != NULL)
{
GetTokenInformation(hToken,TokenIntegrityLevel , NULL, 0, &dwSize);
if (dwSize != 0)
{
pTokenInfo = (PTOKEN_MANDATORY_LABEL)LocalAlloc(0, dwSize);
dwRet = GetTokenInformation(hToken,TokenIntegrityLevel , pTokenInfo, dwSize, &dwSize);
if (dwRet != 0)
{
dwRet = *GetSidSubAuthority(pTokenInfo->Label.Sid, *GetSidSubAuthorityCount(pTokenInfo->Label.Sid) - 1);
}
LocalFree(pTokenInfo);
}
CloseHandle(hToken);
}
}
return dwRet;
}
int main()
{
printf("%d\n",GetIntegrityLevel());
system("pause");
return 1;
}
现在的问题是需要在驱动里面实现,乍一碰到,有点手麻,不知道杂去搜索。可以想到搜出来的内容要是没点关键词那肯定是毛用都没。
既然没办法了,那就自己手动分析处理。
先看关键函数GetSidSubAuthority,一搜知道是advapi32.dll里面的。那么来看看。代码如下
.text:77DB5550 ; PDWORD __stdcall GetSidSubAuthority(PSID pSid, DWORD nSubAuthority)
.text:77DB5550 public _GetSidSubAuthority@8
.text:77DB5550 _GetSidSubAuthority@8 proc near ; DATA XREF: .text:off_77DA16CCo
.text:77DB5550
.text:77DB5550 pSid = dword ptr 8
.text:77DB5550 nSubAuthority = dword ptr 0Ch
.text:77DB5550
.text:77DB5550 mov edi, edi
.text:77DB5552 push ebp
.text:77DB5553 mov ebp, esp
.text:77DB5555 push 0 ; dwErrCode
.text:77DB5557 call ds:__imp__SetLastError@4 ; SetLastError(x)
.text:77DB555D pop ebp
.text:77DB555E jmp ds:__imp__RtlSubAuthoritySid@8 ; RtlSubAuthoritySid(x,x)
.text:77DB555E _GetSidSubAuthority@8 endp
还真是够简单的。啥也没有,直接就是调用 RtlSubAuthoritySid
心想这下有更进一步的关键词了。下来看看 ntkrnlpa.exe(我在xp里实验) 其他环境得(ntoskrnl.exe)
看了一下导出表如下
序列 地址 名字
00000486 00456160 RtlSplay
00000487 00511E3C RtlStringFromGUID
00000488 0050BF36 RtlSubAuthorityCountSid
00000489 0050BF1E RtlSubAuthoritySid
0000048A 004562F0 RtlSubtreePredecessor
0000048B 004562CC RtlSubtreeSuccessor
0000048C 00454DDE RtlTestBit
心里想肯定就是它了。同样的方法OpenProcessToken和GetTokenInformation也可以进一步的得到
ZwOpenProcessTokenEx和ZwQueryInformationToken
于是就有了完整的代码如下:
BOOLEAN IsSystemIntegrity(HANDLE pid)
{
NTSTATUS ret;
PEPROCESS proc;
HANDLE hProcHandle;
HANDLE hToken;
BOOLEAN bSystemIntegrity = FALSE;
ULONG size;
TOKEN_MANDATORY_LABEL *pLabel;
DWORD dwIntegrityLevel = 0;
if (NT_SUCCESS(ret = PsLookupProcessByProcessId(pid, &proc)))
{
if (NT_SUCCESS(ret = ObOpenObjectByPointer(proc, OBJ_KERNEL_HANDLE, NULL, 0, *PsProcessType, KernelMode, &hProcHandle)))
{
if (NT_SUCCESS(ret = ZwOpenProcessTokenEx(hProcHandle, TOKEN_QUERY, OBJ_KERNEL_HANDLE, &hToken)))
{
if (STATUS_BUFFER_TOO_SMALL == (ret = ZwQueryInformationToken(hToken, TokenIntegrityLevel, NULL, 0, &size)))
{
if (pLabel = ExAllocatePoolWithTag( PagedPool ,size,'_EL_'))
{
if (NT_SUCCESS(ret = ZwQueryInformationToken(hToken, TokenIntegrityLevel, pLabel, size, &size)))
{
dwIntegrityLevel = *RtlSubAuthoritySid(pLabel->Label.Sid,(DWORD)(UCHAR)(*RtlSubAuthorityCountSid(pLabel->Label.Sid)-1));
DbgPrint(("DEMO:%-4d [INFO] dwIntegrityLevel = %d.\n", __LINE__,dwIntegrityLevel));
if (SECURITY_MANDATORY_SYSTEM_RID == dwIntegrityLevel)
bSystemIntegrity = TRUE;
}
ExFreePoolWithTag(pLabel, '_EL_');
}
}
}
}
}
return bSystemIntegrity;
}
HANDLE PsGetSystemSvchost()
{
NTSTATUS ret = STATUS_SUCCESS;
PSYSTEM_PROCESS_INFORMATION pInfo = NULL, buf;
ULONG len = 0;
HANDLE dwPid = 0;
ULONG os;
PsGetVersion(NULL, NULL, &os, NULL);
if (STATUS_INFO_LENGTH_MISMATCH == (ret = ZwQuerySystemInformation(SystemProcessesAndThreadsInformation, pInfo, len, &len)))
{
if (!(pInfo = (PSYSTEM_PROCESS_INFORMATION)ExAllocatePoolWithTag(NonPagedPool, len, '_EL_')))
{
DbgPrint(("DEMO:%-4d [ERRO] ExAllocatePoolWithTag failed with size %d.\n", __LINE__, len));
}
else
{
buf = pInfo;
if (NT_SUCCESS(ret = ZwQuerySystemInformation(SystemProcessesAndThreadsInformation, pInfo, len, &len)))
{
for (;;)
{
LPWSTR pszProcessName = pInfo->ImageName.Buffer;
if (pszProcessName == NULL)
pszProcessName = L"NULL";
if (_wcsnicmp(pszProcessName,L"svchost.exe",wcslen(L"svchost.exe")) == 0)
{
if (os < 6000)
{
dwPid = pInfo->ProcessId;
break;
}
else
{
if (IsSystemIntegrity(pInfo->ProcessId))
{
dwPid = pInfo->ProcessId;
break;
}
}
}
if (!pInfo->NextEntryOffset)
break;
pInfo = (PSYSTEM_PROCESS_INFORMATION)(((PUCHAR)pInfo) + pInfo->NextEntryOffset);
}
}
ExFreePoolWithTag(buf, '_EL_');
}
}
else
{
DbgPrint(("DEMO:%-4d [ERRO] ZwQuerySystemInformation failed with 0x%p.\n", __LINE__, ret));
}
return dwPid;
}
事后根据自己写好的关键词去一搜索,哎呀,网上还真不少。都是自己孤漏寡闻。
写代码的事情就是这个样子,自认为需要研究的东西,或者是自己觉的很有难度的东西,曾经在n年前,都被n个大牛研究的烂了,都不稀罕研究了
写代码最大的悲哀或许就是如此~没啥成就感。。。
|
评分
-
查看全部评分
|