【猿人学】 雪碧图、样式干扰 数字图片还原,css样式分析

0 阅读10分钟

暗号:aHR0cHM6Ly9tYXRjaC55dWFucmVueHVlLmNuL21hdGNoLzQ=

 

题目:

image.png

先抓包分析端口,发现请求参数和请求头中并无加密参数:

image.png

再看请求到的数据内容,一共包含81k 的img标签数据:

image.png

并且接口中还获取到了很多张图片,图片中的内容就是我们要的数字:

image.png

所以可以推测:内容是直接通过图片形式传回来的,然后需要根据图片的解析出我们要的数字

那我们先分析图片的链接是否是固定的

先看数字1

image.png

image.png

再看数字8

image.png

image.png

发现虽然他们的值并不一样,但是长度是很相似的,所以我们可以根据长度生成一个还原数字的字典,字典如下(有些数字的长度并不一定只有一个):

numdict = {

    '1094':0,

    '910':5,

    '434':1,

    '1090':0,

    "430":1,

    '1002':2,

    '1066': 3,

    '770':4,

    '906':5,

    '1198':6,

    '774':7,

    '1278':8,

    '1202':9,

    '998':2,

    '1194':6

}


 

再通过下面步骤定位和检查网页中的图片元素:

image.png

仔细观察下面的内容:

image.png

image.png

这些数字的class 和 style是不一样的,这里的class 里面的数据,如果是这个数字是由5个数组成,会发现有5个的class是一样的,如果是这个数字是由6个数组成,会发现有6个的class是一样的,所以应该是根据class调整要显示的图片,

再看style:

image.png

这里的style信息只得是偏题,left是向左偏移,观察8.5和17.0的关系,其实是两倍的关系,所以我们可以将所有数的style里面的值都除以8.5,就能得到数字的排列顺序

image.png

所以接下来的问题就是需要找到class里面加密值的生成逻辑:

于是在接口最后一个堆栈下断点分析:

image.png

在req里面的success里面我们看到的md5的字样,这里success是获取数据成功后会执行的代码,所以推测加密其实就是这个:

image.png

于是下断点进行分析:

这里主要对key和value进行了加密:

image.png

而key和value其实就在浏览器返回给我们的数据当中了:

image.png

所以下一步只需要还原加密就可以了,但是要检查他的加密逻辑是否有进行修改:

Btoa是JavaScript中的base64加密,这里的值能够对应的上,所以没有进行修改:

image.png

再看md5加密,1的md5加密应该是c4ca4238a0b923820dcc509a6f75849b,但程序中的并不是,所以这里的hex_md5加密被修改过,所以需要扣代码还原:

image.png

最终还原的js代码我放在了最后

于是接下来,每次获取网页后只需要读取网页的每一个img图片长度,key 、 value  ,在通过key和value生成对应的加密值,再去将img信息中class里面包含这个加密值的数据提取出来,然后再根据style里面的值还原数字的出现顺序,即可完成本题:

附上python代码(header和cookie已删除):


import requests

from lxml import etree

import re

import execjs

numdict = {

    '1094':0,

    '910':5,

    '434':1,

    '1090':0,

    "430":1,

    '1002':2,

    '1066': 3,

    '770':4,

    '906':5,

    '1198':6,

    '774':7,

    '1278':8,

    '1202':9,

    '998':2,

    '1194':6

}

sum = 0

for i in range(1,6):

    headers = {

 

    }

    cookies = {

 

    }

    url = "<https://match.yuanrenxue.cn/api/question/4>"

    params = {

        "page": str(i),

        "pageSize": "10",

        "kw": ""

    }

    if i == 5:

        headers\['user-agent'] = 'yuanrenxue'

    response = requests.get(url, headers=headers, cookies=cookies, params=params).json()

    key = response\['key']

    value = response\['value']

    response = response\['info']

    list = \[]

    md5list = \[]

    for i in re.findall("<td>.\*?</td>", response):

        sz = \[]

        for j in re.findall('\<img.\*?>',i):

            try:

                src = re.findall('src="(.\*?)"',j)\[0]

                class\_ = re.findall('class="(.\*?)"',j)\[0]

                style = re.findall('style="(.\*?)"',j)\[0]

                sz.append(\[numdict\[str(len( src))],float(style.split(':')\[1].replace('px',''))/8.5,class\_.replace('img\_number ','')])

 

                md5list.append(class\_.replace('img\_number ',''))

            except:

                print(len(src), src)

        list.append(sz)

    #统计出现次数最多的值

    md5 = execjs.compile(open('雪花.js', 'r').read()).call("result",key,value)

    for i in list:

        nl = \[]

        k = 0

        sz = \[]

        for j in i:

            if j\[2] != md5:

                sz.append(int(j\[1])+ k)

                k += 1

                nl.append(j\[0])

 

        ss = \[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1]

        for i in range(len(sz)):

            ss\[sz\[i]] = str(nl\[i])

        while -1 in ss:

            ss.remove(-1)

        number = int(''.join(ss))

        print(number)

 

        sum += number

