Skip to content

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

东方航空 M 端航班查询 — 全链路逆向工程

Python 3.10+ Node.js License

针对 m.ceair.com 移动端航班查询接口的完整逆向工程,实现纯 Python 协议请求绕过阿里云 WAF 多层防护(Web SDK 指纹 + Keepper 挑战 + 请求签名 + AES 加解密),并提供 Tkinter 桌面 GUI。


目录


功能特性

  • 纯协议请求 — 不依赖浏览器自动化,直接 HTTP 请求获取航班数据
  • 多层 WAF 绕过 — 阿里云 WAF(Web SDK + Keepper 挑战 + refer__1036 签名)
  • AES 白盒加解密 — 请求体加密 + 响应体解密,调用 Node.js WASM 模块
  • Tkinter 桌面 GUI — 城市选择 + 日期输入 + 航班列表展示
  • AST 反混淆 — Babel 12 步流水线,还原控制流平坦化 / 字符串表 / 常量混淆
  • 模块化架构 — JS 签名层与 Python 业务层分离,可单独复用

防护体系总览

┌──────────────────────────────────────────────────────────────────┐
│                    m.ceair.com 阿里云 WAF 防护                    │
├──────────────┬──────────────────┬────────────────────────────────┤
│  层 1: Cookie│ ssxmod_itna      │ 浏览器指纹采集 (屏幕/WebGL/字体) │
│              │ ssxmod_itna2     │ LZ 压缩 + 随机种子签名           │
├──────────────┼──────────────────┼────────────────────────────────┤
│  层 2: TLS   │ Chrome 指纹校验   │ JA3/JA4 TLS 握手特征检测        │
├──────────────┼──────────────────┼────────────────────────────────┤
│  层 3: Body  │ M-CEAIR-ENCRYPTED│ WASM 白盒 AES-CBC 加密           │
│              │ req={base64}     │ 固定 IV + 嵌入 WASM 的密钥       │
├──────────────┼──────────────────┼────────────────────────────────┤
│  层 4: WAF   │ _waf_bd8ce2ce37  │ Keepper 挑战 token (一次性)      │
│   Challenge  │ _waf_a86dfdc5f2  │ 时间戳绑定                      │
├──────────────┼──────────────────┼────────────────────────────────┤
│  层 5: 签名  │ refer__1036      │ LZ 压缩 (洗牌 alphabet)          │
│              │                  │ MD5 + 时间戳 + 指纹掩码          │
│              │                  │ 7 字段联合签名                   │
└──────────────┴──────────────────┴────────────────────────────────┘

逆向路线图

                            ┌──────────────┐
                            │  发现目标接口  │
                            │ shoppingv2   │
                            └──────┬───────┘
                                   │
                    ┌──────────────▼──────────────┐
                    │  Charles / F12 抓包         │
                    │  识别加密参数 & 防护层次      │
                    └──────────────┬──────────────┘
                                   │
          ┌────────────────────────┼────────────────────────┐
          │                        │                        │
  ┌───────▼───────┐        ┌───────▼───────┐        ┌───────▼───────┐
  │ AES 加解密     │        │ WAF JS 提取    │        │ Cookie 分析    │
  │ WASM wbsk_Wbox │        │ keepper 内联    │        │ ssxmod_itna    │
  │ 固定 IV 调用    │        │ 脚本还原        │        │ 指纹数据       │
  └───────┬───────┘        └───────┬───────┘        └───────┬───────┘
          │                        │                        │
          │                ┌───────▼───────┐                │
          │                │ AST 12步还原   │                │
          │                │ encode→decode  │                │
          │                └───────┬───────┘                │
          │                        │                        │
          │                ┌───────▼───────┐                │
          │                │ 关键变量捕获    │                │
          │                │ alphabet 洗牌   │                │
          │                │ L3 指纹 枚举    │                │
          │                └───────┬───────┘                │
          │                        │                        │
          └────────────────────────┼────────────────────────┘
                                   │
                          ┌────────▼────────┐
                          │   Python 集成    │
                          │   Execjs & 协议  │
                          └────────┬────────┘
                                   │
                          ┌────────▼────────┐
                          │   Tkinter GUI    │
                          │   终端用户交付    │
                          └─────────────────┘

技术栈

层级 技术 用途
协议请求 curl_cffi 0.15.0 HTTP/2 + TLS 指纹伪装 (Chrome 136)
JS 执行 PyExecJS 1.5.1 Node.js 子进程运行签名算法
AES 加解密 Node.js + WASM 白盒 AES-CBC (wbsk_Wbox)
AST 反混淆 @babel/parser @babel/traverse @babel/generator JS 混淆代码 → 可读源码
日志 loguru 0.7.3 GUI 模式日志输出
GUI Tkinter (内置) 桌面查询工具
抓包分析 Charles / F12 HAR 请求对比 & 参数验证

核心难点与解决方案

1. WASM 白盒 AES — 请求体/响应体加解密

问题: 网站使用 WASM 白盒 AES (wbsk_Wbox.js),密钥嵌入 WASM 二进制不可提取。

方案: 保留原始 wbsk_Wbox.js + enc_and_dec.js,通过 subprocess 调用 Node.js 执行加解密:

  • 加密: aes_encrypt(json_payload) → Base64 密文
  • 解密: aes_decrypt(base64_response) → JSON 明文
  • 解决 Windows 命令行长度限制: dec_file 模式将密文写入临时文件

2. Keepper 挑战 — _waf_bd8ce2ce37 动态 Token

问题: 首次 POST 返回 Keepper HTML,内含一次性 challenge token,后续请求必须携带该 token 生成的签名。

