Response content encryption and anti-crawling case 1: Obtaining 4K high-definition and uncensored pictures of a certain Jane’s wallpaper

Table of Contents

Preface

need

Destination URL

detailed steps

1. Find the data interface

2. Analyze the source of encrypted data

3. Stack backtrace and analyze the function logic

4. Enter the decryption function

5. Generate js encryption logic code

6. Build python code logic

Foreword

Page flipping and crawling are prohibited. Attacks or distributed crawling of the website are not allowed. This is for learning reference only.

Requirement

Crawl the 4K images from this website and filter them according to different categories.

Destination URL

aHR0cHM6Ly9iei56enptaC5jbi9pbmRleA==

Detailed steps

1. Find the data interface

2. Analyze the source of encrypted data

3. Stack backtrace and analyze the function logic

4. Enter the decryption function

5. Generate js encryption logic code

window = global
function _0x4e58da(_0x3d1ba4) {
            let _0x481fd7, _0x1af3a1, _0x7ac69c = '';
            for (var _0x1074ee = 0x0; _0x1074ee < _0x3d1ba4['length']; )
                _0x481fd7 = _0x3d1ba4[_0x1074ee],
                _0x1af3a1 = 0x0,
                _0x481fd7 >>> 0x7 === 0x0 ? (_0x7ac69c + = String['fromCharCode'](_0x3d1ba4[_0x1074ee]),
                _0x1074ee + = 0x1) : 0xfc === (0xfc & _0x481fd7) ? (_0x1af3a1 = (0x3 & _0x3d1ba4[_0x1074ee]) << 0x1e,
                _0x1af3a1 |= (0x3f & amp; _0x3d1ba4[_0x1074ee + 0x1]) << 0x18,
                _0x1af3a1 |= (0x3f & amp; _0x3d1ba4[_0x1074ee + 0x2]) << 0x12,
                _0x1af3a1 |= (0x3f & amp; _0x3d1ba4[_0x1074ee + 0x3]) << 0xc,
                _0x1af3a1 |= (0x3f & amp; _0x3d1ba4[_0x1074ee + 0x4]) << 0x6,
                _0x1af3a1 |= 0x3f & amp; _0x3d1ba4[_0x1074ee + 0x5],
                _0x7ac69c + = String['fromCharCode'](_0x1af3a1),
                _0x1074ee + = 0x6) : 0xf8 === (0xf8 & _0x481fd7) ? (_0x1af3a1 = (0x7 & _0x3d1ba4[_0x1074ee]) << 0x18,
                _0x1af3a1 |= (0x3f & amp; _0x3d1ba4[_0x1074ee + 0x1]) << 0x12,
                _0x1af3a1 |= (0x3f & amp; _0x3d1ba4[_0x1074ee + 0x2]) << 0xc,
                _0x1af3a1 |= (0x3f & amp; _0x3d1ba4[_0x1074ee + 0x3]) << 0x6,
                _0x1af3a1 |= 0x3f & amp; _0x3d1ba4[_0x1074ee + 0x4],
                _0x7ac69c + = String['fromCharCode'](_0x1af3a1),
                _0x1074ee + = 0x5) : 0xf0 === (0xf0 & _0x481fd7) ? (_0x1af3a1 = (0xf & _0x3d1ba4[_0x1074ee]) << 0x12,
                _0x1af3a1 |= (0x3f & amp; _0x3d1ba4[_0x1074ee + 0x1]) << 0xc,
                _0x1af3a1 |= (0x3f & amp; _0x3d1ba4[_0x1074ee + 0x2]) << 0x6,
                _0x1af3a1 |= 0x3f & amp; _0x3d1ba4[_0x1074ee + 0x3],
                _0x7ac69c + = String['fromCharCode'](_0x1af3a1),
                _0x1074ee + = 0x4) : 0xe0 === (0xe0 & _0x481fd7) ? (_0x1af3a1 = (0x1f & _0x3d1ba4[_0x1074ee]) << 0xc,
                _0x1af3a1 |= (0x3f & amp; _0x3d1ba4[_0x1074ee + 0x1]) << 0x6,
                _0x1af3a1 |= 0x3f & amp; _0x3d1ba4[_0x1074ee + 0x2],
                _0x7ac69c + = String['fromCharCode'](_0x1af3a1),
                _0x1074ee + = 0x3) : 0xc0 === (0xc0 & _0x481fd7) ? (_0x1af3a1 = (0x3f & _0x3d1ba4[_0x1074ee]) << 0x6,
                _0x1af3a1 |= 0x3f & amp; _0x3d1ba4[_0x1074ee + 0x1],
                _0x7ac69c + = String['fromCharCode'](_0x1af3a1),
                _0x1074ee + = 0x2) : (_0x7ac69c + = String['fromCharCode'](_0x3d1ba4[_0x1074ee]),
                _0x1074ee + = 0x1);
            return _0x7ac69c;
        }

