首页 文章

当您使用硒与铬氢化合物时,网站可以检测到吗?

提问于
浏览
205

我一直在用Chromedriver测试Selenium,我注意到有些页面可以检测到你正在使用Selenium,即使根本没有自动化 . 即使我只是通过Selenium和Xephyr使用chrome手动浏览,我经常会得到一个页面,说明检测到可疑活动 . 我已经检查了我的用户代理和浏览器指纹,它们与普通的Chrome浏览器完全相同 .

当我在普通镀铬中浏览这些网站时,一切正常,但是当我使用Selenium的时候,我已经检测到了 .

从理论上讲,chromedriver和chrome应该看起来与任何网络服务器完全相同,但不知何故,它们可以检测到它 .

如果你想要一些测试代码试试这个:

from pyvirtualdisplay import Display
from selenium import webdriver

display = Display(visible=1, size=(1600, 902))
display.start()
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--disable-extensions')
chrome_options.add_argument('--profile-directory=Default')
chrome_options.add_argument("--incognito")
chrome_options.add_argument("--disable-plugins-discovery");
chrome_options.add_argument("--start-maximized")
driver = webdriver.Chrome(chrome_options=chrome_options)
driver.delete_all_cookies()
driver.set_window_size(800,800)
driver.set_window_position(0,0)
print 'arguments done'
driver.get('http://stubhub.com')

如果您浏览stubhub,您将在一两个请求中被重定向和“阻止” . 我一直在研究这个,我无法弄清楚他们如何判断用户是否正在使用Selenium .

他们是如何做到的呢?

编辑更新:

我在Firefox中安装了Selenium IDE插件,当我在普通的firefox浏览器中使用附加插件访问stubhub.com时,我被禁止了 .

编辑:

当我使用Fiddler来查看来回发送的HTTP请求时,我注意到“假浏览器”的请求通常在响应头中有“无缓存” .

编辑:

像这样的结果Is there a way to detect that I'm in a Selenium Webdriver page from Javascript表明你应该没有办法检测你何时使用webdriver . 但是这个证据表明不然 .

编辑:

该网站将指纹上传到他们的服务器,但我检查了使用chrome时硒的指纹与指纹相同 .

编辑:

这是他们发送到服务器的指纹有效负载之一

{"appName":"Netscape","platform":"Linuxx86_64","cookies":1,"syslang":"en-US","userlang":"en-US","cpu":"","productSub":"20030107","setTimeout":1,"setInterval":1,"plugins":{"0":"ChromePDFViewer","1":"ShockwaveFlash","2":"WidevineContentDecryptionModule","3":"NativeClient","4":"ChromePDFViewer"},"mimeTypes":{"0":"application/pdf","1":"ShockwaveFlashapplication/x-shockwave-flash","2":"FutureSplashPlayerapplication/futuresplash","3":"WidevineContentDecryptionModuleapplication/x-ppapi-widevine-cdm","4":"NativeClientExecutableapplication/x-nacl","5":"PortableNativeClientExecutableapplication/x-pnacl","6":"PortableDocumentFormatapplication/x-google-chrome-pdf"},"screen":{"width":1600,"height":900,"colorDepth":24},"fonts":{"0":"monospace","1":"DejaVuSerif","2":"Georgia","3":"DejaVuSans","4":"TrebuchetMS","5":"Verdana","6":"AndaleMono","7":"DejaVuSansMono","8":"LiberationMono","9":"NimbusMonoL","10":"CourierNew","11":"Courier"}}

它在硒和铬中相同

编辑:

VPN仅供一次使用,但在加载第一页后会被检测到 . 很明显,正在运行一些javascript来检测Selenium .

