• 调试ASP.NET应用程序Security Token Handle Leak


    问题现象

    ASP.NET应用程序security token相关的句柄泄露一般都与impersonate机制相关。通常发生了这种问题会导致整个操作系统性能减慢,在系统日志中有可能记录2020错误。

    复制代码
    Event Type: Error
    Event Source: Srv
    Event Category: None
    Event ID: 2020
    Date: 12/24/2008
    Time: 12:13:31 AM
    User: N/A
    Computer: MYW2K3
    Description:
    The server was unable to allocate from the system paged pool because the pool was empty.
    复制代码

    如果在这种情况下抓系统kernel dump,查看dump中paged pool,可以发现大部分都被token占用。从进程管理器我们也可以看到w3wp.exe和lsass.exe的handle数量远大于其他进程,并且持续增长。

    0: kd> !token ea698028
    _TOKEN ea698028
    TS Session ID: 0
    User: S-1-5-21-606747145-527237240-1605580848-740255

    如何在不同版本的操作系统中抓取kernel dump,可以参考如下文章。

    How To Enable Windows XP to Capture a Complete or Kernel Memory Dump
    How to generate a kernel dump file or a complete memory dump file in Windows Server 2003
    How to generate a kernel or a complete memory dump file in Windows Server 2008 and Windows Server 2008 R2

    另外关于paged/nonpaged pool, 可以参考Mark Russinovich的博客文章

    Pushing the Limits of Windows: Paged and Nonpaged Pool

    问题调试

    在没有源代码的情况下如何找到什么地方调用了impersonate相关的方法呢?我们可以尝试以下两种方式。

    1. 在应用程序dump文件中直接搜索该方法调用。 要实现impersonate就必须要调用相关的Windows APIs:LogonUserDuplicateToken,我们可以在内存中搜索哪些assembly引用了这些API,然后通过ILSpy之类的IL反汇编工具来查看相应的代码。

    复制代码
    0:018> s-a 0 L?7fffffff "LogonUserA" 
    0e752a90  4c 6f 67 6f 6e 55 73 65-72 41 00 44 75 70 6c 69  LogonUserA.Dupli 
    0e762a90  4c 6f 67 6f 6e 55 73 65-72 41 00 44 75 70 6c 69  LogonUserA.Dupli 
    77f747e4  4c 6f 67 6f 6e 55 73 65-72 41 00 4c 6f 67 6f 6e  LogonUserA.Logon 
    
    0:018> !address 0e752a90  
    0e750000 : 0e752000 - 00002000 
                        Type     01000000 MEM_IMAGE 
                        Protect  00000020 PAGE_EXECUTE_READ 
                        State    00001000 MEM_COMMIT 
                        Usage    RegionUsageImage 
    FullPath C:\WINNT\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\securityhandleleak\91744b5d\ab584e94\App_Web_oeootcha.dll
    复制代码

    如果该命令返回记录比较多,我们可以通过以下命令来查看

    复制代码
    0:000> .foreach (place { s-[1]a 0 L?7fffffff "LogonUser" }) {!address place} 
        03530000 : 03532000 - 0000e000 
                        Type     01000000 MEM_IMAGE 
                        Protect  00000020 PAGE_EXECUTE_READ 
                        State    00001000 MEM_COMMIT 
                        Usage    RegionUsageImage 
                        FullPath C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\erpapv\be46890c\b4f7eeae\assembly\dl3\83aa2552\f8a67fd5_af8fc901\Assembly1.DLL
     
        03590000 : 03592000 - 0000e000 
                        Type     01000000 MEM_IMAGE 
                        Protect  00000020 PAGE_EXECUTE_READ 
                        State    00001000 MEM_COMMIT 
                        Usage    RegionUsageIsVAD 
        035b0000 : 035b2000 - 00011000 
                        Type     01000000 MEM_IMAGE 
                        Protect  00000020 PAGE_EXECUTE_READ 
                        State    00001000 MEM_COMMIT 
                        Usage    RegionUsageImage 
                        FullPath C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\erpapv\be46890c\b4f7eeae\assembly\dl3\73e6c81e\fcbd4e76_6f96c901\Approve.DLL
     
        03700000 : 03702000 - 00032000 
                        Type     01000000 MEM_IMAGE 
                        Protect  00000020 PAGE_EXECUTE_READ 
                        State    00001000 MEM_COMMIT
                        Usage    RegionUsageImage 
                        FullPath C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\erpapv\be46890c\b4f7eeae\assembly\dl3\19c4bca1\9a54ebdc_5a97c901\Assembly2.DLL
     
    ……………
    复制代码

    2. 第二种方法是通过调试器在程序运行过程中记录相应API调用栈。

    • 安装调试工具Debug Tool for Windows 将以下配置文件存为TokenLeak.cfg,将OutputDir中目录更改为你需要存log的目录。
    • 打开命令行,转到调试器安装目录,运行以下命令
    • Cscript.exe –p <PID of the w3wp.exe has token leak problem> -c <FullPathTo TokenLeak.cfg>
    • 监测w3wp.exe handle数量增长情况并查看生成的日志文件,日志文件中记录了调用相应API调用栈,根据这些调用栈我们可以回头查看源代码来将没有关闭的handle释放掉。
    复制代码
    # ChildEBP RetAddr  Args to Child
    00 01f1ef08 0e49126a 01f1f128 01f1f028 01f1ef28 ADVAPI32!LogonUserA (FPO: [Non-Fpo]) (CONV: stdcall) 
    01 01f1f244 0e790605 00000001 00000000 060e3178 CLRStub[StubLinkStub]@e49126a 
    02 01f1f2a4 0e790505 00000000 00000000 00000000 App_Web_oeootcha!_Default.impersonateValidUser(System.String, System.String, System.String)+0x7d*** WARNING: Unable to verify checksum for C:\WINNT\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\securityhandleleak\91744b5d\ab584e94\App_Web_oeootcha.dll  (Managed) 
    03 00000000 66f12980 00000000 00000000 00000000 App_Web_oeootcha!_Default.Page_Load(System.Object, System.EventArgs)+0x3d (Managed) 
    04 01f1f504 6628efd2 00000000 00000000 00000000 
    复制代码
    复制代码
    Configuration File:
     
    <ADPlus> 
          <Settings> 
                          <RunMode> CRASH </RunMode> 
                          <Sympath> http://msdl.microsoft.com/download/symbols </Sympath> 
                          <Option> Quiet </Option> 
                          <OutputDir> d:\HandleLeak </OutputDir> 
          </Settings> 
          <Breakpoints> 
                          <NewBP> 
                                          <Address> advapi32!LogonUserA </Address> 
                                          <Type> BP </Type> 
                                          <Actions> stack  </Actions> 
                                          <CustomActions>  </CustomActions> 
                                          <ReturnAction> G </ReturnAction> 
                          </NewBP>   
                          <NewBP>
     
                                          <Address> advapi32!LogonUserW </Address> 
                                          <Type> BP </Type> 
                                          <Actions> stack  </Actions> 
                                          <CustomActions>  </CustomActions> 
                                          <ReturnAction> G </ReturnAction> 
                            </NewBP>  
          </Breakpoints> 
    </ADPlus>
    复制代码

    希望以上内容对你有所帮助

    微软互联网开发支持专家

    weizhao

     
     
  • 相关阅读:
    leetcode 350. Intersection of Two Arrays II
    leetcode 278. First Bad Version
    leetcode 34. Find First and Last Position of Element in Sorted Array
    leetcode 54. Spiral Matrix
    leetcode 59. Spiral Matrix II
    leetcode 44. Wildcard Matching
    leetcode 10. Regular Expression Matching(正则表达式匹配)
    leetcode 174. Dungeon Game (地下城游戏)
    leetcode 36. Valid Sudoku
    Angular Elements
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3012266.html
Copyright © 2020-2023  润新知