如何自己搭建釣魚網站檢測系統
0×01基本系統架構
隨著電子商務、互聯網金融的快速發展,在利益的驅使下,從事“釣魚攻擊”的黑產呈逐漸上升趨勢。“釣魚攻擊”不僅對企業的品牌形象造成嚴重損害,還對用戶的賬戶安全、甚至資金安全構成了極大的威脅。
目前“釣魚攻擊”已經為了網絡欺詐的重要一環,因此反釣魚系統在電子商務、金融證券、電信運營商等企業的安全運營中起著越來越重要的地位。
反釣魚系統一般有如下兩種架構。
對于這種架構主要適用于缺乏終端控制力的企業。企業可以從各個渠道收集待檢測的url,檢測引擎調用利用WebKit引擎獲取頁面渲染后的有效內容,然后調用檢測算法對頁面內容進行檢測。檢測后將檢測結果存至數據庫,之后將檢測結果輸出至第三方的攔截系統、關停服務提供商等,最終遏制“釣魚攻擊”的發生。
對于第二種架構,適用于擁有大量終端的企業,利用終端的能力代替了WebKit。終端直接將疑似頁面的特征發回后端的檢測引擎,檢測引擎生成檢測結果、產出黑名單,同時將檢測結果的返回至終端。
0×02檢測引擎
檢測引擎做為反釣魚系統的核心承擔著識別頁面是否為釣魚網站的任務。針對釣魚網站的檢測手段主要有IP黑名單,url分析,域名注冊信息分析,頁面內容分析,圖像識別等方法。
其中頁面內容分析一直是釣魚頁面識別的主要手段。頁面識別的主要算法有貝葉斯算法、機器學習算法、Html文檔特征等算法。
下面介紹下如何使用貝葉斯算法進行頁面識別。
貝葉斯算法簡介
貝葉斯分類是一類分類算法的總稱,是關于隨機事件A和B的條件概率和邊緣概率的一則定理。
- P(A)是A的先驗概率或邊緣概率。之所以稱為”先驗”是因為它不考慮任何B方面的因素;
- P(A|B)是已知B發生后A的條件概率,也由于得自B的取值而被稱作A的后驗概率;
- P(B|A)是已知A發生后B的條件概率,也由于得自A的取值而被稱作B的后驗概率;
- P(B)是B的先驗概率或邊緣概率,也作標準化常量。
分類原理
我們用W來代表一個待分類的網頁,用h+釣魚網頁,用h-代表正常網頁。利用貝葉斯公式,判定頁面是否為釣魚網頁可描述為:
- P(h+|W)=P(h+)*P(W|h+)/P(W)
- P(h-|W)=P(h-)*P(W|h-)/P(W)
P(W)為常量,可以暫時忽略。P(h+)、P(h-)為先驗概率,即一個真實的網頁集合中,釣魚網頁的比例與正常網頁的比例。
為了求得P(W|h),我們可以將W進行分詞,W={w1,w2,w3…}。如果我們假設w1,w2等是條件無關的,則P(W|h+)=P(w1|h+)*P(w2|h+)*P(w3|h+)。
P(wi|h+)經過Laplacean平滑處理后,P(wi|h+)=(1 + 特征詞wi在h+訓練集中的詞頻) / (全部特征詞去重個數 + h+下所有詞出現總數)。
這樣我們便能計算出P(h+|W)與P(h-|W),比較大小可知頁面屬于哪一分類。
數據準備
為了獲取待檢測域名,我們可以從ICANN的Centralized Zone Data Service免費獲取到全球的域名列表,做差量可得到全球的每日新增域名。之后將每日新增的域名導入到我們的待檢測列表。
我們可以通過Python調用Phantomjs去獲取頁面中內容。
Phantomjs:
var webPage = require('webpage');
var system = require('system');
var page = webPage.create();
if (system.args.length === 1) {
console.log("error");
phantom.exit();
} else {
url = system.args[1];
page.open(url, function (status) {
if (status == 'success') {
var content = page.content;
console.log(content);
} else {
console.log("error");
}
phantom.exit();
});
};
</code></pre>
Python:
def get_page_content(url):
cmd = 'phantomjs getPageContent.js %s' % (url)
stdout, stderr = subprocess.Popen(cmd, shell = True,
stdout = subprocess.PIPE, stderr = subprocess.PIPE).communicate()
return stdout
為了得到一個貝葉斯分類器,需要一個樣本集對其進行訓練。首先要對頁面做打標分類,一類為釣魚頁面樣本集,一類為正常頁面樣本集。樣本集就是我們的原始訓練素材。
建立模型
這里針對中文的釣魚頁面建立分類模型,我們先使用正則提取出原始頁面中的中文字符。
def get_chinese_content(raw_page_content):
content_list = re.findall(ur"[\u4e00-\u9fa5]+", raw_page_content)
return "".join(content_list)
獲取頁面中文內容后,我們對其進行分詞。
def get_seg_list(chinese_content):
return jieba.cut(chinese_content)
有了基礎數據后,就可以開始訓練貝葉斯模型。我們需要一份停用詞表,類似下面的無意義作為停用詞,從樣本集的分詞結果中去掉。
一,一下,一個,一些,的,了,和,是,就,都,而,及,與,著,或,一何,一切......
我們需要統計出在兩個樣本集中總共出現了多少個不同的詞 all_unique_word_count。之后我們需要分別求出釣魚樣本集與正常樣本集各自出現了多少詞匯,all_phish_word_count, all_normal_word_count。
def count_all_unique_word(word_list):
return len(set(word_list))
all_unique_word_count = count_all_unique_word(all_word_list)
</code></pre>
接下來我們分別統計釣魚網頁樣本集與正常網頁樣本集中各個詞語的詞頻信息,phish_word_frenquency_dict, normal_word_frequency_dict。
def get_word_frequency(word_list):
frequency_dict = dict()
for w in word_list:
if frequency_dict.has_key(w):
frequency_dict[w] = frequency_dict[w] + 1
else:
frequency_dict[w] = 1
return frequency_dict
phish_word_frenquency_dict = get_word_frequency(phish_word_list)
normal_word_frequency_dict = get_word_frequency(normal_word_list)
</code></pre>
根據貝葉斯分類器原理推導的公式,可以計算出P(wi|h+)概率列表phish_word_probability_table與P(wi|h-)的概率列表normal_word_probability_table,這兩個table就是貝葉斯模型的核心,需要保存下來。
def get_word_probability_table(word_frequency_dict, category_word_count, all_unique_word_count):
probability_dict = dict()
for key, value in word_frequency_dict.items():
probability_dict[key] = (1 + value) / (all_unique_word_count + category_word_count)
return probability_dict
phish_word_probability_table = get_word_probability_table(phish_word_frequency_dict, all_phish_word_count, all_unique_word_count)
normal_word_probability_table = get_word_probability_table(normal_word_frequency_dict, all_normal_word_count, all_unique_word_count)
</code></pre>
P(h+)、P(h-)我們可以直接求出,即訓練樣本集中釣魚網頁數目與正常網頁數目的比例probability_phish,probability_normal。
釣魚檢測
當有了訓練好的模型后,只要獲取了頁面的內容,進行分詞。查詢phish_word_probability_table與P(wi|h-),計算出P(h+|W)與P(h-|W),比較大小,判定是否為釣魚頁面。
def analyse_page(raw_page_content, probability_phish, probability_normal, phish_word_probability_table, normal_word_probability_table):
page_word_list = get_seg_list(get_chinese_content(raw_page_content))
p_phish = probability_phish
p_normal = probability_normal
for w in page_word_list:
p_phish = p_phish * phish_word_probability_table[w]
p_normal = p_phish * normal_word_probability_table[w]
return True if p_phish > p_normal else False
0×03 策略、改進
“釣魚攻擊”者為了躲避反釣魚系統的檢測,常常采取屏蔽反釣魚檢測系統IP,屏蔽特定UA,頁面使用js或flash進行動態渲染,全頁面圖片化等手段。
反釣魚系統為了與之對抗,需要充分利用云端與終端的優勢,突破釣魚網站對檢測系統的屏蔽,并采取動態渲染的方式加載js、flash獲取頁面內容。檢測技術也從單一的文本分析進化到了大數據統計分析、機器學習分類算法、HTML特征、圖像識別等手段,對可疑頁面進行實時的分析。甚至是僅僅注冊了釣魚域名,釣魚網站還未開通,就對高危域名做出了預判,對風險進行感知,以降低用戶受到網絡欺詐的風險。
來自: http://www.freebuf.com/articles/web/104870.html