通行证│用户名: 密码: 验证码: 验证码,看不清楚?请点击刷新验证码 电信网通铁通移动   在线
文章搜索:
热门搜索:红客 黑鹰 红客技术 安全动画 红客培训
首页 文章 软件 动画 资源 励志 论坛 邮箱 会员 军事 科技 博客 爱心红客 最近更新 800g资源
 业内新闻 漏洞公告 病毒公告 电脑知识 网络知识 菜鸟入门 攻防教程 黑客攻防 安全编程 工具使用 综合安全 个人安全 安全相关 Q Q安全 原创精华 红客人物 站内事件
您现在的位置: 爱国者安全网 >> 文章类 >> 红客教程 >> 网络编程 >> 文章正文
创建高权限进程的方法
责任编辑:水土不服   更新日期:2007-1-30
 

写这个初衷是为了让 Windows 任务管理器可以结束掉一些服务和僵死进程,用 pslist/pskill 之类工具无法获得象任务管理器那样丰富的信息,还得来回切换,麻烦的很。最初想写个驱动监视任务管理器运行,使用 SYSTEM 进程 TOKEN 替换来达到目的。

后来觉得通用性不好,就改用了这种方法。此方法还可使Regedit查看、编辑 SAM 等注册表键,何乐而不为。






// wssrun taskmgr.exe 
// wssrun regedit.exe 
// 


#include 
#include 
#include 
#include 
#include 
#include 
#include 

#pragma comment(lib,"Shlwapi.lib") 


///////////////////////////////////////////////////////////////// 
// 函数类型 :自定义工具函数 
// 函数模块 : 
//////////////////////////////////////////////////////////////// 
// 功能 :提升当前进程权限 
// 注意 : 
///////////////////////////////////////////////////////////////// 
// 作者 : sinister 
// 发布版本 : 1.00.00 
// 发布日期 : 2006.2.09 
///////////////////////////////////////////////////////////////// 
// 重   大   修   改   历   史 
//////////////////////////////////////////////////////////////// 
// 修改者 : 
// 修改日期 : 
// 修改内容 : 
///////////////////////////////////////////////////////////////// 

BOOL 
EnableDebugPriv( LPCTSTR szPrivilege ) 
{ 
HANDLE hToken; 
LUID sedebugnameValue; 
TOKEN_PRIVILEGES tkp; 

if ( !OpenProcessToken( GetCurrentProcess(), 
                TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, 
                &hToken ) ) 
{ 
  return FALSE; 
} 
if ( !LookupPrivilegeValue( NULL, szPrivilege, &sedebugnameValue ) ) 
{ 
  CloseHandle( hToken ); 
  return FALSE; 
} 

tkp.PrivilegeCount = 1; 
tkp.Privileges[0].Luid = sedebugnameValue; 
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 

if ( !AdjustTokenPrivileges( hToken, FALSE, &tkp, sizeof tkp, NULL, NULL ) ) 
{ 
  CloseHandle( hToken ); 
  return FALSE; 
} 

return TRUE; 
} 

///////////////////////////////////////////////////////////////// 
// 函数类型 :自定义工具函数 
// 函数模块 : 
//////////////////////////////////////////////////////////////// 
// 功能 :通过指定进程名得到其进程 ID 
// 注意 : 
///////////////////////////////////////////////////////////////// 
// 作者 : sinister 
// 发布版本 : 1.00.00 
// 发布日期 : 2006.2.09 
///////////////////////////////////////////////////////////////// 
// 重   大   修   改   历   史 
//////////////////////////////////////////////////////////////// 
// 修改者 : 
// 修改日期 : 
// 修改内容 : 
///////////////////////////////////////////////////////////////// 

DWORD 
GetProcessId( LPCTSTR szProcName ) 
{ 
PROCESSENTRY32 pe;   
DWORD dwPid; 
DWORD dwRet; 
BOOL bFound = FALSE; 

// 
// 通过 TOOHLP32 函数枚举进程 
// 

HANDLE hSP = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ); 
if ( hSP ) 
{ 
  pe.dwSize = sizeof( pe ); 

  for ( dwRet = Process32First( hSP, &pe ); 
      dwRet; 
      dwRet = Process32Next( hSP, &pe ) ) 
  { 
    // 
    // 使用 StrCmpNI 比较字符传,可忽略大小写 
    // 
    if ( StrCmpNI( szProcName, pe.szExeFile, strlen( szProcName ) ) == 0 ) 
    { 
    dwPid = pe.th32ProcessID; 
    bFound = TRUE; 
    break; 
    } 
  } 

  CloseHandle( hSP ); 

  if ( bFound == TRUE ) 
  { 
    return dwPid; 
  } 
} 

