U验证任意文件读取(CVE-2024-26559)
U验证任意文件读取(CVE-2024-26559)
076w中文:
U验证网络用户管理系统存在任意文件读取漏洞
搜索引擎: body=”U用户验证系统1.0”
Github: https://github.com/51154393/uverif
Gitee: https://gitee.com/dagg/uverif
后台任意文件读取
当前最新测试版本为v2.0.4-beta,正式发布版本为v2.0,均存在此类漏洞
其漏洞点在于登录后台后生成卡密导出的下载处
http://127.0.0.1/admin/download?path=./app/data/kami/202401210556174.txt
修改路径即可构造任意文件读取, “./“代表当前目录,可读取数据库配置文件,当前管理员账户密码等
http://127.0.0.1/admin/download?path=./config/admin.php
http://127.0.0.1/admin/download?path=./config/config.php
查看源码
https://github.com/51154393/uverif/blob/main/Ue/tools/download.php
这是一个PHP命名空间为Ue\tools的类download的代码。该类提供了一个静态方法download,用于下载文件。
方法接受两个参数:$filename表示要下载的文件路径,$downLoadName表示下载时保存的文件名(可选,默认为原始文件名)。
该方法的主要逻辑如下:
- 首先检查$downLoadName是否为空,如果为空则将其设为$filename。
- 检查$filename中是否包含.,如果不包含则返回false,表示无法确定文件类型。
- 设置响应的MIME类型为application/octet-stream,表示通用的二进制文件类型。
- 使用fopen函数以只读方式打开文件,并通过fread函数读取文件的内容。
- 关闭文件句柄。
- 判断客户端的HTTP_USER_AGENT中是否包含”MSIE”,如果是,则设置一系列响应头信息,包括Content-Type、Content-Disposition等,以支持在IE浏览器中下载文件。
- 如果不是IE浏览器,则设置另一组响应头信息。
- 最后使用exit函数输出文件内容,并结束脚本的执行。
当前搭建环境为Windows系统且检查$filename中是否包含”.”,所以尝试读取win.ini文件
C:\Windows\win.ini
尝试读取hosts文件,检查“.”所以在hosts文件后加“.”
原理是Windows系统默认删除文件后缀的“.”和空格。若网站后端过滤时没有过滤末尾的点,便可进行绕过。
C:\Windows\System32\drivers\etc\hosts.
尝试读取linux系统下文件
/etc/resolv.conf
前台任意文件读取
尝试扩大危害,将漏洞升级
观察 Cookie 字段中 admcookies 为 jwt 加密,尝试解密
查看源码分析构造
https://github.com/51154393/uverif/blob/main/Ue/tools/Jwt.php
JWT(JSON Web Token)是一种用于身份验证和授权的开放标准。它由三部分组成:头部(header)、载荷(payload)和签名(signature)。
在给定的代码中,JWT的参数生成如下:
- 头部(header):使用算法HS256(HMAC SHA-256)生成签名,在代码中表示为’alg’ => ‘HS256’。
- 载荷(payload):包含了一些声明信息,可根据需要自定义。在代码中,载荷包含以下字段:
- iss:表示该JWT的签发者。
- iat:表示签发时间,使用time()函数获取当前时间。
- exp:表示过期时间,当前时间加上24小时。
- nbf:该时间之前不接收处理该Token。
- sub:表示面向的用户,默认为当前请求的域名。
- jti:表示该Token的唯一标识,使用md5(uniqid(‘JWT’) . time())生成。
- claim:表示自定义数据,可根据需要设置。
- 签名(signature):使用密钥(key)对头部和载荷进行签名生成。签名算法使用HS256,通过调用self::signature()方法实现。
最终,通过将base64编码后的头部、载荷和签名拼接在一起,并用”.”分隔,形成JWT Token。
用python生成Cookie
1 | import hashlib |
抓取登陆数据包,替换生成的Cookie并发包
访问漏洞url,并替换Cookie发包即可
http://127.0.0.1/admin/download?path=./config/config.php
批量检测POC:
url.txt存放检测的url,源码直接运行,无需修改
1 | import requests |
English:
There is an arbitrary file reading vulnerability in the U-verification network user management system
search engine: body=”U用户验证系统1.0”
Official website: https://user.uverif.com/
Github: https://github.com/51154393/uverif
Gitee: https://gitee.com/dagg/uverif
Read any file in the background
The latest test version is v2.0.4-beta and the officially released version is v2.0, both of which have such vulnerabilities.
The vulnerability lies in the download place where the card password is exported after logging in to the backend.
http://127.0.0.1/admin/download?path=./app/data/kami/202401210556174.txt
Modify the path to construct any file to read, “./“ represents the current directory, and can read the database configuration file, current administrator account password, etc.
http://127.0.0.1/admin/download?path=./config/admin.php
http://127.0.0.1/admin/download?path=./config/config.php
View source code
https://github.com/51154393/uverif/blob/main/Ue/tools/download.php
This is a code for class download in the PHP namespace Ue\tools. This class provides a static method download for downloading files.
The method accepts two parameters: $filename represents the path of the file to be downloaded, $downLoadName represents the file name saved during downloading (optional, defaults to the original file name).
The main logic of this method is as follows:
- First check whether $downLoadName is empty, and if it is empty, set it to $filename.
- Check whether $filename contains ., if not, return false, indicating that the file type cannot be determined.
- Set the response MIME type to application/octet-stream, which represents a common binary file type.
- Use the fopen function to open the file in read-only mode, and read the contents of the file through the fread function.
- Close the file handle.
- Determine whether the client’s HTTP_USER_AGENT contains “MSIE”. If so, set a series of response header information, including Content-Type, Content-Disposition, etc., to support downloading files in the IE browser.
- If it is not an IE browser, set another set of response header information.
- Finally, use the exit function to output the file content and end the execution of the script.
The current build environment is a Windows system and check whether $filename contains “.”, so try to read the win.ini file
C:\Windows\win.ini
Try to read the hosts file and check “.” so add “.” after the hosts file.
The principle is that the Windows system deletes the “.” and spaces in the file suffix by default. If the back-end filtering of the website does not include the dot at the end of the filter, it can be bypassed.
C:\Windows\System32\drivers\etc\hosts.
Try to read files under linux system
/etc/resolv.conf
Read any file in the foreground
Try to expand the harm and upgrade the vulnerability
Observe that admcookies in the Cookie field is encrypted by jwt and try to decrypt it.
View source code analysis structure
https://github.com/51154393/uverif/blob/main/Ue/tools/Jwt.php
JWT (JSON Web Token) is an open standard for authentication and authorization. It consists of three parts: header, payload and signature.
In the given code, the parameters of the JWT are generated as follows:
- Header: Use algorithm HS256 (HMAC SHA-256) to generate a signature, represented in the code as ‘alg’ => ‘HS256’.
- Payload: Contains some declaration information and can be customized as needed. In the code, the payload contains the following fields:
- iat: indicates the issuance time, use the time() function to obtain the current time.
- iss: Indicates the issuer of the JWT.
- exp: indicates the expiration time, the current time plus 24 hours.
- nbf: The Token will not be processed before this time.
- sub: indicates the user targeted, defaulting to the currently requested domain name.
- jti: represents the unique identifier of the Token, generated using md5(uniqid(‘JWT’) . time()).
- claim: represents custom data, which can be set as needed.
- Signature: Use the key to generate signatures for the header and payload. The signature algorithm uses HS256 and is implemented by calling the self::signature() method.
Finally, the JWT Token is formed by splicing the base64-encoded header, payload and signature together and separating them with “.”.
Generate cookies using python
1 | import hashlib |
Capture the login data packet and replace the generated Cookie concurrent packet
Visit the vulnerability URL and replace the cookie to send the package.
http://127.0.0.1/admin/download?path=./config/config.php
Batch testing POC:
Try to write a python script to construct jwt and write a poc
url.txt stores the detected URL, and the source code can be run directly without modification.
1 | import requests |