print(sum)

JavaScript代码:


function binl2hex(binarray) {

        var hex\_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";

        var str = "";

        for (var i = 0; i < binarray.length \* 4; i++) {

            str += hex\_tab.charAt((binarray\[i >> 2] >> ((i % 4) \* 8 + 4)) & 0xF) + hex\_tab.charAt((binarray\[i >> 2] >> ((i % 4) \* 8)) & 0xF)

        }

        return str

    }

function hex\_md5(s) {

        return binl2hex(core\_md5(str2binl(s), s.length \* chrsz))

    }

function core\_md5(x, len) {

        x\[len >> 5] |= 0x80 << ((len) % 32);

        x\[(((len + 64) >>> 9) << 4) + 14] = len;

        var a = 1732584193;

        var b = -271733879;

        var c = -1732584194;

        var d = 271733878;

        for (var i = 0; i < x.length; i += 16) {

            var olda = a;

            var oldb = b;

            var oldc = c;

            var oldd = d;

            a = md5\_ff(a, b, c, d, x\[i + 0], 7, -680876936);

            d = md5\_ff(d, a, b, c, x\[i + 1], 12, -389564586);

            c = md5\_ff(c, d, a, b, x\[i + 2], 17, 606105819);

            b = md5\_ff(b, c, d, a, x\[i + 3], 22, -1044525330);

            a = md5\_ff(a, b, c, d, x\[i + 4], 7, -176418897);

            d = md5\_ff(d, a, b, c, x\[i + 5], 12, 1200080426);

            c = md5\_ff(c, d, a, b, x\[i + 6], 17, -1473231341);

            b = md5\_ff(b, c, d, a, x\[i + 7], 22, -45705983);

            a = md5\_ff(a, b, c, d, x\[i + 8], 7, 1770035416);

            d = md5\_ff(d, a, b, c, x\[i + 9], 12, -1958414417);

            c = md5\_ff(c, d, a, b, x\[i + 10], 17, -42063);

            b = md5\_ff(b, c, d, a, x\[i + 11], 22, -1990404162);

            a = md5\_ff(a, b, c, d, x\[i + 12], 7, 1804603682);

            d = md5\_ff(d, a, b, c, x\[i + 13], 12, -40341101);

            c = md5\_ff(c, d, a, b, x\[i + 14], 17, -1502002290);

            b = md5\_ff(b, c, d, a, x\[i + 15], 22, 1236535329);

            a = md5\_gg(a, b, c, d, x\[i + 1], 5, -165796510);

            d = md5\_gg(d, a, b, c, x\[i + 6], 9, -1069501632);

            c = md5\_gg(c, d, a, b, x\[i + 11], 14, 643717713);

            b = md5\_gg(b, c, d, a, x\[i + 0], 20, -373897302);

            a = md5\_gg(a, b, c, d, x\[i + 5], 5, -701558691);

            d = md5\_gg(d, a, b, c, x\[i + 10], 9, 38016083);

            c = md5\_gg(c, d, a, b, x\[i + 15], 14, -660478335);

            b = md5\_gg(b, c, d, a, x\[i + 4], 20, -405537848);

            a = md5\_gg(a, b, c, d, x\[i + 9], 5, 568446438);

            d = md5\_gg(d, a, b, c, x\[i + 14], 9, -1019803690);

            c = md5\_gg(c, d, a, b, x\[i + 3], 14, -187363961);

            b = md5\_gg(b, c, d, a, x\[i + 8], 20, 1163531501);

            a = md5\_gg(a, b, c, d, x\[i + 13], 5, -1444681467);

            d = md5\_gg(d, a, b, c, x\[i + 2], 9, -51403784);

            c = md5\_gg(c, d, a, b, x\[i + 7], 14, 1735328473);

            b = md5\_gg(b, c, d, a, x\[i + 12], 20, -1926607734);

            a = md5\_hh(a, b, c, d, x\[i + 5], 4, -378558);

            d = md5\_hh(d, a, b, c, x\[i + 8], 11, -2022574463);

            c = md5\_hh(c, d, a, b, x\[i + 11], 16, 1839030562);

            b = md5\_hh(b, c, d, a, x\[i + 14], 23, -35309556);

            a = md5\_hh(a, b, c, d, x\[i + 1], 4, -1530992060);

            d = md5\_hh(d, a, b, c, x\[i + 4], 11, 1272893353);

            c = md5\_hh(c, d, a, b, x\[i + 7], 16, -155497632);

            b = md5\_hh(b, c, d, a, x\[i + 10], 23, -1094730640);

            a = md5\_hh(a, b, c, d, x\[i + 13], 4, 681279174);

            d = md5\_hh(d, a, b, c, x\[i + 0], 11, -358537222);

            c = md5\_hh(c, d, a, b, x\[i + 3], 16, -722521979);

            b = md5\_hh(b, c, d, a, x\[i + 6], 23, 76029189);

            a = md5\_hh(a, b, c, d, x\[i + 9], 4, -640364487);

            d = md5\_hh(d, a, b, c, x\[i + 12], 11, -421815835);

            c = md5\_hh(c, d, a, b, x\[i + 15], 16, 530742520);

            b = md5\_hh(b, c, d, a, x\[i + 2], 23, -995338651);

            a = md5\_ii(a, b, c, d, x\[i + 0], 6, -198630844);

            d = md5\_ii(d, a, b, c, x\[i + 7], 10, 1126891415);

            c = md5\_ii(c, d, a, b, x\[i + 14], 15, -1416354905);

            b = md5\_ii(b, c, d, a, x\[i + 5], 21, -57434055);

            a = md5\_ii(a, b, c, d, x\[i + 12], 6, 1700485571);

            d = md5\_ii(d, a, b, c, x\[i + 3], 10, -1894986606);

            c = md5\_ii(c, d, a, b, x\[i + 10], 15, -1051523);

            b = md5\_ii(b, c, d, a, x\[i + 1], 21, -2054922799);

            a = md5\_ii(a, b, c, d, x\[i + 8], 6, 1873313359);

            d = md5\_ii(d, a, b, c, x\[i + 15], 10, -30611744);

            c = md5\_ii(c, d, a, b, x\[i + 6], 15, -1560198380);

            b = md5\_ii(b, c, d, a, x\[i + 13], 21, 1309151649);

            a = md5\_ii(a, b, c, d, x\[i + 4], 6, -145523070);

            d = md5\_ii(d, a, b, c, x\[i + 11], 10, -1120210379);

            c = md5\_ii(c, d, a, b, x\[i + 2], 15, 718787259);

            b = md5\_ii(b, c, d, a, x\[i + 9], 21, -343485551);

            a = safe\_add(a, olda);

            b = safe\_add(b, oldb);

            c = safe\_add(c, oldc);

            d = safe\_add(d, oldd)

        }

        return Array(a, b, c, d)

    }

