草庐IT

c - 临时冒充和启用特权?

coder 2024-06-14 原文

我们维护一个 DLL,做很多与系统相关的事情;遍历文件系统、注册表等。此 DLL 的调用者可能使用也可能不使用模拟。为了更好地支持所有可能的场景,我正在尝试将其修改为更智能。我将使用删除文件的示例。目前我们只调用 DeleteFile(),如果失败,那就结束了。我想出了以下内容:

BOOL TryReallyHardToDeleteFile(LPCTSTR lpFileName)
{
    // 1. caller without privilege
    BOOL bSuccess = DeleteFile(lpFileName);
    DWORD dwError = GetLastError();
    if(!bSuccess && dwError == ERROR_ACCESS_DENIED)
    {
        // failed with access denied; try with privilege
        DWORD dwOldRestorePrivilege = 0;
        BOOL bHasRestorePrivilege = SetPrivilege(SE_RESTORE_NAME, SE_PRIVILEGE_ENABLED, &dwOldRestorePrivilege);
        if(bHasRestorePrivilege)
        {
            // 2. caller with privilege
            bSuccess = DeleteFile(lpFileName);
            dwError = GetLastError();
            SetPrivilege(SE_RESTORE_NAME, dwOldRestorePrivilege, NULL);
        }
        if(!bSuccess && dwError == ERROR_ACCESS_DENIED)
        {
            // failed with access denied; if caller is impersonating then try as process
            HANDLE hToken = NULL;
            if(OpenThreadToken(GetCurrentThread(), TOKEN_QUERY | TOKEN_IMPERSONATE, TRUE, &hToken))
            {
                if(RevertToSelf())
                {
                    // 3. process without privilege
                    bSuccess = DeleteFile(lpFileName);
                    dwError = GetLastError();
                    if(!bSuccess && dwError == ERROR_ACCESS_DENIED)
                    {
                        // failed with access denied; try with privilege
                        bHasRestorePrivilege = SetPrivilege(SE_RESTORE_NAME, SE_PRIVILEGE_ENABLED, &dwOldRestorePrivilege);
                        if(bHasRestorePrivilege)
                        {
                            // 4. process with privilege
                            bSuccess = DeleteFile(lpFileName);
                            dwError = GetLastError();
                            SetPrivilege(SE_RESTORE_NAME, dwOldRestorePrivilege, NULL);
                        }
                    }
                    SetThreadToken(NULL, hToken);
                }
                CloseHandle(hToken);
                hToken = NULL;
            }
        }
    }
    if(!bSuccess)
    {
        SetLastError(dwError);
    }
    return bSuccess;
}

所以首先它会尝试作为调用者。如果访问被拒绝而失败,它会暂时启用调用者 token 中的特权并重试。如果由于访问被拒绝而失败并且调用者正在模拟,它会暂时取消模拟并重试。如果因访问被拒绝而失败,它会暂时启用进程 token 中的特权并重试。我认为这几乎可以处理任何情况,但我想知道是否有更好的方法来实现这一点?有很多操作我们可能希望使用此方法(即几乎所有访问安全对象的操作)。

最佳答案

备份和恢复权限一起将提供对所有文件的完全访问,句号。这些对 LocalSystem 可用。您必须使用 FILE_FLAG_BACKUP_SEMANTICS 打开文件才能使用它。某些 Win32 API 并非设计用于此,并且不会将标志传递给内核,尽管在某些情况下您可以使用 CreateFile 打开目录。 (对于内核而言,目录只是另一种文件)。

如果您真的需要能够访问所有内容,我会说启用这些权限并执行应该成功的扫描操作,而不管未模拟调用者的安全性如何。

一个突出的问题是文件可以被锁定或打开但不能共享访问权限。没有办法从用户模式解决这个问题(如果不杀死拥有该资源的进程,可能会矫枉过正)。这就是为什么我所知道的主流扫描器都使用内核模式文件系统过滤器驱动程序来实现此功能。

此外,请考虑审计:您是否希望审计条目显示给 LocalSystem 或与调用进程关联的用户?

关于c - 临时冒充和启用特权?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2464158/

