python爬虫---假链接的简单破解

前提:只为学习爬虫知识,请不要对目标网站造成影响。

缘由

有幸同事介绍一个新的网址:http://ggzy.gzlps.gov.cn/ 全国公共资源交易平台,其中的详情链接在实际爬虫中是假的链接,也就是假链,索性看看。
在这里插入图片描述
通过检查调试发现了链接,那么实际复制出来的链接显示的界面却是如下图
在这里插入图片描述
如果你爬虫访问的话,后台一定会断定你是爬虫进而封你IP,那么问题来了?真的链接怎么找到呢?那么实际访问时候链接是:http://ggzy.gzlps.gov.cn/xxgkdt/x%5EleuEg0wj71ILzES7wZBQ.jhtml
在这里插入图片描述

破解

分析:
既然我们知道了是 触发点击事件 那么点击一定绑定了函数,这个函数或许是加密的关键,那么寻找之,建议使用fireFox浏览器。
通过查看
在这里插入图片描述
很明显我们发现了这个函数,那么复制出来:

function() {
  var hh = $(this).attr("href");
  if (typeof(hh) == 'undefined' || hh == '#') {
    return
  }
  var aa = hh.split("/");
  var aaa = aa.length;
  var bbb = aa[aaa - 1].split('.');
  var ccc = bbb[0];
  var cccc = bbb[1];
  var r = /^\+?[1-9][0-9]*$/;
  var ee = $(this).attr('target');
  if (r.test(ccc) && cccc.indexOf('jhtml') != -1) {
    var srcs = CryptoJS.enc.Utf8.parse(ccc);
    var k = CryptoJS.enc.Utf8.parse(s);
    var en = CryptoJS.AES.encrypt(srcs, k, {
      mode: CryptoJS.mode.ECB,
      padding: CryptoJS.pad.Pkcs7
    });
    var ddd = en.toString();
    ddd = ddd.replace(/\//g, "^");
    ddd = ddd.substring(0, ddd.length - 2);
    var bbbb = ddd + '.' + bbb[1];
    aa[aaa - 1] = bbbb;
    var uuu = '';
    for (i = 0; i < aaa; i++) {
      uuu += aa[i] + '/'
    }
    uuu = uuu.substring(0, uuu.length - 1);
    if (typeof(ee) == 'undefined') {
      window.location = uuu
    } else {
      window.open(uuu)
    }
  } else {
    if (typeof(ee) == 'undefined') {
      window.location = hh
    } else {
      window.open(hh)
    }
  }
  return false
}

分析上边的函数所需要的库和参数:

var hh = $(this).attr("href"); 很明显是:http://ggzy.gzlps.gov.cn:80/xxgkdt/20640.jhtml
var ee = $(this).attr('target'); 很明显是:_blank
var k = CryptoJS.enc.Utf8.parse(s); 密钥:待寻找,我们知道反正浏览器已经帮我们加载过密钥了,那么改造这个加密函数,控制台上走一波看是否能够打印出真的链接。
CryptoJS.AES看到这个显然考虑到 AES 加密,那么问题点 CryptoJS 这个加密文件待寻找。

改造函数:

function cryptojS() {
        var hh = 'http://ggzy.gzlps.gov.cn:80/xxgkdt/20640.jhtml';
        if (typeof(hh) == 'undefined' || hh == '#') {
            return
        }
        var aa = hh.split("/");
        var aaa = aa.length;
        var bbb = aa[aaa - 1].split('.');
        var ccc = bbb[0];
        var cccc = bbb[1];
        var r = /^\+?[1-9][0-9]*$/;
        var ee = '_blank';
        if (r.test(ccc) && cccc.indexOf('jhtml') != -1) {
            var srcs = CryptoJS.enc.Utf8.parse(ccc);
            var k = CryptoJS.enc.Utf8.parse(s);
            var en = CryptoJS.AES.encrypt(srcs, k, {
                mode: CryptoJS.mode.ECB,
                padding: CryptoJS.pad.Pkcs7
            });
            var ddd = en.toString();
            ddd = ddd.replace(/\//g, "^");
            ddd = ddd.substring(0, ddd.length - 2);
            var bbbb = ddd + '.' + bbb[1];
            aa[aaa - 1] = bbbb;
            var uuu = '';
            for (i = 0; i < aaa; i++) {
                uuu += aa[i] + '/'
            }
            uuu = uuu.substring(0, uuu.length - 1);
            return uuu
        }
    }

在控制台上调试如下图得出链接:http://ggzy.gzlps.gov.cn:80/xxgkdt/x^leuEg0wj71ILzES7wZBQ.jhtml 经过测试是真的链接,不用怀疑。
在这里插入图片描述
控制台上是调试出来了,因为浏览器帮你加载了很多东西,写成代码就不一定了那么还需要什么呢?
CryptoJS.AES看到这个显然考虑到 AES 加密,那么问题点 CryptoJS 这个加密文件怎么找?以及加密密钥
进一步寻找CryptoJS 文件
在这里插入图片描述
很容易发现这个加密函数是来自http://ggzy.gzlps.gov.cn/r/cms/com.ggzyjy.www/com.ggzyjy.www/js/jquery.lyh-1.1.0.js这个js文件,那么查看之
在这里插入图片描述
进一步寻找密钥
看到上边我们发现就那么几个js文件,那么密钥一定在另外的js文件上,进一步寻找,需耐心。
在这里插入图片描述
通过耐心查找终于找到了密钥:qnbyzzwmdgghmcnm
那么一切的条件都有了,破解吧,我们知道python 自带的Ctypto库进行AES加密 难道要正面刚?作者这里试过了,正面刚是不行的太难了。那么只有走pyV8这条路来进行破解。

破解代码实现

第一步:我们知道需要http://ggzy.gzlps.gov.cn/r/cms/com.ggzyjy.www/com.ggzyjy.www/js/jquery.lyh-1.1.0.js 这个加密文件,下载下来并保存下来,命名为ase_encryption.js文件。代码如下:

# -*- coding:utf-8 -*-
import PyV8

ctxt = PyV8.JSContext()
ctxt.enter()
js_info = """
    aesEncrypt = function () {
        var hh = 'http://ggzy.gzlps.gov.cn:80/xxgkdt/20640.jhtml';
        if (typeof(hh) == 'undefined' || hh == '#') {
            return
        }
        var aa = hh.split("/");
        var aaa = aa.length;
        var bbb = aa[aaa - 1].split('.');
        var ccc = bbb[0];
        var cccc = bbb[1];
        var r = /^\+?[1-9][0-9]*$/;
        var ee = '_blank';
        if (r.test(ccc) && cccc.indexOf('jhtml') != -1) {
            var srcs = CryptoJS.enc.Utf8.parse(ccc);
            var k = CryptoJS.enc.Utf8.parse('qnbyzzwmdgghmcnm');
            var en = CryptoJS.AES.encrypt(srcs, k, {
                mode: CryptoJS.mode.ECB,
                padding: CryptoJS.pad.Pkcs7
            });
            var ddd = en.toString();
            ddd = ddd.replace(/\//g, "^");
            ddd = ddd.substring(0, ddd.length - 2);
            var bbbb = ddd + '.' + bbb[1];
            aa[aaa - 1] = bbbb;
            var uuu = '';
            for (i = 0; i < aaa; i++) {
                uuu += aa[i] + '/'
            }
            uuu = uuu.substring(0, uuu.length - 1);
            return uuu
        }
    }
"""
if __name__ == "__main__":
    with open('ase_encryption.js')as f:
        a = f.read()
    func = ctxt.eval(a + js_info) 
    print(func())

结果却出人意料:

Traceback (most recent call last):
  File "F:/PycharmWork/yufan_mao/66.py", line 43, in <module>
    func = ctxt.eval(a + js_info)
ReferenceError: ReferenceError: $ is not defined (  @ 1 : 0 )  -> $(function(){$("a").click(function(){var hh=$(this).attr("href");if(typeof(hh)

分析得出:$是内置的,浏览器实例的,execjs只能运行基本的语法,那么ase_encryption.js这个js文件就需要改造了,那么能不能尝试把$给替换掉呢?那就试着来吧。
在这里插入图片描述
意外的是替换掉结果还真的出来了,苦笑不得,由于自己水平比较低,这次纯属运气吧。
参考作者:https://www.jianshu.com/p/055e1ddf7bb2

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值