【问题标题】:Stack overflow in IIRF (a C program, ISAPI)IIRF 中的堆栈溢出(C 程序,ISAPI)
【发布时间】:2010-11-05 14:52:30
【问题描述】:

我正在使用IIRF - 一个用于漂亮 URL 的 ISAPI 重写过滤器。在这些问题上,我无法从开发人员那里获得太多帮助。我希望通过对这个转储有所了解,这样我就可以在代码中找到有问题的区域并自己重建它。我对C不是超级熟悉,但可以解决。我是否需要使用调试符号来构建它以从转储中获取任何有用的信息?

这些堆栈溢出异常发生在我们的实时生产网络服务器上,因此我无法使用调试模式单步执行此代码。发生的事情是我的应用程序池进程 (w3wp.exe) 收到此错误事件:

为应用程序池“dotNET 池”提供服务的进程与万维网发布服务发生了致命的通信错误。进程 ID 为“6924”。数据字段包含错误号。

有人可以帮我理解这些数据吗?它是来自 IIS 调试诊断工具的转储。我如何解释它并找到异常的来源?它似乎是第 3 方 PCRE 正则表达式库中的一个例外。

WARNING - DebugDiag was not able to locate debug symbols for IsapiRewrite4.dll, so the information below may be incomplete.

在 w3wp__PID__3760__Date__06_23_2009__ Time_01_29_55PM__916__Second_Chance_Exception_C00000FD.dmp 中 IsapiRewrite4!pcre_exec+12f9 in C:\IIRF1.2.15R5\IsapiRewrite4.dll 的汇编指令在尝试写入时导致堆栈溢出异常 (0xC00000FD) /p>

执行的分析类型崩溃分析 机器名称 WEB 操作系统 Windows Server 2003 Service Pack 2 处理器数量 4 进程 ID 8056 进程映像 c:\WINDOWS\system32\inetsrv\w3wp.exe 系统正常运行时间 0 天 09:26:25 处理正常运行时间 0 天 02:17:00 线程 4 - 系统 ID 6624 入口点 w3tp!THREAD_MANAGER::ThreadManagerThread 创建时间 2009 年 6 月 23 日上午 11:12:56 在用户模式下花费的时间 0 天 0:0:40.906 在内核模式下花费的时间 0 天 0:0:6.312 功能 参数 1 参数 2 参数 3 源 IsapiRewrite4!pcre_exec+12f9 08166a27 01b6741f 081669b8 IsapiRewrite4!pcre_exec+2779 08166a27 01b6746b 081669b8 IsapiRewrite4!pcre_exec+1660 08166a26 01b6741f 081669b8 IsapiRewrite4!pcre_exec+2779 08166a26 01b6746b 081669b8 IsapiRewrite4!pcre_exec+1660 08166a25 01b6741f 081669b8 IsapiRewrite4!pcre_exec+2779 08166a25 01b6746b 081669b8 IsapiRewrite4!pcre_exec+1660 08166a24 01b6741f 081669b8 IsapiRewrite4!pcre_exec+2779 08166a24 01b6746b 081669b8 IsapiRewrite4!pcre_exec+1660 08166a23 01b6741f 081669b8 IsapiRewrite4!pcre_exec+2779 08166a23 01b6746b 081669b8 IsapiRewrite4!pcre_exec+1660 08166a22 01b6741f 081669b8 [……剪断……]


此调试过程的更新

我相信我找到了罪魁祸首,在调整 IIS 调试诊断工具以提供更多信息后,我发现 URL 如下所示。它似乎类似于 SQL 注入攻击,但我不认为是 SQL 注入。

[original_url]/Forum+Result:+%E8%F1%EF%EE%EB%FC%E7%EE%E2%E0%ED+%ED%E8 %EA%ED%E5%E9%EC+%22Rifsadasy%22;%EF%E8%EA%F2%EE%EA%EE%E4+%E4%E5%F8%E8 %F4%F0%EE%E2%E0%ED;%E7%E0%F0%E5%E3%E8%F1%F2%F0%E8%F0%EE%E2%E0%EB%E8%F1 %FC+100%25+%28%E2%EA%EB%FE%F7%E5%ED+%F0%E5%E6%E8%EC+%F2%EE%EB%FC%EA%EE +%F0%E5%E3%E8%F1%F2%F0%E0%F6%E8%E8%29;

