javascript 開いているブラウザ あなたは Chrome ドライバで Selenium を使用しているときにウェブサイトを検出できますか?




selenium 開いているブラウザ python (10)

私はChromedriverでSeleniumをテストしていましたが、オートメーションがまったくないにもかかわらず、一部のページでSeleniumを使用していることを検出できることに気付きました。 セレンとXephyrでクロムを使って手動で閲覧しているだけでも、疑わしいアクティビティが検出されたというページが表示されることがよくあります。 ユーザーエージェントとブラウザの指紋を確認したところ、通常のクロムブラウザとまったく同じです。

通常のクロムでこれらのサイトを参照するとすべてうまく動作しますが、セレニウムを使用する瞬間に検出されます。

理論的には、クロムドライバとクロムは文字通りどのウェブサーバにも同じように見えるはずですが、何らかの形でそれを検出することができます。

いくつかのテストコードでこれを試してみたいです:

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をブラウズすると、1つまたは2つのリクエスト内でリダイレクトされ、ブロックされます。 私はこれを調査しており、ユーザがセレンを使用していることをどのように伝えることができるのか理解できません。

どうやってやっているの?

EDIT UPDATE:

私はFirefoxにSelenium IDEプラグインをインストールしました。追加のプラグインだけで通常のFirefoxブラウザでstubhub.comに行ったとき、私は禁止されました。

編集:

Fiddlerを使用して前後に送信されるHTTPリクエストを表示すると、「偽のブラウザ\ 'のリクエストにレスポンスヘッダーに「no-cache」が含まれていることに気がつきました。

編集:

このような結果JavascriptのSelenium Webdriverページにあることを検出する方法は、Webdriverを使用しているときに検出する方法がないはずであることを示唆しています。 しかし、この証拠は別のことを示唆している。

編集:

サイトは自分のサーバーに指紋をアップロードしますが、私はチェックして、セレンの指紋は、クロムを使用するときの指紋と同じです。

編集:

これは、サーバーに送信する指紋ペイロードの1つです

{"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は1回の使用で動作しますが、最初のページをロードした後に検出されます。 明らかに、いくつかのjavascriptがSeleniumを検出するために実行されています。


一部のサイトでこれを検出しています。

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) {}

たとえあなたが適切なデータをすべて送っているとしても(Seleniumが拡張子として表示されない、適切な解像度/ビット深度、&c)、訪問者の行動をプロファイリングする多くのサービスとツールがあります。アクターはユーザーまたは自動システムです。

たとえば、サイトを訪問した後すぐにマウスを関連するボタンに直接移動させて何らかのアクションを実行しようとすると、1秒未満で実際には何もしないことになります。

https://panopticlick.eff.org/などのサイトを使用してブラウザがどのようにユニークであるかを確認するためのデバッグツールとしても便利です。 Seleniumで実行中であることを示す特定のパラメータがあるかどうかを確認するのにも役立ちます。


私が見たボットの検出は、より洗練されているか、少なくとも以下の答えで読んだものとは異なっているようです。

実験1:

  1. 私は、PythonコンソールからSeleniumでブラウザとWebページを開きます。
  2. マウスは、ページが読み込まれるとリンクが表示されることがわかっている特定の場所に既にあります。 私はマウスを決して動かさない。
  3. マウスの左ボタンを1回押します(これは、Pythonが実行されているコンソールからブラウザにフォーカスするために必要です)。
  4. マウスの左ボタンをもう一度押します(カーソルは特定のリンクの上にあります)。
  5. リンクは正常に開きます。

実験2:

  1. 前と同じように、PythonコンソールからブラウザとWebページをSeleniumで開きます。

  2. 今度は、マウスでクリックするのではなく、Selenium(Pythonコンソール)を使って同じ要素をランダムなオフセットでクリックします。

  3. リンクは開かれませんが、サインアップページに移動します。

含意:

  • セレンを介してWebブラウザを開くことは、私が人間に見えることを排除するものではありません
  • 人間のようにマウスを動かすことは、人間として分類する必要はありません
  • オフセットのあるセレンを介して何かをクリックしてもアラームが発生する

不思議なことだと思うが、ブラウザがセレンを介して開かれているかどうかは気にしないが、アクションがセレンから起きたものかどうかを判断することができると思う。 または、ウィンドウにフォーカスがあるかどうかを判断できますか? 誰もが洞察力を持っている場合は聞くのは面白いでしょう。


Firefoxは、webdriverを使って作業する場合、 window.navigator.webdriver === trueを設定すると言われています。 これは古い仕様書( archive.org )の1つに従っていましたが、付録の非常に曖昧な言葉を除いて、 新しいものでは見つかりませんでした。

そのテストはファイルfingerprint_test.jsセレンコードにあります。最後のコメントには「現在のところFirefoxのみで実装されています」と書かれていますが、単純なgrep使ってその方向のコードを特定することはできませんでした現在の(41.0.2)FirefoxのリリースツリーやChromiumツリーにはありません。

また、 2015年1月から firefoxドライバb82512999938で指紋に関する古いコミットについてのコメントが見つかりました。 そのコードは、昨日javascript/firefox-driver/extension/content/server.jsでダウンロードしたSelenium GIT-masterに残っています。コメントは、現在のw3c webdriver仕様のやや異なる言葉にリンクしています。


