爬取js加密和混淆的例子

摘要:
click_btn){vartimestamp=Date.parse(newDate());page=1&num=15&token=26c8bc7&page='+page+'&setHtml+=“<”+item.ip.toString()+“&lt”;
作业讲解:js逆向

概述

url:https://nyloner.cn/proxy

需求:将这个网页中的代理ip和端口号进行爬取
难点:
	动态变化的请求参数
	js加密
	需要js逆向

分析

  • 爬取的数据是动态加载

  • 并且我们进行了抓包工具的全局搜索,没有查找到结果

    • 意味着:爬取的数据从服务端请求到的是加密的密文数据
  • 页面每10s刷新一次,刷新后发现数据更新,但是浏览器地址栏的url没有变,说明加载出的数据是由ajax请求到的。

    • 动态加载出来的数据是由ajax请求到的,并且请求到的数据为加密数据
  • 定位到ajax数据包,从中可以看到url和动态变化的请求参数和加密的响应数据

  • 将ajax请求到的密文数据捕获

    • 动态地获取动态变化的请求参数

    • 基于抓包工具进行了动态变化请求参数token的全局搜索,定位到了token的源头,就是如下js代码:

      var token = md5(String(page) + String(num) + String(timestamp));
      
    • 对密文数据进行解密

      • 通过解析找到了解密的js函数:decode_str(encode_str)
    • 查找encode_str的实现:

      • js逆向:将js代码转换成python代码。开发环境只能执行python代码

答案

动态参数解析

# 我们抓包看到 token是加密生成 则把它进行加密
var token = md5(String(page) + String(num) + String(timestamp));
# 进行加密
def getToken():
    page = str(1)
    num = str(15)
    t = str(int(time.time()))
    md5 = hashlib.md5()
    md5.update((page+num+t).encode('utf-8'))
    token = md5.hexdigest()
    return token

网页源码js

# 动态参数加密
function get_proxy_ip(page, num, click_btn) {
    var timestamp = Date.parse(new Date());
    timestamp = timestamp / 1000;
    # token的加密
    var token = md5(String(page) + String(num) + String(timestamp));
    # ajax 请求 类似这样的url:https://nyloner.cn/proxy?page=1&num=15&token=26c8bc7&t=1575
    $.get('../proxy?page=' + page + '&num=' + num + '&token=' + token + '&t=' + timestamp, function (result) {
        # 判断 是否为True 
        if (result.status === 'true') {
            var setHtml = "";
            $("#ip-list").html(setHtml);
            var encode_str = result.list;
            # decode_str 是解密函数
            var items = str_to_json(decode_str(encode_str));
            for (var index = 0; index < items.length; ++index) {
                item = items[index];
                setHtml += "<tr>
<td>" + (index + 1) + "</td>
";
                setHtml += "<td>" + item.ip.toString() + "</td>
";
                setHtml += "<td>" + item.port.toString() + "</td>
";
                setHtml += "<td>" + item.time.toString() + "</td>
</tr>
";
            }
            $("#ip-list").html(setHtml);
            if (click_btn === 'next') {
                document.getElementById("last-page").disabled = false;
                if (items.length < 15) {
                    document.getElementById("next-page").disabled = true;
                }
            } else {
                document.getElementById("next-page").disabled = false;
                if (page === 1) {
                    document.getElementById("last-page").disabled = true;
                }
            }

        }
    });
}

获取token 向url发请求获取加密的数据

import time
import hashlib
import requests
import base64
#js逆向之后的结果
def decode_str(scHZjLUh1):
    #解密成字符串
    scHZjLUh1 = base64.decodestring(scHZjLUh1.encode())
    key = 'nyloner'
    lenth = len(key)
    code = ''
    sch_lenth = len(scHZjLUh1)
    for i in range(sch_lenth):
        coeFYlqUm2 = i % lenth
        #chr(0-255)返回对应编码的字符
        #ord(a-z)返回编码数值
        code += chr(scHZjLUh1[i] ^ ord(key[coeFYlqUm2]))
    code = base64.decodestring(code.encode())
    code = code.decode('utf-8')
    code
#     return code

将加密的数据进行解析

token = getToken()
url = 'https://nyloner.cn/proxy'
param = {
    'num':'15',
    'page':'1',
    't':str(int(time.time())),
    'token':token
    
}

headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36',
    'Cookie':'sessionid=2cj1fd0hpbv64qrxe6xckek8tu3uad4m'
}
code = requests.get(url,headers=headers,params=param).json().get('list')
str_code = decode_str(code)
str_code

js加密,混淆

需求概述

url:https://www.aqistudy.cn/html/city_detail.html
获取该url的数据

