首页
社区
课程
招聘
转:超越ADMINISTRATOR权限.
发表于: 2005-5-13 17:55 5021

转:超越ADMINISTRATOR权限.

2005-5-13 17:55
5021
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");
  }
}
}

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 1852
活跃值: (504)
能力值: (RANK:1010 )
在线值:
发帖
回帖
粉丝
2
好文,值得深入学习
2005-5-13 18:27
0
雪    币: 162
活跃值: (63)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
蛋蛋兄总算发了篇详细点的了
虽然是转的总算是勤快点了
2005-5-13 19:45
0
游客
登录 | 注册 方可回帖
返回