有人见过这种类型的攻击吗?他们知道那是什么吗? 我尝试使用 HEX、Base64 和其他一些方法对此进行解码,但除了这个 ASCII 文本之外,我什么也没想到:

èñïîëüçîâàí+íèêíåéì+"Rifsadasy";ïèêòîêîä+äåøèôðîâàí;çàðåãèñòðèðîâàëèñü+100%+(âêëþ÷åí+ðåæèì+òîëüêî+ðåãèñòðàöèè);

【问题讨论】:

    标签: c debugging dump pcre iirf


    【解决方案1】:

    PCRE 反复递归调用两个函数,直到堆栈空间用完。您可以尝试将 Rewrite DLL 升级到没有错误的版本,或者尝试更改您的重写规则,使其不会遇到 PCRE 错误。

    【讨论】:

    • 这不是重写器中的错误。这是模式和配置中的错误。堆栈溢出发生在 pcre_exec 中,这是执行正则表达式的地方。这是一种退化的情况,但应该在配置中处理(例如,删除所有带有 % 的 URL)。
    • 任何可以说服在某个输入上堆栈溢出的正则表达式解析器都有一个错误;虽然我同意在配置中解决这个问题可能最容易
    • 任何通用正则表达式都允许重复空组,这立即允许无限循环的可能性。结论:所有正则表达式引擎都有问题!
    • 所以你是说所有那些 Web Regex 网站都可以通过在其中输入一个重复的空组来轻松关闭
    • 没有。我是说,无论输入如何,都可以构建一个自身递归的正则表达式。而且,我还说(或者我应该说),用更复杂的输入构建一个损坏的正则表达式更容易。任何足够通用的正则表达式解析器都支持递归,除非它在递归逻辑中进行故障安全检查,否则它将溢出。 PCRE 有一个故障保护(sas the doc),但在这种情况下它显然不起作用。无论如何,我与 Mase 一起更改了他的正则表达式并避免了这个问题。
    【解决方案2】:

    看起来你已经让 pcre_exec 递归并耗尽了你所有的堆栈空间。我会检查并查看您使用的正则表达式。

    【讨论】:

      【解决方案3】:

      根据最底部的堆栈跟踪,看起来程序正在进入无限递归,两个函数相互调用而没有终止。这将由于最终耗尽可用堆栈而导致堆栈溢出异常。

      【讨论】:

        【解决方案4】:

        你能找出发送到无限递归的 URL 吗?看起来您有两个相互触发的重写规则。除非你有 IsapiRewrite4.dll 的源代码,否则它不会有太大帮助——你可以得到汇编代码——但即使你有源代码(你可以反编译),它也不会没有帮助,因为我认为您需要查看通过的 URL。

        它是否也转储了内存(或者你可以让它这样做)。 Arg1、Arg2 或 Arg3 可能是指向 URL 的指针?

        【讨论】:

        • 我确实有 IsapieRewrite4.dll 的源代码。它是开源的,可在 IIRF website 上获得
        • 1.使用 pdb 进行构建 2. 将带有 pdb 的 dll 部署在同一个目录中 3. 重现问题 4. (也许调试诊断会读取 pdb),如果没有,请在本地计算机上使用 dll 和 pdb 加载 IIS同一个目录。在错误中找到函数。 5. 向函数添加日志记录,这样你就知道正在重写哪个 URL——看看你是否能弄清楚函数在堆栈上的次数(线程局部变量计数器?),如果它在那里超过几次,记录正在发生的事情。 5.在生产中运行新的dll。
        • 谢谢娄...如果我能重现这个问题,我不会发布这个问题。另外,我尝试使用 PDB 部署 DLL,但调试诊断没有读取符号,它说它找不到它们。
        • 好的,但是现在你有一个 PDB,用 ISAPI DLL 在你的开发机器上加载 IIS 并转到调试诊断中的地址——你应该能够看到符号(把 PDB在与 DLL 相同的目录中)。我认为这不会有太大帮助,因为我认为问题出在实际传递的 URL 中。也许您可以通过让函数检测到它处于相互递归循环中并以错误或异常退出来进行修补。
        • 您不需要 IIRF 的可调试版本。很明显,堆栈溢出发生在 pcre_exec 函数中,这是计算/执行正则表达式的地方。它溢出是因为规则在循环。这在正则表达式处理中并不少见。小心!
        【解决方案5】:

        所以我相信我已经找到了原因错误。虽然我不确定这是否仍然是 IIRF ISAPI 过滤器中的错误?它至少不应该多次迭代重写函数而导致堆栈溢出。

        我可以通过在我的服务器上请求此 URL 来重现我在事件日志中看到的错误: [original_url]/论坛+结果:+%E8%F1%EF%EE%EB%FC%E7%EE%E2%E0%ED+%ED%E8 %EA%ED%E5%E9%EC+%22Rifsadasy%22; %EF%E8%EA%F2%EE%EA%EE%E4+%E4%E5%F8%E8 %F4%F0%EE%E2%E0%ED;%E7%E0%F0%E5%E3%E8% F1%F2%F0%E8%F0%EE%E2%E0%EB%E8%F1 %FC+100%25+%28%E2%EA%EB%FE%F7%E5%ED+%F0%E5%E6 %E8%EC+%F2%EE%EB%FC%EA%EE +%F0%E5%E3%E8%F1%F2%F0%E0%F6%E8%E8%29;

        所以我创建了一个重写规则来为这个 URL 返回一个 404 状态。

        但我需要知道这是否是某种类型的攻击,我还不能完全确定,但这是我认为加密字符串所说的内容。该 URL 来自俄罗斯的 IP 地址,所以我做了以下翻译:

        1. 十六进制到 ASCII:

          èñïîëüçîâàí+íèêíåéì+"Rifsadasy";ïèêòîêîä+äåøèôðîâàí;çàðåãèñòðèðîâàëèñü+100%+(âêëþ÷åí+ðåæèì+òîëüêî+ðåãèñòðàöèè)

        2. 然后是西里尔文到俄文:

          использован+никнейм+"Rifsadasy";пиктокод+дешифрован;зарегистрировались+100%+(включен+режим+только+регистрации)

        3. 然后是俄语到英语:

          使用昵称“Rifsadasy”; piktokod 解密;注册 100(仅限模式)
          或者,类似地
          它被用于 никнейм “Rifsadasy”; пиктокод 它被解码;已注册 100 人(包括仅模式注册)

        【讨论】:

        • 你做对了。拒绝那些长 URL,保护你的服务器。
        【解决方案6】:

        我认为堆栈溢出不是由于 重写器 中的错误。这是由于过滤器配置的配置中使用的模式中的一个错误。

        创建一个无限循环的单个正则表达式实际上很容易,PCRE 和 IIRF 都没有办法阻止这种情况。还可以在重写规则中创建逻辑循环,以便您无休止地重定向或重写。同样,过滤器无法阻止您在脚上射击自己。你必须小心。当使用任何依赖于 PCRE 的重写器或任何模块化正则表达式引擎时,这些风险都存在。

        堆栈溢出发生在 pcre_exec 中,这是执行正则表达式的地方。这是一种退化的情况,但应该在配置中处理。先前的规则应该已经过滤掉了这种无效的情况。这是a post about using a rewriting filter as a security barrier

        尽早并经常测试。有人认为,因为过滤规则“只是配置”,不需要进行严格的测试。一般来说,这不是一个安全的假设。像对待任何代码模块一样对待 IIRF 规则。你只是在使用不同的语言。

        【讨论】:

        • 芝士!很高兴看到你在这里插话……我一直需要你的帮助。我的理解是 IterationLimit 设置阻止了这成为一个问题。将 IterationLimit 设置为 5 或 10 意味着一个 URL 在 10 次重写后将停止重写。在重新阅读此设置的描述时,似乎迭代限制仅适用于一次通过规则。一旦 URL 再次进入规则集的顶部,就会重置迭代限制。它是否正确?不管怎样,现在我知道要开始剖析我的规则以找出循环被捕获的位置。
        猜你喜欢
        • 2013-12-12
        • 2010-12-11
        • 2014-12-28
        • 2012-12-20
        • 2011-03-02
        • 2014-01-17
        • 1970-01-01
        • 2015-09-08
        相关资源
        最近更新 更多