├── 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