起因

之前挖过爬取免费代理ip的坑,一个比较帅的同事热心发我有免费代理ip的网站,遂研究了下:https://proxy.coderbusy.com/

解密

因为之前爬过类似的网站有了些经验,大概知道这些家伙都是啥套路于是就随手ctrl+shift+c选了一下端口号:

端口元素有个奇怪的data字段,怀疑是在这个数字8781的基础上生成的8080,查看源代码看看返回的是什么样的:

果然返回的html中的数字跟页面上显示的数字不一致,基本可以确定端口号是在页面加载完成后通过js在data-i字段的基础上生成的新端口号。

在此元素上右击,打一个dom断点并刷新网页:

当此元素被修改的时候自动停在了断点,格式化,分析js:

这是对所有的.port应用b方法,b方法是什么方法呢,在断点调试模式下选中此变量-->在控制台执行:

然后单击一下控制台上的输出,跳到了内存中的某段js,这段就是加密逻辑:

将其拿出:

$(function() {
$('\x2e\x70\x6f\x72\x74\x2d\x62\x6f\x78')["\x65\x61\x63\x68"](function(wssP1, fnDKXroKU2) {
var ClpoEy3 = $(fnDKXroKU2);
var jgemfCG4 = ClpoEy3["\x64\x61\x74\x61"]('\x69\x70');
var TO5 = window["\x70\x61\x72\x73\x65\x49\x6e\x74"](ClpoEy3["\x64\x61\x74\x61"]('\x69'));
var tVF6 = jgemfCG4["\x73\x70\x6c\x69\x74"]('\x2e');
for (var d7 = 0; d7 < tVF6["\x6c\x65\x6e\x67\x74\x68"]; d7++) {
TO5 -= window["\x70\x61\x72\x73\x65\x49\x6e\x74"](tVF6[d7])
}
ClpoEy3["\x74\x65\x78\x74"](TO5)
})
})

但是jQuery的选择器和方法都被转为了十六进制,完全看不懂是个啥啊,现在的问题就是怎么把上面的\x十六进制部分转成可读的形式:十六进制将\x部分去掉,然后使用String.fromCharCode()将剩下的部分转为字符,写出解密逻辑:

<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body> <script id="raw_code" type="text/code-template">
$(function() {
$('\x2e\x70\x6f\x72\x74\x2d\x62\x6f\x78')["\x65\x61\x63\x68"](function(wssP1, fnDKXroKU2) {
var ClpoEy3 = $(fnDKXroKU2);
var jgemfCG4 = ClpoEy3["\x64\x61\x74\x61"]('\x69\x70');
var TO5 = window["\x70\x61\x72\x73\x65\x49\x6e\x74"](ClpoEy3["\x64\x61\x74\x61"]('\x69'));
var tVF6 = jgemfCG4["\x73\x70\x6c\x69\x74"]('\x2e');
for (var d7 = 0; d7 < tVF6["\x6c\x65\x6e\x67\x74\x68"]; d7++) {
TO5 -= window["\x70\x61\x72\x73\x65\x49\x6e\x74"](tVF6[d7])
}
ClpoEy3["\x74\x65\x78\x74"](TO5)
})
})
</script> <script type="text/javascript"> let content = document.getElementById('raw_code').innerHTML;
content = content.replace(/\\x../g, hex => {
hex = parseInt(hex.replace(/\\x/, ""), 16);
return String.fromCharCode(hex)
});
document.write(content); </script> </body>
</html>

十六进制转为字符串之后:

$(function() {
$('.port-box')["each"](function(wssP1, fnDKXroKU2) {
var ClpoEy3 = $(fnDKXroKU2);
var jgemfCG4 = ClpoEy3["data"]('ip');
var TO5 = window["parseInt"](ClpoEy3["data"]('i'));
var tVF6 = jgemfCG4["split"]('.');
for (var d7 = 0; d7 < tVF6["length"]; d7++) {
TO5 -= window["parseInt"](tVF6[d7])
}
ClpoEy3["text"](TO5)
})
})