return NULL; 
} 

///////////////////////////////////////////////////////////////// 
// 函数类型 :自定义工具函数 
// 函数模块 : 
//////////////////////////////////////////////////////////////// 
// 功能 : 创建具有高权限的进程 
// 注意 : 
///////////////////////////////////////////////////////////////// 
// 作者 : sinister 
// 发布版本 : 1.00.00 
// 发布日期 : 2006.2.09 
///////////////////////////////////////////////////////////////// 
// 重   大   修   改   历   史 
//////////////////////////////////////////////////////////////// 
// 修改者 : 
// 修改日期 : 
// 修改内容 : 
///////////////////////////////////////////////////////////////// 

BOOL 
CreateSystemProcess( LPTSTR szProcessName ) 
{ 
HANDLE hProcess; 
HANDLE hToken, hNewToken; 
DWORD dwPid; 

PACL pOldDAcl = NULL; 
PACL pNewDAcl = NULL; 
BOOL bDAcl; 
BOOL bDefDAcl; 
DWORD dwRet; 

PACL pSacl = NULL; 
PSID pSidOwner = NULL; 
PSID pSidPrimary = NULL; 
DWORD dwAclSize = 0; 
DWORD dwSaclSize = 0; 
DWORD dwSidOwnLen = 0; 
DWORD dwSidPrimLen = 0; 

DWORD dwSDLen; 
EXPLICIT_ACCESS ea; 
PSECURITY_DESCRIPTOR pOrigSd = NULL; 
PSECURITY_DESCRIPTOR pNewSd = NULL; 

STARTUPINFO si; 
PROCESS_INFORMATION pi; 

BOOL bError; 

if ( !EnableDebugPriv( "SeDebugPrivilege" ) ) 
{ 
  printf( "EnableDebugPriv() to failed!\n" ); 

  bError = TRUE; 
  goto Cleanup; 
} 

// 
// 选择 WINLOGON 进程 
// 
if ( ( dwPid = GetProcessId( "WINLOGON.EXE" ) ) == NULL ) 
{ 
  printf( "GetProcessId() to failed!\n" );   

  bError = TRUE; 
  goto Cleanup; 
} 

hProcess = OpenProcess( PROCESS_QUERY_INFORMATION, FALSE, dwPid ); 
if ( hProcess == NULL ) 
{ 
  printf( "OpenProcess() = %d\n", GetLastError() );   

  bError = TRUE; 
  goto Cleanup; 
} 

if ( !OpenProcessToken( hProcess, READ_CONTROL | WRITE_DAC, &hToken ) ) 
{ 
  printf( "OpenProcessToken() = %d\n", GetLastError() ); 

  bError = TRUE; 
  goto Cleanup; 
} 

// 
// 设置 ACE 具有所有访问权限 
// 
ZeroMemory( &ea, sizeof( EXPLICIT_ACCESS ) ); 
BuildExplicitAccessWithName( &ea, 
                    "Everyone", 
                    TOKEN_ALL_ACCESS, 
                    GRANT_ACCESS, 
                    0 ); 

if ( !GetKernelObjectSecurity( hToken, 
                      DACL_SECURITY_INFORMATION, 
                      pOrigSd, 
                      0, 
                      &dwSDLen ) ) 
{ 
  // 
  // 第一次调用给出的参数肯定返回这个错误,这样做的目的是 
  // 为了得到原安全描述符 pOrigSd 的长度 
  // 
  if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER ) 
  { 
    pOrigSd = ( PSECURITY_DESCRIPTOR ) HeapAlloc( GetProcessHeap(), 
                                  HEAP_ZERO_MEMORY, 
                                  dwSDLen ); 
    if ( pOrigSd == NULL ) 
    { 
    printf( "Allocate pSd memory to failed!\n" ); 

    bError = TRUE; 
    goto Cleanup; 
    } 

    // 
    // 再次调用才正确得到安全描述符 pOrigSd 
    // 
    if ( !GetKernelObjectSecurity( hToken, 
                        DACL_SECURITY_INFORMATION, 
                        pOrigSd, 
                        dwSDLen, 
                        &dwSDLen ) ) 
    { 
    printf( "GetKernelObjectSecurity() = %d\n", GetLastError() ); 
    bError = TRUE; 
    goto Cleanup; 
    } 
  } 
  else 
  { 
    printf( "GetKernelObjectSecurity() = %d\n", GetLastError() ); 
    bError = TRUE; 
    goto Cleanup; 
  } 
} 

