標籤:構建 b站 傳回值 similar imp 根據 check 技術 ret
某些網站為了實現友好的使用者互動,提供了一種自訂的錯誤頁面,而不是顯示一個大大的404 ,比如CSDN上的404提示頁面如下:
這樣雖然提高了使用者體驗,但是在編寫對應POC進行檢測的時候如果只根據返回的HTTP頭部資訊判斷,則很可能造成誤判,為了能準確檢測到404頁面,
需要從狀態代碼和頁面內容兩個方面來進行判斷。
從狀態代碼來判斷比較簡單。可以直接使用requests庫發送http請求,得到響應碼即可。
從頁面內容上進行判斷的話,採用的思路是訪問web網站上明顯不存在的頁面,擷取頁面內容進行儲存,然後訪問目標頁面,將二者進行比較,如果相似性達到某一閾值,則該頁面為404頁面,否則為正常頁面。
為了判斷兩個頁面的相似性,採用Python的simhash庫,這個庫具體實現的演算法我不太懂,但是Python的好處就是:不懂無所謂,直接拿來用就行。這裡也只是簡單的拿來用一下:
#-*- encoding:utf-8 -*-# 404 頁面識別from hashes.simhash import simhashimport requestsclass page_404: def __init__(self, domain): #檢測網站 self._404_page = [] # 404頁面 self._404_url = [] #404 url self._404_path = ["test_404.html", "404_test.html", "helloworld.html", "test.asp?action=modify&newsid=122%20and%201=2%20union%20select%201,2,admin%2bpassword,4,5,6,7%20from%20shopxp_admin"] #404頁面路徑,用於產生一部分404頁面 self._404_code = [200, 301, 302] #當前可能是404頁面的http請求的傳回值 #自己構造404url,以便收集一些404頁面的資訊 for path in self._404_path: for path in self._404_path: if domain[-1] == "/": url = domain + path else: url = domain + "/" + path response = requests.get(url) if response.status_code in self._404_code: self.kb_appent(response.content, url) def kb_appent(self, _404_page, _404_url): if _404_page not in self._404_page: self._404_page.append(_404_page) if _404_url not in self._404_url: self._404_url.append(_404_url) def is_similar_page(self, page1, page2): hash1 = simhash(page1) hash2 = simhash(page2) similar = hash1.similarity(hash2) if similar > 0.85: #當前閾值定義為0.85 return True else: return False def is_404(self, url): if url in self._404_url: return True response = requests.get(url) if response.status_code == 404: return True if response.status_code in self._404_code: for page in self._404_page: if self.is_similar_page(response.content, page): self.kb_appent(url, response.content) #如果是404頁面,則儲存當前的url和頁面資訊 return True else: return False return False
上面的代碼中,檢測類中主要儲存了這樣幾個資訊:
_404_page:404頁面,用於與其他請求的頁面進行相似性判斷,以便識別404頁面,這裡用列表主要為了防止一個網站有多種404頁面,這段代碼已耗用時間越長它的準確度越高
_404_url:404 頁面的url,儲存之前判斷出頁面是404的url,已經判斷出來的就不再判斷,為了提升效率
_404_path:構建不存在頁面的url,最後一個是一個sql注入的代碼,這裡為了識別出那些被防火牆攔截而顯示的錯誤頁面
_404_code:可能返回404頁面的響應碼,如果響應碼為這些,則需要對頁面進行判斷
類在初始化時需要傳入一個網域名稱,根據這個網域名稱來拼接幾個不存在的或者會被防火牆攔截的請求並提交這些請求,得到返回資訊,將這些資訊作為判斷的資訊進行儲存。
在判斷時首先根據之前儲存的404 url資訊進行判斷,如果當前url是404頁面則直接返回,提高效率。然後提交正常的http請求並擷取響應資訊,
如果響應碼為404則返回True,否則再狀態代碼是否在_404_code列表中,最後再與之前儲存的404頁面資訊進行比較得到結果。
這段代碼的測試代碼如下:
from page_404 import page_404if __name__ == ‘__main__‘: domain = "http://xzylrd.gov.cn" check_404 = page_404(domain) dest_url = "http://xzylrd.gov.cn/TEXTBOX2.ASP?action=modify&newsid=122%20and%201=2%20union%20select%201,2,admin%2bpassword,4,5,6,7%20from%20shopxp_admin" print (check_404.is_404(dest_url))
python檢測404頁面