JS inverso: descifra los parámetros cifrados de oklink y los datos cifrados

Declaración de derechos de autor: la originalidad no es fácil, el plagio y la reimpresión están prohibidos en este artículo, ¡y se debe investigar la infracción!

1. JS Reverse Goal - Será al final

Introducción necesita
oklink es una organización de cadena de bloques, que incluye eth, btc, tron, polygon, bsc y otros navegadores de cadena de bloques. La mayoría de sus transacciones, direcciones, etiquetas y otros datos se pueden encontrar en este sitio web. Tiene una tarea,a oklink: dinero dirección, si es una dirección de hacker, etc. Dirección de ejemplo de combate real inversa JS:




https://www.oklink.com/cn/eth/address/0xdac17f958d2ee523a2206206994597c13d831ec7


Como se mencionó anteriormente, usamos la dirección de Ethereum, es decir, la dirección de longitud de 42 bits que comienza con 0x como ejemplo de la página

de ejemplo de combate real inverso de JS:
inserte la descripción de la imagen aquí
Nota : el cuadro rojo son los datos que queremos

rastrear .
parámetros de cifrado de encabezado:
inserte la descripción de la imagen aquí

datos de cifrado:
inserte la descripción de la imagen aquí

2. Análisis inverso de JS: no conozco la verdadera cara del monte Lushan

En general, hay varias formas de capturar datos, como el posicionamiento de elementos de la página web (css/xpath/re, etc.), solicitudes de interfaz (ajax, fetch, etc.), simulación automatizada (selenium/palywrigth, etc.), etc. ; los datos de la etiqueta json devueltos están encriptados Sí, en este momento es posible que queramos capturar datos ubicando elementos de la página web, pero al analizar el html de la página web, encontraremos que no se pueden ubicar los datos de la etiqueta. capturado por simulación automática, el rendimiento del costo es demasiado bajo

. Si hay 100,000 piezas de datos, entonces es necesario simular 100,000 clics. Cuanto mayor sea la cantidad de datos, más lenta será la velocidad de rastreo . vamos primero mire la API de esta interfaz, como se muestra en la figura anterior, la interfaz API es:




inserte la descripción de la imagen aquí

https://www.oklink.com/api/explorer/v1/eth/address/0xdac17f958d2ee523a2206206994597c13d831ec7/more?t=1680606330657

Entre ellos se encuentra un parámetro de URL t, que es una marca de tiempo de 13 bits

y el parámetro de cifrado del encabezado de la solicitud es:

x-apikey: LWIzMWUtNDU0Ny05Mjk5LWI2ZDA3Yjc2MzFhYmEyYzkwM2NjfDI3OTE3MTc0NDE3NjQxNjU=

El parámetro se parece al cifrado base64, usemos la herramienta en línea para descifrarlo:

URL de la herramienta de cifrado y descifrado en línea:

https://33tool.com/base64/

inserte la descripción de la imagen aquí

La cadena descifrada usando base64 es:

-b31e-4547-9299-b6d07b7631aba2c903cc|2791717441764165

Si se descifra directamente, usamos la cadena descifrada para solicitar directamente, y la solicitud falla, entonces el proceso de cifrado debe haber pasado por algún otro proceso de cifrado o lógica de codificación.Use la búsqueda global, como se muestra en la figura a continuación: ingrese el parámetro x-apikey

para la búsqueda
inserte la descripción de la imagen aquí

global , luego formatee y vea el código JS:
inserte la descripción de la imagen aquí

Muy bien, parece que se puede buscar directamente. El nombre de la variable y el nombre del método no han sido confundidos por JS, que es relativamente amigable para los rastreadores. Se puede ver fácilmente al observar el código JS que al establecer el valor del

inserte la descripción de la imagen aquí
parámetro . x-apikey a través del método setRequestHeader (), es Use el método getApiKey (), use la tecla de método abreviado ctrl + f para buscar el nombre del método getApiKey: observe la lógica del código en el método getApiKey (), puede ver fácilmente que el último retorno es this.comb(e, t) , esto es similar a The self en python, el método comb tiene dos parámetros, e se obtiene mediante el método encryptApiKey (), y el parámetro t obtiene primero la hora actual, que es una marca de tiempo de 13 bits y luego llama al método encryptTime(t) para comparar el tiempo. El parámetro t realiza el procesamiento de la lógica de cifrado, como el segundo parámetro de peine. Veamos primero cómo encryptApiKey() realiza el cifrado:
inserte la descripción de la imagen aquí



