大多數(shù) IT 安全專業(yè)人員現(xiàn)在都非常清楚惡意機(jī)器人以及它們對(duì)任何在線業(yè)務(wù)所構(gòu)成的持續(xù)威脅。因此,對(duì)反機(jī)器人軟件的需求正在迅速增加。高效的機(jī)器人程序保護(hù)解決方案必須能夠準(zhǔn)確地區(qū)分不良機(jī)器人程序、良好機(jī)器人程序和人類,最好是實(shí)時(shí)進(jìn)行。為了確定訪問者是人還是機(jī)器人,我們可以從服務(wù)器端和客戶端、瀏覽器或移動(dòng)應(yīng)用程序中收集信息。
在下文中,我們將演示為什么完全依賴服務(wù)器端檢測(cè)的解決方案對(duì)某些類型的機(jī)器人無能為力,以及為什么必須由客戶端信號(hào)完成分析才能真正有效地保護(hù)機(jī)器人。
服務(wù)器端指紋識(shí)別基本機(jī)器人
服務(wù)器端檢測(cè)通常基于以下信息:
HTTP指紋:由瀏覽器發(fā)送的HTTP頭組成的指紋,例如用戶代理或支持的壓縮算法。
TCP 指紋:TCP 指紋利用 TCP 堆棧中的差異(例如數(shù)據(jù)包的順序)來確定發(fā)送請(qǐng)求的瀏覽器或設(shè)備的性質(zhì)。
TLS 指紋:這些指紋使用一組受支持的TLS 密碼套件來識(shí)別發(fā)出請(qǐng)求的設(shè)備和軟件(例如移動(dòng)應(yīng)用程序)的性質(zhì)。
服務(wù)器端行為特征:請(qǐng)求的數(shù)量、頻率、是否存在瀏覽模式,可以用來判斷用戶是否為人。
這種服務(wù)器端檢測(cè)是必要的主要措施,但還不夠。
服務(wù)器端機(jī)器人檢測(cè)的局限性是什么?
面對(duì)最新一代的機(jī)器人程序,僅具有服務(wù)器端檢測(cè)功能的安全解決方案很快就會(huì)遇到其局限性。這是因?yàn)檫@些高級(jí)機(jī)器人使用與人類用戶完全相同的瀏覽器——Chrome、Firefox、Safari——或像 Headless Chrome 這樣的無頭瀏覽器。
與不能執(zhí)行 JavaScript 的基本機(jī)器人不同,這些高級(jí)機(jī)器人具有一致的 HTTP、TCP 和 TLS 指紋。
此外,無論何時(shí)存在小的不一致,例如非人類用戶代理,都可以通過向機(jī)器人添加幾行代碼或使用開源檢測(cè)框架來偽造一致的指紋來輕松修復(fù)(我們將對(duì)此進(jìn)行更詳細(xì)的討論以下)。
如果您只做服務(wù)器端檢測(cè),那么您對(duì)這些機(jī)器人程序完全視而不見。您唯一的機(jī)會(huì)是依靠服務(wù)器端的行為特征,并等待機(jī)器人觸發(fā)您的請(qǐng)求量閾值,然后您才能阻止它們。
這種方法總是會(huì)錯(cuò)過使用代理頻繁更改其 IP 地址的機(jī)器人。即使他們不這樣做,在您識(shí)別并阻止它們時(shí),針對(duì)客戶關(guān)鍵接觸點(diǎn)(例如您的登錄頁(yè)面)的機(jī)器人可能已經(jīng)造成了很多傷害。這就是為什么真正有效的機(jī)器人檢測(cè)解決方案必須將服務(wù)器端檢測(cè)與客戶端檢測(cè)相結(jié)合的原因。
客戶端機(jī)器人檢測(cè)功能:
客戶端(瀏覽器內(nèi))跟蹤可以記錄和分析有關(guān)用戶設(shè)備和瀏覽器發(fā)出請(qǐng)求的各種低級(jí)事實(shí),以及行為信號(hào)。
例如:
瀏覽器跟蹤:功能存在、js 挑戰(zhàn)……
應(yīng)用跟蹤:相機(jī)版本、屏幕分辨率、觸摸點(diǎn)數(shù)量……
設(shè)備跟蹤:CPU 內(nèi)核數(shù)、設(shè)備內(nèi)存、GPU……
用戶事件跟蹤:鼠標(biāo)移動(dòng)和觸摸事件……
這些客戶端信號(hào)對(duì)于檢測(cè)最先進(jìn)的機(jī)器人程序至關(guān)重要,即使它們偽造指紋以繞過不太復(fù)雜的安全系統(tǒng)也是如此。但是不要相信我們的話:讓我們通過放大一個(gè)特定的用例和一種客戶端檢測(cè)方法,向您展示當(dāng)您不收集任何客戶端信號(hào)時(shí)會(huì)發(fā)生什么。
用例:修改指紋以避免檢測(cè)的高級(jí)無頭 Chrome 機(jī)器人。
在此用例中,惡意行為者試圖使用數(shù)千個(gè)基于 Headless Chrome 和Puppeteer 的機(jī)器人進(jìn)行撞庫(kù)攻擊。
默認(rèn)情況下,Headless Chrome 可以通過其用戶代理在服務(wù)器端被識(shí)別:
Mozilla/5.0 (X11; Linux x86_64)
AppleWebKit/537.36 (KHTML, like Gecko)
HeadlessChrome/79.0.3945.88
Safari/537.36
但是,流行的開源庫(kù)(例如Puppeteer extra)使開發(fā)人員能夠擦除這些明顯的檢測(cè)信號(hào)。
Puppeteer extra 庫(kù)為 Puppeteer 檢測(cè)框架添加了更多功能。得益于其隱身插件,黑客可以輕松修改其 Headless Chrome 機(jī)器人的指紋。僅此一項(xiàng)就足以繞過大多數(shù)現(xiàn)有的機(jī)器人檢測(cè)系統(tǒng)。
默認(rèn)情況下,Puppeteer extra 將更改機(jī)器人的用戶代理,以便它們與人類訪問者保持一致,并刪除傳統(tǒng)上用于檢測(cè) Headless Chrome 的屬性,例如navigator.webdriver 。
該庫(kù)還使機(jī)器人開發(fā)人員能夠偽造其他幾個(gè)屬性,例如插件列表、可用編解碼器或 GPU。
如果您想自己嘗試,可以使用以下代碼輕松啟動(dòng)基于 Puppeteer 隱身的爬蟲。與傳統(tǒng)的 Puppeteer 程序相比,主要區(qū)別在于您不導(dǎo)入puppeteer,而是導(dǎo)入 puppeteer-extra:
const puppeteer = require('puppeteer-extra')
// 啟用帶有所有規(guī)避的隱身插件
puppeteer.use(require('puppeteer-extra-plugin-stealth')());
(async () => {
// 以無頭模式啟動(dòng)瀏覽器并設(shè)置頁(yè)面。const
browser = await puppeteer.launch({
headless: true
})
const page = await browser.newPage()
// 導(dǎo)航到將執(zhí)行測(cè)試的頁(yè)面。
const url = “https://你的網(wǎng)站……”;
等待 page.goto(url)
等待 browser.close()
})()
如果您現(xiàn)在驗(yàn)證機(jī)器人的用戶代理,您可以看到它已成為合法用戶代理:
const userAgent = await page.evaluate(() => {
return navigator.userAgent;
})
console.log(userAgent)
// Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome /80.0.3987.0 野生動(dòng)物園/537.36
Headless Chrome 有一個(gè)等于 true 的navigator.webdriver屬性。當(dāng)我們?cè)?Puppeteer stealth 中驗(yàn)證這個(gè)值時(shí),我們可以看到navigator.webdriver不再出現(xiàn)在 bot 的指紋中,這使得這種技術(shù)無法檢測(cè)到它。
const webdriver = await page.evaluate(() => {
return navigator.webdriver;
})
console.log(webdriver)
// undefined
由于用戶代理和 HTTP 標(biāo)頭都與人類用戶相同,因此簡(jiǎn)單的服務(wù)器端 HTTP 指紋識(shí)別不足以將此訪問者識(shí)別為機(jī)器人。如果您的 bot 保護(hù)解決方案完全依賴服務(wù)器端檢測(cè),您唯一的希望是它遲早會(huì)顯示可疑行為。
另一方面,由于先進(jìn)的客戶端檢測(cè),像 DataDome 這樣的解決方案可以在他們第一次請(qǐng)求時(shí)識(shí)別這些高級(jí)機(jī)器人,即使它們是故意設(shè)計(jì)來避免檢測(cè)的。
例如,Puppeteer stealth 用來繞過檢測(cè)的技術(shù)之一是覆蓋 canPlayType函數(shù),該函數(shù)用于測(cè)試音頻和視頻編解碼器的存在。
但是,這樣做會(huì)留下痕跡。實(shí)際上,我們可以通過執(zhí)行以下代碼來測(cè)試 canPlayType 函數(shù)是否已被覆蓋。
在Puppeteer stealth plugin 2.4.5版本中,運(yùn)行如下代碼,可獲得:
const canPlayTypeTs = await page.evaluate(() => {
var audioElt = document.createElement(“audio”);
return audioElt.canPlayType.toString();
})
console.log(canPlayTypeTs)
// 'function () { [本機(jī)代碼] }'
但是,對(duì)于人類使用的合法 Chrome 瀏覽器,您獲得了:
'函數(shù) canPlayType() { [本地代碼] }'
結(jié)論:第一個(gè)用戶是一個(gè)機(jī)器人。