听Ta说

  • {{ item.name }}
  • 目标
  • 分析
  • 无限debugger
  • debugger:一律不在此处暂停
  • console:使用FD本地替换
  • 请求
  • 编码请求代码
  • 解密
  • 完整代码
  • 首页
  • 归档

猿人学_1_初级混淆

  • Gorkys
  • 2022-10-27
  • 0

目标

考点:js 混淆 - 源码乱码

题目1:抓取所有(5页)机票的价格,并计算所有机票价格的平均值,填入答案。

https://match.yuanrenxue.com/match/1

分析

无限debugger

按下f12,就见到了到debugger,然后就是无限console,分别解决掉它们

debugger:一律不在此处暂停

容易栈溢出,导致卡顿

截图

console:使用FD本地替换

截图

请求

通过网络请求找到价格接口

#第一页
https://match.yuanrenxue.com/api/match/1?m=198fda140e60831667d4593cd8a444ec%E4%B8%A81663855939
#第二页
https://match.yuanrenxue.com/api/match/1?page=2&m=278a90a0e05a38797776e118f40c1be1%E4%B8%A81663856478

接口参数中有一个m加密,去调用堆栈跟一下

截图

编码请求代码

截图

简单的unicode混淆,将代码保存下来,使用python转换一下编码就可了。

# ==================================
# --*-- coding: utf-8 --*--
# @Time    : 2022/9/21 17:15
# @Author  : Gorkys
# @FileName: match_1.py
# @Software: PyCharm
# @describe: 猿人学第一题
# ==================================

with open("1.js", "r", encoding="utf-8") as file_1:
    file_1_res = file_1.read()
    s = file_1_res.encode('utf-8').decode("unicode_escape")
with open("1_de.js", "w", encoding="utf-8") as file_2:
    file_2.write(s)

解码后,可以很清晰的看见m的组成。(后面发现在https://www.sojson.com/中美化代码就可以直接转换编码)

截图

解密

解读一下代码

_0x2268f9 = 当前时间的时间戳(不含毫秒13位)+ (16798545 + -72936737 + 156138192)

其中后面的计算得出为:100000000

结果 = _0x2268f9.toString()

加密(结果)+ window['f']

其中window['f']在控制台打印一下,得到字符串:c512e7663ac285e462b493106df106fd

截图

然后再全局搜索一下oo0O0方法,发现就在html的<script>中,先将html格式化,再将目标代码格式化掉。

截图

先看结尾处返回的是一个空,所以这个函数本身是不会返回有用的结果,那么在上面的代码中肯定是对window.f做什么手脚

for循环赋值给window.b逻辑上是在组装着什么,去控制台打印一下结果。

window.b本身是被base64加密过,在后面的eval代码也可以看出使用了atob解密执行。

截图

注意到最后的window.f=hex_md5(mwqqppz),果然,用md5加密了一个值赋给了window.f,继续看后面的代码,通过解密函数J解密后得到如下明文

eval(atob(window['b'])['replace']('mwqqppz', '\x27' + mw + '\x27'));

也就是说是将mwqqppz替换成了之前通过计算传入的时间戳。\x27编码后为单引号。所以最终加密的是'时间戳'

完整代码

# ==================================
# --*-- coding: utf-8 --*--
# @Time    : 2022/9/21 17:15
# @Author  : Gorkys
# @FileName: match_1.py
# @Software: PyCharm
# @describe: 猿人学第一题
# ==================================

# with open("1.js", "r", encoding="utf-8") as file_1:
#     file_1_res = file_1.read()
#     s = file_1_res.encode('utf-8').decode("unicode_escape")
# with open("1_de.js", "w", encoding="utf-8") as file_2:
#     file_2.write(s)

import requests
import time
import execjs

with open("md5.js", "r", encoding="utf-8") as file:
    js = file.read()

def getSign():
    int_t = int(int(time.time()) * 1e3) + int(1e8)
    t = int(int_t / 1e3)
    runJs = execjs.compile(js)
    sign_tem = runJs.call("hex_md5", f'{str(int_t)}')
    return f"{sign_tem}丨{t}"

def getPriceList(page, ua):
    headers = {
        'referer': 'https://match.yuanrenxue.com/match/1',
        'user-agent': ua,
    }

    params = {
        'page': f'{page}',
        'm': getSign()
    }

    response = requests.get('https://match.yuanrenxue.com/api/match/1', params=params, headers=headers)
    return response.json()["data"]

userAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36'
priceList = []
for i in range(5):
    if i + 1 >= 4:
        userAgent = "yuanrenxue.project"
    priceList += getPriceList(i + 1, userAgent)

priceCount = 0

for i in range(len(priceList)):
    priceCount += priceList[i]['value']

print(priceCount / len(priceList))
# 4700.0
© 2025 听Ta说
湘ICP备2021002328号
Theme by Wing