{
    
    
    key: "encryptApiKey",
    value: function() {
    
    
        var t = this.API_KEY
          , e = t.split("")
          , n = e.splice(0, 8);
        return t = e.concat(n).join("")
    }
}

La variable inicial t es una cadena codificada:

['a', '2', 'c', '9', '0', '3', 'c', 'c', '-', 'b', '3', ………………]

La variable e divide la variable t y devuelve una lista de caracteres individuales:

['a', '2', 'c', '9', '0', '3', 'c', 'c', ………………]

Luego borre los primeros 8 caracteres de la lista e y vuelva a formar la variable n, que también es una lista:

['a', '2', 'c', '9', '0', '3', 'c', 'c']

Finalmente, con la lista e al frente y la lista n al final, realice una conexión sin firmar para obtener la variable final t, que es la variable e en el método getApiKey()

-b31e-4547-9299-b6d07b7631aba2c903cc

Echemos un vistazo a la lógica en el método encryptTime():

{
    
    
    key: "encryptTime",
    value: function(t) {
    
    
        var e = (1 * t + a).toString().split("")
          , n = parseInt(10 * Math.random(), 10)
          , r = parseInt(10 * Math.random(), 10)
          , o = parseInt(10 * Math.random(), 10);
        return e.concat([n, r, o]).join("")
    }
}

Se puede ver en el código JS que la variable t aquí es una marca de tiempo de entero de 13 bits A través del análisis, la variable aquí también es una variable entera codificada 1111111111111. Después del cálculo, conviértalo al tipo str antes de continuar La división sin signo se divide en una lista para formar la variable e, y las variables n, r y o son números enteros aleatorios entre 0 y 10. Finalmente, las cuatro variables se conectan sin signo para obtener el valor de retorno final, que es el método getApiKey() La variable t en

el último vistazo al método final peine():

{
    
    
    key: "comb",
    value: function(t, e) {
    
    
        var n = "".concat(t, "|").concat(e);
        return window.btoa(n)
    }
}

Una cosa a tener en cuenta aquí, this.comb(e, t), después de que las variables e y t se pasan al método peine, la variable de parámetro real e se convierte en la variable de parámetro formal t, y la variable de parámetro real t se convierte en el parámetro formal e , y luego use el conector "|" para conectarse con el parámetro formal t primero y el parámetro formal e después, y la variable devuelta finalmente es la variable cifrada por el método btoa (), es decir, el método base64. al JS inverso

aquí Es relativamente simple, sin ofuscación lógica y ofuscación JS, etc. Se puede completar escribiendo código en python, y no hay necesidad de usar execujs, node.js, etc. para simular la ejecución de JS código A través del análisis anterior, el código después de la ingeniería inversa es el siguiente

:

import requests
import time
import random
import base64

def get_apikey():
    API_KEY = "a2c903cc-b31e-4547-9299-b6d07b7631ab"
    key1 = API_KEY[0:8]
    key2 = API_KEY[8:]
    new_key = key2 + key1
    current_time = int(time.time() * 1000)
    new_time = str(1 * current_time + 1111111111111)
    random1 = str(random.randint(0, 9))
    random2 = str(random.randint(0, 9))
    random3 = str(random.randint(0, 9))
    current_time = new_time + random1 + random2 + random3
    last_key = new_key + '|' + current_time
    x_apiKey = base64.b64encode(last_key.encode('utf-8'))
    return str(x_apiKey, encoding='utf-8')

Ejecute el método get_apikey ():

LWIzMWUtNDU0Ny05Mjk5LWI2ZDA3Yjc2MzFhYmEyYzkwM2NjfDI3OTE3ODQ3MTU2NDMzMjk=

El código inverso está escrito

3. Prueba inversa de JS: solo porque estoy en esta montaña

A continuación, solo queda la prueba, porque tanto la interfaz API como el código inverso usan marcas de tiempo. Para mantener la consistencia de las marcas de tiempo, pasamos las marcas de tiempo como parámetros a get_apikey(now_time), y luego escribimos un código simple para la prueba. el código es el siguiente:

# -*- coding: utf-8 -*-
import requests
import time
import random
import base64


def get_apikey(now_time):
    API_KEY = "a2c903cc-b31e-4547-9299-b6d07b7631ab"
    key1 = API_KEY[0:8]
    key2 = API_KEY[8:]
    new_key = key2 + key1
    new_time = str(1 * now_time + 1111111111111)
    random1 = str(random.randint(0, 9))
    random2 = str(random.randint(0, 9))
    random3 = str(random.randint(0, 9))
    now_time = new_time + random1 + random2 + random3
    last_key = new_key + '|' + now_time
    x_apiKey = base64.b64encode(last_key.encode('utf-8'))
    return str(x_apiKey, encoding='utf-8')

