从Apache整体结构入手分析Apache CVE-2021-40438

渗透技巧 2年前 (2021) admin
907 0 0

点击蓝字

从Apache整体结构入手分析Apache CVE-2021-40438

关注我们



声明

本文作者:wendell
本文字数:4099

阅读时长:11min

附件/链接:点击查看原文下载

本文属于【狼组安全社区】原创奖励计划,未经许可禁止转载


由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,狼组安全团队以及文章作者不为此承担任何责任。

狼组安全团队有对此文章的修改和解释权。如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经狼组安全团队允许,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的。



前言



最近Apache出了不少洞, 但更多的是漏洞局部的分析, 我更想知道这些漏洞在Apache的整体构架的位置,模块之间是如何作用的,导致产生了这样的漏洞,所以 有了这篇分析.


这篇文章,我准备从以下几个问题入手


  1. 整个Apache的程序结构是什么.

  2. 个个模块之间是如何影响http处理的

  3. 如何以宏观的视角分析最近Apache SSRF CVE-2021-40438

    一、

    Apache整体结构



    我们先看一下apache的层次结构,


    从Apache整体结构入手分析Apache CVE-2021-40438


    整个Apache可被划分为四个大层次,


    • 可移值运行库(APR)

      • Apache的跨平台特性主要是通过APR来实现的, 例如进程的创建,APR提供了apr_proc_create函数,对上层调用者屏蔽了unix系列的fork,或者win系列的createProcess的不同系统调用的差别,这样apache开发者就不必顾虑操作系统细节

    从Apache整体结构入手分析Apache CVE-2021-40438

    • Apache核心功能层

      • 核心功能层, 包括Apache的一些核心组件和核心模块,核心组件用于实现Apache服务器的基本功能,包括启动Apache, conf处理,接受处理Http连接, mod_core核心模块,进行大部分配置解析,mod_so核心模块负责动态加载其他模块.

    • Apache 可选功能层,

      • 一般是一些Apache的可选模块

    • Apache第三方支持库.

    二、

    核心组件和模块的关系


    那么模块是如何发挥作用的呢
    一般这中多个模块影响主流程的情况,可以使用hook思想来做, Apache也是这样处理的
    那么apache的hook是怎样实现的呢


    从Apache整体结构入手分析Apache CVE-2021-40438

    对Apache核心来说,并没有对核心模块和可选模块的区分,都是通过Hook点进行调用.


    我们先看一下Apache如何声明和触发Hook


    在http_connection中,通过AP_DECLARE_HOOK宏声明一个handler这样一个hook,这个hook最终是通过下面这样一个宏来实现的


    //include/http_connfig.hAP_DECLARE_HOOK(int,handler,(request_rec *r))
    #define APR_DECLARE_EXTERNAL_HOOK(ns,link,ret,name,args) typedef ret ns##_HOOK_##name##_t args; link##_DECLARE(void) ns##_hook_##name(ns##_HOOK_##name##_t *pf,                                       const char * const *aszPre,                                       const char * const *aszSucc, int nOrder); link##_DECLARE(ret) ns##_run_##name args; APR_IMPLEMENT_HOOK_GET_PROTO(ns,link,name); typedef struct ns##_LINK_##name##_t     {     ns##_HOOK_##name##_t *pFunc;     const char *szName;     const char * const *aszPredecessors;     const char * const *aszSuccessors;     int nOrder;     } ns##_LINK_##name##_t;


    在Apache中,可以通过 ap_run_hookname(), 例如ap_run_handler(),触发一个hook,


    可以看到在apache核心组件中调用了ap_run_handler触发了这个hook,而ap_invoke_handler,又被ap_process_async_request调用,这些都在apache核心组件的请求处理流程中.


    #server/config.cAP_CORE_DECLARE(int) ap_invoke_handler(request_rec *r){    ...    ap_run_insert_filter(r);  ...    result = invoke_filter_init(r, r->input_filters);    if (result != OK) {        return result;    }    result = invoke_filter_init(r, r->output_filters);   ....        result = ap_run_handler(r);


    对于一个模块来说


    static void register_hooks(apr_pool_t *p)
    static const char * const aszSucc[] = { "mod_rewrite.c", NULL};
    static const char *const aszPred[] = { "mpm_winnt.c", "mod_proxy_balancer.c", "mod_proxy_hcheck.c", NULL}; ... ap_hook_handler(proxy_handler, NULL, NULL, APR_HOOK_FIRST); /* filename-to-URI translation */ ap_hook_translate_name(proxy_trans, aszSucc, NULL, APR_HOOK_FIRST); /* walk <Proxy > entries and suppress default TRACE behavior */ ap_hook_post_read_request(proxy_detect, NULL, NULL, APR_HOOK_FIRST); ... proxy_util_register_hooks(p);}
    AP_DECLARE_MODULE(proxy) ={ STANDARD20_MODULE_STUFF, create_proxy_dir_config, /* create per-directory config structure */ merge_proxy_dir_config, /* merge per-directory config structures */ create_proxy_config, /* create per-server config structure */ merge_proxy_config, /* merge per-server config structures */ proxy_cmds, /* command table */ register_hooks};


    通过AP_DECLARE_MODULE声明一个模块,在register_hooks中通过ap_hook_handler(proxy_handler, NULL, NULL, APR_HOOK_FIRST);将模块自己实现的proxy_handler函数注册进入hook点handler中


    从Apache整体结构入手分析Apache CVE-2021-40438


    这种图列出了一些请求流程中一些常见的hook,


    所有hook可以参考这个文档


    https://ci.apache.org/projects/httpd/trunk/doxygen/group__hooks.html


    apache中也可以自己定义hook,代理模块就,就自定义定义了大量hook


    至此,模块如何影响组件已经分析完成了, 其他还是一个关键点指令和配置的解析没有设计,不过他并不影响漏洞的主线,就暂且不分析.

    三、

    Apache ssrf漏洞分析


    我们知道问题产生于


    从Apache整体结构入手分析Apache CVE-2021-40438


    在对r.filename的判断中, 使用了搜索unix:的子串方式,导致可以利用url查询参数伪造,fix_uds_filename被ap_proxy_pre_request调用,进一步回溯,调用者为proxy_handler,正是我们之前分析注册在handler hook点的函数.


    static int proxy_handler(request_rec *r){        ... 
    /* Try to obtain the most suitable worker */ access_status = ap_proxy_pre_request(&worker, &balancer, r, conf, &url);
    ...}


    而r.filename来自与哪里呢,


    在http.conf配置了反代目的服务器为http服务器后,


    proxy_http_canon中进行了r→filename的设置


    这里根据反代配置,修正请求地址,并且把查询参数,附加在请求地址后,正是这里为我们引入了可控的查询字符.


    从Apache整体结构入手分析Apache CVE-2021-40438


    proxy_http_canon注册在canon_handler,canon_handler其实是一个mod_proxy声明的一个hook,


    在mod_proxy的proxy_fixup中调用了proxy_run_canon_handler,触发了这个hook,


    而proxy_fixup正是注册在请求流程的fixups hook中的。



    后记


    参考资料


    http://httpd.apache.org/docs/2.4/en/developer/


    https://articles.zsxq.com/id_8fvzqudhj1fm.html


    《Apache源代码全景分析》


    https://www.leavesongs.com/PENETRATION/apache-mod-proxy-ssrf-cve-2021-40438.html


    扫描关注公众号回复加群

    和师傅们一起讨论研究~


    WgpSec狼组安全团队

    微信号:wgpsec

    Twitter:@wgpsec


    从Apache整体结构入手分析Apache CVE-2021-40438
    从Apache整体结构入手分析Apache CVE-2021-40438


    原文始发于微信公众号(WgpSec狼组安全团队):从Apache整体结构入手分析Apache CVE-2021-40438

    版权声明:admin 发表于 2021年11月8日 上午9:00。
    转载请注明:从Apache整体结构入手分析Apache CVE-2021-40438 | CTF导航

    相关文章

    暂无评论

    您必须登录才能参与评论!
    立即登录
    暂无评论...