稍稍整理下变量名,让可读性好一些:

$(function() {
$('.port-box')["each"](function(i, elt) {
var self = $(elt);
var ip = self["data"]('ip');
var falseIp = window["parseInt"](self["data"]('i'));
var ipArray = ip["split"]('.');
for (var i = 0; i < ipArray["length"]; i++) {
falseIp -= window["parseInt"](ipArray[i])
}
self["text"](falseIp)
})
})

值得一提的是上面的方法调用都采用了[“…”]的方式是因为方法名都被十六进制编码了,如果还用点.来调用的话可能编译都通不过啦。

分析上面代码,先将此对象转为了jQuery对象,然后调用jQuery的data()方法取数据字段,data()是jQuery对h5的一个支持,只需要data-*后面的*号部分就可以取出数据。

将ip和i字段取出,比如取出172.87.221.221和8781,然后将ip按照点号分割,即分为四段,然后使用8781减去每一段的值即为最终的端口。

可依据此逻辑写出java代码:

    private static int decode(String ip, String basePortStr) {
int basePort = Integer.parseInt(basePortStr);
int ipSum = Arrays.stream(ip.split("\\.")).map(Integer::parseInt).reduce(0, Integer::sum);
return basePort - ipSum;
}

完整爬取demo:

package org.cc11001100.mybatis_study_001;

import org.jsoup.Jsoup;

import java.io.IOException;
import java.net.URL;
import java.util.Arrays;
import java.util.List; import static java.util.stream.Collectors.toList; /**
* @author CC11001100
*/
public class CoderBusyProxyCrawler { private static int decode(String ip, String basePortStr) {
int basePort = Integer.parseInt(basePortStr);
int ipSum = Arrays.stream(ip.split("\\.")).map(Integer::parseInt).reduce(0, Integer::sum);
return basePort - ipSum;
} private static List<String> grab(String url) throws IOException {
return Jsoup.parse(new URL(url), 3000)
.select(".table .port-box")
.stream().map(elt -> {
String ip = elt.attr("data-ip");
String falsePort = elt.attr("data-i");
return ip + ":" + decode(ip, falsePort);
}).collect(toList());
} public static void main(String[] args) throws IOException {
grab("https://proxy.coderbusy.com/").forEach(System.out::println);
} }