function _0x3b44b8(_0x4f208f) {
            let _0x238f61 = [-0x6f, 0x34, 0x5b, 0x41, -0x41, 0x74, 0x77, 0x6a, -0x79, -0x52, -0x5, 0x50, 0x33, 0x61, 0x44, -0x53, -0x70, -0x33, 0x1 7, -0x2e, -0x22, -0x72, -0x37, -0xb, -0x7f, 0x5a, 0x21, 0x16, -0x1f, 0x32, -0x11, 0x14, -0x2c, 0xf, -0x5e, -0x7b, 0x76, -0x17, -0x3d, 0x72, 0x47, -0x68, -0x7e, -0x75, -0x51, -0x36, -0x12, -0x6e, -0x4, -0x5f, -0x5b, 0x5e, -0x50, -0xe, 0x78, 0x69, 0x55 , 0x68, -0x56, -0x6c, 0x43, 0x19, 0x65, 0x6c, 0x10, -0x69, 0x6f, -0xa, 0x75, -0x49, 0x4d, 0x59, -0x1d, -0x62, -0x44, 0x70, 0x6b, - 0x1, 0x56, 0x79, 0x58, -0x65, -0x7c, 0x45, -0x1e, -0x8, -0x71, -0x4a, -0x76, 0x39, -0x19, 0xc, -0x73, -0x6a, 0x5f, 0x7f, 0x54, 0x7c, -0x66, -0x1c, 0x49, 0x2b, -0x3c, 0x1c, 0x2e, 0x73, 0x1e, 0x7a, -0x4b, 0x7d, -0x43, -0x4d, 0x3, -0x7, -0x35, -0xd, 0x35, 0x4e , -0x48, 0x1, 0xb, -0x47, -0x27, -0x4f, -0x3, 0x13, 0x29, 0x7e, -0x2b, -0x7d, -0x1b, 0x22, 0x3f, 0x8, 0x48, -0x23, -0x29, - 0x3f, 0x3c, -0x18, 0x66, 0x2f, -0x77, -0x67, -0x16, 0x2d, 0x3b, 0x40, -0x60, 0x31, 0x53, -0x6b, -0x78, -0x39, -0x46, 0x0, -0x26, -0x54, -0x28, 0x18, 0xe, 0x30, 0x1d, 0x2c, -0x24, -0x2f, 0x38, -0x5c, 0x26, 0x25, 0x4, -0x32, 0x67, 0xa, -0x59, 0x37, 0x71, -0x1a, 0x6e, 0x36, 0x24, -0x14, -0x4e, -0xc, -0x74, 0x46, -0x25, 0x5, -0x3e, -0x4c, -0x30, -0x40, 0x4f, 0x64, 0x28, 0x6, -0x3a, -0x5a , -0x13, -0x9, 0x27, 0x5d, -0x63, 0x15, 0x7, 0x1a, -0x2, 0x1b, -0x2d, 0x51, 0x3a, -0x7a, 0x4c, -0x42, 0x2, 0x5c, -0x2a, 0x62, - 0x10, 0x9, 0x3d, 0x3e, -0xf, 0x63, -0x15, 0x1f, -0x38, 0x57, 0x11, -0x34, -0x45, -0x21, -0x3b, -0x55, 0x42, 0x4a, 0x12, -0x5d, - 0x80, -0x57, -0x20, 0x2a, 0x20, -0x58, 0x6d, 0x60, 0xd, -0x6, 0x4b, -0x64, -0x31, 0x23, -0x61, 0x52, -0x6d, 0x7b]
              , _0x50bcf2 = 0x0
              , _0x1d05b1 = 0x0
              , _0x53f98c = 0x0
              , _0x14fbfd = new Array();
            for (let _0x3fc84b = 0x0; _0x3fc84b < _0x4f208f['length']; _0x3fc84b + + ) {
                _0x50bcf2 = _0x50bcf2 + 0x1 & 0xff,
                _0x1d05b1 = (0xff & amp; _0x238f61[_0x50bcf2]) + _0x1d05b1 & amp; 0xff;
                const _0x1d2346 = _0x238f61[_0x50bcf2];
                _0x238f61[_0x50bcf2] = _0x238f61[_0x1d05b1],
                _0x238f61[_0x1d05b1] = _0x1d2346,
                _0x53f98c = (0xff & _0x238f61[_0x50bcf2]) + (0xff & _0x238f61[_0x1d05b1]) & 0xff,
                _0x14fbfd['push'](_0x4f208f[_0x3fc84b] ^ _0x238f61[_0x53f98c]);
            }
            return _0x14fbfd;
        }