function str2binl(str) {

        chrsz = 8

        var bin = Array();

        var mask = (1 << chrsz) - 1;

        for (var i = 0; i < str.length \* chrsz; i += chrsz) bin\[i >> 5] |= (str.charCodeAt(i / chrsz) & mask) << (i % 32);

        return bin

    }

 

    function md5\_ff(a, b, c, d, x, s, t) {

        return md5\_cmn((b & c) | ((\~b) & d), a, b, x, s, t)

    }

function md5\_cmn(q, a, b, x, s, t) {

        return safe\_add(bit\_rol(safe\_add(safe\_add(a, q), safe\_add(x, t)), s), b)

    }

 

 

    function md5\_gg(a, b, c, d, x, s, t) {

        return md5\_cmn((b & d) | (c & (\~d)), a, b, x, s, t)

    }

 

    function md5\_hh(a, b, c, d, x, s, t) {

        return md5\_cmn(b ^ c ^ d, a, b, x, s, t)

    }

 

    function md5\_ii(a, b, c, d, x, s, t) {

        return md5\_cmn(c ^ (b | (\~d)), a, b, x, s, t)

    }

 

    function core\_hmac\_md5(key, data) {

        var bkey = str2binl(key);

        if (bkey.length > 16) bkey = core\_md5(bkey, key.length \* chrsz);

        var ipad = Array(16), opad = Array(16);

        for (var i = 0; i < 16; i++) {

            ipad\[i] = bkey\[i] ^ 0x36363636;

            opad\[i] = bkey\[i] ^ 0x5C5C5C5C

        }

        var hash = core\_md5(ipad.concat(str2binl(data)), 512 + data.length \* chrsz);

        return core\_md5(opad.concat(hash), 512 + 128)

    }

 

    function safe\_add(x, y) {

        var lsw = (x & 0xFFFF) + (y & 0xFFFF);

        var msw = (x >> 16) + (y >> 16) + (lsw >> 16);

        return (msw << 16) | (lsw & 0xFFFF)

    }

function bit\_rol(num, cnt) {

        return (num << cnt) | (num >>> (32 - cnt))

    }

hexcase = 0

function result(key,value){

a = hex\_md5(btoa(key + value).replace(/=/g, ''))

console.log(a)

return a;

}

console.log(result("93NqabKB12","xW5apqtlhz"))