需求分析

  • 1.点击不同气象指标的选项卡,发现没有相关的请求发送,说明当前页面加载出来的时候,所有的气象数据已经加载完毕

  • 2.数据是否为动态加载

    • 数据是动态加载出来
  • 3.修改查询的条件(城市的切换,时间的修改),点击搜索按钮就会加载出新的数据

  • 4.在抓包工具的xhr中获取到了两个数据包

    • url一样
    • 都有一个d这样的请求参数
    • 两个数据包的请求参数d的数据值不同
    • d这个请求参数是经过加密且动态变化
      爬取js加密和混淆的例子第1张
  • 处理动态变化且加密的请求参数d

    • 对请求参数d进行全局搜索(不可行)

    • 点击页面中的搜索按钮后,在抓包工具中就捕获到了那两个ajax请求的数据包

      • 点击按钮发起ajax请求,找按钮的点击事件(click)
      • 借助火狐浏览器的开发者工具进行按钮点击时间的定位
        • getDate()js函数
          爬取js加密和混淆的例子第2张
    • 分析getDate这个js函数的实现:目的就是为了找到ajax请求对应的js代码

      • type=='HOUR',按照小时为时间单位进行查询
      • 并没有在该函数的实现中发现ajax请求对应的代码,但是发现了另外的两个函数调用getAQIData();getWeatherData();
        • 分析getWeatherData();和getAQIData()这两个函数的定义,想要去找到ajax请求对应的代码:
          • 这两个函数实现的区别
            • method变量赋值的字符串不一样
              • GETDETAIL
              • GETCITYWEATHER
          • 相同:
            • 都没有出现ajax请求对应的代码,但是发现另一个函数的调用:
              • getServerData(method,param,匿名函数,0.5)
                • method:GETDETAIL或者GETCITYWEATHER
                • param:字典,有四组键值对
                  • city:查询城市的名称
                  • type:HOUR
                  • starttime:查询开始时间
                  • endTIME:查询结束的时间
                    • 分析getServerDate(method,param,匿名函数,0.5)这个函数的实现,还是为了找到ajax请求对应的代码

                    • 基于抓包工具的全局搜索才可以找到
                      爬取js加密和混淆的例子第3张

                    • 发现这个函数的实现代码看不懂,函数的实现好像是一组密文

                    • 说明:网站对js函数的实现加密

                    • js混淆:对js函数的实现代码进行加密

                    • js反混淆:将加密的js代码解密成原文

                    • 暴力破解:https://www.bm8.com.cn/jsConfusion/

                    • 分析getServerData函数的实现:

                    • 终于找到了ajax请求对应的代码

                    • 参数d的构成:getParam(method,object)返回

                    • method:method

                    • object:param字典,四个键值分别是城市名称。type,起始时间,结束时间

                    • 请求到的密文数据的解密方式

                    • decodeData(data):data参数就是响应的密文数据,返回值就是解密后的原文数据

                    • JS逆向

                    • 使用PyExecJS库来实现模拟JavaScript代码执行

                    • 环境的安装:

                    • pip install PyExecJS

                    • 必须还要安装nodeJS的开发环境

          • 请求到加密的响应数据
          • 将加密的响应数据进行解密
  • 获取动态变化且加密的请求参数(d)

import execjs
import requests
headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36'
}
node = execjs.get()
file = 'test.js'
ctx = node.compile(open(file,encoding='utf-8').read())

#如何五个变量会作为getPostParamCode的参数
method = 'GETDETAIL'#GETCITYWEATHER
city = '北京'
type = 'HOUR'
start_time = '2018-01-25 00:00:00'
end_time = '2018-01-25 23:00:00'
#模拟执行getPostParamCode函数
js = 'getPostParamCode("{0}", "{1}", "{2}", "{3}", "{4}")'.format(method, city, type, start_time, end_time)
params = ctx.eval(js)
# print(params)#请求参数d
url = 'https://www.aqistudy.cn/apinew/aqistudyapi.php'
data = {
    'd':params
}
#获取了加密的响应数据
response_code = requests.post(url=url,headers=headers,data=data).text
# response_code

#模拟执行decodeData函数对密文数据进行解密
js = 'decodeData("{0}")'.format(response_code)
page_text = ctx.eval(js)
print(page_text)

免责声明:文章转载自《爬取js加密和混淆的例子》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇visual studio 2017 30天到期,不能输入注册码STM32 LED闪烁 初学笔记下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

关于DataGridView的索引

最近在做一个课堂练习是被郁闷了一把。现成的事成了想当然的事。案例如下。 是一个WinForm程序,在DataGridView绑定控件后,选择一行,进行操作,代码如下: 数据绑定代码: SqlDataAdapter da = newSqlDataAdapter("select id from shuji","server=.;database=tushudb...

DOM,javascript,Web API之间的关系——onclick 引起的思考与调研

平时习惯了用js操作dom树来与html页面进行交互,基本都是通过web API接口实现的,最近看闭包和原生js的知识点比较多,昨天无意中看到了onclick中的this指向问题,遂用native js方式模拟了onclick再html标签里的this和js事件里的this,详见上一篇博客:用js的eval函数模拟Web API中的onclick事件 下文...

webpack的使用方法

我常用的webpack版本是3.8.1版本 https://www.cnblogs.com/QxQstar/p/5961387.html    这个是他的网址 那么我们说一下webpack,他是一个前端资源加载或打包的工具,他可以打包:img,css,js,json等 第一步:下载   npm  install  -g  webpack@3.8.1    ...

节点操作--JavaScript

1 - 概念 网页中的所有内容都是节点(标签、属性、文本、注释),在DOM中,节点使用node来表示。 HTML DOM树中的所有节点均可通过JS进行访问,所有HTML元素(节点)均可被修改,也可以创建或者删除。 一般地,节点至少拥有nodeType(节点类型)、nodeName(节点名称)和nodeValue(节点值)这三个基本属性。 元素节点 nod...

初识websocket及java服务端的简单实现

概念:WebSocket是一种在单个TCP连接上进行全双工通信的协议。 WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输 背景:很多网站为了实现推送技术,所用的技术都是轮询。轮询是在特定的的...

[视频播放] HLS协议之M3U8、TS流详解

本文转载自:《hls之m3u8、ts流格式详解》 HLS,Http Live Streaming 是由Apple公司定义的用于实时流传输的协议,HLS基于HTTP协议实现,传输内容包括两部分,一是M3U8描述文件,二是TS媒体文件。 1、M3U8文件    用文本方式对媒体文件进行描述,由一系列标签组成。 #EXTM3U #EXT-X-TARGETDURA...