字体反反爬实战

背景介绍

‘字体反爬’是一种比较常见的反爬手段,它是通过页面和前端字体文件配合完成的一种反爬虫措施,常见的网站有58同城,汽车之家,猫眼电影,大众点评,美团等网站。

实战操作

本文实战链接

第一步 f12查看源码

可以看到 关键性数据已经加密,现在我们需要解密它。

第二步 找到字体文件

通过上面的class找到字体文件

下载字体文件用FontCreator工具打开

我们可以看到woff文件中每个字符都有一个编码对应,.woff实际上就是编码和字符的映射表。

第三步 我们查看网页接口数据来源

发现进行了2次加密。

那我们只有查看网页源代码 尝试查找解密代码。

image

通过接口名搜索到接口调用

发现解密方法。接下来就是查找它的源码了。

image
经过一番查找,在jquery文件中发现解密方法 复制出来。

 function d(_s) {
     _s = '' + _s;
     var t = [];
     var st = 0;
     while (true) {
         if (st > _s.length) {
             break;
         }
         var l = _s.slice(st, st + 1);
         l = parseInt(l);
        if (isNaN(l)) {
             break;
         }
         t.push(_s.slice(st, (st + l + 3)));
         st += (l + 3);
     }
     var r = '';
     for (i = 0; i < t.length; i++) {
         var _ss = t[i].slice(1);
         _ss = _ss.replace(/[0,1,5,9]/g, '').replace(/[a,b,c,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,w]/g, '');
         var ts = _ss.split('').sort();
         if (ts.length == 1) {
             ts.push('9');
         }
         if (ts[1] == '3' && (ts[0] == '2' || ts[0] == '1')) {
             var p = ts[0];
            ts[0] = ts[1];
             ts[1] = p;
         }
         if (ts[0] == ts[1] && ts[0] == '4') {
             ts[0] = '5';
             ts[1] = '0';
        }
         r += ('&#xe6' + ts.join('') + ';');
     }
     return r;
}

测试一下

image
得到值
发现与字体文件编码后四位一致

image

至此,该网站对我们已经不再神秘 ,胜利就在眼前。

改造解密方法

//对应关系表
const cmap={
    "&#xe622;":0,
    "&#xe624;":9,
    "&#xe627;":8,
    "&#xe628;":7,
    "&#xe62d;":6,
    "&#xe62e;":5,
    "&#xe62f;":4,
    "&#xe636;":3,
    "&#xe637;":2,
    "&#xe639;":1,
    "&#xe650;":"一"
};

function decode(_s) {
     _s = '' + _s;
     var t = [];
     var st = 0;
     while (true) {
         if (st > _s.length) {
             break;
         }
         var l = _s.slice(st, st + 1);
         l = parseInt(l);
        if (isNaN(l)) {
             break;
         }
         t.push(_s.slice(st, (st + l + 3)));
         st += (l + 3);
     }
     var r = '';
     for (i = 0; i < t.length; i++) {
         var _ss = t[i].slice(1);
         _ss = _ss.replace(/[0,1,5,9]/g, '').replace(/[a,b,c,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,w]/g, '');
         var ts = _ss.split('').sort();
         if (ts.length == 1) {
             ts.push('9');
         }
         if (ts[1] == '3' && (ts[0] == '2' || ts[0] == '1')) {
             var p = ts[0];
            ts[0] = ts[1];
             ts[1] = p;
         }
         if (ts[0] == ts[1] && ts[0] == '4') {
             ts[0] = '5';
             ts[1] = '0';
        }
        // r += ('&#xe6' + ts.join('') + ';');  注释原来的代码
       const tempStr='&#xe6' + ts.join('') + ';';
       //替换成正常数字
        r += cmap[tempStr];
     }

     return r;
}

测试下

image

到此,我们已经完成破解。

2 Likes