如前文所述,提权后的管理员还是不尽拥有一些Privilege,前文留下了2个问题,第一个如 "如何将提权后的某些DIsabled 状态的Privilege改为abled呢?"先不在本文给予答复,
第二个问题:"怎么添加那些没有的,即无中生有呢?",这就是本文的任务呢...且慢,我还要抛出一个问题: 就算我拿到了那些 "失落的"Privilege有能有什么用呢? 比如说SE_TCB_NAME,
SE_CREATE_TOKEN_NAME即是本文准备给管理员加上去的,
其中SE_TCB_NAME 的作用,我好像在msdn中发现了微弱的一丝( 可遇不可求 ),比如:
WTSQueryUserToken函数
网页上给予的相关说明
Obtains the primary access token of the logged-on user specified by the session ID. To call this function successfully,
the calling application must be running within the context of the LocalSystem account and have the SE_TCB_NAME privilege.
通过Session ID 获取登录用户的 Primary Token ,想要成功调用这个函数,程序必须运行在LocalSystem 账户下且需要SE_TCB_NAME Privilege
那么其他的呢?...如果有类似的例子望告知在下一下~
好了,进入正题:
// LSA.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <windows.h>
#include <ntsecapi.h>
#include <Sddl.h>
#include <ntstatus.h>
VOID AddPrivilege(LSA_HANDLE handle,LPTSTR privilege)
{
//获取sid
DWORD dwRet1 = 0;
DWORD dwRet2 = 0;
SID_NAME_USE snu ;
NTSTATUS status;
status = LookupAccountName(NULL,
TEXT("admin"),
NULL,
&dwRet1,
NULL,
&dwRet2,
&snu
);
BYTE* pSid = (BYTE*)calloc(dwRet1,1);
if(pSid == NULL)
{
MessageBox(0,TEXT("分配内存产生错误!"),0,0);
ExitProcess(0);
}
TCHAR* pName = (TCHAR*)calloc(dwRet2,sizeof(TCHAR));
if(pName == NULL)
{
MessageBox(0,TEXT("分配内存产生错误!"),0,0);
ExitProcess(0);
}
status = LookupAccountName(NULL,
TEXT("admin"),
(PSID)pSid,
&dwRet1,
pName,
&dwRet2,
&snu
);
LPTSTR str = NULL;
ConvertSidToStringSid(pSid,&str);
_tprintf(str);
LSA_UNICODE_STRING lsaUnicodeString;
lsaUnicodeString.Buffer = privilege ;
lsaUnicodeString.Length = lstrlen(privilege)*sizeof(TCHAR);
lsaUnicodeString.MaximumLength = lsaUnicodeString.Length;
status = LsaAddAccountRights(handle,
pSid,
&lsaUnicodeString,
1
);
if(status != STATUS_SUCCESS)
{
MessageBox(0,TEXT("添加特权Privilege失败"),0,0);
ExitProcess(0);
}
PLSA_UNICODE_STRING plsau = NULL;
DWORD count = 0;
//枚举一次
LsaEnumerateAccountRights(handle,pSid,&plsau,&count);
_tprintf(TEXT("\n"));
for(int i = 0; i < count; i++)
{
_tprintf((plsau + i)->Buffer);
_tprintf(TEXT("\n"));
}
//
LsaFreeMemory(plsau);
FreeSid(str);
free(pSid);
free(pName);
return;
}
VOID RemovePrivilege(LSA_HANDLE handle,LPTSTR privilege)
{
//获取sid
DWORD dwRet1 = 0;
DWORD dwRet2 = 0;
SID_NAME_USE snu ;
NTSTATUS status;
status = LookupAccountName(NULL,
TEXT("admin"),
NULL,
&dwRet1,
NULL,
&dwRet2,
&snu
);
BYTE* pSid = (BYTE*)calloc(dwRet1,1);
if(pSid == NULL)
{
MessageBox(0,TEXT("内存分配失败"),0,0);
ExitProcess(0);
}
TCHAR* pName = (TCHAR*)calloc(dwRet2,sizeof(TCHAR));
if(pName == NULL)
{
MessageBox(0,TEXT("内存分配失败"),0,0);
ExitProcess(0);
}
status = LookupAccountName(NULL,
TEXT("admin"),
(PSID)pSid,
&dwRet1,
pName,
&dwRet2,
&snu
);
LPTSTR str = NULL;
ConvertSidToStringSid(pSid,&str);
_tprintf(str);
LSA_UNICODE_STRING lsaUnicodeString2;
lsaUnicodeString2.Buffer = privilege;
lsaUnicodeString2.Length = lstrlen(privilege)*sizeof(TCHAR);
lsaUnicodeString2.MaximumLength = lsaUnicodeString2.Length;
status=LsaRemoveAccountRights(handle,
pSid,
FALSE,
&lsaUnicodeString2,
1
);
if(status != STATUS_SUCCESS)
{
MessageBox(0,TEXT("删除特权Privilege失败"),0,0);
ExitProcess(0);
}
//枚举一次
PLSA_UNICODE_STRING plsau = NULL;
DWORD count = 0;
LsaEnumerateAccountRights(handle,pSid,&plsau,&count);
_tprintf(TEXT("\n"));
for(int i = 0; i < count; i++)
{
_tprintf((plsau + i)->Buffer);
_tprintf(TEXT("\n"));
}
//
LsaFreeMemory(plsau);
FreeSid(str);
free(pSid);
free(pName);
return;
}
int _tmain(int argc, _TCHAR* argv[])
{
//opens a handle to the Policy object on a local
LSA_HANDLE handle=NULL;
LSA_OBJECT_ATTRIBUTES loa = {0};
NTSTATUS status = LsaOpenPolicy(NULL,&loa,POLICY_ALL_ACCESS,&handle);
AddPrivilege(handle,SE_CREATE_TOKEN_NAME);
AddPrivilege(handle,SE_TCB_NAME);
//RemovePrivilege(handle,SE_CREATE_TOKEN_NAME);
//RemovePrivilege(handle,SE_TCB_NAME);
LsaClose(handle);
system("pause");
return 0;
}
这个程序得右键管理员运行
还是刚才的那样提权后的Process Explorer.exe
另外成功执行了程序后,你登录的用户帐号获得的新的privilege并不会立刻显现,需要你重启一下机器,
重启了后,你还是得右键管理员运行Process Explorer.exe,然后找到Process Explorer.exe对应的进程,双击进去,
发现这时多了刚才添加的两项
是不是成功添加上去了?并且已经生效了?, 可是这并没有解决 这么做 能有什么用的问题? 这个问题的答案我也不知?可有大侠知?