模拟用户登录

模拟用户登录

--张佩

1. 用户模拟

如果将文件test.exe的安全属性设置成Guest用户无法访问的话,以Guest用户登录后,访问者就不能访问test.exe文件了。但有一个办法可以让访问者在使用Guest账户登录的情况下也能够访问此文件,就是使用用户模拟的方式,暂时以高权用户的身分访问这个文件!下面的代码实现了用户模拟:

    HANDLEhToken;
        DWORD dwError;
        STARTUPINFOW   si;  
        PROCESS_INFORMATION pi;  
 
        ZeroMemory(&si, sizeof(si));
        ZeroMemory(&pi, sizeof(pi));
        si.cb = sizeof(si);
 
        if(0 ==LogonUser("administ", ".", "password", LOGON32_LOGON_INTERACTIVE,LOGON32_PROVIDER_DEFAULT, &hToken))
        {
                printf("Failed to call LogonUser/r/n");
                dwError = GetLastError();
        }
        else
        {
                if(CreateProcessAsUserW(hToken,L"c://test.exe",NULL,
                        NULL, NULL,
                        FALSE, NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE,
                        NULL, NULL, &si, &pi))
                {/×成功×/}
        }
        代码调用了两个关键函数:LogonUser获取高权用户的令牌(Token),令牌代表了用户所能拥有的系统权限,使用这个API需要将用户名称和密码作为参数输入;CreateProcessAsUser利用此用户令牌创建进程,从而执行有安全保护的文件。

如果要提权的不是可执行程序,而是一个文档(比如:text.txt),比如要读取它里面的数据,应怎么办呢?其实很简单,代码如下:
bRet = ImpersonateLoggedOnUser(hToken);
    if(bRet)
    {
        FILE* hFile = fopen("c://test.txt", "r");
        RevertToSelf();
    }
         ImpersonateLoggedOnUser的作用是模拟用户,就是让当前执行进程暂时以被模拟用户的身份来运行,并完全使用被模拟用户的权限级别来操作。输入参数hToken就是前面已经获取的用户令牌。调用RevertToSelf让当前进程恢复到本身的用户环境。

2. 问题和改进

上面的方法有一个缺点,通过LogonUser打开用户令牌的时候,必须输入用户名和密码作为必备参数,可移植性太差。如果有更好的办法获取高权用户Token就好了。每个进程在运行的时候都保存一个用户令牌,而用户令牌又是可以获取的,从这一点出发,我们能想到更好的办法。winlogon.exe进程总是以System用户权限运行,下面的代码将从Winlogon中提取System用户令牌(代码作者是我的同事 jiurl):
   
    pid = FindWinlogon();//取得winlogon.exe的进程ID,从略
        if(pid<0 )
        {
                return 0;
        }
 
        hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pid );
        if(hProcess==NULL )
        {
                return 0;
        }
 
        rc = OpenProcessToken( hProcess, TOKEN_ALL_ACCESS, &hOldToken );
        if(rc==0 )
        {
                CloseHandle(hProcess);
                return 0;
        }
 
        rc = DuplicateTokenEx(hOldToken,NULL, NULL, SecurityIdentification, TokenPrimary, &hNewToken);
        if(rc==0 )
        {
                CloseHandle(hProcess);
                CloseHandle(hOldToken);
                return 0;
        }
       (注:上面的代码一般应在单独的服务中运行,否则代码本身可能会因为权限问题而中途失败)
       代码分成了三个部分,首先是找到Winlogon进程,具体方法很多,代码从略。然后获取进程令牌,通过调用OpenProcessToken函数实现。最后复制一个令牌给当前进程使用,从而生成新的令牌句柄,这一步通过调用DuplicateToken/DuplicateTokenEx实现。
得到新的令牌句柄hNewToken后,我们就可以继续第一节中的用户模拟,从而实施高权操作了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值