ysoserial
ysoserial是一個可以生成反序列化payload的工具,它可以讓用戶根據自己選擇的利用鏈,生成反序列化利用資料,通過將這些資料發送給目標,從而執行用戶預先定義的命令,用法:
點擊查看代碼
$ java -jar ysoserial.jar
Y SO SERIAL?
Usage: java -jar ysoserial.jar [payload] '[command]'
Available payload types:
Payload Authors Dependencies
------- ------- ------------
AspectJWeaver @Jang aspectjweaver:1.9.2, commons-collections:3.2.2
BeanShell1 @pwntester, @cschneider4711 bsh:2.0b5
C3P0 @mbechler c3p0:0.9.5.2, mchange-commons-java:0.2.11
Click1 @artsploit click-nodeps:2.3.0, javax.servlet-api:3.1.0
Clojure @JackOfMostTrades clojure:1.8.0
CommonsBeanutils1 @frohoff commons-beanutils:1.9.2, commons-collections:3.1, commons-logging:1.2
CommonsCollections1 @frohoff commons-collections:3.1
CommonsCollections2 @frohoff commons-collections4:4.0
CommonsCollections3 @frohoff commons-collections:3.1
CommonsCollections4 @frohoff commons-collections4:4.0
CommonsCollections5 @matthias_kaiser, @jasinner commons-collections:3.1
CommonsCollections6 @matthias_kaiser commons-collections:3.1
CommonsCollections7 @scristalli, @hanyrax, @EdoardoVignati commons-collections:3.1
FileUpload1 @mbechler commons-fileupload:1.3.1, commons-io:2.4
Groovy1 @frohoff groovy:2.3.9
Hibernate1 @mbechler
Hibernate2 @mbechler
JBossInterceptors1 @matthias_kaiser javassist:3.12.1.GA, jboss-interceptor-core:2.0.0.Final, cdi-api:1.0-SP1, javax.interceptor-api:3.1, jboss-interceptor-spi:2.0.0.Final, slf4j-api:1.7.21
JRMPClient @mbechler
JRMPListener @mbechler
JSON1 @mbechler json-lib:jar:jdk15:2.4, spring-aop:4.1.4.RELEASE, aopalliance:1.0, commons-logging:1.2, commons-lang:2.6, ezmorph:1.0.6, commons-beanutils:1.9.2, spring-core:4.1.4.RELEASE, commons-collections:3.1
JavassistWeld1 @matthias_kaiser javassist:3.12.1.GA, weld-core:1.1.33.Final, cdi-api:1.0-SP1, javax.interceptor-api:3.1, jboss-interceptor-spi:2.0.0.Final, slf4j-api:1.7.21
Jdk7u21 @frohoff
Jython1 @pwntester, @cschneider4711 jython-standalone:2.5.2
MozillaRhino1 @matthias_kaiser js:1.7R2
MozillaRhino2 @_tint0 js:1.7R2
Myfaces1 @mbechler
Myfaces2 @mbechler
ROME @mbechler rome:1.0
Spring1 @frohoff spring-core:4.1.4.RELEASE, spring-beans:4.1.4.RELEASE
Spring2 @mbechler spring-core:4.1.4.RELEASE, spring-aop:4.1.4.RELEASE, aopalliance:1.0, commons-logging:1.2
URLDNS @gebl
Vaadin1 @kai_ullrich vaadin-server:7.7.14, vaadin-shared:7.7.14
Wicket1 @jacob-baines wicket-util:6.23.0, slf4j-api:1.6.4
因為該專案里面就包含了URLDNS的payload生成類,可以用該專案除錯分析URLDNS鏈
URLDNS
URLDNS鏈是一條檢測鏈,因為不能“利用”的原因,他只能進行一次DNS請求,并不能執行命令,但因為其如下的優點,非常適合我們在檢測反序列化漏洞時使用:
- 使用Java內置的類構造,對第三方庫沒有依賴
- 在目標沒有回顯的時候,能夠通過DNS請求得知是否存在反序列化漏洞
通過ysoserial專案分析URLDNS呼叫鏈
下載原始碼,然后用Intellij IDEA打開,等待maven依賴加載完畢(需要一段時間),找到pom.xml檔案,找到專案入口主類GeneratePayload.java

