首页
社区
课程
招聘
[原创]在任意的远程桌面的session中运行指定的程序
发表于: 2009-12-11 11:46 6461

[原创]在任意的远程桌面的session中运行指定的程序

2009-12-11 11:46
6461
文章作者:pt007[at]vip.sina.com
信息来源:邪恶八进制信息安全团队(www.eviloctal.com)

注:文章首发I.S.T.O信息安全团队,后由原创作者友情提交到邪恶八进制信息安全团队技术讨论组。I.S.T.O版权所有,转载需注明作者。
//在其它session中(如远程桌面的session)运行指定的程序,需要具有system权限,可以在任意的桌面里运行指定程序

#include <windows.h>
#include <stdio.h>
#include <process.h>
#include <Tlhelp32.h>
#include <tchar.h>
#include <psapi.h>
#include <stdio.h>
#include <STDLIB.H>
#include <tlhelp32.h> 
#include <WtsApi32.h>
#pragma comment(lib, "WtsApi32.lib")
#pragma  comment (lib,"psapi")


// Get username from session id
bool GetSessionUserName(DWORD dwSessionId, char username[256])
{
        LPTSTR pBuffer = NULL;
        DWORD dwBufferLen;
        
        BOOL bRes = WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, dwSessionId, WTSUserName, &pBuffer, &dwBufferLen);
        
        if (bRes == FALSE)
                return false;
        
        lstrcpy(username ,pBuffer);
        WTSFreeMemory(pBuffer);
        
        return true;
}

// Get domain name from session id
bool GetSessionDomain(DWORD dwSessionId, char domain[256])
{
        LPTSTR pBuffer = NULL;
        DWORD dwBufferLen;
        
        BOOL bRes = WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, dwSessionId, WTSDomainName, &pBuffer, &dwBufferLen);
        
        if (bRes == FALSE)
        {
                printf("WTSQuerySessionInformation Fail!\n");
                return false;
        }
        
        lstrcpy(domain,pBuffer);
        WTSFreeMemory(pBuffer);
        
        return true;
}



HANDLE GetProcessHandle(LPSTR szExeName)  //遍历进程PID

{  
        
        PROCESSENTRY32 Pc = { sizeof(PROCESSENTRY32) };  
        
        HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);  
        
        if(Process32First(hSnapshot, &Pc)){  
                
                do{  
                        
                        if(!stricmp(Pc.szExeFile, szExeName)) {   //返回explorer.exe进程的PID
                                printf("explorer's PID=%d\n",Pc.th32ProcessID);
                                return OpenProcess(PROCESS_ALL_ACCESS, TRUE, Pc.th32ProcessID);  
                                
            }  
                        
                }while(Process32Next(hSnapshot, &Pc));  
                
    }  
        
        
        
        return NULL;  
} 


//输出帮助的典型方法:
void Usage (void)
{
        fprintf(stderr,"===============================================================================\n"
                "\t名称:在任意的远程桌面的session中运行指定的程序,需要具有system权限\n"
                "\t环境:Win2003 + Visual C++ 6.0\n"
                "\t作者:pt007@vip.sina.com\n"
                "\t  QQ:7491805\n"
                "\t声明:本软件由pt007原创,转载请注明出处,谢谢!\n"
                "\n"
                "\t使用方法:\n"
                "\tsession 1 c:\\win2003\\system32\\svchosts.exe //在会话1里面运行程序!\n"
                 "===============================================================================\n");
}

