Análisis de la Herramienta de Desarrollo de WeChat para Ejecutar Juegos de Terceros

Intenté ejecutar un juego desarrollado por otro usando la herramienta de desarrollo de WeChat. Aunque es posible iniciar el juego, la verificación de inicio de sesión falla debido a la discrepancia entre el appid del juego y el appid de prueba personal. Configurar forzosamente el appid de otro provoca un error en la herramienta, indicando que no se es desarrollador de ese appid.

El inicio de sesión se realiza mediante la API wx.login. En lugar de depender del appid, exploré técnicas para interceptar esta API. Primero, descomprimí el archivo wxapkg y segmenté el archivo game.js en múltiples archivos usando un script de Python.


# Script en Python para dividir archivos de juego
import os
import expresiones_regulares

def guardar_archivo(datos):
    ruta = os.path.dirname(datos[0])
    if ruta != '' and not os.path.exists(ruta):
        os.makedirs(ruta)
    with open(datos[0], 'wb') as archivo:
        archivo.write(bytes(datos[1], 'utf8'))

def dividir_juego(contenido):
    if contenido is None:
        print('Contenido vacío')
        return
    coincidencias = expresiones_regulares.findall(
        r'\W+define\(\"(.*?)\",\Wfunction\(require,\Wmodule,\Wexports\)\{ \t\t\t\n(.*?)\W\t\t\t\}\)\;\n',
        contenido, expresiones_regulares.M | expresiones_regulares.DOTALL
    )
    if coincidencias:
        for coincidencia in coincidencias:
            guardar_archivo(coincidencia)
    else:
        print('No se encontraron coincidencias')

def leer_contenido(nombre_archivo):
    with open(nombre_archivo, 'r') as archivo:
        return archivo.read()

dividir_juego(leer_contenido('game2.js'))

Mediante depuración, identifiqué dos ubicaciones de appid en el archivo asdebug.js: __devtoolsConfig.appid y __wxConfig.accountInfo.appid. Sin embargo, dado que asdebug se ejecuta en un entorno virtual (VM), el objeto window no coincide con el de game.js. Intenté enganchar variables globales como __global.parent, pero el problema persistía.

Al probar, descubrí que modificar el appid no resuelve la verificación, ya que la llamada a wx.login no incluye información del appid. En su lugar, envía una solicitud WebSocket. Además, el archivo core.wxvpkg tiene validación de firma RSA-SHA1, que teóricamente no debería modificarse. No obstente, enganchando el método de validación de firma, pude alterar core.wxvpkg para permitir la ejecución.

En esencia, wx.login se basa en una solicitud HTTP POST para obtener un código. Ejemplo de solicitud curl:


curl -H 'host: servicewechat.com' --data-binary '{"scope":["snsapi_base"]}' 'https://servicewechat.com/wxa-dev-logic/jslogin?_r=0.700034971603429&newticket=tl1MUNfnG4w1C9n8DyWnxbJB1XrdZuhXDwuC3FrmZag&appid=wx418ad5760dd5bcba&platform=0&ext_appid=&os=darwin&clientversion=1052102020'

Implementé un hook para registrar actividades, interceptando funciones de consola y enviando datos a un servidor local.


// Script en JavaScript para enganchar registros
setTimeout(() => {
    const solicitud = require("request");
    var ejecutar = require('child_process').exec;

    function registrarEvento(mensaje, argumentos) {
        solicitud({
            url: "http://localhost:3000/echo",
            method: "POST",
            json: true,
            headers: { "content-type": "application/json" },
            body: { mensaje, argumentos }
        });
    }

    try {
        var comando = 'netstat -anp tcp | grep 3000 | grep LISTEN';
        ejecutar(comando, (error, salida, errorEstandar) => {
            if (String(salida) !== '') {
                console.log = (...args) => registrarEvento("log", Array.from(args));
                console.error = (...args) => registrarEvento("error", Array.from(args));
                console.info = (...args) => registrarEvento("info", Array.from(args));
            }
        });
    } catch (error) {
        console.error(error.message);
    }
}, 1000);

El archivo para este hook se encuentra en /Applications/wechatwebdevtools.app/Contents/Resources/package.nw/js/unpack/hackrequire/index.js. Finalmente, concluí que wx.login no puede ser vulnerado, ya que el código se obtiene del servidor, que verfiica los permisos de la cuenta de WeChat con el appid. Esto significa que solo se puede acceder a códigos para appids con permisos de desarrollo o prueba, gestionados por administradores del proyecto. Cualquier intento de obtener un código para otro appid resulta en el error DEV_APP_NOT_BAND: -80002.

Las medidas de seguridad de Tencent demuestran ser robustas contra tales intentos de manipulación.

Etiquetas: wechat-developer-tools wx-login wxapkg JavaScript Python

Publicado el 6-26 19:31