LOADING

正在加载

JS逆向登录分析

壹 起因和前言

在做爬虫登录的时候,除了一些简单的爬取或者传参,不需要设置太过复杂的参数构造,但是大多数情况下一些网站的用户名或者密码都会在前端进行一次加密,然后传输到后端进行登录,这时候我们可以选择对前端页面登录方式进行逆向分析。

注意:本篇文章主要是讲解在登陆时对JS的逆向分析,当然文章中的一些方法,不仅仅是局限与登录调试。

说到逆向,很多人会想,不会要反编译什么的高级操作吧!事实上,前端的逆向通俗来说就是在浏览器的调试器中,对存在的前端代码(这里的前端代码包括htmljscss)进行分析,通过分析其逻辑获取其中的路由、加密方式、敏感信息泄露等。在前端开发中,前端语言之间的关系类似下面这种情况。

语言 比较
Html 人类的骨架
JavaScript 人类身体各部分之间产生的行为
CSS 人类的外形面貌

可以看出,前端代码的灵活性主要是由JavaScript进行实现的,所以一般来说对前端进行逆向分析,就是对JavaScript进行逆向分析。接着我们需要熟悉以下几个点:

  • 首先我们需要明确前端的加密一定是在JavaScript语言中,所以对前端页面的逆向分析一般是对JavaScript的逆向分析
  • 在浏览器中,提供了两个很好的功能,即:控制台(Console)和调试器(Sources),这两个功能进行在线的Javascript逆向时非常有用,控制台(Console)可以事实运行Javascript的代码,而调试器(Sources)可以快速搜索代码和进行断点调试
  • 在进行登录页面的Javascript逆向分析时,我们一般都是通过分析提交的登录参数或者加解密关键字为切入点,需要确认网站的用户名密码是否加密,如果加密,同一个密码提交后是否改变,以及是否随用户名改变、验证码的变化规律等(需要根据实际情况判断)

贰 找到加密函数

一般我们要想找到加密的函数,有三种方法:

  • 通过页面对使用的方法进行追溯和跟踪
  • 使用关键字进行搜索
  • 通过XHR断点进行调试(推荐)

2.1 通过页面对使用的方法进行追溯和跟踪

当我们对登录页面进行逆向时,我们可以通过页面中的表单提交确认调用的javascript函数,例如下面函数中的loginByPhoneAndPwd
3ed116f9ed049e0eda1ca0d6448f279e.png
接着在javascript代码中搜索该方法的名字,可以发现方法中存在pwd密码关键字并且进行了加密:
9dc0e1410482bd444dd76816a1a1d351.png

2.2 使用关键字进行搜索

如果在登录页面中不好找到表单提交确认调用的函数,可以通过搜索Encryptloginkeypasswdpassword的关键字,来确认使用的加密函数:
90fdc64e0c1e4e71eec508c921cba479.png
当确认可疑的方法后我们可以通过断点来调试确认该方法是否为登录时加密密码使用的函数:
da0a104a34db5a76f11ade5864c4710d.png
能看到我们运行后就被拦截,并且传入密码,说明该点十有八九就是密码的加密函数。

2.3 通过XHR断点进行调试

这里我们需要了解在用户输入数据到后台之前浏览器做了什么?逻辑就是用户输入数据(例如密码)到输入框中,JavaScript会进行检测(当然可能也需要用户点击登录按钮才会检测)是否需要进行一些特殊处理操作,例如:加密、混淆等,最后将处理好的数据通过XHR发送到后端中。可以看到整个流程中,真正需要我们逆向分析的是这个特殊处理操作,那么我们就需要知道这个处理操作的头和尾,头一般就是前面的说的传递参数值,尾就是XHR

XHR断点进行调试的思想就是头不容易找到,但是尾是可以通过XHR找到的,通过XHR断点反追踪调试到前面的加密方法,接下来就是进行XHR断点调试,首先找到调试器(Sources),选择XHR断点(记得删除所有断点信息):
484080e5fc2243e271a16b57d03ce5a7.png
然后在登录页面登录抓包,发现密码存在加密,这时我们获取登录请求的路径(这里是/login),将其放到浏览器的调试器(Sources)的XHR断点中(记得burp放包):
d7efc2cc1ac5e83f787e894a69c6e581.png
再次尝试登录,发现调试器跳转到了xhr.send中,并且发现调用堆栈出现了一些方法,这些方法就是我们需要回溯翻阅的可能存在加密的方法,我们可以看到这个a参数中有一个data参数存放用户名密码信息,我们就需要对这个a.data参数进行追踪:
080d6901301236e636fbf202723e961e.png
尝试回溯,选择send的下个方法ajax,发现ajax中的k就是send中的a,但是没有关于加密的迹象:
d10d9fa653587a2319be578419470c1b.png
接着继续回溯上一个方法模块login,这时候我们就能明显的看到password被加密后的数据,还是没有看到加密函数的尾巴:
368f21cf749f7d8f54f67f144c050105.png
接着我们继续回溯,发现密码的加密块就在cs模块中,进行了aes加密:
6ee6fae8e4a5a185aa6f768ecd9a9dbf.png
这里的分析比较简单的一笔带过,但是实战中还是需要进行详细跟踪的。

叁 解密过程

