浏览器的开发者工具(DevTools),可通过热键F12、热键Ctrl+Shift+I、右键菜单等方法进行打开。
(这是开发者工具的全貌)
防-屏蔽开发者工具的调用
既然知道DevTools的打开方式会通过热键、右键菜单,那么最基础的,可以通过屏蔽热键、右键菜单的方式进行反调试。
屏蔽热键:
onkeydown = function() { function ban() { window.event.cancelBubble = true; window.event.returnValue = false; window.event.keyCode = 0; return false; } if(window.event && (window.event.keyCode === 123 || window.event.which === 123)) { ban(); } if(window.event && window.event.ctrlKey && window.event.shiftKey && window.event.keyCode==73) { ban(); } }
通过在keydown上添加一个EventListener实现热键屏蔽。
屏蔽右键菜单:
oncontextmenu = function(){return false;}
同理的,在contextmenu添加一个EventListener实现右键菜单屏蔽。
攻-绕过热键屏蔽和右键菜单屏蔽
打开开发者工具,不仅仅可以通过组合键以及右键菜单进行打开,还可以通过工具栏进行打开。
工具栏打开绕过屏蔽:
无论网页的JS如何屏蔽,也是无法屏蔽从外部调用的开发者工具。
防-反制工具栏打开的绕过方法
的确,网页的JS无法屏蔽从网页外调用的开发者工具,但仍然可以通过开发者工具打开时的特征来判断开发者工具是否被打开,然后通过无限debugger来让打开的开发者工具也无法正常使用。
监控window.visualViewport的高度与宽度变化并无限debugger:
var width = window.visualViewport.width; var height = window.visualViewport.height; setInterval(function () { var new_width = window.visualViewport.width; var new_height = window.visualViewport.height; if(new_width<width||new_height<height){ eval(\'!function(){debugger}()\') } },800)
DevTools检测(Chrome)并无限debugger:
var element = new Image(); Object.defineProperty ( element,\'id\', { get:function() { debugger; } } ); setInterval(function(){console.log(element)},800);
这样,可以使得开发者工具无限debugger而无法正常使用。
攻-绕过无限debugger
上一个防御手段中,最关键的技术是无限debugger,而这一手段并非无法绕过,在我之前的文章《paused in debugger解决方法总结》中,就有方法来绕过无限debugger。
那么,如果不采用无限debugger,是否可以反制这个绕过手段呢?
防-反制绕过无限debugger
当检测到开发者工具打开,直接关闭页面,那么绕过手段将失效,毕竟最难组织的,是自毁。
页面自毁:
var element = new Image(); Object.defineProperty ( element,\'id\', { get:function() { window.opener = null; window.open(\'\',\'_self\'); window.close(); } } ); console.log(element);
目前这个似乎只能配合DevTool检测方法,如果配合监控window.visualViewport,则会直接自毁(没有打开开发者工具也是),原因不明。
攻-绕过页面自毁
防守的手段哪怕再丰富,归根到底也是利用了js来执行,而js属于前端代码,在我看来,前端即是用户可以随意更改的地方,因此,只要让js无法执行,或者篡改前端,把这些js语句删掉,那么再厉害的js语句也无济于事。
在这里,我们使用抓包软件如burpsuite,直接篡改前端,即可绕过一切防守措施。
结尾
攻与防永远是不会停止的,到最后,似乎攻击者使用了抓包软件,就能彻底打败防守者,但事实真的是如此吗?
如果防守者将JS代码进行高强度的混淆、加密,使攻击者看不懂也不敢乱删改,那么防守者仍然能反制成功。
同样的,如果攻击者的代码水平并不低于防守者,能看破JS的混淆与加密,那么攻击者仍然能绕过。
攻与防是总是永不停息,唯有不断的学习,才能摘得胜利的果实。