方案: 两步协议流程:

  1. 首次 POST → 提取 <textarea id="renderData"> 中的 _waf_bd8ce2ce37
  2. 生成 refer__1036 签名 → 二次 POST 携带签名
  3. _waf_a86dfdc5f2 时间戳必须在收到 Keepper 响应之后获取

3. 洗牌 Alphabet — 运行时 LZ 压缩表

问题: WAF 的 v(z) 函数在运行时对 LZ 压缩 alphabet 进行 Fisher-Yates 洗牌,种子依赖 E[] 数组。使用标准 alphabet 会导致服务端解压失败。

方案: 浏览器 F12 日志断点捕获洗牌后的 alphabet:

WupoePhf73Q6wvF1jtJY9ig8bTk0zNmnEAlBR5VxU=crCyqaLDdGXM/2O_s4SKIZH

验证方法: v(z) 使用确定性 LCG (H() 函数),每次页面加载 alphabet 相同。

4. 双重 URL 编码 — 请求参数被重复编码

问题: en_refer1036.jsLK() 返回 encodeURIComponent(Lg),Python 的 session.post(params=...) 对参数值再编码一次。=%3D%253D

方案: HAR 对比验证 → JS 中 LK() 返回值改为 Lg(不编码),由 Python HTTP 库处理编码。

5. 控制流平坦化 — AST 反混淆

问题: WAF JS 使用 while(!![]) + switch 控制流平坦化,-597 + 1*-937 + 110*15 整数混淆,LA(0x1a) 字符串表索引。

方案: 编写 Babel AST 12 步还原流水线,详见 AST 反混淆流水线

6. TLS 指纹模拟

问题: 服务端检测 JA3/JA4 TLS 指纹,错误的 Chrome 版本会被下发更严格的 aliyun_waf_aa/bb 挑战。

方案: curl_cffi 伪装 Chrome 136 TLS 指纹(最接近目标 Chrome 140)。

7. 环境指纹消除 — Node.js 特征

问题: Node.js execjs 环境中 L2() 函数检测到 global.Buffer 存在(浏览器无此对象),指纹异常。

方案: window.Buffer = undefined 清除 Node.js 特征。


AST 反混淆流水线

encode.js (混淆WAF源码)
    │
    ▼  12步 Babel AST 变换
    │
    ├─ 1. 元信息提取 (IIFE名/checksum/解码器/hash函数)
    ├─ 2. VM 沙箱加载解码器 (tk=276)
    ├─ 3. 解码调用替换: LA(0x1a) → "window"
    ├─ 4. Hex raw 清理: 0x1a → 26
    ├─ 5. 对象属性替换: tg.x → 160
    ├─ 6. 字符串拼接折叠: "push"+"s" → "pushs"
    ├─ 7. 常量折叠: -597+1*-937+110*15 → 116
    ├─ 8. x 对象解析: x["key"] → x.key / 字面量
    ├─ 9. x wrapper 内联: x.ylVFE(a,b) → a==b
    ├─ 10. 控制流平坦化还原: while(!![]){switch...} → 顺序语句
    ├─ 11. 死代码删除: try{push(175)...finally{pop()}}
    └─ 12. 未使用变量清理 (5轮)
    │
    ▼
decode.js (可读源码)
    │
    ▼  手动调整
en_refer1036.js (execjs 可用)

反混淆效果统计:

指标 还原前 还原后
可读性 完全不可读 函数名/逻辑清晰
控制流 while+switch 平坦化 顺序语句
字符串 全为 LA(0xNN) 调用 明文字符串
常量 三个整数运算拼接 单个数值
x 对象调用 大量 x.xxx() wrapper 内联为原生运算

项目结构

dh/
├── main.py               # 协议请求主程序 (命令行)
├── tk_dh.py              # Tkinter GUI 桌面工具
├── en_refer1036.js       # refer__1036 签名生成 (execjs)
├── ssxmod.js             # ssxmod Cookie 生成 (execjs)
├── enc_and_dec.js        # AES 加解密 Node.js 脚本
├── wbsk_Wbox.js          # WASM 白盒 AES 模块
├── requirements.txt      # Python 依赖
├── .gitignore            # Git 忽略规则
├── decode.js             # WAF 原始内联脚本 (仅供参考)
├── README.md             # 本文档
├── AST_refer1036/        # AST 反混淆工具链 (WAF)
├── AST_jquery/           # AST 反混淆工具链 (ssxmod 风格)
│   ├── ast.js            # Babel 12 步还原
│   ├── encode.js         # 混淆源码 (输入)
│   ├── decode.js         # 还原后 (输出)
│   └── test_verify.js    # 功能验证
├── m.ceair.com.har       # 浏览器抓包 (调试用)
└── m.ceair.com_*.har     # 代理抓包 (调试用)

快速开始

环境要求

  • Python 3.10+
  • Node.js 22+
  • Windows (Tkinter GUI)

安装

git clone https://github.com/luminouspathway/dh_inquire.git
cd dh_inquire
pip install -r requirements.txt

运行

命令行模式:

python main.py

GUI 模式:

python tk_dh.py

关键配置

main.py 中需修改:

CWD = r'你的路径\enc_and_dec.js 所在目录'

运行截图

运行截图


License

MIT License — 仅供学习交流,请勿用于非法用途。


免责声明

本项目仅用于技术研究与学习,严禁用于任何商业用途或非法爬取行为。使用者须自行承担一切法律责任,开发者概不负责。


本项目是对阿里云 WAF 防护体系的完整逆向分析,核心技术点包括白盒 AES、运行时 Alphabet 洗牌、控制流平坦化 AST 还原、TLS 指纹模拟等。

About

东方航空全链路逆向 | 阿里云WAF绕过 | WASM白盒AES | Keepper挑战 | AST反混淆

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages