• Pwn2Own Austin 2021 Cisco RV34x RCE 漏洞链复现


    前言

    这个RCE漏洞利用链的实现是由几个逻辑洞的结合而导致的,这几天我花了一些时间复现了一遍,在此记录一下。

    固件解压

    我下载的是RV345 v1.0.03.24,从官网下载到压缩包解压之后可以看到它的rootfsubi格式的img。之前我都是使用kali里的 binwalk 对其进行解压可以直接得到解压之后的文件系统。但是由于前几天我的虚拟机坏了,不得不进行重装,但是我还没有装 kali。故找了一下提取ubi格式的方式。在github上有一个项目:https://github.com/nlitsme/ubidump ,通过里面的ubidump.py可以很轻松的提取出ubi格式的文件。命令如下:

    python3 ubidump.py -s . 0.ubi
    

    漏洞分析

    CVE-2022-20705 Improper Session Management Vulnerability

    CVE-2022-20705 Improper Session Management Vulnerability,是由于nginx的配置不当导致的。nginx的配置文件是/etc/nginx/nginx.conf,如下

    user www-data;
    worker_processes  4;
    
    error_log /dev/null;
    
    events {
        worker_connections  1024;
    }
    
    http {
    	access_log off;
    	#error_log /var/log/nginx/error.log  error;
    
    	upstream jsonrpc {
    		server 127.0.0.1:9000;
    	}
    
    	upstream rest {
    		server 127.0.0.1:8008;
    	}
    
    	# For websocket proxy server
    	include /var/nginx/conf.d/proxy.websocket.conf;
    	include /var/nginx/sites-enabled/*;
    }
    

    可以发现它又加载了/var/nginx/conf.d/proxy.websocket.conf和/var/nginx/sites-enabled/,但是固件解压出来的rootfs里的var目录有些问题,所以笔者只能根据别人的文章找一下漏洞发生的配置文件。结合rest.url.confproxy.conf来看。

    location /api/ {
            proxy_pass http://rest;
            include /var/nginx/conf.d/proxy.conf;
    }
    
    location /api/operations/ciscosb-file:file-copy {
    	proxy_pass http://rest;
    	include /var/nginx/conf.d/proxy.conf;
    	proxy_read_timeout 3600;
    	proxy_send_timeout 3600;
    }
    
    location /api/operations/ciscosb-file:form-file-upload {
    	set $deny 1;
     
    	if ($http_authorization != "") {
    		set $deny "0";
    	}
    
    	if ($deny = "1") {
    		return 403;
    	}
    
    
    	upload_pass /form-file-upload;
    	upload_store /tmp/upload;
    	upload_store_access user:rw group:rw all:rw;
    	upload_set_form_field $upload_field_name.name "$upload_file_name";
    	upload_set_form_field $upload_field_name.content_type "$upload_content_type";
    	upload_set_form_field $upload_field_name.path "$upload_tmp_path";
    	upload_aggregate_form_field "$upload_field_name.md5" "$upload_file_md5";
    	upload_aggregate_form_field "$upload_field_name.size" "$upload_file_size";
    	upload_pass_form_field "^.*$";
    	upload_cleanup 400 404 499 500-505;
    	upload_resumable on;
    }
    
    location /restconf/ {
            proxy_pass http://rest;
            include /var/nginx/conf.d/proxy.conf;
    }
    
    location /restconf/operations/ciscosb-file:file-copy {
            proxy_pass http://rest;
            include /var/nginx/conf.d/proxy.conf;
            proxy_read_timeout 3600;
            proxy_send_timeout 3600;
    }
    
    proxy_http_version 1.1;
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header Authorization $http_authorization;
    proxy_set_header Accept-Encoding "";
    proxy_set_header Connection "";
    proxy_ssl_session_reuse off;
    server_name_in_redirect off;
    

    如果我们请求中Authorization不为空,此时set $deny "0",就可以向下调用upload模块。它会在调用/form-file-upload前,把文件上传到/tmp/upload下。并且由于没有设置level,它的存储格式类似/tmp/upload/0000000001。至此我们可以实现任意文件上传至/tmp/upload

    我们接着向下分析,可以在rootfs/etc/nginx/conf.d下找到web.upload.conf如下:

    location /form-file-upload {
    	include uwsgi_params;
    	proxy_buffering off;
    	uwsgi_modifier1 9;
    	uwsgi_pass 127.0.0.1:9003;
    	uwsgi_read_timeout 3600;
    	uwsgi_send_timeout 3600;
    }
    
    location /upload {
    	set $deny 1;
    
            if (-f /tmp/websession/token/$cookie_sessionid) {
                    set $deny "0";
            }
    
            if ($deny = "1") {
                    return 403;
            }
    
    	upload_pass /form-file-upload;
    	upload_store /tmp/upload;
    	upload_store_access user:rw group:rw all:rw;
    	upload_set_form_field $upload_field_name.name "$upload_file_name";
    	upload_set_form_field $upload_field_name.content_type "$upload_content_type";
    	upload_set_form_field $upload_field_name.path "$upload_tmp_path";
    	upload_aggregate_form_field "$upload_field_name.md5" "$upload_file_md5";
    	upload_aggregate_form_field "$upload_field_name.size" "$upload_file_size";
    	upload_pass_form_field "^.*$";
    	upload_cleanup 400 404 499 500-505;
    	upload_resumable on;
    }
    

    我们可以发现其对/upload进行了$cookie_sessionid的检验,但是并没有对/form-file-upload进行检验。我们看一下/form-file-upload的后端处理程序。启动脚本(uwsgi-launcher)如下:

    #!/bin/sh /etc/rc.common
    
    export UWSGI_PLUGIN_DIR=/usr/lib/uwsgi/plugins
    
    start() {
            uwsgi -m --ini /etc/uwsgi/jsonrpc.ini &
            uwsgi -m --ini /etc/uwsgi/blockpage.ini &
            uwsgi -m --ini /etc/uwsgi/upload.ini &
    }
    
    stop() {
            killall -9 uwsgi
    }
    

    我们再去找一下/etc/uwsgi/upload.ini

    [uwsgi]
    plugins = cgi
    workers = 1
    master = 1
    uid = www-data
    gid = www-data
    socket=127.0.0.1:9003
    buffer-size=4096
    cgi = /www/cgi-bin/upload.cgi
    cgi-allowed-ext = .cgi
    cgi-allowed-ext = .pl
    cgi-timeout = 300
    ignore-sigpipe = true
    

    从上述文件中我们可以知道/form-file-upload它对应的后端处理程序是/www/cgi-bin/upload.cgi。因此我们可以无条件访问upload.cgi

    同时上述配置文件中我们可以看到检查了/tmp/websession/token/$cookie_sessionid文件是否存在。但是存在缺陷,就是这里的$cookie_sessionid是用户在http请求中传进去的一个值,它并没有检查是否存在../../,也就是说我们可以通过跨目录来导致授权绕过。如:我们可以传递../../../etc/firmware_version

    同时也可以看到在upload.cgi里对sessionid=进行了检查,限制了它的字符,但是并没有考虑到传多个sessionid=的情况。因为这里的sessionid=是遍历HTTP_COOKIE并且取出它最后一个sessionid=作为实际的sessionid=使用,所以我们可以传两个sessionid=。前一个用来绕过web.upload.conf里的判断,后一个当作正常的数据用来通过upload.cgi的判断。这样也可以实现无条件访问upload.cgi

    我们接着看upload.cgi

    传入适当的参数可以使得我们有能力任意文件移动到/tmp/www下,通过这两个漏洞我们也可以伪造出一个session

    CVE-2022-20707 Command Injection

    我们继续查看upload.cgi

    这个漏洞可以使得任意命令执行。

    参考链接

    https://bestwing.me/Pwning a Cisco RV340 漏洞分析(CVE-2022-20705 和 CVE-2022-20707.html

    https://blog.relyze.com/2022/04/pwning-cisco-rv340-with-4-bug-chain.html

    https://paper.seebug.org/1890/

    https://onekey.com/blog/advisory-cisco-rv34x-authentication-bypass-remote-command-execution/

    https://nosec.org/home/detail/4985.html

    文章首发

    https://mp.weixin.qq.com/s/2joZwexIdVdgc5NL8W3J-A


    __EOF__

  • 本文作者: 狒猩橙
  • 本文链接: https://www.cnblogs.com/pwnfeifei/p/17174093.html
  • 关于博主: 评论和私信会在第一时间回复。或者直接私信我。
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
  • 声援博主: 如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。
  • 相关阅读:
    每天分享几个面试题(六)
    Redis篇:缓存更新策略最佳实践
    Excel的Index+MATCH组合使用方法
    HTML小游戏12 —— 汽车赛道飙车游戏(附完整源码)
    JS基础之实现数组reduce方法
    git奇怪报错
    Springboot餐饮点餐系统毕业设计源码301749
    C/C++简单计算器 2019年12月电子学会青少年软件编程(C/C++)等级考试一级真题答案解析
    总结网络中的一些基本概念——javaee
    PyTorch框架中torch、torchvision、torchaudio与python之间的版本对应关系(9月最新版)
  • 原文地址:https://www.cnblogs.com/pwnfeifei/p/17174093.html