// 
// 得到原安全描述符的访问控制列表 ACL 
// 
if ( !GetSecurityDescriptorDacl( pOrigSd, &bDAcl, &pOldDAcl, &bDefDAcl ) ) 
{ 
  printf( "GetSecurityDescriptorDacl() = %d\n", GetLastError() ); 

  bError = TRUE; 
  goto Cleanup; 
} 

// 
// 生成新 ACE 权限的访问控制列表 ACL 
// 
dwRet = SetEntriesInAcl( 1, &ea, pOldDAcl, &pNewDAcl ); 
if ( dwRet != ERROR_SUCCESS ) 
{ 
  printf( "SetEntriesInAcl() = %d\n", GetLastError() ); 
  pNewDAcl = NULL; 

  bError = TRUE; 
  goto Cleanup; 
} 

if ( !MakeAbsoluteSD( pOrigSd, 
                pNewSd, 
                &dwSDLen, 
                pOldDAcl, 
                &dwAclSize, 
                pSacl, 
                &dwSaclSize, 
                pSidOwner, 
                &dwSidOwnLen, 
                pSidPrimary, 
                &dwSidPrimLen ) ) 
{ 
  // 
  // 第一次调用给出的参数肯定返回这个错误,这样做的目的是 
  // 为了创建新的安全描述符 pNewSd 而得到各项的长度 
  // 
  if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER ) 
  { 
    pOldDAcl = ( PACL ) HeapAlloc( GetProcessHeap(), 
                        HEAP_ZERO_MEMORY, 
                        dwAclSize ); 
    pSacl = ( PACL ) HeapAlloc( GetProcessHeap(), 
                      HEAP_ZERO_MEMORY, 
                      dwSaclSize ); 
    pSidOwner = ( PSID ) HeapAlloc( GetProcessHeap(), 
                        HEAP_ZERO_MEMORY, 
                        dwSidOwnLen ); 
    pSidPrimary = ( PSID ) HeapAlloc( GetProcessHeap(), 
                          HEAP_ZERO_MEMORY, 
                          dwSidPrimLen ); 
    pNewSd = ( PSECURITY_DESCRIPTOR ) HeapAlloc( GetProcessHeap(), 
                                  HEAP_ZERO_MEMORY, 
                                  dwSDLen ); 

    if ( pOldDAcl == NULL || 
      pSacl == NULL || 
      pSidOwner == NULL || 
      pSidPrimary == NULL || 
      pNewSd == NULL ) 
    { 
    printf( "Allocate SID or ACL to failed!\n" ); 

    bError = TRUE; 
    goto Cleanup; 
    } 

    // 
    // 再次调用才可以成功创建新的安全描述符 pNewSd 
    // 但新的安全描述符仍然是原访问控制列表 ACL 
    // 
    if ( !MakeAbsoluteSD( pOrigSd, 
                  pNewSd, 
                  &dwSDLen, 
                  pOldDAcl, 
                  &dwAclSize, 
                  pSacl, 
                  &dwSaclSize, 
                  pSidOwner, 
                  &dwSidOwnLen, 
                  pSidPrimary, 
                  &dwSidPrimLen ) ) 
    { 
    printf( "MakeAbsoluteSD() = %d\n", GetLastError() ); 

    bError = TRUE; 
    goto Cleanup; 
    } 
  } 
  else 
  { 
    printf( "MakeAbsoluteSD() = %d\n", GetLastError() ); 

    bError = TRUE; 
    goto Cleanup; 
  } 
} 

// 
// 将具有所有访问权限的访问控制列表 pNewDAcl 加入到新的 
// 安全描述符 pNewSd 中 
// 
if ( !SetSecurityDescriptorDacl( pNewSd, bDAcl, pNewDAcl, bDefDAcl ) ) 
{ 
  printf( "SetSecurityDescriptorDacl() = %d\n", GetLastError() ); 

  bError = TRUE; 
  goto Cleanup; 
} 

// 
// 将新的安全描述符加到 TOKEN 中 
// 
if ( !SetKernelObjectSecurity( hToken, DACL_SECURITY_INFORMATION, pNewSd ) ) 
{ 
  printf( "SetKernelObjectSecurity() = %d\n", GetLastError() ); 

  bError = TRUE; 
  goto Cleanup; 
} 