对于已经找到的加密函数,我们可以通过例子方法去运用其加密函数:

  • 通过对加密函数的分析,进行逐步跟踪
  • 通过其他脚本语言调用该JavaScript代码文件

3.1 通过对加密函数的分析,进行逐步跟踪

这里我们选取一个只进行密码加密,没有验证码的例子进行说明,首先我们打开网络查看功能(windowsF12),尝试提交一个用户名密码是as\as的用户信息,然后查看网络功能,网络功能会将我们提交到服务端的信息显示出来(有些网站由于会进行交互刷新,不好查看,我们可以用BP抓包,这里这个网站不进行交互刷新可以直接在网络功能查看payload
image-20221115113752688.png

as/as加密后的信息是:
as/df211ccdd94a63e0bcb914bf38a016980503b40f46df1665b8a9f96878e9e3079814ffa29cb98375261bfc130c74d4f716f6f23f6ecf2d754f985b2eca6152dcc15c3fe1158b33892e0fe6ae427a249484a49d60

接着我们到调试器去查找password这个变量,在javascript逆向中,变量一般会用:或者=进行赋值,所以我们可以通过搜索password:或者password=查找:
image-20221115172931998.png
可以看到,有两个赋值给password的操作,第一个是空列表,明显不是我们需要的,所以我们进入第二个,查看源代码,进到第二个代码文件中,我们可以发现存在encrypt这种加密的字样函数,初步推断这个是加密函数,这里我们可以尝试打断点进行分析,点击下图中左边的数字即可:
image-20221115173141262.png
我们进一步分析encryptString函数,进入函数后,看到n=as,说明n就是我们传递的密码,接着打断点,进到第一个pu函数中:
image-20221115174641315.png
发现pu函数是一个sha1加密,加密后将其赋值给l
image-20221115174814447.png
接着进一步调试,发现下面两个操作是将l进行切割分别赋值给tu
image-20221115175039204.png
接着就是进行hmac哈希加密,并拼接前面得到的qu,返回其值:
image-20221115175545510.png
这时由于没有变量查看返回的值,但是我们可以到控制台处运行加密函数:
image-20221115175859284.png
image-20221115175754800.png
可以看到对应的值与前面加密后的值一样,至此分析结束,我们可以去构造对应的脚本生成密码进行登录。

3.2 通过其他脚本语言调用该JavaScript代码文件

对于一些复杂的加密函数,上面的方法比较复杂,这时候我们可以通过其他基本语言调用该JavaScript代码文件,我们将存在加密函数的文件复制下来:
227e1f361b0c95b5c31f9561a1699a22.png
然后使用node.js运行,在运行过程中,会出现很多报错,通过对应的报错信息进行修补即可,下面这个是没有引入CryptoJS,直接百度,引入即可:
5c128f1d3cdc817edf2c844010bb545f.png
接着直接执行看是否有报错,没有报错说明环境是没有问题了,通过在jsconsole.log打印加密后的信息。
9f0e649b5b42af3c398de4b4068aca2e.png
最后使用第三方脚本语言pythonexecjs库进行调用即可:

# 引入方法
import execjs,requests,os
# 读取js文件
with open("main.js",errors='ignore') as f:
    js_data = f.read()

key = "as"
# 加载文件
js_com = execjs.compile(js_data)
# 调用方法
print(js_com.call("encryptByAES","as",key))

1d8ba82b7fdfb6c50cbbbc902d540333.png

肆 小结

  • 了解熟悉javascript的基本语法
  • 当我们需要查看指定变量的变化时,我们可以在右边添加一个对应的变量,查看其变化:
    image-20221115174547788.png
  • 我们可以通过提交的payload进行分析其参数,也可以通过关键字的搜索,例如搜索Encryptloginkeypasswdpassword这种关键字
  • 需要注意,如果需要在控制台运行类里面的方法,只有在javascript运行的时候才可以在控制台运行
  • 熟悉常用的加密方法,例如:DES3DESRSAmd5
  • 有些网站会用到网上现成的加密函数,例如:Crypto-JS,这是一个非常常用的javascript密码库:crypto-js-develop.zip

js逆向相对于其他语言的逆向来说,不算太难,因为不需要使用ida这种工具进行反汇编,就一个简单的浏览器即可。
例子上登录分析,我们可以看出,js逆向代审更多的是通过提交的payload进行一步一步分析,只要了解js的基本语法,都能看到个大概,然后结合控制台进行运行调试,可以看出,js逆向相对于其他语言的逆向来说,不算太难,因为不需要使用ida这种工具进行反汇编,就一个简单的浏览器即可。
js逆向的应用场景不单单只是用于爬虫的登录,假设有这么一个场景,有一个登录框,没有验证码或者验证码复用,但是密码被前端加密了,我们可以通过对其进行分析,获得对应的加密算法进行构造,从而进行爆破。在做信息收集时,我们同样可以通过js发现一些蛛丝马迹,因为js是前端,需要与后端进行交互,这时候,很多开发会将大量的接口显示在前端,我们就可以收集这些接口,对网站进行进一步渗透:
image-20221117105237216.png
开发前端时也会使用一些公开的js框架,例如:VuejQuerynode等,这些框架同样会有漏洞,例如:CVE-2021-21315NodeJs命令注入等。

avatar
小C&天天

修学储能 先博后渊


今日诗句