JS逆向:破解淘宝浏览器指纹识别风控策略

指纹识别原理

  • 在 selenium 抓取数据的时候,会暴露一些预定义的 JavaScript 变量,通过这些变量可以识别到用户是否使用了 selenium 驱动;
  • 比较典型的例子,是 “window.navigator.webdriver”,在非selenium环境下其值为undefined,而在selenium环境下,其值为true;

  • 除了 navigator,还有一些其它的标志性字符串(不同的浏览器可能会有所不同),常见的特征串如下所示:

webdriver  
__driver_evaluate  
__webdriver_evaluate  
__selenium_evaluate  
__fxdriver_evaluate  
  
__webdriver_unwrapped  
__selenium_unwrapped  
__fxdriver_unwrapped  
_Selenium_IDE_Recorder  
_selenium  calledSelenium  
_WEBDRIVER_ELEM_CACHE  
ChromeDriverw  
driver-evaluate  
webdriver-evaluate  
selenium-evaluate  
webdriverCommand  
webdriver-evaluate-response  
__webdriverFunc  
__webdriver_script_fn  
__$webdriverAsyncExecutor  
__lastWatirAlert  
__lastWatirConfirm  
__lastWatirPrompt  
$chrome_asyncScriptInfo  
$cdc_asdjflasutopfhvcZLmcfl_

反指纹识别方法

  • webdriver 配置
    options = webdriver.ChromeOptions()
    options.add_experimental_option("excludeSwitches", ["enable-automation"])
    browser = webdriver.Chrome(chrome_options=options)
    driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
     "source": """Object.defineProperty(navigator, 'webdriver', {get: () => undefined})""",
    })
    
  • mitmproxy 篡改参数
# coding: utf-8
# modify_response.py

from mitmproxy import ctx


def response(flow):
    """Modify response data
    """
    if '/js/yoda.' in flow.request.url:
        # Screening selenium detection
        for webdriver_key in ['webdriver', '__driver_evaluate', '__webdriver_evaluate', '__selenium_evaluate',
                              '__fxdriver_evaluate', '__driver_unwrapped', '__webdriver_unwrapped',
                              '__selenium_unwrapped', '__fxdriver_unwrapped', '_Selenium_IDE_Recorder', '_selenium',
                              'calledSelenium', '_WEBDRIVER_ELEM_CACHE', 'ChromeDriverw', 'driver-evaluate',
                              'webdriver-evaluate', 'selenium-evaluate', 'webdriverCommand',
                              'webdriver-evaluate-response', '__webdriverFunc', '__webdriver_script_fn',
                              '__$webdriverAsyncExecutor', '__lastWatirAlert', '__lastWatirConfirm',
                              '__lastWatirPrompt', '$chrome_asyncScriptInfo', '$cdc_asdjflasutopfhvcZLmcfl_']:
            ctx.log.info('Remove "{}" from {}.'.format(webdriver_key, flow.request.url))
            flow.response.text = flow.response.text.replace('"{}"'.format(webdriver_key), '"NO-SUCH-ATTR"')
            print(webdriver_key)
        flow.response.text = flow.response.text.replace('t.webdriver', 'false')
        flow.response.text = flow.response.text.replace('ChromeDriver', '')
mitmdump.exe -p Port number  -s modify_response.py