然后找到ysoserial.payloads.URLDNS.java類,該類可以生成這條鏈的payload,首先在注釋就可以看到利用鏈

然后看到getObject方法,ysoserial會調?用這個方法獲得 Payload,這個方法回傳的是一個物件,這個物件就是最后將被序列化的物件,在這里是HashMap
{:height="50%" }
而HashMap也就是該鏈的關鍵,因為實作了Serializable介面,有readObject方法,看到HashMap的readObject方法
點擊查看代碼
private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException {
ObjectInputStream.GetField fields = s.readFields();
// Read loadFactor (ignore threshold)
float lf = fields.get("loadFactor", 0.75f);
if (lf <= 0 || Float.isNaN(lf))
throw new InvalidObjectException("Illegal load factor: " + lf);
lf = Math.min(Math.max(0.25f, lf), 4.0f);
HashMap.UnsafeHolder.putLoadFactor(this, lf);
reinitialize();
s.readInt(); // Read and ignore number of buckets
int mappings = s.readInt(); // Read number of mappings (size)
if (mappings < 0) {
throw new InvalidObjectException("Illegal mappings count: " + mappings);
} else if (mappings == 0) {
// use defaults
} else if (mappings > 0) {
float fc = (float)mappings / lf + 1.0f;
int cap = ((fc < DEFAULT_INITIAL_CAPACITY) ?
DEFAULT_INITIAL_CAPACITY :
(fc >= MAXIMUM_CAPACITY) ?
MAXIMUM_CAPACITY :
tableSizeFor((int)fc));
float ft = (float)cap * lf;
threshold = ((cap < MAXIMUM_CAPACITY && ft < MAXIMUM_CAPACITY) ?
(int)ft : Integer.MAX_VALUE);
// Check Map.Entry[].class since it's the nearest public type to
// what we're actually creating.
SharedSecrets.getJavaOISAccess().checkArray(s, Map.Entry[].class, cap);
@SuppressWarnings({"rawtypes","unchecked"})
Node<K,V>[] tab = (Node<K,V>[])new Node[cap];
table = tab;
// Read the keys and values, and put the mappings in the HashMap
for (int i = 0; i < mappings; i++) {
@SuppressWarnings("unchecked")
K key = (K) s.readObject();
@SuppressWarnings("unchecked")
V value = https://www.cnblogs.com/yiaho/p/(V) s.readObject();
putVal(hash(key), key, value, false, false);
}
}
}
這里呼叫的hash方法

繼續跟入發現又呼叫的key物件的hashCode方法

URLDNS 中使用的這個key是一個java.net.URL物件,看看其hashCode 方法發現又呼叫了handler的hashCode方法:

繼續跟進:

再跟進getHostAddress方法:

發現是URL類里的getHostAddress方法的呼叫,再跟進一步:

InetAddress.getByName(host)的作用是根據主機名,獲取其IP地址,在網路上其實就是一次DNS查詢,這也就是這條鏈的觸發點
因此這條鏈跟到這里就結束了,呼叫鏈如下:
1. HashMap->readObject()
2. HashMap->hash()
3. URL->hashCode()
4. URLStreamHandler->hashCode()
5. URLStreamHandler->getHostAddress()
6. InetAddress->getByName()
實際測驗
撰寫如下代碼:
點擊查看代碼
import java.net.URL;
import java.util.HashMap;
public class Demo{
public static void main(String[] args) throws Exception {
HashMap<URL, String> hashMap = new HashMap<URL, String>();
URL url = new URL("http://yiaho.ygzip5.dnslog.cn");//dnslog.cn平臺新建鏈接
url.hashCode();
}
}
首先進入hashCode函式,呼叫的URLStreamHandler里的hashCode函式

然后來到URLStreamHandler類的hashCode函式呼叫getHostAddress函式

連續跟進,最后再URL類的getHostAddress函式下呼叫了InetAddress.getByName


此時查看dnslog就會看到一次訪問記錄
參考文章:p神的java安全漫談
It is never too late to learn 個人博客:yiaho.cn轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/470618.html
標籤:其他
下一篇:交換機及路由基礎