function _0x1fa292(_0x4f3d95) {
            const _0x4c382b = window['atob'](_0x4f3d95)
              , _0x177f05 = new Int8Array(_0x4c382b['length']);
            for (let _0x293dd4 = 0x0; _0x293dd4 < _0x4c382b['length']; _0x293dd4 + + )
                _0x177f05[_0x293dd4] = _0x4c382b['charCodeAt'](_0x293dd4);
            return _0x177f05;
        }

function Geturllist(_0x5e36f6) {
            return _0x4e58da(_0x3b44b8(_0x1fa292(_0x5e36f6)));
        }

_0x5e36f6 = 'ak + 9VCsq4dEdB + UdVPGo8kh5JDEbMHGTCmF/ACXJQ0IgHk + vVwivRFLre9HkhFPP2wTUOEjYP/pK5AyOXezyjt/nZCxMAPEUpmpIjRo2LZiizd7JG1j6Eh/bWp9BcjXF3RMgB0/P 2kFG5fHQLsuyMdL + FT/KvJSgFAL8blAKj + 8ZPyohkzbxrrcgNxStVi5MGukt01Z6hZgJ0vuBLeHPQ4WPcc + pZmk5dO4FmTSXrxie + iq1IXGrQxOYv2xenaUN/j/5BwaCgccqiLAi3fFd5HbMeHozvkDw 9WxFzatw98cEpoLETFx74ZxgiCrYeRIKNSU + TghsmM49KOf3IaHOZuLFGXr0Pml7AxKnO7TsHYSrHqhNKA2CUOh2OH1qt + 64POe7OpsKhMBlb9fMyhagmwO2u3RHfC44AsAJWEXH76JfyM0VT0gZ + Gx70 wCUTOTc459ZPT4QQXGVWXmrYwalKsFPvIL3QJxGbbINGYZIE1G4mWLBHFGbB8MVW + D + TpY38BWKh3IiZ0/JTGdS0DdIDwWrfxTR2E2cCrXb8eEBJWVwp6AYL7z/74rAgaIeCXWBt5Zq1aA1pEMT6 r0o+ /lxAHWx9bluM/Kg/tzxZuwRGw1N9jKB6EVJKmAW9dtuqy4sTzzrsUWLoId7R09clXPIfb9umiQqI0RTTQxdu9MuamB3JNxx + AS9s28bAepK/aEsof1DqpfNKfnbmHstW5h2NKRn7Lfd2gwPzqSNGnB q1UbGFjxsqKfjEtbiqc8HTUP1hb6win6j2cUaz + UnORGbhJMu8XI2Ix7diicsPXK7n7bUL6WRFc4mqN9VuN4heDQkXJa95mWG + LxGhBlFNjOyp + KZlN/csWdNOmnqcfVaV00tz74Fijany5AB3Z7xf NoR6CVBgxgSobos/9 + iNb8HRDEeoNB9P6KNmIx + QhVQe6iCC/02up/4YMpoD0x7O4loU9nPEsvnigdXvnXLclre/W2oHtglEZWvKTnZ9l4udalcMgJ5GfEhnmZhjgD + + 8dSfSBn2keCfIfKV9iS mfvk0WG9Wij8HVVXfEDfl5Nr1mrjT66xnZBWmbZiOeC3UJx + Tg + 8RpohALXT4Ym6kgJCDuV2OtkrSnnTeTvF5JRpbxLDweuwTiIG + PIU3zNTskP92/ASkqTzJ8HDHuvYW6ZSiBq7NYQCWUN4qS6t nPOpPE2m7LtUS/vlsl4DdmCUgv6Bf1RAnAQZ09fL7Q9PPooQhlKyiKx5WnFFomIbi2UG42uQQPr8Z5kL6QoJiXxdRrVMYfOTOjnMHZqe66POm3I5bku6VvoZe4UeiHik3Dz0lWZJbob + VnpVejD5S VM9 + gP9sQHl7xy4GJepIBWpwetMhxVybOMvEW4VeV8aJRzXfB3UoKJrZLx6SJpo7mXw0CpEQ4HvTV6if/cgUIHxBmCjH4gWCn8tpxxGlpZ3S24KV0QJSHrvG62LLGHqY4eWKA4Mgx1mB1fCH fB8BJGu9bwE0Ehtca5tFzRKNZ6qWcVnZqxOBV/ dYsEFUwVDMtR9BsxCQljGJyflEyZFPYLAGIUT0yetfnhJCNpN04Rt6FpOF + JFdDzdsJwPutvpLXV8iP2D0mhT + bsjXglLbePFPoYOhxH09v5TPeiKK1WqvIbvP1e77ayXo9koTBKQxFT5fkHSPER ZGirZ08MXyj6XbSLA7rlIPcgvlH2xF9oJPnk15EOXSnHkxW47v3 + w2kfl + JBa9/DPZvW + 8at8lRXuAeeSAMy44SMkOQgXmL1pEQ8SUqjc1QdgRvphtmAKy73cJYcy0goptmiauEnW4I1RMNydgTiwq9M 4Iomk6 + l1sIQ6qWQhIVw60bD4/kohciYUmz1X + KMQen/QlvRRUs1Fi3f0h8vPOek2KR/ZXeNSET8cF + e5cUdc/eLigkk9u8cfSnzjX91BENrmubJlqzfgzj8KE8mGrdfqm7KapQ6ea1P8s7tmFHK1 RUYVYRSvnc1fZNDRNxGKoFbZ6nHohzFBw03Tnf6 + MdbWcr93Nq/ + OY9GGue8WexeWI5WQhPoA/lzfSJFjVJRVfSlLmNs5meNxLQimvBQJCOhKrju/hCI37JaZ09GlWt03b/bA0 + uAnE0fAIo17 Z7yuf9na0vJIBh4130SwAJoBormCVhAJ7k4CrUNtU6k2G/xofL5slSTt7hasGil03Cv5OYDclGq0gBcUwFvAajQbUK'
console.log(Geturllist(_0x5e36f6))