// 
// 再次打开 WINLOGON 进程的 TOKEN,这时已经具有所有访问权限 
// 
if ( !OpenProcessToken( hProcess, TOKEN_ALL_ACCESS, &hToken ) ) 
{ 
  printf( "OpenProcessToken() = %d\n", GetLastError() );   

  bError = TRUE; 
  goto Cleanup; 
} 

// 
// 复制一份具有相同访问权限的 TOKEN 
// 
if ( !DuplicateTokenEx( hToken, 
                TOKEN_ALL_ACCESS, 
                NULL, 
                SecurityImpersonation, 
                TokenPrimary, 
                &hNewToken ) ) 
{ 
  printf( "DuplicateTokenEx() = %d\n", GetLastError() );   

  bError = TRUE; 
  goto Cleanup; 
} 


ZeroMemory( &si, sizeof( STARTUPINFO ) ); 
si.cb = sizeof( STARTUPINFO ); 

// 
// 不虚拟登陆用户的话,创建新进程会提示 
// 1314 客户没有所需的特权错误 
// 
ImpersonateLoggedOnUser( hNewToken ); 


// 
// 我们仅仅是需要建立高权限进程,不用切换用户 
// 所以也无需设置相关桌面,有了新 TOKEN 足够 
// 


// 
// 利用具有所有权限的 TOKEN,创建高权限进程 
// 
if ( !CreateProcessAsUser( hNewToken, 
                  NULL, 
                  szProcessName, 
                  NULL, 
                  NULL, 
                  FALSE, 
                  NULL, //NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE, 
                  NULL, 
                  NULL, 
                  &si, 
                  &pi ) ) 
{ 
  printf( "CreateProcessAsUser() = %d\n", GetLastError() );   

  bError = TRUE; 
  goto Cleanup; 
} 

bError = FALSE; 

Cleanup: 
if ( pOrigSd ) 
{ 
  HeapFree( GetProcessHeap(), 0, pOrigSd ); 
} 
if ( pNewSd ) 
{ 
  HeapFree( GetProcessHeap(), 0, pNewSd ); 
} 
if ( pSidPrimary ) 
{ 
  HeapFree( GetProcessHeap(), 0, pSidPrimary ); 
} 
if ( pSidOwner ) 
{ 
  HeapFree( GetProcessHeap(), 0, pSidOwner ); 
} 
if ( pSacl ) 
{ 
  HeapFree( GetProcessHeap(), 0, pSacl ); 
} 
if ( pOldDAcl ) 
{ 
  HeapFree( GetProcessHeap(), 0, pOldDAcl ); 
} 

CloseHandle( pi.hProcess ); 
CloseHandle( pi.hThread ); 
CloseHandle( hToken ); 
CloseHandle( hNewToken ); 
CloseHandle( hProcess ); 

if ( bError ) 
{ 
  return FALSE; 
} 

return TRUE; 
} 


void 
main( int argc, char** argv ) 
{ 
if ( argc 〈 2 ) 
{ 
  printf( "Usage: wssrun \n" ); 
  return ; 
} 

if ( CreateSystemProcess( argv[1] ) == FALSE ) 
{ 
  printf( "wssrun: CreateSystemProcess() to failed!\n" ); 
  return ; 
} 
}

【以上内容,仅供参考!】

  • 上一篇文章:
  • 下一篇文章:
  • 最近更新
    固顶文章 爱国者安全网2007年度优秀版主评选
    普通文章 瑞星公司01月11日发布 每日计算机病毒及木马播报
    普通文章 破解博彩神助(专注彩票) V2.8.01
    推荐文章 推荐:跨站脚本执行漏洞代码的六点思路
    普通文章 Windows系统下的远程堆栈溢出 实战篇
    普通文章 Windows系统下的远程堆栈溢出 原理篇
    普通文章 MsSQLServer是如何加密口令的
    普通文章 浅谈国内的渗透评估过程
    普通文章 Dvbbs8.1 0DAY(通杀Access和mssql版本)
    普通文章 微软:我们的代码比赛门铁克更安全
    热门文章
    普通文章REAL蛀虫利用播放器漏洞下载恶意程序
    普通文章李彦宏:中国要在互联网领域逐渐超越美国
    普通文章马云:阿里巴巴的成功是一个生态链的成功
    普通文章Ingres用户认证非授权访问漏洞
    普通文章TCPreen FD_SET()函数远程栈溢出漏洞
    普通文章Winace UUE文件解压堆溢出漏洞
    普通文章Pclxav木马猎手第一代特征码引擎源代码
    普通文章IE收藏夹管理小精灵算法分析
    普通文章Extra Drive Pro算法分析历程
    普通文章雨过天晴自我注册
    精彩专题