码农代理免费代理ip端口字段js加密破解的更多相关文章

  1. 码农很忙代理IP系统V1.0版本上线

    码农很忙代理IP系统V1.0版本上线 经过为期一个月的重写和测试,新版本的码农很忙代理IP系统已于今日正式上线.新版本拥有更精准的匿名类型识别和更高效的验证调度算法. 新版本仍旧采用ASP.NET B ...

  2. 蚂蚁代理免费代理ip爬取(端口图片显示+token检查)

    分析 蚂蚁代理的列表页大致是这样的: 端口字段使用了图片显示,并且在图片上还有各种干扰线,保存一个图片到本地用画图打开观察一下: 仔细观察蓝色的线其实是在黑色的数字下面的,其它的干扰线也是,所以这幅图 ...

  3. Nginx配置二级目录/路径 映射不同的反向代理和规避IP+端口访问

       当配置Nginx来映射不同的服务器 可以通过二级路径来反向代理 来解决一个外网端口实现多个服务访问. 配置如下: server { listen ; server_name demo.domai ...

  4. ip端口协议,SSHj加密连接

    SSH协议----一旦linux服务器开机,SSH协议就不断的侦听22端口,一旦有连接到达,就校验连接用户名和密码: 可以理解为连接ip端口为找到一栋大楼,发送用户名和密码为向大楼保安出示证件.SSH ...

  5. 记一次企业级爬虫系统升级改造(六):基于Redis实现免费的IP代理池

    前言: 首先表示抱歉,春节后一直较忙,未及时更新该系列文章. 近期,由于监控的站源越来越多,就偶有站源做了反爬机制,造成我们的SupportYun系统小爬虫服务时常被封IP,不能进行数据采集. 这时候 ...

  6. 如何维护一个1000 IP的免费代理池

    楔子 好友李博士要买房了, 前几天应邀帮他抓链家的数据分析下房价, 爬到一半遇到了验证码. 李博士的想法是每天把链家在售的二手房数据都抓一遍, 然后按照时间序列分析. 链家线上在交易的二手房数据大概有 ...

  7. Python3.x:免费代理ip的批量获取并入库

    Python3.x:免费代理ip的批量获取并入库 一.简介 网络爬虫的世界,向来都是一场精彩的攻防战.现在许多网站的反爬虫机制在不断的完善,其中最令人头疼的,莫过于直接封锁你的ip.但是道高一尺魔高一 ...

  8. 采集15个代理IP网站,打造免费代理IP池

    采集的站点: 免费代理IP http://ip.yqie.com/ipproxy.htm66免费代理网 http://www.66ip.cn/89免费代理 http://www.89ip.cn/无忧代 ...

  9. nginx代理tomcat后,tomcat获取真实(非proxy,非别名)nginx服务端ip端口的解决方案

    nginx代理tomcat后,tomcat获取服务端ip端口的解决方案 1.注意修改nginx配置代理,标红地方 #user nginx; worker_processes ; error_log l ...

随机推荐

  1. Django—中间件

    中间件简介 什么是中间件 中间件是一个用来处理Django的请求和响应的框架级别的钩子.它是一个轻量.低级别的插件系统,用于在全局范围内改变Django的输入和输出.每个中间件组件都负责做一些特定的功 ...

  2. [洛谷P2234][HNOI2002] 营业额统计 - Treap

    Description Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额. ...

  3. python 杂货铺

    python 杂货铺之不知道的python操作 1.交互模式下的神奇的_ windos中cmd交互模式中下(python2,python3),最近一个表达式的值赋给变量 _.这样我们就可以把它当作一个 ...

  4. jacascript 事件对象event

    前言:这是笔者学习之后自己的理解与整理.如果有错误或者疑问的地方,请大家指正,我会持续更新! 在触发DOM上的某个事件时,会产生一个事件对象 event,这个对象中包含着所有与事件有关的信息.所有浏览 ...

  5. Linux下内存问题检测神器:Valgrind

    在写大型C/C++工程时难免会发生内存泄漏现象,系统编程中一个重要的方面就是有效地处理与内存相关的问题.你的工作越接近系统,你就需要面对越多的内存问题.有时这些问题非常琐碎,而更多时候它会演变成一个调 ...

  6. Spring Cloud学习笔记-006

    服务容错保护:Spring Cloud Hystrix 在微服务架构中,我们将系统拆分成了很多服务单元,各单元的应用间通过服务注册与订阅的方式互相依赖.由于每个单元都在不同的进程中运行,依赖通过远程调 ...

  7. Xshell实现Windows上传文件到Linux主机

    我是怎么操作的: 1.打开一台本地Linux虚拟机,使用mount 挂载Windows的共享文件夹到Linux上,然后拷贝数据到Linux虚拟机里面:(经常第一步都不顺利,无法挂载Windows的文件 ...

  8. Java四种线程池的学习与总结

    在Java开发中,有时遇到多线程的开发时,直接使用Thread操作,对程序的性能和维护上都是一个问题,使用Java提供的线程池来操作可以很好的解决问题. 一.new Thread的弊端 执行一个异步任 ...

  9. [LeetCode] Employee Free Time 职员的空闲时间

    We are given a list schedule of employees, which represents the working time for each employee. Each ...

  10. 处处留心皆学问——由“display:inline-block;”导致的间距引发的思考。

    昨天在做一个demo时遇到了一个问题:我有五个li需要并排排列,然后自然而然的我给它们设了display:inline-block;但是,过了很久之后发现,除了我写的样式外,它默认有一个间距,我们都不 ...