说明:
本文只针对新手入门了解,高手绕道。 只做技术性研究,请勿用于非法渠道。
目标
https://www.gm99.com/
前言
1、首先准备Chrome内核浏览器,我用的360极速版浏览器。 2、打开目标网址,按F12或者网页空白处右键审查元素(有的浏览器叫检查),打开开发者调试工具。 3、基础不好的看下之前简单得文章,这里不做过多描述。
正式开始
1、随意输入账号密码,点击登录,查看登录请求发现password:被加密。如下图: 2、懂一点前端应该可以看到这个用的jquery里面有个ajax请求,鼠标放到juqury-1.7.1.js上可以看到,这个发表的函数调用顺序,也就是栈。 3、点击函数后面提示可以跟到函数调用位置,一般情况如果能看到ajax发包,进上一步,基本就是组包位置。如果调用比较复杂就需要跟栈了,这里ajax上一个s.login看字面意思大概率就是了。点进去看看。 4、可以看出明显ajax请求data就是传输的数据。这里可以看到,data=p 往上看p是一个对象其中包含password,等于r,再去看r等于g.encode(t.password, s)。大概率就是这个位置加密。 5、下断点,重新登录,断到183行,可以看到g.encode(t.password, s)第一个参数就是明文,第二参数时间戳。 控制台输出可以看到直接返回加密后的密文。 至此加密位置算是找到了,其实用之前几篇文章简单搜索关键词也是可以定位到这里。本次主要知识点是如何抠webpack模式代码。
webpack区分以及简要讲解。
当前断点位置是 g.encode(t.password, s)加密函数调用g对象,这个函数根本没有定义,肯定是对象中其他地方定义。往上翻如下图,g是new出来的,再看大方法, function(t, e, n) 前面是个逗号。 再往上看,这个函数是被括号+中括号包裹起来的说明,是一个数组,可以理解pytohn中一个列表中包含多个def函数。最外层的括号,是执行函数传参,一直翻到上面函数开始位置。发现是一个自执行函数。 为了方便查看复制整个代码到本地notepad++语言选择javascript,视图中折叠所有。展开第一个函数,和函数自执行括号中参数如下图。 这个就是webpack的结构体。
本地模拟下大概这个样子:
!function(x){
function xxx() {
return x.call(x,x1,x2,x3),
}
}(
[函数一,函数二,函数三]
)
webpack抠代码流程
1、找到加载器(加载模块的方法) 2、找到要调用的模块 3、构造一个自执行方法
一、直接复制网站加载器模块:
!function(i) {
var s = {};
function n(t) {
if (s[t])
return s[t].exports;
var e = s[t] = {
i: t,
l: !1,
exports: {}
};
return i[t].call(e.exports, e, e.exports, n),
e.l = !0,
e.exports
}
}(
)
好了下一步找到加密用的的模块也就是函数填入自执行方法的括号中,用n方法加载就可以了。 鼠标放到加密位置点击提示,进入加密函数。 如图片: 发现这里也是一层封装, n.prototype.encode这个位置调用的this.jsencrypt.encrypt(i)位置才是真正的加密位置。先不管,这个方法也一起复制。加我们抠的代码中。
!function(i) {
var s = {};
function n(t) {
if (s[t])
return s[t].exports;
var e = s[t] = {
i: t,
l: !1,
exports: {}
};
return i[t].call(e.exports, e, e.exports, n),
e.l = !0,
e.exports
}
}(
{
jiami:function(t, e, r) {
var i;
(i = function(t, e, i) {
var s = r(3);
function n() {
void 0 !== s && (this.jsencrypt = new s.JSEncrypt,
this.jsencrypt.setPublicKey("-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDq04c6My441Gj0UFKgrqUhAUg+kQZeUeWSPlAU9fr4HBPDldAeqzx1UR92KJHuQh/zs1HOamE2dgX9z/2oXcJaqoRIA/FXysx+z2YlJkSk8XQLcQ8EBOkp//MZrixam7lCYpNOjadQBb2Ot0U/Ky+jF2p+Ie8gSZ7/u+Wnr5grywIDAQAB-----END PUBLIC KEY-----"))
}
n.prototype.encode = function(t, e) {
var i = e ? e + "|" + t : t;
return encodeURIComponent(this.jsencrypt.encrypt(i))
}
,
i.exports = n
}
.call(e, r, e, t)) === undefined || (t.exports = i)
}
}
)
现在return encodeURIComponent(this.jsencrypt.encrypt(i))位置下断点,找到这个函数所在位置。 同样鼠标放到函数上,鼠标点击进入函数如图片: 大概看了下这个大方法还是很长的,为了方便抠,复制整个代码到本地,notepad++语言选择javascript,视图中折叠所有。直接搜索 this.getKey().encrypt(t)。 一直往上翻,找到折叠开始的位置。点击大括号,行号显示红线,一直复制到红线结束。 全部复制。加入我们抠的代码中。注意对象中方法用逗号分隔。 代码太长就不贴了,结构如图: 现在问题,抠的代码是一个自执行方法,如何使用加载模块功能,我们可以导出n方法到全局变量。 复制全部代码到浏览器:console测试无报错。查看_n可以看到n方法如图片:
分析加密模块开头。
1、加载加密模块; 首先加载这个模块一会再说,先看流程,this.jsencrypt 是被s.JSencrypt new出来,s等于r(3) 首先r肯定是一个函数,3是这个函数的参数。 也就是说这个加密模块是通过调用一个函数传入参数3加载的。 那么可以大胆猜测r就是模块加载器(不放心可以下断点跟过去看看)。这里就可以改成var s = r(‘jsencrypt’); 因为我们是传入的对象不是数组不用数组下标获取。 改好复制全部代码到浏览器测试: 无报错,定义变量(jiami)接收加载模块返回。 控制台执行输出,jiami: 发现就是加密需要用的的n方法。 加密函数。n.prototype.encode 也就是说我们new 出来这个方法直接使用就可以了 直接得到n调用encode。浏览器中可以看到第一个参数密码明文,第二个参数时间戳。
抠取webpack模块代码本地允许。
好的现在把代码复制到本地调试环境。我用鬼鬼。 调用前写个test方法执行刚才的流程。 加载代码无报错,执行test。报navigator和window未定义。开头补下。执行代码无问题。 这里提醒下window这个对象。也就是代码环境本身,如果定义{}空对象,可能出现很多其他错误哦。
看不懂可以试试先去看看上一篇。
JS逆向01之新手初体验,实战案例熟悉整个过程。
QQ交流群:23440618
微信公众号:Python硕博联盟
|