WEB前端逆向拦截页面跳转

一、背景介绍

云海碰上个URL,没开F12的情况下,访问中途会自动跳转到「aboub:blank」。起初因为其他原因,他没往js反调试上想,出于对浏览器二进制漏洞的敏感,想别的方向去了。

我看了一下目标URL,用「Script First Statement」断点一个个看过去

————————————————————————–
Event Listener Breakpoints
Script
Script First Statement
————————————————————————–

确认跳转发生时流程位于一个混淆过的js中,obfuscation那种风格的。应该就是反调试代码干的,不知为何误判在F12调试,从而跳转。Babel反混淆js,再Overrides,应该能看出误判原因。这个站有其他选择,不必面对自动跳转,我们也是正常访问,又不是要搞它,所以不考虑反混淆js细究。

我想快速断在目标js中,找到触发跳转的js代码,确认是它导致的,仅此而已。问题演变成一个通用技术问题,知道某页面中途发生跳转,如何快速定位跳转代码所在。

本文记录了提出问题、解决问题的学习过程。

二、js跳转页面

向AI提问,AI回答如下

————————————————————————–
Q:

js将当前页面跳转到「aboub:blank」,大概怎么写?

A:

window.location.href = “about:blank”;
window.open( “about:blank”, “_self” );

Q:

_self怎么理解,可以是什么值?

A:

_blank 在新窗口或标签页中打开
_self 在当前窗口或标签页中打开 (默认行为)
_parent 在当前窗口父级框架中打开,若页面没有父级,则表现为_self
_top 在最顶层框架中打开,即使嵌套了多个iframe,也会在整个窗口中打开
————————————————————————–

AI回答,不背书,未查官方文档,可在F12 Console中实测。或有其他方案,但猜测目标js大概率使用前述两种方案之一,更可能是href那种。

三、beforeunload事件

网友UID(3110320275)提供了两组解决方案,第二组是他参考另一网友解答后对第一组的改进。

1) 方案1 (较重)

a. 写一个beforeunload事件监听方法,在Console中输入进去
b. 在F12 Sources面板启用「Event Listener Breakpoints->Load->beforeunload」
c. 触发页面跳转行为,查看调用栈回溯

步骤a代码如下

————————————————————————–
window.addEventListener(
‘beforeunload’,
function ( event ) {
/*
* 这些console.log无所谓
*/
console.log( window.location.href );
console.log( event );
/*
* 若有这句,F8继续时Chrome弹框提示Leave或Cancel。若无这句,F8继续
* 时不弹框提示,直接跳转。若只为查看调用栈回溯,并不打算阻止跳转,
* 不需要这句。
*
* 上面是一般情况。云海那个目标URL似乎存在某种对抗措施,即使有这句,
* Chrome也不弹框提示Leave或Cancel,而直接跳转,暂不清楚原因。
*/
event.preventDefault();
}
);
————————————————————————–

步骤c可在Console中输入

window.location.href = “about:blank”;

步骤b所设断点命中,停在function(event)的入口代码处,上例就是第一条log()处。此时调用栈的上一层就是「window.location.href = …」。

离开function(event)后,Chrome弹框提示Leave或Cancel,前者完成跳转,后者放弃跳转。若放弃跳转,可重复步骤c,再次测试整个流程。

2) 方案2

a. 写一个beforeunload事件监听方法,在Console中输入进去
b. 触发页面跳转行为,查看调用栈回溯

步骤a代码如下

————————————————————————–
window.addEventListener(
‘beforeunload’,
function ( event ) {
event.preventDefault();
debugger;
}
);
————————————————————————–

步骤b可在Console中输入

window.location.href = “about:blank”;

相比方案1,略去原步骤b,用debugger语句断下来,操作更简洁。

四、navigate事件

网友UID(6161718960)在github提供基于navigate事件的解决方案,参看

https://github.com/LingYanSi/blog/issues/167

————————————————————————–
/*
* 通过js触发的页面跳转
*/
navigation.addEventListener(
‘navigate’,
( event ) => {
console.log( event );
/*
* 若有这句,F8继续时不跳转。若无这句,F8继续时发生跳转。若只为查
* 看调用栈回溯,并不打算阻止跳转,不需要这句。
*
* 对href而言,navigate事件在beforeunload事件之前,若有这句,后续
* 触发beforeunload事件,若无这句,后续不会触发beforeunload事件。
*/
event.preventDefault();
debugger;
}
);
————————————————————————–
/*
* 通过a/form标签触发的页面跳转
*/
window.addEventListener(
‘click’,
( event ) => {
const findParent = ( d, check ) => {
while ( d ) {
if ( check( d ) ) {
return d;
}
d = d.parentElement;
}
return null;
}
const dom = findParent( event.target, (d) => /^(a|form)$/i.test(d.tagName) );
dom && console.log( ‘dom element’, dom );
},
{
capture: true
}
)
————————————————————————–

在Console中测试

window.location.href = “about:blank”;

测了第一段代码,满足原始需求。第二段代码未碰上测试场景,备忘。

五、满足原始需求

云海那个目标URL,用这组测试方案

————————————————————————–
Event Listener Breakpoints
Script
Script First Statement
————————————————————————–
navigation.addEventListener(
‘navigate’,
( event ) => {
event.preventDefault();
debugger;
}
);
————————————————————————–

确认在那个混淆js中执行

window.document.location = “about:blank”;

由于preventDefault(),不会跳转。后续会触发无限debugger,关掉F12之后,页面功能符合预期。

本文原始需求的解决方案可能存在各种对抗措施,未碰上非解决不可的场景,打住。

Spread the word. Share this post!

Meet The Author