├── serial-whitelist-application-trainer ├── src │ └── main │ │ ├── resources │ │ └── META-INF │ │ │ └── MANIFEST.MF │ │ └── java │ │ └── swat │ │ ├── SwatAgent.java │ │ └── WhitelistBuildingTransformer.java └── pom.xml ├── .gitignore ├── NOTICE.md └── README.md /serial-whitelist-application-trainer/src/main/resources/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Premain-Class: swat.SwatAgent 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | 3 | # Mobile Tools for Java (J2ME) 4 | .mtj.tmp/ 5 | 6 | # Package Files # 7 | *.jar 8 | *.war 9 | *.ear 10 | 11 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 12 | hs_err_pid* 13 | -------------------------------------------------------------------------------- /NOTICE.md: -------------------------------------------------------------------------------- 1 | Feel free to use or modify this OpenSource agent as it fits your needs. 2 | 3 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 4 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 5 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 6 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 7 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 8 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 9 | OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SWAT (Serial Whitelist Application Trainer) 2 | 3 | This is a simple JVM instrumentation agent, which helps you to build a whitelist 4 | for classic Java deserialization occurrences as well as XStream based ones. Once (on a test server) the instrumentation runs, it creates and logs files (under the folder where the JVM process was started from) with the observed deserialization classes. This can be used to build a reasonable whitelist by observing the deserializations on a test server. 5 | 6 | Usage: 7 | Add as agent to the JVM start via -javaagent:/pointing/to/this/swat-agent-file.jar 8 | 9 | Resulting whitelist will get logged to stdout and also into file whitelist.swat 10 | 11 | -------------------------------------------------------------------------------- /serial-whitelist-application-trainer/src/main/java/swat/SwatAgent.java: -------------------------------------------------------------------------------- 1 | package swat; 2 | 3 | import java.io.IOException; 4 | import java.lang.instrument.ClassFileTransformer; 5 | import java.lang.instrument.Instrumentation; 6 | 7 | public class SwatAgent { 8 | 9 | // invoked when agent is started via -javaagent switch before application 10 | public static void premain(String args, Instrumentation instrumentation) throws IOException { 11 | System.out.println("Registering SWAT agent through premain"); 12 | initialize(args, instrumentation); 13 | } 14 | 15 | // invoked when agent is attached via Sun tools API while application is running 16 | public static void agentmain(String args, Instrumentation instrumentation) throws IOException { 17 | System.out.println("Registering SWAT agent through agentmain"); 18 | initialize(args, instrumentation); 19 | } 20 | 21 | private static void initialize(String args, Instrumentation instrumentation) { 22 | ClassFileTransformer classFileTransformer = new WhitelistBuildingTransformer(); 23 | instrumentation.addTransformer(classFileTransformer); 24 | } 25 | 26 | public static void main(String[] args) { 27 | System.out.println("Usage: add as agent to the JVM start via -javaagent:/pointing/to/this/agent-file.jar"); 28 | System.out.println("Resulting whitelist will get logged to stdout and also into file whitelist.swat"); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /serial-whitelist-application-trainer/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | swat 5 | serial-whitelist-application-trainer 6 | 0.0.1-SNAPSHOT 7 | Serial Whitelist Application Trainer 8 | 9 | 10 | 1.7 11 | 1.7 12 | 13 | 14 | 15 | 16 | org.javassist 17 | javassist 18 | 3.20.0-GA 19 | 20 | 21 | 22 | 23 | 24 | 25 | maven-assembly-plugin 26 | 27 | 28 | package 29 | 30 | single 31 | 32 | 33 | 34 | 35 | 36 | jar-with-dependencies 37 | 38 | 39 | src/main/resources/META-INF/MANIFEST.MF 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /serial-whitelist-application-trainer/src/main/java/swat/WhitelistBuildingTransformer.java: -------------------------------------------------------------------------------- 1 | package swat; 2 | 3 | import java.lang.instrument.ClassFileTransformer; 4 | import java.lang.instrument.IllegalClassFormatException; 5 | import java.security.ProtectionDomain; 6 | 7 | import javassist.ClassPool; 8 | import javassist.CtClass; 9 | import javassist.CtField; 10 | import javassist.CtMethod; 11 | import javassist.LoaderClassPath; 12 | 13 | public class WhitelistBuildingTransformer implements ClassFileTransformer { 14 | 15 | public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, 16 | ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { 17 | if ("java/io/ObjectInputStream".equals(className)) { 18 | return applyWhitelistBuildingCodeOIS(loader, classfileBuffer); 19 | } else if ("com/thoughtworks/xstream/mapper/DefaultMapper".equals(className)) { 20 | return applyWhitelistBuildingCodeXStream(loader, classfileBuffer); 21 | } 22 | return null; 23 | } 24 | 25 | 26 | private byte[] applyWhitelistBuildingCodeOIS(ClassLoader loader, byte[] classfileBuffer) { 27 | try { 28 | ClassPool classPool = ClassPool.getDefault(); 29 | classPool.appendClassPath(new LoaderClassPath(loader)); 30 | CtClass ctClass = classPool.get("java.io.ObjectInputStream"); 31 | 32 | ctClass.addField( CtField.make("private static java.util.Set whitelist = new java.util.HashSet();", ctClass) ); 33 | ctClass.addField( CtField.make("private static java.io.FileWriter exportWriter = new java.io.FileWriter(\"whitelist-ois.swat\");", ctClass) ); 34 | ctClass.addField( CtField.make("private static java.io.FileWriter exportWithStacktracesWriter = new java.io.FileWriter(\"whitelist-ois-with-stacktraces.swat\");", ctClass) ); 35 | 36 | ctClass.addMethod( CtMethod.make("protected static synchronized void addToWhitelist(Object what) {" 37 | + " if (what != null && what instanceof java.io.ObjectStreamClass) {" 38 | + " java.io.ObjectStreamClass candidate = (java.io.ObjectStreamClass)what;" 39 | + " if (!whitelist.contains(candidate.getName())) {" 40 | + " whitelist.add(candidate.getName());" 41 | + " String name = candidate.getName();" 42 | + " System.out.println(\"Adding to SWAT OIS whitelist:\"+name);" 43 | + " exportWriter.write(name+\"\\n\");" 44 | + " exportWriter.flush();" 45 | + " exportWithStacktracesWriter.write(name+\"\\n---\\n\");" 46 | + " StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();" 47 | + " for (int i=2; i