int main(int argc, char **argv) 
{ 
    

  if(argc==1) //遍历所有的session

  {// 函数的句柄

     HMODULE hInstKernel32    = NULL;

     HMODULE hInstWtsapi32    = NULL;

// 这里的代码用的是VC6,新版的SDK已经包括此函数,无需LoadLibrary了。
     typedef DWORD (WINAPI *WTSGetActiveConsoleSessionIdPROC)();

     WTSGetActiveConsoleSessionIdPROC WTSGetActiveConsoleSessionId = NULL;

     hInstKernel32 = LoadLibrary("Kernel32.dll");

if (!hInstKernel32)

{

    return FALSE;

}


   WTSGetActiveConsoleSessionId = (WTSGetActiveConsoleSessionIdPROC)GetProcAddress(hInstKernel32,"WTSGetActiveConsoleSessionId");

if (!WTSGetActiveConsoleSessionId)

{

   return FALSE;

}


// WTSQueryUserToken 函数,通过会话ID得到令牌

   typedef BOOL (WINAPI *WTSQueryUserTokenPROC)(ULONG SessionId, PHANDLE phToken );

   WTSQueryUserTokenPROC WTSQueryUserToken = NULL;

   hInstWtsapi32 = LoadLibrary("Wtsapi32.dll");

if (!hInstWtsapi32)

{

   return FALSE;

}


   WTSQueryUserToken = (WTSQueryUserTokenPROC)GetProcAddress(hInstWtsapi32,"WTSQueryUserToken");

if (!WTSQueryUserToken)

{

   return FALSE;

}




//遍历3389登录的session:
/*
typedef struct _WTS_SESSION_INFO {
        DWORD                  SessionId;
        LPTSTR                 pWinStationName;
        WTS_CONNECTSTATE_CLASS State;
}WTS_SESSION_INFO, *PWTS_SESSION_INFO;
*/
   WTS_SESSION_INFO *sessionInfo = NULL;
   DWORD sessionInfoCount;
   char domain1[256];
   char username1[256];
   BOOL result = WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &sessionInfo, &sessionInfoCount);

   unsigned int userCount(0);
int num=0;
for(unsigned int i = 0; i < sessionInfoCount; ++i)
{
        if( (sessionInfo[i].State == WTSActive) || (sessionInfo[i].State == WTSDisconnected) )
                
        {   
                printf("session %d information:\n",num++);
                printf("\tsessionInfo.SessionId=%d\n",sessionInfo[i].SessionId);
                GetSessionDomain(sessionInfo[i].SessionId, domain1); //获得Session Domain
                printf("\tSession Domain = %s\n",domain1); 

            GetSessionUserName(sessionInfo[i].SessionId,username1);
                printf("\tSession user's name = %s\n",username1); 

                userCount++;
        }
  }
   printf("session's number:%d\n\n",userCount);
     Usage();
   //printf("example:\n\tsession 1 c:\\win2003\\system32\\svchosts.exe //在会话1里面运行程序!\n");
   //printf("程序说明:在其它session中(如任意的远程桌面的session中)运行指定的程序,需要具有system权限\n");
   WTSFreeMemory(sessionInfo); //释放
  
  }
   else if(argc==3) //session 1 c:\win2003\temp\klog.exe
  {

  
// 得到当前登录用户的令

/*HANDLE hTokenDup = NULL;
bRes = WTSQueryUserToken(dwSessionId, &hTokenDup);

if (!bRes)

{
        printf("WTSQueryUserToken Failed!%d\n",GetLastError());
        
        return FALSE;
        
}*/



/*bRes = ImpersonateLoggedOnUser(hTokenDup);

if (!bRes)

{
        printf("ImpersonateLoggedOnUser!%d\n",GetLastError());

return FALSE;

}*/


//MessageBox(NULL,"test2","test1",MB_OK);
//system("winver.exe");

HANDLE hThisProcess = GetCurrentProcess(); // 获取当前进程句柄

        //HANDLE   hThisProcess   = GetProcessHandle("EXPLORER.EXE");   
        //if(hThisProcess   ==   NULL) 
// return   0; 

// 打开当前进程令牌

HANDLE hTokenThis = NULL;
HANDLE hTokenDup = NULL;

OpenProcessToken(hThisProcess, TOKEN_ALL_ACCESS, &hTokenThis);



// 复制一个进程令牌,目的是为了修改session id属性,以便在其它session中创建进程



DuplicateTokenEx(hTokenThis, MAXIMUM_ALLOWED,NULL, SecurityIdentification, TokenPrimary, &hTokenDup);
//获取活动session id,这里要注意,如果服务器还没有被登录而使用了远程桌面,这样用是可以的,如果有多个session存在,
//不能简单使用此函数,需要枚举所有session并确定你需要的一个,或者干脆使用循环,针对每个session都执行后面的代码

//SetTokenInformation(hTokenDup, TokenSessionId, &dwSessionId, sizeof(DWORD)); //把session id设置到备份的令牌中
DWORD dwSessionId=atoi(argv[1]); //与会话进行连接
bool bRes;
bRes=SetTokenInformation(hTokenDup, TokenSessionId, &dwSessionId, sizeof(DWORD));


if (!bRes)
         
{
         printf("SetTokenInformation!%d\n",GetLastError());
         return FALSE;
}

// 好了,现在要用新的令牌来创建一个服务进程。注意:是“服务”进程!如果需要以用户身份运行,必须在前面执行LogonUser来获取用户令牌


STARTUPINFO si;

PROCESS_INFORMATION pi;

ZeroMemory(&si, sizeof(STARTUPINFO));

ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));

si.cb = sizeof(STARTUPINFO);

si.lpDesktop = "WinSta0\\Default";



LPVOID pEnv = NULL;

DWORD dwCreationFlag = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE; // 注意标志

//CreateEnvironmentBlock(&pEnv, hTokenDup, FALSE); // 创建环境块

// 创建新的进程,这个进程就是你要弹出窗口的进程,它将工作在新的session中
   char path[MAX_PATH];
   lstrcpy(path,argv[2]);
   CreateProcessAsUser(hTokenDup, NULL, (char *)path, NULL, NULL, FALSE, dwCreationFlag, pEnv, NULL, &si, &pi);
  }
    return 0;
}

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
支持 PT啊 哈哈
2009-12-11 11:49
0
雪    币: 74
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
先收藏
2009-12-11 20:32
0
雪    币: 250
活跃值: (25)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
好东西,收藏一下~
2009-12-11 22:23
0
游客
登录 | 注册 方可回帖
返回
//