次のコードでhtmlページを作成します。 DOMでセレンが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>


partial interface Navigator { readonly attribute boolean webdriver; };

Navigatorインタフェースのwebdriver IDL属性は、最初はfalseであるwebdriver-activeフラグの値を返す必要があります。

このプロパティを使用すると、WebDriverによってユーザーエージェントが制御されていることをWebサイトが判断でき、サービス拒否攻撃を軽減するのに役立てることができます。

2017 W3C編集者のWebDriverのドラフトから直接取ったものです。 これは、セレンのドライバーの将来の反復が、誤用を防ぐために特定できることを意味します。 最終的には、ソースコードなしで正確に特定のクロムドライバが検出可能であることを伝えるのは難しいです。


彼らはWebアプリケーションファイアウォールの背後にいるように思えます。 modsecurityとowaspを見て、それらの仕組みを見てみましょう。 実際には、ボットの検出を回避する方法が求められています。 それはセレンのウェブドライバーのためのものではありません。 それはあなたのWebアプリケーションをテストするためのもので、他のWebアプリケーションには当てはまりません。 可能であれば、WAFがルールセット内で探しているものを見て、可能であればセレンで回避することができます。 それでも、使用しているWAFがわからないため、まだ動作しない可能性があります。 あなたは最初のステップを踏んで、それはユーザーエージェントを偽造しています。 それでもうまくいかない場合は、WAFが準備されており、おそらくもっと手間がかかります。

編集:他の回答から得られたポイント。 ユーザーエージェントが実際に正しく設定されていることを確認してください。 たぶんそれは、ローカルのWebサーバーを攻撃したり、トラフィックを出すのを嗅ぐことがあります。


Macユーザーの場合

VimやPerlを使ってcdc_変数を置き換える

あなたはvimを使うことができます。あるいは、@ Vic Seed doubleyewは、@ Erti-Chris Eelmaa( perl )の答えで、 cdc_変数を置き換えることをcdc_ます( その変数の詳細については、@ Erti-Chris Eelmaaの記事を参照してください )。 vimperlを使うと、ソースコードを再コンパイルしたり、16進エディタを使う必要がなくなります。 元のchromedriverコピーを作成してから編集してください。 また、以下の方法をchromedriver version 2.41.578706試験した。

Vimの使用

vim /path/to/chromedriver

上の行を実行した後、おそらくあなたは恐ろしいの束を見ます。 以下をせよ:

  1. /cdc_と入力してreturn /cdc_を押して、 cdc_検索します。
  2. aを押しa編集を有効にaます。
  3. $cdc_lasutopfhvcZLmcfl任意の量を削除し、削除されたものを等量の文字で置き換えます。 そうしないと、 chromedriverは失敗します。
  4. 編集が終わったら、 esc押します。
  5. 変更を保存して終了するには、次のように入力し:wq! returnを押します。
  6. 変更を保存せずに終了したい場合は、次のように入力し:q! returnを押します。
  7. あなたは終わった。

変更されたchromedriver移動し、ダブルクリックします。 terminalウィンドウが開きます。 出力にkilledが表示killedれない場合は、ドライバを正常に変更しました。

Perlの使用

以下の行はcdc_dog_置き換えます:

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

置換文字列が検索文字列と同じ文字数であることを確認してください。そうでない場合、 chromedriverは失敗します。

Perlの説明

s///gは、文字列を検索し、それをグローバルに別の文字列に置き換える(すべての文字列を置き換える)ことを示します。

例: s/string/replacment/g

そう、

s///は文字列の検索と置換を意味します。

cdc_は検索文字列です。

dog_は置換文字列です。

gは文字列のすべての文字列を置き換えるグローバルキーです。

Perlの置換がうまくいったかどうかを調べる方法

次の行は、検索文字列cdc_出現するたびに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が表示killedれない場合は、ドライバを正常に変更しました。

ラッピング

chromedriverバイナリを変更した後、変更されたchromedriverバイナリの名前がchromedriverであり、元のバイナリが元の場所から移動されたか、または名前が変更されたことを確認します。

この方法での私の経験

私は以前にウェブサイトでログインしようとしていましたが、 cdc_を同じサイズの文字列に置き換えた後、ログインできました。この方法を使用した後も他の多くの理由があります。 だから、あなたは、VPN、別のネットワーク、または何を持っているあなたを検出していたサイトにアクセスしようとする必要があります。


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 !+""

基本的にセレンの検出の仕方は、セレンで実行するときに表示されるあらかじめ定義されたjavascript変数をテストすることです。 ボット検出スクリプトは通常、(ウィンドウオブジェクト上の)任意の変数に単語 "selenium" / "webdriver"を含むものを検索し、 $cdc_$wdc_というドキュメント変数も$wdc_ます。 もちろん、これはすべてあなたがどのブラウザを使用しているかによって異なります。 すべてのブラウザが異なることを公開しています。

私にとっては、クロムを使用していたので、 私がしなければならなかったのは、 $cdc_がドキュメント変数として存在しなくなったこととクロールドライバを変更して別の名前で$cdc_を再コンパイルすること$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];
}

(コメントに注意してrandomblabla_ 。私は$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によれば、hexedエディタでchromedriver.exeを単に開くだけで、実際にコンパイルすることなく、手動で置き換えることもできます。





selenium-chromedriver