有关c - 临时冒充和启用特权?的更多相关文章

  1. ruby-on-rails - 启用 Rack::Deflater 时 ETag 发生变化 - 2

    在启用Rack::Deflater来gzip我的响应主体时偶然发现了一些奇怪的东西。也许我遗漏了一些东西,但启用此功能后,响应被压缩,但是资源的ETag在每个请求上都会发生变化。这会强制应用程序每次都响应,而不是发送304。这在没有启用Rack::Deflater的情况下有效,我已经验证页面源没有改变。我正在运行一个使用thin作为Web服务器的Rails应用程序。Gemfile.lockhttps://gist.github.com/2510816有没有什么方法可以让我从Rack中间件获得更多的输出,这样我就可以看到发生了什么?提前致谢。 最佳答案

  2. ruby - 使用 Selenium WebDriver 启用/禁用 javascript - 2

    出于某种原因,我必须为Firefox禁用javascript(手动,我们按照提到的步骤执行http://support.mozilla.org/en-US/kb/javascript-settings-for-interactive-web-pages#w_enabling-and-disabling-javascript)。使用Ruby的SeleniumWebDriver如何实现这一点? 最佳答案 是的,这是可能的。而是另一种方式。您首先需要查看链接Selenium::WebDriver::Firefox::Profile#[]=

  3. ruby-on-rails - 如何在 Rails 中启用 Ruby 警告? - 2

    我在test.rb中做了这个:defsome_methodp"Firstdefinition"enddefsome_methodp"Seconddefinition"endsome_method当我调用rubytest.rb时,它打印出Seconddefinition(预期)当我调用ruby-wtest.rb时,它会打印Seconddefinition(预期)并打印警告test。rb:5:警告:方法重新定义;丢弃旧的some_method有没有办法在Rails中启用这些警告?(并将警告打印到控制台/日志文件)为什么我要启用警告:例如,如果我无意中重新定义Controller中的一个方法

  4. ruby - 为什么这个启用 SSL 的 Ruby 服务器/客户端测试有效? - 2

    我正在努力在Ruby中创建启用SSL的服务器,以及与服务器一起使用的相应Ruby客户端。为了进行测试,我使用以下命令创建了自己的根CA证书。$:~/devel/ssl-test/ssl/CA$opensslgenrsa-outTestCA.key2048GeneratingRSAprivatekey,2048bitlongmodulus............+++...........................+++eis65537(0x10001)$:~/devel/ssl-test/ssl/CA$opensslreq-new-keyTestCA.key-outTestCA.

  5. ruby-on-rails - Ruby 自动删除临时文件? - 2

    我很困惑。这是我的代码:require'csv'require'tempfile'f=Tempfile.new('csv','/tmp')f.write'justwannatest'f.closepf.path如果我打开输出路径,它是空的。我认为这是因为每次ruby​​session退出时,TempFile都会自动从文件系统中删除。但是,我如何确切知道文件何时被删除?因为我想用它在我的Rails应用程序中创建临时文件,我担心文件在使用前是否被删除了。 最佳答案 来自文档:WhenaTempfileobjectisgarbagecol

  6. ruby - 创建一个临时文件而不在 Ruby 中打开它 - 2

    有没有办法在不打开临时文件的情况下创建它?我必须运行一个可执行文件,将它的输出重定向到一个文件,然后读取并解析它。tempfile创建的所有内容都已打开,这会触发错误,因为文件已锁定。 最佳答案 你也可以使用Dir::TmpnameDir::Tmpname.create('your_application_prefix'){|path|putspath}路径将包含唯一路径参见https://github.com/ruby/ruby/blob/ruby_1_9_3/lib/tmpdir.rb#L116

  7. ruby-on-rails - rails - x-sendfile + 临时文件 - 2

    前段时间我写了aquestion关于在Rails应用程序中使用临时文件。在特殊情况下,我决定使用tempfile如果我还想使用x-sendfile指令(asaparameterinRails2,orasaconfigurationoptioninRails3)以便文件发送由我的Web服务器直接处理,而不是我的Rails应用程序,这会导致问题。所以我想做这样的事情:require'tempfile'deffoo()#createsatemporaryfileintmp/Tempfile.open('prefix',"#{Rails.root}/tmp")do|f|f.print('ate

  8. ruby-on-rails - 如何通过表单获取临时文件的内容 - 2

    index.html.erb=form_for:file_upload,:html=>{:multipart=>true}do|f|=f.label:uploaded_file,'Uploadyourfile.'=f.file_field:uploaded_file=f.submit"Loadnewdictionary"模型deffile_uploadfile=Tempfile.new(params[:uploaded_file])begin@contents=fileensurefile.closefile.unlink#deletesthetempfileendend索引defin

  9. ruby - 带有临时文件的奇怪的 Ruby IO - 2

    这让我发疯。请考虑以下事项:require'open-uri'#setuptempfileextname=File.extnamefile_urlbasename=File.basename(file_url,extname)file=Tempfile.new([basename,extname])#readformURIintotempfileuri=URI.parse(file_url)num_bytes_writen=file.write(uri.read)puts"Wrote#{num_bytes_writen}bytes"#Readingfrommytempfileputs"

  10. ruby - 在 Rails 控制台中启用异常堆栈转储 - 2

    我正在使用带有prygem的RubyonRails。当rake任务期间发生错误时,我得到一个非常好的堆栈跟踪。然而,当我在我的Rails控制台中执行某些触发异常的操作时,我只能看到错误消息和触发它的一行代码(大部分时间在Rails核心中的某个地方)。有没有办法在控制台中启用这些堆栈转储? 最佳答案 我自己找到了解决方案。显然,我需要pry附带的命令wtf?。[7]project»p.known_attributesNoMethodError:undefinedmethod`foo'for#from/[...]/gems/active

随机推荐