now_time = int(time.time()) * 1000
headers = {
    
    
    'x-apikey': get_apikey(now_time),
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36'
}
api = f'https://www.oklink.com/api/explorer/v1/eth/address/0xdac17f958d2ee523a2206206994597c13d831ec7/more?t={
      
      now_time}'
res = requests.get(url=api, headers=headers)
print(res.json())

Salida de la consola (formatearla):

{
    
    
    'code': 0, 
    'msg': '', 
    'detailMsg': '', 
    'data': 
        {
    
    
            'entityTags': 
                    ['QayvIUbQGpJhs4QOJk7Ccw==: dlWG6vsFQhA+YAnbzdnYNg==. igTdUMG1sXqlL+ISnaIU8Q=='], 
            'propertyTags': 
                    ['BYqzosCjwa3Hdj/jGp99Xg==', 'B3N0UYJLaM9LPazO98GU9Q==']
        }
}

inserte la descripción de la imagen aquí

Ahora la respuesta se puede devolver normalmente, pero se puede ver en la salida que incluso si desciframos los parámetros de encriptación del encabezado de la solicitud, los datos de la etiqueta de respuesta aún están encriptados, por lo que ahora necesitamos descifrar aún más la lógica de encriptación de la etiqueta. datos?

4. JS anti-reverse - Sauces y flores iluminan otro pueblo

Ciertamente, es factible analizar más a fondo la lógica de encriptación de los datos de la etiqueta en la respuesta, pero pensemos en ello, no importa qué lógica de encriptación se adopte en JS, su cadena inicial permanece sin cambios:

API_KEY = "a2c903cc-b31e-4547-9299-b6d07b7631ab"

¿Qué sucederá si usamos esta cadena en lugar de x-apikey para realizar una solicitud directamente? @>_<@

Sí, escribimos directamente x-apikey en API_KEY:

now_time = int(time.time()) * 1000
headers = {
    
    
    'x-apikey': 'a2c903cc-b31e-4547-9299-b6d07b7631ab',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36'
}
api = f'https://www.oklink.com/api/explorer/v1/eth/address/0xdac17f958d2ee523a2206206994597c13d831ec7/more?t={
      
      now_time}'
res = requests.get(url=api, headers=headers)
print(res.json())

Salida de la consola (formatearla):

{
    
    
    'code': 0, 
    'msg': '', 
    'detailMsg': '', 
    'data': 
        {
    
    
            'entityTags': 
                    ['DeFi: Tether. USDT Stablecoin'], 
            'propertyTags': 
                    ['ERC20', 'Tether USDT']
        }
}

Fíjate, esta idea es factible, y debería ser de la manera que queremos, no solo obtenemos los datos reales descifrados, sino que también incluimos el tipo de dirección de blockchain: Defi, ERC20, y este tipo de datos está en Es invisible en el página web, y solo se puede obtener solicitando datos a través de la interfaz. Hasta ahora, hemos completado la ingeniería inversa JS, no la ingeniería inversa JS
inserte la descripción de la imagen aquí

. Entonces, ¿por qué es esto? Es posible solicitar datos con éxito directamente a través de cadenas codificadas, y los datos obtenidos aún son datos sin cifrar. La

razón puede ser que este sitio web adopta la lógica inversa JS inversa, por lo que aquellos que están demasiado enfocados en los datos de código de lógica de construcción inversa JS capturar El tomador caerá en un malentendido, pero no puede encontrar la forma más real, simple y directa, y es golpeado con un anti-entorno.Este

tipo de lógica inversa JS inversa es una existencia relativamente diferente.Aunque es relativamente simple , vale la pena nuestra atención y reflexión

Five, oklink revertir descarga completa de código

oklink revertir la descarga completa del código fuente

Descargo de responsabilidad: este artículo es solo para fines de estudio e investigación, ¡no lo use de manera ilegal!

6. Información del autor

Autor: La rutina de pesca de Xiaohong, Objetivo: ¡Hacer que la programación sea más interesante!

Concéntrese en algoritmos, reptiles, sitios web, desarrollo de juegos, análisis de datos, procesamiento de lenguaje natural, IA, etc. Esperamos su atención, ¡crezcamos y codifiquemos juntos!

Nota de derechos de autor: ¡Este artículo prohíbe el plagio y la reimpresión, y la infracción debe investigarse!

Supongo que te gusta

Origin blog.csdn.net/qq_44000141/article/details/130251026
Recomendado
Clasificación