6. Build python code logic

import execjs
import requests
import json
def GetData():
    headers = {
        "authority": "api.zzzmh.cn",
        "accept": "application/json, text/plain, */*",
        "accept-language": "zh-CN,zh;q=0.9,en;q=0.8",
        "cache-control": "no-cache",
        "content-type": "application/json;charset=UTF-8",
        "origin": "https://bz.zzzmh.cn",
        "pragma": "no-cache",
        "referer": "https://bz.zzzmh.cn/",
        "sec-ch-ua": ""Chromium";v="118", "Google Chrome";v=\\ "118", "Not=A?Brand";v="99"",
        "sec-ch-ua-mobile": "?0",
        "sec-ch-ua-platform": ""macOS"",
        "sec-fetch-dest": "empty",
        "sec-fetch-mode": "cors",
        "sec-fetch-site": "same-site",
        "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36"
    }
    url = "https://api.zzzmh.cn/bz/v3/getData"
    data = {
        "size": 24,
        "current": 1,
        "sort": 0,
        "category": 0,
        "resolution": 0,
        "color": 0,
        "categoryId": 0,
        "ratio": 0
    }
    data = json.dumps(data, separators=(',', ':'))
    response = requests.post(url, headers=headers, data=data)

    result = response.json().get('result')
    # print(result,type(result))
    return result

def Geturl(result):
    with open('minimalist wallpaper.js',mode='r',encoding='utf-8')as f:
        data = f.read()
        urllist = execjs.compile(data).call('Geturllist',result)
    urllist = json.loads(urllist).get('list')
    # print(urllist,type(urllist))
    return urllist

def Getpicture(urllist):
    headers = {
        "authority": "api.zzzmh.cn",
        "accept": "image/avif,image/webp,image/apng,image/svg + xml,image/*,*/*;q=0.8",
        "accept-language": "zh-CN,zh;q=0.9,en;q=0.8",
        "cache-control": "no-cache",
        "pragma": "no-cache",
        "referer": "https://bz.zzzmh.cn/",
        "sec-ch-ua": ""Chromium";v="118", "Google Chrome";v=\\ "118", "Not=A?Brand";v="99"",
        "sec-ch-ua-mobile": "?0",
        "sec-ch-ua-platform": ""macOS"",
        "sec-fetch-dest": "image",
        "sec-fetch-mode": "no-cors",
        "sec-fetch-site": "same-site",
        "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36"
    }
    for i in urllist:
        url = f"https://api.zzzmh.cn/bz/v3/getUrl/{i.get('i')}{i.get('t')}1"
        # The small picture is 0 and the big picture is 1
        # print(url)
        smallheaders = requests.get(url=url,headers=headers,allow_redirects=False).headers
        # print(smallheaders)
        Location = smallheaders.get('Location')
        # print(Location)
        with open(f"images/{i.get('i')}{i.get('t')}1.jpg",mode='wb')as f:
            f.write(requests.get(url=Location,headers=headers).content)
        print(f"{i.get('i')}{i.get('t')}0.jpg download completed!")


if __name__ == '__main__':

    result = GetData()

    urllist = Geturl(result)

    Getpicture(urllist)

The code has been uploaded and you can download the pictures yourself.