码农代理免费代理ip端口字段js加密破解

 

起因

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

 

解密

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

image

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

image

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

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

image

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

image

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

image

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

image

将其拿出:

$(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);
    }

}

转载于:https://www.cnblogs.com/cc11001100/p/8606160.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值