1   1  /  1  页   跳转

创建高权限进程

创建高权限进程

文件名    : wssrun.c
  描述    : 创建高权限进程


*****************************************************************/


//
// 写这个初衷是为了让 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 ;
  }
}




WSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。


用户系统信息:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 1.7; TencentTraveler 4.0; (R1 1.5))
爱交朋友
有什么问题我能帮忙的我一定帮你解答,解决
-----------------------------------------------
天生我材必有用,DZ和PHP程序/ASP整站/图像制作/电脑技术与故障解决/专业技术交流/谈天说地
分享到:
gototop
 

回复:创建高权限进程

这都是楼主自己写的啊~~真牛~~
gototop
 

回复 2F 银色灰烬 的帖子

会编程的都会
这个是基础
爱交朋友
有什么问题我能帮忙的我一定帮你解答,解决
-----------------------------------------------
天生我材必有用,DZ和PHP程序/ASP整站/图像制作/电脑技术与故障解决/专业技术交流/谈天说地
gototop
 

回复:创建高权限进程

转帖请注明。
这个代码早就满天飞了
病毒样本请发到可疑文件交流区
gototop
 

回复:创建高权限进程

厉害啊!我也很想学编程,无处入手,请高手指教。是不是学好了英文就能学编程的?我怎么学也学不会,怎么办啊!

一点点的激情,一点点的执着,让我一步一步的走入了自己梦寐以求的行业。从一个学校里年少轻狂的孩子,成为了一名信息安全的研发工程师。从只知道写代码,真正开始慢慢的去思考、设计和实现一种技术、一种算法、一个模块、一个软件乃至一个系统。
人生本来就该不断的追求梦想,不断的跨过一个又一个不可能穿越的鸿沟。别人看来,我很疯狂,但我笑了,人生能有几回疯?真正疯狂的人是不计后果的向前冲的,至少我还不是。我所想的,只是别人不敢想的。我所做的,只是别人不敢做的。一个一个虚无缥缈的事物,都必须是有一个一个疯狂的人逐渐的具体和完善。但愿我是这样的人,我只愿做这样的人。
gototop
 

回复:创建高权限进程

我的天,原来楼主还是这样的高手啊!
幸福是奋斗出来的!
gototop
 

回复:创建高权限进程

该用户帖子内容已被屏蔽
gototop
 

回复:创建高权限进程

这个代码有问题,wssrun为普通权限有可能无法打开WINLOGON的token(即使调用过AdjustTokenPrivileges,所以这个代码估计只能在xp以下使用,而且代码中的最大bug在于遍历进程时没有判定当前的SessionID,如果系统存在2个以上的WINLOGON时CreateProcessAsUser会将exe起到另一个桌面。总之问题很多。:default9:
最后编辑person997 最后编辑于 2008-11-07 14:57:04
gototop
 
1   1  /  1  页   跳转
页面顶部
Powered by Discuz!NT