美团滑块(1-18,js逆向)

网址:aHR0cHM6Ly9wYXNzcG9ydC5tZWl0dWFuLmNvbS9hY2NvdW50L3VuaXRpdmVsb2dpbg==
整体流程:
1、获取主页参数
2、逆向pwd、h5Fingerprint
3、请求page_data链接
4、逆向Authencation、behavior、token_
5、最终请求验证

一、获取主页参数

url_ = "https://passport.meituan.com" + re.search(r'id="J-normal-form" action="(.*?)"', response).group(1).replace('=', '=').replace('amp;', '')
csrf = re.search(r'"csrf" value="(.*?)"', response).group(1)
uuid = re.search(r'uuid=(.*?)&', url_).group(1)
token_id = re.search(r'token_id=(.*?)&', url_).group(1)
continues = url_.split('continue=')[1]

二、逆向pwd、h5Fingerprint

(1)pwd,跟进去发现是个rsa,简单扣下就ok美团滑块(1-18,js逆向)_第1张图片

(2) h5Fingerprint,定位:
在这里插入图片描述

继续跟进这个混淆后的js,看到是通过n生成sign的,n是主页返回的一些东西
美团滑块(1-18,js逆向)_第2张图片

再往后跟就会发现是btoa,直接改写下就ok
美团滑块(1-18,js逆向)_第3张图片

然后到这里,将sign赋值给C,再加密,ts和cts稍微改下,其他固定即可(注意这里的环境值,后面滑块也会有,需要保持一致)
美团滑块(1-18,js逆向)_第4张图片
注:这个js如果觉得看得麻烦可以用ast反混淆下变量名,代码如下:

// 这个文件是run.js,demo.js放需要需要解混淆的js,decrypt_func.js是解密函数
const fs = require('fs');
const {parse} = require("@babel/parser");
const traverse = require("@babel/traverse").default;
const types = require("@babel/types");
const generator = require("@babel/generator").default;
const _0x24f5 = require("./decrypt_func");

let jscode = fs.readFileSync("./demo.js", {
    encoding: "utf-8"
});
let ast = parse(jscode);

// 十六进制转换
function delete_unicode(path){
    if (path.node.extra == undefined){return;}
    delete path.node.extra
    path.skip()
}

// 找到需要替换的调用函数,push到数组
name_array = ['a7_0x3a83']
function find_decode_name(path){
    let node = path.node;
    if (!node.declarations || node.declarations[0].init == null || node.declarations[0].init.name == undefined){return}
    let call_name = node.declarations[0].id.name;
    let binding = path.scope.getBinding(call_name);
    if (call_name == '_0x41c885' || binding.references<=0){return}
    if (name_array.indexOf(call_name) == -1){
           name_array.push(call_name)
    }
}

// 替换字符串
function replace_name(path){
    let node = path.node;
    if (!node.arguments[0]){return}
    if(node.arguments[0].type == 'NumericLiteral' && node.callee.type == 'Identifier'){
         const key = node.callee.name;
         const value = node.arguments[0].value;
         if (key == '_0x24f5'){
              let value_new = _0x24f5(value);
              console.log(value_new,"<-->",key,"<-->",value)
              let string_node = types.stringLiteral(value_new)
              path.replaceWith(string_node)
         }
    }
}

traverse(ast,{"NumericLiteral|StringLiteral": delete_unicode})
console.log("十六进制还原结束~~")
traverse(ast,{"CallExpression": replace_name})
console.log("变量名还原结束~~")

let {code} = generator(ast,opts = {jsescOption:{"minimal":true}});
fs.writeFile('decode.js', code, (err)=>{});

