超越Administrator的权限

NT的安全组件里有一个叫Local Security Authority Protected Subsystem.当我们以ADMINISTRATOR登陆时,系统根据缺省的授权,赋予ADMINISTRATOR16个授权.下面乃是详细的清单. 
 SeChangeNotifyPrivilege 
 SeSecurityPrivilege 
 SeBackupPrivilege 
 SeRestorePrivilege 
 SeSystemtimePrivilege 
 SeShutdownPrivilege 
 SeRemoteShutdownPrivilege 
 SeTakeOwnershipPrivilege 
 SeDebugPrivilege 
 SeSystemEnvironmentPrivilege 
 SeSystemProfilePrivilege 
 SeProfileSingleProcessPrivilege 
 SeIncreaseBasePriorityPrivilege 
 SeLoadDriverPrivilege 
 SeCreatePagefilePrivilege 
 SeIncreaseQuotaPrivilege 
其中 SeChangeNotifyPrivilege是缺省打开的.其他则需要调整TOKEN来打开.拥有了这么多的权限后,ADMIN真可谓强大,没有任何其他用户拥有这么多的权限了.但是,仍然有几个更有威力的权限没有赋予ADMIN.那就是SeTcbPrivilege和SeCreateTokenPrivilege. SeTcbPrivilege表示当前用户的操作代表了系统的操作,SeCreateTokenPrivilege更可赤裸裸地为任意令牌创建权限.乃是无上的特权.如果任何人拥有了这两个权限,在NT世界的权利就太夸张了.所以,NT根本就不给任何用户以这两个权限. 
出于对权利的渴望,通常病毒,HACKER都会想法获取最高权限.现在,由于NT的保护,直接地获取这2个权限是不行了.那么就需要饶个弯子了. 
由于没有直接的API可以增加TOKEN的特权,我们只好通过LSA POLICY库调整用户权限.因为用户权限在LSA POLICY库里被提取出来.当LSA POLICY库里增加了一个特权,用户可以在下一个进程里打开该特权.HEHE... ADMIN组对LSA POLICY库有写权.:DDD ADMIN没有超级特权,LSA对用户的特权从POLICY库里提取... 真是个可爱的连环套啊. :) 
下面是我写的程序,打开ADMINISTRATOR的SeTcbPrivilege特权.尽管我在程序里面设置了ADMIN检查,但是通过少量的改写就可以时普通用户获取一些超级权限.:)里面的小技巧大家自己通常可以动出脑筋的.当然并不是通过删除ADMINISTRATOR检验就可以完成的. :) 
当然,这里有编译好的版本供下载. 
/*++ 
sec.cpp 

  Written by Lu Lin. 2000.1.30 

  A security program demo. 
  Show Administrator's SID, and privileges. 
  At last we add SE_TCB_NAME right to administrator. 
  Of course, this right is almost useless to administrator, 
  but you can port it for other users. :) 
  You should logon as administrator for run this program 
  though ADMIN group's authority is enough. 
  Tip: We may get a authority beyound admin for a normal 
  user through this demo by a small trick. Think about it 
  yourself.:) 
--*/ 

#define UNICODE 
#include <windows.h> 
#include <iostream.h> 
#include <stdio.h> 
#include <ntsecapi.h> 

// 
//Global vars 
// 
LSA_HANDLE PolicyHandle; 
PSID Sid=0; 
DWORD cbSid=0; 
LPTSTR ReferencedDomainName=0; 
DWORD cbReferencedDomainName=0; 
SID_NAME_USE peUse; 
PUNICODE_STRING UserRights=0; //UnicodeString Pointer to PRIVILEGE 
ULONG Count=0; // 
WCHAR textSid[200]; 
HANDLE token=0; 
PTOKEN_PRIVILEGES TokenInformation=0; 
BOOL owned=0; 