14 回答

  • 100

    听起来他们是Web应用程序防火墙的幕后推手 . 看看modsecurity和owasp,看看它们是如何工作的 . 实际上,你要问的是如何进行机器人检测规避 . 这不是selenium web驱动程序的用途 . 它用于测试您的Web应用程序而不是其他Web应用程序 . 这是可能的,但基本上,你必须看看WAF在他们的规则集中寻找什么,如果可以的话,特别是用selenium来避免它 . 即使这样,它仍然可能无法工作,因为你不知道他们正在使用什么样的WAF . 您做了正确的第一步,即伪造用户代理 . 如果这不起作用,那么WAF就位,您可能需要更加棘手 .

    编辑:取自其他答案的点 . 确保首先正确设置了用户代理 . 也许让它打到本地网络服务器或嗅到流出的流量 .

  • 8

    即使你发送所有正确的数据(例如Selenium没有显示为扩展,你有一个合理的分辨率/位深度,&c),有许多服务和工具可以描述访问者的行为,以确定是否actor是用户或自动化系统 .

    例如,访问一个站点,然后通过在不到一秒的时间内将鼠标直接移动到相关按钮来立即执行某些操作,这是用户实际上无法做到的事情 .

    作为调试工具,使用https://panopticlick.eff.org/这样的网站来检查浏览器的独特性也是很有用的 . 它'll also help you verify whether there are any specific parameters that indicate you'在Selenium中运行 .

  • 1

    如何在wellsfargo.com上实施它的示例:

    try {
     if (window.document.documentElement.getAttribute("webdriver")) return !+[]
    } catch (IDLMrxxel) {}
    try {
     if ("_Selenium_IDE_Recorder" in window) return !+""
    } catch (KknKsUayS) {}
    try {
     if ("__webdriver_script_fn" in document) return !+""
    
  • 18

    我见过的机器人检测似乎比我在下面的答案中读到的更复杂或至少不同 .

    EXPERIMENT 1:

    • 我从Python控制台打开了一个带有Selenium的浏览器和网页 .

    • 鼠标已经在特定位置,我知道一旦页面加载就会出现一个链接 . I never move the mouse.

    • 我按下鼠标左键一次(这需要从运行Python的控制台获取焦点到浏览器) .

    • 我再次按下鼠标左键(记住,光标位于给定的链接上方) .

    • 链接正常打开,应该如此 .

    EXPERIMENT 2:

    • 和以前一样,我从Python控制台打开浏览器和Selenium的网页 .

    • 这一次,我使用Selenium(在Python控制台中)点击具有随机偏移的相同元素,而不是单击鼠标 .

    • 链接未打开,但我被带到注册页面 .

    IMPLICATIONS:

    • 通过Selenium打开网络浏览器并不妨碍我出现人类

    • 像人类一样移动鼠标不必被归类为人类

    • 通过Selenium点击一些带有偏移的东西仍会引发警报

    看起来很神秘,但我猜他们可以确定一个动作是否来自Selenium,而他们并不关心浏览器本身是否是通过Selenium打开的 . 或者他们可以确定窗口是否有焦点?如果有人有任何见解会很有趣 .

  • 2

    据说Firefox如果使用webdriver,设置 window.navigator.webdriver === true . 这是根据一个较旧的规格(例如:archive.org)但我在_338652中找不到它,除了附录中一些非常模糊的措辞 .

    对它的测试是在文件fingerprint_test.js的selenium代码中,最后的注释显示为"Currently only implemented in firefox"但是我无法使用一些简单的 grep 来识别该方向上的任何代码,在当前(41.0.2)Firefox中都没有释放树也不在Chromium树中 .

    我还在firefox驱动程序b82512999938 from January 2015中找到了关于指纹识别的旧提交的注释 . 该代码仍然是昨天在 javascript/firefox-driver/extension/content/server.js 下载的Selenium GIT-master中的一条评论链接到当前w3c webdriver规范中略有不同措辞的附录 .

  • 4

    一些网站正在检测到:

    function d() {
    try {
        if (window.document.$cdc_asdjflasutopfhvcZLmcfl_.cache_)
            return !0
    } catch (e) {}
    
    try {
        //if (window.document.documentElement.getAttribute(decodeURIComponent("%77%65%62%64%72%69%76%65%72")))
        if (window.document.documentElement.getAttribute("webdriver"))
            return !0
    } catch (e) {}
    
    try {
        //if (decodeURIComponent("%5F%53%65%6C%65%6E%69%75%6D%5F%49%44%45%5F%52%65%63%6F%72%64%65%72") in window)
        if ("_Selenium_IDE_Recorder" in window)
            return !0
    } catch (e) {}
    
    try {
        //if (decodeURIComponent("%5F%5F%77%65%62%64%72%69%76%65%72%5F%73%63%72%69%70%74%5F%66%6E") in document)
        if ("__webdriver_script_fn" in document)
            return !0
    } catch (e) {}
    
  • 1

    正如我们已经在问题和已发布的答案中找到的那样,这里有一个反Web抓取和Bot检测服务,名为"Distil Networks" . 而且,根据公司CEO的说法interview

    即使他们可以创建新的机器人,我们找到了一种方法来识别他们正在使用的工具Selenium,所以无论他们在该机器人上迭代多少次,我们都会阻止Selenium . 我们现在正在使用Python和许多不同的技术 . 一旦我们看到一种类型的机器人出现了一种模式,那么我们就会对他们使用的技术进行逆向工程并将其识别为恶意技术 .

    要了解他们究竟是如何检测Selenium还需要时间和其他挑战,但目前我们可以肯定地说:

    • 它's not related to the actions you take with selenium - once you navigate to the site, you get immediately detected and banned. I'已尝试在操作之间添加人工随机延迟,在页面加载后暂停 - 没有任何帮助

    • 它也不是关于浏览器指纹 - 在多个浏览器中尝试使用干净的配置文件而不是隐身模式 - 没有任何帮助

    • 因为,根据采访中的提示,这是"reverse engineering",我怀疑这是通过在浏览器中执行的一些JS代码来完成的,这是通过selenium webdriver实现的浏览器自动化

    决定将其作为答案发布,因为很清楚:

    当您使用硒与铬氢化合物时,网站可以检测到吗?

    是 .


    此外,我没有尝试过的是较旧的selenium和较旧的浏览器版本 - 理论上,在某些点上可能会有一些实现/添加到Distil Networks bot探测器目前所依赖的内容 . 然后,如果是这种情况,我们可能会检测(是的,让我们检测探测器)在哪个点/版本上进行相关更改,查看更改日志和更改集,并且可能,这可以为我们提供有关在哪里查看的更多信息他们用什么来检测一个基于webdriver的浏览器 . 这只是一个需要测试的理论 .

  • 4

    使用以下代码编写html页面 . 您将看到在DOM中,selenium在outerHTML中应用了webdriver属性

    <html>
    <head>
      <script type="text/javascript">
      <!--
        function showWindow(){
          javascript:(alert(document.documentElement.outerHTML));
        }
      //-->
      </script>
    </head>
    <body>
      <form>
        <input type="button" value="Show outerHTML" onclick="showWindow()">
      </form>
    </body>
    </html>
    
  • 3

    适用于Mac用户

    Replacing cdc_ variable using Vim or Perl

    您可以使用 vim ,或者@Vic来自@Ver,他是在@ Erti-Chris Eelmaa, perl 的答案中指出的,以替换 chromedriver 中的 cdc_ 变量(请参阅@ Erti-Chris Eelmaa的帖子以了解有关该变量的更多信息) . 使用 vimperl 可以防止您重新编译源代码或使用十六进制编辑器 . 在尝试编辑之前,请务必复制原始 chromedriver . 此外,以下方法在 chromedriver version 2.41.578706 上进行了测试 .


    使用Vim

    vim /path/to/chromedriver
    

    在运行上面的行之后,你可能会看到一堆乱码 . 请执行下列操作:

    • 键入 /cdc_ 并按 return 搜索 cdc_ .

    • a 启用编辑 .

    • 删除任意数量的 $cdc_lasutopfhvcZLmcfl 并用等量字符替换已删除的内容 . 如果不这样做, chromedriver 将失败 .

    • 完成编辑后,按 esc .

    • 要保存更改并退出,请键入 :wq! 并按 return .

    • 如果您不想保存更改,但想要退出,请键入 :q! 并按 return .

    • 你已经完成了 .

    转到更改后的 chromedriver 并双击它 . 应该打开一个 terminal 窗口 . 如果在输出中没有看到 killed ,则表示您已成功更改了驱动程序 .


    使用Perl

    下面的行用 dog_ 替换 cdc_

    perl -pi -e 's/cdc_/dog_/g' /path/to/chromedriver
    

    确保替换字符串与搜索字符串具有相同的字符数,否则 chromedriver 将失败 .

    Perl Explanation

    s///g 表示您要搜索字符串并将其全局替换为另一个字符串(替换所有出现的字符串) .

    例如,s / string / replacment / g

    所以,

    s ///表示搜索并替换字符串 . cdc_是搜索字符串 . dog_是替换字符串 . g是全局键,它替换字符串的每个匹配项 .

    How to check if the Perl replacement worked

    以下行将打印搜索字符串 cdc_ 的每次出现:

    perl -ne 'while(/cdc_/g){print "$&\n";}' /path/to/chromedriver

    如果没有返回任何内容,则 cdc_ 已被替换 .

    相反,你可以使用这个:

    perl -ne 'while(/dog_/g){print "$&\n";}' /path/to/chromedriver

    查看您的替换字符串 dog_ 现在是否在 chromedriver 二进制文件中 . 如果是,则替换字符串将打印到控制台 .

    转到更改后的 chromedriver 并双击它 . 应该打开一个 terminal 窗口 . 如果在输出中没有看到 killed ,则表示您已成功更改了驱动程序 .


    结束

    更改 chromedriver 二进制文件后,请确保更改的 chromedriver 二进制文件的名称为 chromedriver ,并且原始二进制文件要么从其原始位置移动,要么重命名 .


    我用这种方法的经验

    我以前在尝试登录时在网站上被检测到,但在用相同大小的字符串替换 cdc_ 之后,我能够登录 . 就像其他人说的那样,如果你已经被检测到,你可能会被阻止使用这种方法后,还有很多其他原因 . 因此,您可能必须尝试访问使用VPN,不同网络或您拥有的网站检测到您的网站 .

  • 7

    基本上,硒检测的工作方式是,它们测试使用selenium运行时出现的预定义的javascript变量 . 机器人检测脚本通常在任何变量(窗口对象)中查找包含单词"selenium" / "webdriver"的任何内容,还包含名为 $cdc_$wdc_ 的文档变量 . 当然,所有这些都取决于您使用的浏览器 . 所有不同的浏览器都暴露不同的东西

    对我来说,我使用了chrome,所以, all that I had to 确保 $cdc_ 不再存在作为文档变量,并且瞧(下载chromedriver源代码,修改chromedriver并以不同的名称重新编译 $cdc_ . )

    这是我在chromedriver中修改的功能:

    call_function.js:

    function getPageCache(opt_doc) {
      var doc = opt_doc || document;
      //var key = '$cdc_asdjflasutopfhvcZLmcfl_';
      var key = 'randomblabla_';
      if (!(key in doc))
        doc[key] = new Cache();
      return doc[key];
    }
    

    (注意评论,我所做的一切,我将 $cdc_ 转为 randomblabla_ .

    这是一个伪代码,演示了僵尸网络可能使用的一些技术:

    runBotDetection = function () {
        var documentDetectionKeys = [
            "__webdriver_evaluate",
            "__selenium_evaluate",
            "__webdriver_script_function",
            "__webdriver_script_func",
            "__webdriver_script_fn",
            "__fxdriver_evaluate",
            "__driver_unwrapped",
            "__webdriver_unwrapped",
            "__driver_evaluate",
            "__selenium_unwrapped",
            "__fxdriver_unwrapped",
        ];
    
        var windowDetectionKeys = [
            "_phantom",
            "__nightmare",
            "_selenium",
            "callPhantom",
            "callSelenium",
            "_Selenium_IDE_Recorder",
        ];
    
        for (const windowDetectionKey in windowDetectionKeys) {
            const windowDetectionKeyValue = windowDetectionKeys[windowDetectionKey];
            if (window[windowDetectionKeyValue]) {
                return true;
            }
        };
        for (const documentDetectionKey in documentDetectionKeys) {
            const documentDetectionKeyValue = documentDetectionKeys[documentDetectionKey];
            if (window['document'][documentDetectionKeyValue]) {
                return true;
            }
        };
    
        for (const documentKey in window['document']) {
            if (documentKey.match(/\$[a-z]dc_/) && window['document'][documentKey]['cache_']) {
                return true;
            }
        }
    
        if (window['external'] && window['external'].toString() && (window['external'].toString()['indexOf']('Sequentum') != -1)) return true;
    
        if (window['document']['documentElement']['getAttribute']('selenium')) return true;
        if (window['document']['documentElement']['getAttribute']('webdriver')) return true;
        if (window['document']['documentElement']['getAttribute']('driver')) return true;
    
        return false;
    };
    

    根据用户@szx,也可以在十六进制编辑器中简单地打开chromedriver.exe,然后手动进行替换,而不实际进行任何编译 .

  • 7

    partial interface Navigator {readonly attribute boolean webdriver; }; Navigator接口的webdriver IDL属性必须返回webdriver-active标志的值,该标志最初为false . 此属性允许网站确定用户代理受WebDriver控制,并可用于帮助缓解拒绝服务攻击 .

    直接取自2017 W3C Editor's Draft of WebDriver . 这在很大程度上意味着,至少在没有源代码的情况下,未来的selenium迭代很难说明,究竟是什么导致特定的chrome驱动程序是可检测的 .

  • 68

    尝试使用具有特定用户配置文件chrome的selenium,这样您就可以将其用作特定用户并定义您想要的任何内容 . 这样做时它将作为“真实”用户运行,使用某个进程资源管理器查看chrome进程和你会看到与标签的区别 .

    例如:

    username = os.getenv("USERNAME")
    userProfile = "C:\\Users\\" + username + "\\AppData\\Local\\Google\\Chrome\\User Data\\Default"
    options = webdriver.ChromeOptions()
    options.add_argument("user-data-dir={}".format(userProfile))
    # add here any tag you want.
    options.add_experimental_option("excludeSwitches", ["ignore-certificate-errors", "safebrowsing-disable-download-protection", "safebrowsing-disable-auto-update", "disable-client-side-phishing-detection"])
    chromedriver = "C:\Python27\chromedriver\chromedriver.exe"
    os.environ["webdriver.chrome.driver"] = chromedriver
    browser = webdriver.Chrome(executable_path=chromedriver, chrome_options=options)
    

    chrome标签列表here

  • 5

    混淆了JavaScripts结果

    我检查了chromedriver源代码 . 这会将一些javascript文件注入浏览器 .
    Every javascript file on this link is injected to the web pages: https://chromium.googlesource.com/chromium/src/+/master/chrome/test/chromedriver/js/

    所以我使用逆向工程和 obfuscated 通过Hex编辑的js文件 . 现在我确信不再使用javascript变量,函数名和固定字符串来发现selenium活动 . 但仍有一些网站和reCaptcha检测硒!
    也许他们检查由chromedriver js执行引起的修改:)

    Edit 1:

    Chrome'导航器'参数修改

    我发现'navigator'中有一些参数可以简单地揭示使用chromedriver . 这些是参数:

    • "navigator.webdriver" 在非自动模式下,它是'undefined' . 在自动模式下它's ' true' .

    • "navigator.plugins" 无头铬合金的长度为0 . 所以我添加了一些假元素来欺骗插件长度检查过程 .

    • navigator.languages" 已设置为默认铬值'[ 338671 , 338672 , 338673 ]' .

    所以我需要的是在网页上运行javascript的chrome扩展 . 我使用文章中提供的js code进行了扩展,并使用another article将压缩扩展名添加到我的项目中 . I have successfully changed the values; But still nothing changed!

    我没有't find other variables like these but it doesn't意味着他们不存在 . 仍然reCaptcha检测到chromedriver,所以应该有更多变量要改变 . next step 应该是我不想做的探测器服务的逆向工程 .

    Now 我不确定是否值得花更多时间在这个自动化过程或寻找替代方法!

  • 0

    在我看来,使用Selenium进行此操作的最简单方法是拦截发送回浏览器指纹的XHR .

    但由于这是一个仅限Selenium的问题,因此使用其他东西会更好 . Selenium应该让这样的事情变得更容易,而不是更难 .

相关问题