zoukankan      html  css  js  c++  java
  • 码农代理免费代理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() {
        $('x2ex70x6fx72x74x2dx62x6fx78')["x65x61x63x68"](function(wssP1, fnDKXroKU2) {
            var ClpoEy3 = $(fnDKXroKU2);
            var jgemfCG4 = ClpoEy3["x64x61x74x61"]('x69x70');
            var TO5 = window["x70x61x72x73x65x49x6ex74"](ClpoEy3["x64x61x74x61"]('x69'));
            var tVF6 = jgemfCG4["x73x70x6cx69x74"]('x2e');
            for (var d7 = 0; d7 < tVF6["x6cx65x6ex67x74x68"]; d7++) {
                TO5 -= window["x70x61x72x73x65x49x6ex74"](tVF6[d7])
            }
            ClpoEy3["x74x65x78x74"](TO5)
        })
    })
    

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

    <!DOCTYPE html>
    <html>
    <head>
    	<title></title>
    </head>
    <body>
    
    <script id="raw_code" type="text/code-template">
    $(function() {
    	$('x2ex70x6fx72x74x2dx62x6fx78')["x65x61x63x68"](function(wssP1, fnDKXroKU2) {
    	    var ClpoEy3 = $(fnDKXroKU2);
    	    var jgemfCG4 = ClpoEy3["x64x61x74x61"]('x69x70');
    	    var TO5 = window["x70x61x72x73x65x49x6ex74"](ClpoEy3["x64x61x74x61"]('x69'));
    	    var tVF6 = jgemfCG4["x73x70x6cx69x74"]('x2e');
    	    for (var d7 = 0; d7 < tVF6["x6cx65x6ex67x74x68"]; d7++) {
    	        TO5 -= window["x70x61x72x73x65x49x6ex74"](tVF6[d7])
    	    }
    	    ClpoEy3["x74x65x78x74"](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);
        }
    
    }
  • 相关阅读:
    JSTL标签库
    JavaScript中数组操作
    jquery . fancybox()
    jQuery ajax
    jquery学习笔记2
    codeforces_1066_B.Heaters
    codeforces_1065_D.three pieces_思维
    codeforces_B. Forgery
    codeforces_C. Sequence Transformation
    codeforces_D. Social Circles
  • 原文地址:https://www.cnblogs.com/cc11001100/p/8606160.html
Copyright © 2011-2022 走看看