// 
//quit 
// 
void quit(int err){ 
 if (Sid) delete Sid; 
 if (ReferencedDomainName) delete ReferencedDomainName; 
 if (UserRights) delete UserRights; 
 if (TokenInformation) delete TokenInformation; 
 if (token) CloseHandle(token); 
 if (PolicyHandle) LsaClose(PolicyHandle); 

 wprintf(L"\n\nWritten by Lu Lin. 2000.1.30\nLicence: Freeware.\n"); 

 if (err){ 
  exit(0xc0000000); 
 } 
 else { 
  exit(0); 
 } 


void printprivilege(LUID_AND_ATTRIBUTES* luid){ 
 WCHAR dispname[100]; 
 ULONG cb=100; 

 if (!LookupPrivilegeName( 
  0, 
  &(luid->Luid), 
  dispname, 
  &cb)){ 
  wprintf(L"I can't translate SOME LUID to privilege!\n"); 
  exit(1); 
 } 

 wprintf(L"\tPrivilege: %s\n",dispname); 

 if (!_wcsicmp(dispname,L"SeTcbPrivilege")) owned=1; 

 switch (luid->Attributes){ 
 case SE_PRIVILEGE_ENABLED_BY_DEFAULT: 
  wprintf(L"\t\tThis privilege is enabled by default\n"); 
  break; 
 case SE_PRIVILEGE_ENABLED: 
  wprintf(L"\t\tThis privilege is enabled.\n"); 
  break; 
 case SE_PRIVILEGE_USED_FOR_ACCESS: 
  wprintf(L"\t\tThis privilege is used for access.\n"); 
  break; 
 case 3: 
  wprintf(L"\t\tThis privilege is always on for you.\n"); 
  break; 
 case 0: 
  wprintf(L"\t\tThis privilege you owned has not been enabled yet.\n"); 
 } 


void init(){ 
 WCHAR username[30]; 
 ULONG cb; 
 OSVERSIONINFO osv; 

 //if nt? 
 ZeroMemory(&osv,sizeof(osv)); 
 osv.dwOSVersionInfoSize=sizeof(osv); 
 GetVersionEx(&osv); 
 if (!osv.dwPlatformId&VER_PLATFORM_WIN32_NT){ 
  wprintf(L"This program only runs on NT"); 
  quit(1); 
 } 

 // 
 //Check if this thread is executed inside administrator's context. 
 // 
 cb=30; 
 GetUserName(username,&cb); 
 if (_wcsicmp(username,L"administrator")){ 
  wprintf(L"Logon as administrator first!\n"); 
  quit(1); 
 } 

 wprintf(L"WINDOWS NT %i.%i Build %i %s\n\n", 
  osv.dwMajorVersion, 
  osv.dwMinorVersion, 
  osv.dwBuildNumber, 
  osv.szCSDVersion); 


BOOL GetTextualSid( 
    PSID pSid,            // binary Sid 
    LPTSTR TextualSid,    // buffer for Textual representation of Sid 
    DWORD dwBufferLen // required/provided TextualSid buffersize 
    ) 

    PSID_IDENTIFIER_AUTHORITY psia; 
    DWORD dwSubAuthorities; 
    DWORD dwSidRev=SID_REVISION; 
    DWORD dwCounter; 
    DWORD dwSidSize; 

    // Validate the binary SID. 

    if(!IsValidSid(pSid)) return FALSE; 

    // Get the identifier authority value from the SID. 

    psia = GetSidIdentifierAuthority(pSid); 

    // Get the number of subauthorities in the SID. 

    dwSubAuthorities = *GetSidSubAuthorityCount(pSid); 

    // Compute the buffer length. 
    // S-SID_REVISION- + IdentifierAuthority- + subauthorities- + NULL 

    dwSidSize=(15 + 12 + (12 * dwSubAuthorities) + 1) * sizeof(TCHAR); 

    // Check input buffer length. 
    // If too small, indicate the proper size and set last error. 

    if (dwBufferLen < dwSidSize) 
    { 
        SetLastError(ERROR_INSUFFICIENT_BUFFER); 
        return FALSE; 
    } 

    // Add 'S' prefix and revision number to the string. 

    dwSidSize=wsprintf(TextualSid, TEXT("S-%lu-"), dwSidRev ); 

    // Add SID identifier authority to the string. 

    if ( (psia->Value[0] != 0) || (psia->Value[1] != 0) ) 
    { 
        dwSidSize+=wsprintf(TextualSid + lstrlen(TextualSid), 
                    TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"), 
                    (USHORT)psia->Value[0], 
                    (USHORT)psia->Value[1], 
                    (USHORT)psia->Value[2], 
                    (USHORT)psia->Value[3], 
                    (USHORT)psia->Value[4], 
                    (USHORT)psia->Value[5]); 
    } 
    else 
    { 
        dwSidSize+=wsprintf(TextualSid + lstrlen(TextualSid), 
                    TEXT("%lu"), 
                    (ULONG)(psia->Value[5]      )   + 
                    (ULONG)(psia->Value[4] <<  8)   + 
                    (ULONG)(psia->Value[3] << 16)   + 
                    (ULONG)(psia->Value[2] << 24)   ); 
    } 

    // Add SID subauthorities to the string. 
    // 
    for (dwCounter=0 ; dwCounter < dwSubAuthorities ; dwCounter++) 
    { 
        dwSidSize+=wsprintf(TextualSid + dwSidSize, TEXT("-%lu"), 
                    *GetSidSubAuthority(pSid, dwCounter) ); 
    } 

    return TRUE; 


void main(){ 
 LSA_OBJECT_ATTRIBUTES ObjectAttributes; 
 ZeroMemory(&ObjectAttributes,sizeof(ObjectAttributes)); 

 init(); 
 // 
 //First open LSA policy database 
 //the call returns a NTSTATUS. NTSTATUS 0 means everything is OK. 
 // 
 if (LsaOpenPolicy( 
                0, 
                &ObjectAttributes, 
                GENERIC_EXECUTE|GENERIC_READ|GENERIC_WRITE, 
                &PolicyHandle 
                )){ 
  wprintf(L"Open Policy error!\n"); 
 } 
 else { 
  Sid=new char[500]; 
  ReferencedDomainName=new WCHAR[100]; 
  cbSid=500; 
  cbReferencedDomainName=100; 

  // 
  //Show Administrator SID 
  // 
  if (!LookupAccountName( 
   0, 
   L"Administrator", 
   Sid, 
   &cbSid, 
   ReferencedDomainName, 
   &cbReferencedDomainName, 
   &peUse 
   )){ 
   wprintf(L"Damn, I can't find out the account looking for!\n"); 
   quit(1); 
  } 
  if (!GetTextualSid(Sid,textSid,200)){ 
   wprintf(L"Damn, Get textual SID error! Maybe a bug in this program.\n"); 
   quit(1); 
  } 

  wprintf(L"The SID of administrator is: %s \n",textSid); 
  wprintf(L"\tOn the server: %s\n",ReferencedDomainName); 

  // 
  //Check current privilege 
  // 
  if (!OpenProcessToken( 
   GetCurrentProcess(), 
   TOKEN_QUERY, 
   &token)){ 
   wprintf(L"Can't open process token! What's happened?\n"); 
   quit(1); 
  } 

  TokenInformation=(PTOKEN_PRIVILEGES)(new char[2000]); 

  if (!GetTokenInformation( 
   token, 
   TokenPrivileges, 
   (void*)TokenInformation, 
   2000, 
   &cbSid //Note, Returned lenght of token information. 
   )){ 
   wprintf(L"Can't get token information\n"); 
   quit(1); 
  } 
  else{ 
   LUID_AND_ATTRIBUTES *luid; 
   luid=(LUID_AND_ATTRIBUTES *)&TokenInformation->Privileges; 

   wprintf(L"\nTotal privilege count: %i\n\n",TokenInformation->PrivilegeCount); 
   for (Count=0;Count<TokenInformation->PrivilegeCount; 
    Count++,luid++){ 
    printprivilege(luid); 
   } 
  } 

  // 
  //Add SeTchPrivilege to Administrator if not owned yet! 
  // 
  if (!owned){ 
   UserRights=new LSA_UNICODE_STRING; 
   UserRights->Buffer=L"SeTcbPrivilege"; 
   UserRights->MaximumLength=28; 
   UserRights->Length=28; 

   if (LsaAddAccountRights( 
    PolicyHandle, 
    Sid, 
    UserRights, 
    1 
    )){ 
    wprintf(L"Damn! Add right failed! :(\n"); 
    quit(1); 
   } 
   else wprintf(L"\nAdd SeTcbPrivilege successfully!\n"); 

   quit(0); 
  } 
  else { 
   wprintf(L"\nYou own SeTcbPrivilege. I don't add it for you.\n"); 
  } 
 } 


超链接

猜你喜欢

转载自blog.csdn.net/weifddx/article/details/40073093
今日推荐