//这个文件是decrypt_func.js
function _0x5b47() {
  var _0x25463d = ["Freefrm721 Blk BT", "postInfo", "slice", "NETWORK_FAILURE_TIP", "

\n "
, "Vivaldi", "YodaKNB", "RISK_GET_VERIFYINFO_LIMIT", "Date", "getUniformIndices", "121011", "OscillatorNode", "121042", "HIGH_FLOAT", "Vagabond", "SimSun-ExtB", "FrankRuehl", "127032", "setTimeout", "fill", "Bradley Hand", "isMobile", "AvantGarde Md BT", "Float32Array", "FRUTIGER", "Adobe Garamond", "pay", "request_code", "constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf", "Tw Cen MT", "Geeza Pro", "_yoda_riskLevel", "NEVIS", "cts", "assign", "-9999px", "MAX_COMBINED_UNIFORM_BLOCKS", " : null", "globalLoadModel", "GOTHAM BOLD", "getActiveUniformBlockName", "toFixed", "TRIANGLES", "Cambria", "121125", "_timelimit", "resetVariable", "root", "yodaCommonThemeColor", "failCallbackFun", "__core-js_shared__", "name", "Serifa BT", "RISK_FACE_POLICE_DATABASE_NOT_FOUND", "RISK_MOBILE_NOT_VALID", "isNeedLoad", "quickapp_miniProgram", "yodaMoveingBar", "rejected", "getContext", "MT Extra", "Bradley Hand ITC", "Arial", "write", "AliApp", "decode", "boxError", "_selenium", "classof", "COMPILE_STATUS", "isLoading", "sliderMaxLenth", "bindEvents", "MS Reference Specialty", "buttonName", "Lithograph Light", "setValueAtTime", "TypoUpright BT", "symbol-registry", "getExtension", "121005", "Khmer UI", "uniform4uiv", "byteOffset", "RISK_USER_NOT_LOAD", "2.2.2", "Vladimir Script", "toDataURL", "MS PGothic", "getUniformBlockIndex", "abnormal", "checkRiskLevel", "EUROSTILE", "customElements", "succCallbackFun", "last", "Noteworthy", "121053", "111", "wRU", "findChild", "00101", "substr", "b_techportal_property_mv", "language", "return (function() ", "bind", "waimai", "precision", "RISK_GET_VERIFY_INFO_ERROR_RETRY", "scrollLeft", "Freestyle Script", "A promise cannot be resolved with itself.", "CordiaUPC", "Footlight MT Light", "Centaur", "121064", "121133", "setResult", "MY_miniProgram", "passive", "padding: .3em .8em; border: 1px solid #999; border-radius: .3em; background: transparent; margin: .6em auto; outline: none; color: ", "floor", "MingLiU_HKSCS-ExtB", "getQuery", "navigator", "_bytes", " \n 请求地址", "51d7c9ad", "apply", "Gill Sans", "Timestamp", "function", "options", "pathname", "[object]", "removeHandler", "MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS", "makeDOMException", "121001", "Raavi", "切换验证方式", "RISK_VERIFY_REQUEST_TIME_OUT", "pageX", "NewsGoth BT", "key", "#A4A3A3", "Mrs Eaves", "title", "request_null", "GeoSlab 703 Lt BT", "Pickwick", "121057", "getProgramParameter", "delta", "Iskoola Pota", "' src='https://s3plus.meituan.net/v1/mss_f231eb419c414559a1837748d11d4312/yoda-resources/help_icon.png'>\n
\n

, "callPhantom", "lwc", "/v2/ext_api/", "shaderSource", "getDate", "121154", "121123", "close", "ネットワークがリダイレクトしました、後でもう一度やり直してください", "925458AfqHQn", "getBufferSubData", "0-0-0-0", "rangeMax", "boxStatic", "Party LET", "ontouchmove", "'>\n ", "enableVertexAttribArray", "wsh", "Goudy Stout", "bindBuffer", "RISK_NOT_VERIFY_BY_ORDER", "wordBreak", "121112", "mouseout", "symbols", "setPrototypeOf", "新版签名正常", "drag", "40zdFOiH", "\n ", "header", "callHandle", "RISK_BOOM_PROOF_DENY", "defenseForm", "style", "no support webgl", "maxContainer", "moveingBar ", "__driver_unwrapped", "Content-MD5", "utf8", "globalCompositeOperation", "getFonts", "formDataPost", "RISK_PARAMS_INVALID_FORMART", "Trident", "isSync", "'>\n

\n
\n
", "customStyle", "ALPHA", "Harrington", "Aparajita", "getInt32", "MUSEO", "exponentialRampToValueAtTime", "\n
\n
, "__selenium_evaluate", "none", "Serifa Th BT", "121050", "call", "Cuckoo", "pageY", "allSettled", "webgl", "moveTo", "RISK_COMMON_PARAMS_LOST", "Lucida Calligraphy", "localStorage", "DFKai-SB", "_setter", "Viner Hand ITC", "Onyx BT", "isKNBEnv", "Kalinga", "getBoundingClientRect", "boxOk ", "arc", "setUint8", "'>\n
\n
为了完成验证,需要您提供多项信息\n
\n \n
"
, "Gill Sans MT Condensed", "Niagara Solid", "fontSize", "Tubular", "Internet Explorer", "normal", "103", "Error: ", "Century Schoolbook", "Bookshelf Symbol 7", "RISK_AUTHORIZE_CODE_EXPIRE", "charCodeAt", "Marion", "Bodoni 72 Smallcaps", "nativeSign sign fail", "Sketch Rockwell", "targetTouches", "新版签名异常", "ネットワークのつなぎ状態が不安定です", "'>\n , "rangeMin", "getStringHashMD5", "availWidth", "Bernard MT Condensed", "drawArrays", "jump", "https://s3plus.meituan.net/v1/mss_f231eb419c414559a1837748d11d4312/yoda-resources/slider/m_loading.png", "invalidateFramebuffer", "top", "Uint16Array", "loadSource", "moveingBarError ", "Vrinda", "withCredentials", "Heiti SC", "label", "Wingdings 3", "Kannada Sangam MN", "[null]", "not a function", "Curlz MT", "Forte", "Constantia", "Amazone BT", "iterator", "动态签名", "121002", "Bandy", "op-symbols", "Pegasus", "RISK_NO_SUCH_METHOD", "getShaderPrecisionFormat", "getwd", "hash", "done", "succCallbackUrl", "Can't call method on ", "MONO", "Tahoma", "BankGothic Md BT", "MAX_COLOR_ATTACHMENTS", "forEach", "safari", "127021", "code=", "FILLPHONENUMBER", "Old English Text MT", "startX", "Bodoni 72", "'>
\n
\n
, "Jester", "constructor", "Browallia New", "String", "121129", "session", "OPR", "121049", "count", "getSourcePath", "Bauer Bodoni", "freeze", "99999", " class='sel ", "then", "UNIFORM_BUFFER_OFFSET_ALIGNMENT", "FRAGMENT_SHADER", "{}.constructor(\"return this\")( )", "keyboardEvent", "onFulfilled", "Wingdings", "MAX_UNIFORM_BLOCK_SIZE", "textDecoration", "Lao UI", "Microsoft Edge", "MingLiU", "handlerHelp", "time", "BatangChe", "Andalus", "CopperplGoth Bd BT", "Matura MT Script Capitals", "clientWaitSync", "race", "loading", "data-verifyid", "utils", "Book Antiqua", "callee", "Yes, D3D9", "_deferreds", "MAX_PROGRAM_TEXEL_OFFSET", "doms", "touchstart", "compileShader", "ceil", "uniformMatrix2x4fv", "isDrag", "setItem", "Rockwell", "createElement", "Kaito", "RISK_PARAMS_LOST", "bufferData", "getOwnPropertySymbols", "Nyala", "WX_miniProgram", "click", "configurable", "Microsoft JhengHei", "clientHeight", "promise", "DOM Exception 5", "#FD9B29", "您的请求出现了异常", "Bank Gothic", "Segoe Print", "chrome", "listenwd", "Fixedsys", "Tw Cen MT Condensed", "globalTimer", "PC上显示了i版的滑动", "RISK_AUTHORIZE_CODE_FAIL", "actualMove", "buffer", "b_techportal_7nezp2sy_mc", "American Typewriter", "Microsoft Yi Baiti", "Corbel", "ChelthmITC Bk BT", "YODA_Bridge", "AES must be instanitated with `new`", "setFloat64", "NETWORK_FAILURE_CODE", "Not available", "Antique Olive", "connect", "Palatino", "Wingdings 2", "GulimChe", "MingLiU-ExtB", "isFrozen", "replace", "English 111 Vivace BT", "dianping", "Url", "\n precision mediump float;\n varying vec4 v_color;\n void main() {\n gl_FragColor = v_color; // return reddish-purple\n }\n ", "RISK_NAME_IDENTITY_INFO_NOT_FOUND", "getElementById", "texImage3D", "Kokila", "MV Boli", "riskLevelInfo", "lowp", "Korinna BT", "render", "加载图片失败", "sendBatch", "#490F44", "121046", "reduce", "circle9", "tagName", "Magneto", "Reflect", "knbFun", "Sinhala Sangam MN", "HIGH_INT", "onVerifySuccess", "PKCS#7 invalid padding byte", "Helvetica Neue", "_getter", "webdriver-evaluate", "Malformed string", "Zurich Ex BT", "editFinishedTimeStamp", "DELICIOUS", "BANKCARDREALNAME", "Rockwell Extra Bold", "Accessors not supported!", "'>\n

立即验证\n

", "webdriverScriptFn", "Gloucester MT Extra Condensed", "valueOf", "'>为了您的账号安全请选择一种方式完成验证

\n
\n
"ALPHA_BITS", "INPUT", "toBytes", "121139", "writable", "getHash", "table", "\n
\n
\"padding-top: 50%;\">\n

\"line-height: 32px;font-size: 1.2em;font-weight: bold; color: #333;\">出错了

\n

\"line-height:32px; font-size: 1em; color: #333;\">", "drawArraysInstanced", "preventExtensions", "Snap ITC", "get", "PTBarnum BT", "

\"text-align: center;\">\n
\n
\n
"Uint8ClampedArray", "Simplified Arabic", "Wide Latin", "使用新版签名", "MODULE_VERSION", "appendChild", "NETWORK_TIMEOUT_CODE", "core", "setInt16", "custom", "styles", "sent", "font", "lineHeight", "yodaInitTime", "yodaVersion", "Gill Sans MT Ext Condensed Bold", "16118iwsyfk", "Chalkduster", "titleWrapper", "highp", "Yes", "jsVersion", "auto", "RISK_UP_SMS_OUT_OF_SERVICE", "setAttribute", "deleteVertexArray", "calledSelenium", "CaslonOpnface BT", "MAX_ELEMENT_INDEX", "maxDecibels", "left", "propertyIsEnumerable", "Cornerstone", "Marker Felt", "100oksGWu", "getUint16", "Sherwood", "getAttribute", "ARNO PRO", "f_e_s_e", "CT_PRESIGN_FAIL", "uniformBlockBinding", "addEventListener", "Univers CE 55 Medium", "now", "startDrag", "IE_PROTO", "contentWindow", "Bodoni MT", "121018", "Mongolian Baiti", "Times", "reload", "Authencation", "David", "MAX_COMBINED_TEXTURE_IMAGE_UNITS", "ids", "reason", "set", "wrapper", "yoda-language", "mousemove", "VOICE", "max", "GeoSlab 703 XBd BT", "RISK_ERROR_OUT_OF_LIMIT_AND_DOWNLOAD_APP", "removeEventListener", "ownKeys", "'>\n
\n \n
"
, "getActiveUniformBlockParameter", "vertexAttribPointer", "vertexAttribDivisor", "RISK_GET_VERIFYINFO_TIMES_LIMIT_ONE_DAY", "Gisha", "event", "Futura Lt BT", "MS LineDraw", "isSealed", "selenium-evaluate", "BUTTON", "FangSong", "Futura Md BT", "moveingbar", "121138", "Apple Color Emoji", "GoudyHandtooled BT", "btn", "IMAGE", "2397388dcLsoC", "&request_code=", "phantom", "iframe", "vertexAttribI4iv", "AVENIR", "sliderType", "encryptToBase64", "ArrayBuffer", "defineProperties", "RISK_VOICE_SEND_TIMES_LIMIT_ONE_DAY", "letterSpacing", "__$webdriverAsyncExecutor", "init", "PC_FACE", "rohr_", "DEPTH_BITS", "canvas", "isDoubleTap", "Script MT Bold", "innerHeight", "cd_frame_id_", "ontouchstart", "GOTHAM", "getTransformFeedbackVarying", "getInternalformatParameter", "mousedown", "Lithograph", "MAX_SAMPLES", "getWebGlReport", "RISK_REAL_NAME_AUTH_STATUS_ERROR", "outline", "Edge", "initSlider", "Zurich BlkEx BT", "Bazooka", "Long Island", "compressedTexImage3D", "OSAKA", "MS Mincho", "Segoe UI", "useProgram", "0123456789ABCDEF", "RISK_LEVEL", "length is not a small enough positive integer.", "getUint8", "LINK_STATUS", "OPTIMA", "Microsoft Tai Le", "_Selenium_IDE_Recorder", "getQueryParameter", "#F4F4F2", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", "Poor Richard", "Arial Unicode MS", "cententWrapper", "Bad UTF-8 encoding 0x", "'>
\n
, "clear", "miniProgram", "当前请求状态", "サーバーが異常です。しばらくしてからもう一度お試しください", "createRadialGradient", "domAutomation", "MAX_SERVER_WAIT_TIMEOUT", "Modern", "message", "Arabic Typesetting", "tabindex", "clearColor", "timeoutCount", "Microsoft Uighur", "RISK_NO_AUTH", " : ", "block", "substring", "l_d_s_c", "Coronet", "invalidateSubFramebuffer", "div", "RISK_MERCHANT_ID_NOT_VALID", "Humanst 521 Cn BT", "jsonp_", "bindBufferRange", "121126", "webView", "textShadow", "Arial Rounded MT Bold", "Tw Cen MT Condensed Extra Bold", "/feedback/manmachine/#/?requestCode=", "ALIASED_LINE_WIDTH_RANGE", "Rage Italic", "publish", "#E10909", "Yes, D3D11", "stencil", "src", "moveingBarY", "attachShader", "'>\n ](_0x4356e7['shift']()); } catch (_0x4f5641) { _0x4356e7['push'](_0x4356e7['shift']()); } } })(_0x5b47, 0xedc46) function _0x24f5(_0x3b92fb, _0x1d45ea) { var _0x1fbea5 = _0x5b47(); return _0x24f5 = function(_0x1415da, _0x306f35) { _0x1415da = _0x1415da - 0x0; var _0x534c81 = _0x1fbea5[_0x1415da]; return _0x534c81; } , _0x24f5(_0x3b92fb, _0x1d45ea); } module.exports = _0x24f5;

三、请求page_data链接

这里用之前返回的requestCode作为参数请求,session、sign、timestamp、verifyMethodVersion、yodaVersion后面都会用到

四、逆向Authencation、behavior、token_
(1)behavior,参数定位:
美团滑块(1-18,js逆向)_第5张图片
注:这里的point轨迹t和后面token加密的mt轨迹是相互验证的
继续往后跟会到这里
美团滑块(1-18,js逆向)_第6张图片
这里对之前拿到的session进行atob,生成一段代码再eval下,会决定接下来走switch的那个case。
再继续往后跟,到这里
美团滑块(1-18,js逆向)_第7张图片
这个f是一开始就生成的,这里是拿了一开始返回的session和sign生成一段代码,最后再执行这段代码得到f,位置如下:
美团滑块(1-18,js逆向)_第8张图片
这里他自己hook了这个window.f
美团滑块(1-18,js逆向)_第9张图片
这里需要补的环境如下(这个滑块也就这点环境,如果发现还检测了其他东西删掉即可,不影响整个算法的生成):

window = global;
var md5 = require('md5-node');
var Buffer_ = window.Buffer;
window.Buffer = undefined;

screen = {
    'availHeight':1040,
    'availLeft':0,
    'availTop':0,
    'availWidth':1920,
    'colorDepth':24,
    'height':1080,
    'pixelDepth':24,
    'width':1920,
    'isExtended':true
}

localStorage = {
    Storage:{
        'length':0
    }
}
navigator = {}
navigator.geolocation = new (class Geolocation{});
navigator.geolocation.getCurrentPosition = function getCurrentPosition(){
   debugger;
};
navigator.geolocation.clearWatch = function clearWatch(){
   debugger;
};
navigator.geolocation.watchPosition = function watchPosition(){
 debugger;
};

HTMLBodyElement = function HTMLBodyElement(){debugger;}

!function(){
	this.atob = function(encodeBase64){
        // debugger;
		return Buffer_.from(encodeBase64, "base64").toString("binary")
	}
	this.btoa = function(decodeBase64){
        // debugger;
		return Buffer_.from(decodeBase64, "binary").toString("base64")
	}
}()
;

(2)token,参数定位:
美团滑块(1-18,js逆向)_第10张图片
token和behavior的生成算法是一样的,所以只说下需要注意的地方
美团滑块(1-18,js逆向)_第11张图片
这里同样是ts和cts需要改下,mt是轨迹,检测较为严格,其他都不怎么检测,再次提醒这个mt和behavior的point是有关联的,打印下对比下就知道了
(3)Authencation,参数定位
美团滑块(1-18,js逆向)_第12张图片
这里用到了很多之前的返回的参数
美团滑块(1-18,js逆向)_第13张图片
注:这个timestamp是返回的,不是实时获取的,后面的验证请求也是这个timestamp

五、请求验证
在这里插入图片描述
晚安~

你可能感兴趣的:(javascript,爬虫,js逆向)