概要
目前akamai广泛应用于国外航空网站,平均每10个航司就有4个用的akamai反爬系统,如 乐桃航空 济州航空 天马航空 精神航空 达美航空 捷星机票 國泰航空,今天我们来解析一下该反爬系统,
学术交流请加vx:lpf1006085679
本帖旨在交流,请勿用于违法途径
akamaijs解析:
下面就是他的js了,可以看到可读性非常之差
下面就是他的数据包,页面每点击一次发送一次封包,内容高度加密
在js里打断点,查看一下加密前的数据
可以看到里面包含了很多浏览器的各种数据,我们将这些数据的每个参数翻译下来
接下来我们直接coding
long ks = hash.get_cf_date();//时间戳
long deltatimestamp = (int)(hash.get_cf_date() - start_ts);
int num = r.next(1, 50);
int z1 = (int)(start_ts / (4064256)); //开始时间戳除以两个2016
int d2 = z1 / 23;//在除23 就是g数组的d2参数
list<string> sensor_data = new list<string>();
sensor_data.add("-100");
string sz = r.next(10, 15).tostring();
string xyt = " mozilla/5.0 (windows nt 10.0; win64; x64; rv:94.0) gecko/20100101 firefox/94.0";
string loc = xyt + ",uaend,11123,20030107,zh-cn,gecko,0,0,0,0,";
loc += z1.tostring() + ",";//开始时间除以两个2016
loc += "0";// d3.tostring();//开始时间取余
string xs = r.next(500, 844).tostring();//664
loc += ",390,844,390,844,390,"+ xs + ",390,,cpen:0,i1:0,dm:0,cwen:0,non:1,opc:0,fc:0,sc:0,wrc:1,isc:0,vib:0,bat:0,x11:0,x12:1,";
loc += hash.kz(xyt) + ",";//对ua进行ab签名 mozilla/5.0 (windows nt 10.0; win64; x64; rv:94.0) gecko/20100101 firefox/94.0
double d = r.nextdouble();
int s = (int)(1000 * d / 2);
string k = d.tostring().substring(0, 11) + s.tostring();
loc += k.tostring() + ",";//取了个随机数
loc += ((double)start_ts / (double)2).tostring() + ",";//开始时间初二
loc += "0,loc:";
int toe_vel = sensor.ke_vel + sensor.me_vel + sensor.doe_vel + sensor.dme_vel + sensor.te_vel + sensor.pe_vel;
list<string> lst90 = new list<string>();
lst90.add(start_ts.tostring());
lst90.add(loc.tostring());
lst90.add(sensor.mact.tostring());
lst90.add(toe_vel.tostring());
lst90.add(deltatimestamp.tostring());
string jl = zhougengxin.jiuling( lst90);// jiuling(2, lst90));
long rm = (int)(hash.get_cf_date() - start_ts);
sensor_data.add(loc);
sensor_data.add("-105");
sensor_data.add("0,0,0,0,-1,1752,0;");//0,0,0,0,-1,1752,0;
sensor_data.add("-108");
sensor_data.add(sensor.kact);//cka函数累加的 按键按下弹起消息
sensor_data.add("-101");
sensor_data.add("do_en,dm_en,t_en");
sensor_data.add("-110");
sensor_data.add(sensor.mact);//cma函数 鼠标移动按下弹起单击事件生成串;
sensor_data.add("-117");
sensor_data.add(sensor.tact);//cta函数生成 touchstart 触摸事件
sensor_data.add("-109");
sensor_data.add(sensor.dmact);//cdma函数生成 devicemotion (设备运动/手势):提供设备的加速度信息,表示为定义在设备上的坐标系中的笛卡尔坐标,其还提供了设备在坐标系中的自转速率。
sensor_data.add("-102");
sensor_data.add("0,0,0,0,-1,1752,0;");
//sensor_data.add("0,0,0,0,-1,-1,0;0,-1,0,0,1049,-1,1;0,-1,0,0,1153,-1,0;");//这个函数是拿input列表 判断了一下密码框? 这个是每次拿后根据条件显示
sensor_data.add("-111");
sensor_data.add(sensor.doact);//cdoa函数生成 deviceorientation事件 方向传感器 陀螺仪生成 提供设备的物理方向信息,表示为一系列本地坐标系的旋角。
sensor_data.add("-114");
sensor_data.add(sensor.pact); //cpa函数生成 pointer events - 指针事件 是一类可以为定点设备所触发的dom事件。它们被用来创建一个可以有效掌握各类输入设备(鼠标、触控笔和单点或多点的手指触摸)的统一的dom事件模型
sensor_data.add("-103");
sensor_data.add(sensor.vcact);//hvc函数生成 上层是hvc visibilitychange 选项卡隐藏显示事件生成
sensor_data.add("-106");
sensor_data.add("5,2" /*+ aj_indx*/);//类型和封包次数
sensor_data.add("-115");
//接下来是g数组组合生成w
stringbuilder wsb = new stringbuilder();
wsb.append((sensor.ke_vel + 1).tostring() + ",");//bmak['ke_vel']+1 按键cka函数生成的次数加上1
wsb.append((sensor.me_vel + 32).tostring() + ","); //bmak['me_vel']+32 cma函数 鼠标消息次数
wsb.append((sensor.te_vel + 32).tostring() + ","); //"32,";//bmak['te_vel']+32 cta生成 touchstart 触摸次数
wsb.append(sensor.doe_vel + ",");// bmak['doe_vel'] cdoa方向传感器 陀螺仪次数
wsb.append(sensor.dme_vel + ",");//bmak['dme_vel'] cdma设备的加速度次数
wsb.append(sensor.pe_vel.tostring() + ","); //bmak['pe_vel'] cpa指针事件次数
wsb.append(toe_vel.tostring() + ","); //s = ke_vel + me_vel + doe_vel + dme_vel + te_vel + pe_vel;前面数加起来 真骚
wsb.append(deltatimestamp.tostring());//bpd开始时间减去开始时间
wsb.append(",0,");// _setinittime 这个函数外部赋值过来的 默认0
wsb.append(start_ts.tostring() + ",");//拿个开始时间
wsb.append(r.next(8, 20) + ",");// 为fpcf.td值, 在a['fpval']函数里 拿 a['fpvalstr']= a['data']();的间隔时间 坑b
wsb.append(d2.tostring() + ","); //开始时间除以两个2016在除23 就是g数组的d2参数
wsb.append(sensor.ke_cnt + ",");//bmak['ke_cnt'] cka函数赋的值 按键按下弹起消息
wsb.append(sensor.me_cnt + ",");//bmak['me_cnt'] cma函数 鼠标点击次数吧
int f = (int)(d2 / 6);// 在除个6
wsb.append(f.tostring() + ",");
wsb.append(sensor.pe_cnt + ",");//bmak['pe_cnt'] cpa函数生成 指针事件
wsb.append(sensor.te_cnt + ",");//bmak['te_cnt'] cta函数生成 触摸事件
wsb.append((rm).tostring() + ",");// _ = hash.get_cf_date() - start_ts; 计算完90后的时间差
wsb.append(sensor.ta + ",");//bmak['ta'] 统计 cdoa+cdma+cma+cpa+cka+cta的一个事件总延迟
wsb.append("0,");//bmak['n_ck'] get_cookie里赋值为1 这个是不是看外部拿没拿ck
wsb.append(abck + ",");//
wsb.append(hash.kz(abck) + ",");//对abck进行运算 就是这个函数阻止直接复制ck使用
wsb.append(rval.tostring() + ",");//a['rval'] = math['floor'](1e3 * math['random']())['tostring']() 取了个随机数
/*小canvas 这里加了1*/ wsb.append(rcfp[rval] + ",");// canvas(1) + ",";//a['rcfp'] 924731892 疑似对浏览器的canvas标签todataurl进行哈希运算
wsb.append("26018161,");//bmak['fas'] 函数生成 浏览器代理 次要版本 蓝牙等进行左移运算生成
wsb.append("pizte,");//k(80) + k(105) + k(90) + k(116) + k(69) 写死的
int[] u = hash.jrs(start_ts); //用开始时间进行签名运算 不能马虎啊
wsb.append(u[0].tostring() + ","); //随机数钥匙
wsb.append(u[1].tostring() + ","); //加密后的值
wsb.append("0,");//hbs函数生成 判断pupp
wsb.append("-1,0");// h = bmak['gwd']() //判断 webdriver 是一种用于web应用程序的自动测试工具
string w = wsb.tostring();
sensor_data.add(w);
sensor_data.add("-112");
sensor_data.add(locurl);
sensor_data.add("-119");
sensor_data.add("-1");//getmr 浏览器实际显示大小求了个圆出来?
sensor_data.add("-122");
sensor_data.add("0,0,0,0,1,0,0");//s= bmak['sed']()这玩意又是浏览器特征吧
sensor_data.add("-123");
//b参数 abck末尾先用~分割取第一个 在用||分割 然后mn_w计算出来 这个应该是百次计算,没遇见过
if (lx == 0) sensor_data.add(dt); else sensor_data.add("");
sensor_data.add("-124");
if (lx == 1) sensor_data.add(dt); else sensor_data.add("");//x参数 同上 这个是千次计算
sensor_data.add("-126");
if (lx == 2) sensor_data.add(dt); else sensor_data.add("");//m参数428炸cpu算法 三万次计算 ,坑比,燃烧我的cpu
sensor_data.add("-127");
sensor_data.add("6");// 11133333331333333333");//bmak['nav_perm'] np函数生成 返回给定api的用户权限状态
sensor_data.add("-128");
sensor_data.add(",0,-2,4,-1,0,0,-1,0,0,apple inc.,apple gpu,-2,60280a6d1894067fa9be4c9ef4625bc3cffd869a690360b444b26682716d66cf");
sensor_data.add("-131");
sensor_data.add("-1,-1,-1,-1,-1,-1,1,-1,-1,-1");
sensor_data.add("-132");
sensor_data.add("nc,,,,-1");
sensor_data.add("-133");
sensor_data.add("");
sensor_data.add("-70");
//a['fpvalstr']= a['data']() -415241711"
string fpvalstr = "-1880212897";
//string fpvalstr = rcfp[0];
fpvalstr+= ";-1;dis;;true;true;true;-480;true;32;32;true;false;-1";
sensor_data.add(fpvalstr);
sensor_data.add("-80");
sensor_data.add(hash.kz(fpvalstr).tostring());//拿了还在签个名 真有你的
sensor_data.add("-90");
sensor_data.add(jl);
sensor_data.add("-116");
sensor_data.add("0");// o9.tostring());// bmak['o9'] 开局to()函数算的 取时间戳算了个东西
sensor_data.add("-129");
stringbuilder esb = new stringbuilder();
//esb.append(fmh_r); esb.append(",");
esb.append("775aa9afccd38782069740f4bb4c40b286cd046a71387099dacd13cc2baac81c"); esb.append(",");
esb.append("3"); esb.append(",");
// esb.append(ssh_r); esb.append(",");
esb.append("b0f180958d8c4b3f7c0196dafd5516a21ee68c4a571f5efc0748c53222e5ed51"); esb.append(",");
esb.append("apple inc."); esb.append(",");
esb.append("apple gpu"); esb.append(",");
//esb.append(weh_r); esb.append(",");
esb.append("169f239fe776836f7d6eb96e165a80272d08a6d1c6971639c9cf430a3c69f5ec"); esb.append(",");
esb.append("24");
string e = esb.tostring();
sensor_data.add(e);
string s0 = hash.gl(sensor_data);//分隔符
string us = string.join(s0, sensor_data.toarray());
string f = "7a74g7m23vrp0o5c";
指纹
`将js逆向完毕后 发现不能并发,可能是指纹的问题,需要真实浏览器指纹数据 就找站点挂机采集了一堆指纹
后来发现还是不能并发 。。
tls
原来这个发包库还有要求啊
tls握手会有很多特征 比如密码套件等 将主流浏览器的各个版本的网络库特征加白名单,就是并发不了的关键了
那么我们修改发包库的特征 让他符合某个浏览器的某版本的ja3指纹
周更新
akamai更新到2.0之后 每周一js代码就会变 里面参数也会略微改变 虽然整体分支改动不大 但是变量名字,函数名,转义符等等都会变,每周会改变秘钥,以及一个参数的算法,挺麻烦
小结
学术交流请加vx:lpf1006085679
发表评论