必发365bifa0000Web安全息息相关(三):开放重定向(Open Redirection)

by admin on 2018年12月25日

   发起的.NET
Core开源社团号召,进展的快慢是我自己也一贯不想到的,很多园友都积极参预(即便有点人率真砸场子,要是以自我原先的宝脾气,那会应该被自己打住院了吧,然则幸而是个别,做一件事总有人说好,也有人说是用马赛话说“闹眼子”),.NET社区不是尚未愿意共享文化的人,只是没有一个完整和美好的生态环境,不问可知希望国内的.NET发展尤其强大。我在此地想到一句话“大家愿意自己可以做巨浪,但我们也心甘情愿做巨浪来袭前的小浪”。

简介

 
 下面扯淡完毕(我这人干正事前,都要将一部分聊天的话,这多少个习惯改不掉了…)

  这些通过请求(如查询字符串和表单数据)指定重定向URL的Web程序可能会被歪曲,而把用户重定向到表面的恶意URL。这种歪曲就被称为开发重定向攻击。

 
 项目中为了及时的通信,有平昔发多少到页面,也有使用短信通告,也有我门前天介绍的邮件组件。我们前几日的首要任务就是上课一下有一个.NET的免费开源的邮件组件Mail基特(Kit)。本文将依然的重组实例和组件底层代码讲解一下相关组件的学问。(项目招人的时候,我都会问一下.NET的最底层原理,有一个大神问我如此有哪些含义呢?咱们也写不出.NET底层这样的上佳处理形式,为什么取掌握那个,其实我个人觉得,问底层的原理,只是向为了跟好的处理局部主次出现的题材,以及对程序编码的时候,采用最合适的艺术进步性能,任何一种办法都有优势和劣势,.NET的类库代码也是如此,假诺我们知道.NET的平底实现,我们在类型的需要实现时,可以依照.NET底层实现,拔取卓越的点子,以求性能最优)。

现象分析

一.Mailkit组件概述

 
 项目中应用Email的操作机会相比较多,一般不怎么大一点的品类,都会利用到邮件操作这多少个操作。对于.NET邮件操作的机件和艺术相比多,前日我们就介绍一款邮件操作的组件Mail基特,那一个邮件组件是一个开源免费的,我们明日就来了然一下这个零部件的特色。Mime基特意在通过尽可能接近地坚守MIME规范来解决这一个题目,同时还为程序员提供了一个异常容易使用的尖端API。

 
 组件的匡助的客户端类型相比较多,例如SMTP客户端、POP3客户端、IMAP客户端。该零件是一个跨平台的Email组件,该器件帮忙.NET
4.0,.NET 4.5,Xamarin.Android,Xamarin.iOS,Windows Phone
8.1之类平台。该零件提供了一个MIME解析器,组件具备的分析特性灵活、性能高、很好的处理千头万绪的破损的MIME格式化。Mime基特的性质实际上与GMime非凡。

   该零件在安全性的依旧相比高的,处理安全的点子较多,SASL认证、帮助S /
MIME v3.2、协理OpenPGP、辅助DKIM签名等等格局。Mailkit组件能够通过CancellationToken裁撤相应的操作,CancellationToken传播应废除操作的关照,一个的CancellationToken使线程,线程池工作类型里面,或注销合作任务的靶子。过实例化CancellationTokenSource对象来创设废除令牌,该对象管理从其CancellationTokenSource.Token属性检索的裁撤令牌。然后,将撤废令牌传递到应有吸纳撤废公告的肆意数量的线程,任务或操作。令牌不可能用于启动撤消。

  Mail基特组件援助异步操作,在里头编写的关于I/O异步操作的类。

 
必发365bifa0000 1

二.MailKit实例:

   
下边介绍了Mail基特(Kit)组件的背景和特色,那里就介绍一下Email组件的粗略利用。

  假若有一个正经网站http://nerddinner.com/,还有一个恶意网站或钓鱼网站http://nerddiner.com/(注意:这里少了个n)。

  1.创建邮件形式:

 public void SentEmail(string path)
        {
            var message = new MimeMessage();
            //获取From标头中的地址列表,添加指定的地址
            message.From.Add(new MailboxAddress("Joey", "joey@friends.com"));
            //获取To头中的地址列表,添加指定的地址
            message.To.Add(new MailboxAddress("Alice", "alice@wonderland.com"));
            //获取或设置消息的主题
            message.Subject = "How you doin?";
            // 创建我们的消息文本,就像以前一样(除了不设置为message.Body)
            var body = new TextPart("plain")
            {
                Text = @"Hey Alice-- Joey"
            };
            // 为位于路径的文件创建图像附件
            var attachment = new MimePart("image", "gif")
            {
                ContentObject = new ContentObject(File.OpenRead(path), ContentEncoding.Default),
                ContentDisposition = new ContentDisposition(ContentDisposition.Attachment),
                ContentTransferEncoding = ContentEncoding.Base64,
                FileName = Path.GetFileName(path)
            };
            // 现在创建multipart / mixed容器来保存消息文本和图像附件
            var multipart = new Multipart("mixed")
            {
                body, attachment
            };
            // 现在将multipart / mixed设置为消息正文 
            message.Body = multipart;
        }

 
 调用该零件发送邮件和为邮件添加附件是比较简单的,第一步是实例化MimeMessage对象,对于该目的的解析将在底下举办,得到MimeMessage对象后,指定邮件的地方和主旨等等相关消息。第二步实例化TextPart对象,为对象设定文本信息。若需要问邮件创造文件的附件,能够拔取MimePart对象,包含内容(如信息正文文本或)的叶节点MIME部分一个附件。第四步为开创的邮件主体和文件以及附件信息后,可以创建Multipart对象,创设邮件容器,用来装载文本信息和附件。最终调用MimeMessage.body属性获取或安装音讯的正文。

  一天,小白收到了外人发的链接:http://nerddinner.com/Account/LogOn?returnUrl=http://nerddiner.com。

    2.邮件音信的剖析:

var message = MimeMessage.Load(stream);

 
 邮件的音信大家需要展开相应的剖析,这里我们应用MimeMessage的Load方法,该格局从指定的流加载Mime基特(Kit).MimeMessage。另一个加载数据的不二法门,可以应用MimeParser类,这里就不再解析了。

  1.
开辟链接后进入了登录界面,小白输入了友好的帐号名密码举行登录。

    3.邮件的吸纳:

   public static void HandleMimeEntity(MimeEntity entity)
        {
            //MimeEntity转化为Multipart实体
            var multipart = entity as Multipart;
            if (multipart != null)
            {
                for (int i = 0; i < multipart.Count; i++)
                    HandleMimeEntity(multipart[i]);
                return;
            }
            var rfc822 = entity as MessagePart;

            if (rfc822 != null)
            {
                var message = rfc822.Message;
                HandleMimeEntity(message.Body);
                return;
            }
            var part = (MimePart)entity;
        }

 
 以上是对吸收到的信息的一个遍历,采纳递归遍历MIME结构。MIME是内容的树结构,很像一个文件系统。MIME确实定义了一组通用规则,用于邮件客户端怎样解释MIME部分的树结构。的 内容处置头是为了给接受客户端提供提示以什么样部分是为着体现作为信息体的一有的,并且目的在于被诠释为附件。其余二种方法这离就不做牵线了。

  2. 登录成功后重定向到了恶意网站。

三.Mail基特(Kit)大旨对象解析

 
 下边介绍了Email的基本操作就不做过多的牵线,在行使该零件时,较为的大概。这里就来探视该零件的类型结构和一些中坚目的。类库结构有如下图:

必发365bifa0000 2

  3. 恶心网站是一个克隆正规网站的登录页面,并在地点指示用户名或密码错误。

    1.MimeMessage.Load():

public static MimeMessage Load (ParserOptions options, Stream stream, bool persistent, 
                                CancellationToken cancellationToken = default (CancellationToken))
        {
            if (options == null)
                throw new ArgumentNullException (nameof (options));

            if (stream == null)
                throw new ArgumentNullException (nameof (stream));

            var parser = new MimeParser (options, stream, MimeFormat.Entity, persistent);

            return parser.ParseMessage (cancellationToken);
        }

   
 该办法从指定的流加载MimeMessage,具有6个章程重载。该措施重临一个MimeMessage对象,有源码可以见见,在该情势内部创制了一个MimeParser对象,MimeParser包含内容(例如邮件正文文本或附件)的叶节点MIME部分。调用ParseMessage方法,解析来自流的信息。

   2.TextPart.Text:

public string Text {
            get {
                if (ContentObject == null)
                    return string.Empty;
                var charset = ContentType.Parameters["charset"];
                using (var memory = new MemoryStream ()) {
                    ContentObject.DecodeTo (memory);
                    var content = memory.ToArray ();
                    Encoding encoding = null;
                    if (charset != null) {
                        try {
                            encoding = CharsetUtils.GetEncoding (charset);
                        } catch (NotSupportedException) {
                        }
                    }
                    if (encoding == null) {
                        try {
                            return CharsetUtils.UTF8.GetString (content, 0, (int) memory.Length);
                        } catch (DecoderFallbackException) {
                            encoding = CharsetUtils.Latin1;
                        }
                    }
                    return encoding.GetString (content, 0, (int) memory.Length);
                }
            }
            set {
                SetText (Encoding.UTF8, value);
            }
        }

   
该属性获取解码的文书内容。该属性是一个可读可写的属性。ContentType.Parameters[“charset”]用于获取charset参数的值。该方法用来将参数的值设置为数量流并设置相应的编码。看到此间的特别处理协会,就想大概的谈几句,.NET的非常相比的懦弱,很多时候在写.NET的百般时就更加的简易,以上是对充裕知识捕获,有些地点并没有做拍卖,有些地点是对特其余地点开展复原。

  4. 小白遵照指示重新输入了帐号密码消息。

   3.MimeEntity.WriteTo():

public virtual void WriteTo (FormatOptions options, Stream stream, bool contentOnly, 
                            CancellationToken cancellationToken = default (CancellationToken))
        {
            if (options == null)
                throw new ArgumentNullException (nameof (options));

            if (stream == null)
                throw new ArgumentNullException (nameof (stream));

            if (!contentOnly)
                Headers.WriteTo (options, stream, cancellationToken);
        }

   
该办法将MimeEntity写入到指定的数额流中,该措施接受参数options格式选项。stream输出数据流,contentOnly判断是否可写。该方法定义为虚方法,在后续此办法后,可以在子类种对该措施举行重写。

  5.
恶心网站保存了客户的用户名密码,然后重定向会正规网站。

四.总结

 
 本人认为在品种开支中,假设引入了第三方组件,大家尽量引入组件的源码,这样我们对整个组件的构造有一个认识,组件的贯彻模式大家也得以展开精雕细刻通晓,尤其是我们在开展调剂的将来尤为有用,大家可以逐一的拓展断点调试。以上是对该零件的一个简单介绍,有趣味的可以去深远的摸底和学习。

  6.
小白继续平日正常的操作。

 

预防开放重定向

  避免开发重定向只需要看清重定向的链接是地点的链接或者是法定的链接即可。

  1.
假使登录链接和站点其他页面都在同一个域名,在ASP.MVC中得以用Url.IsLocalUrl(string
url)来判定。

  2.
一旦登录链接和站点其他页面不在同一个域名,如单点登录,则需要团结去贯彻判断的逻辑。
 
大旨代码

 1        [HttpPost]
 2         public ActionResult LogOn(LogOnModel model, string returnUrl)
 3         {
 4             //Your logon logic here.
 5             FormsAuthentication.SetAuthCookie(model.UserName, false);
 6            //Comment out this code will cause open redirection 
 7             if (!string.IsNullOrEmpty(returnUrl)&& Url.IsLocalUrl(returnUrl))
 8             {
 9                 return Redirect(returnUrl);
10             }
11             return RedirectToAction("Index", "Home");
12         }

 

联想到XSS

  1.
恶心用户在规范网站下挂了跳转到恶意网站的本子。
  2.
普通用户访问到含恶意脚本的页面会跳转到恶意网站。
  3.
黑心网站是一个仿制正规网站的记名页面,并在上头提醒需要再行登录。
  4.
小白遵照提醒重新输入了帐号密码音信。
  5.
黑心网站保存了客户的用户名密码,然后重定向会正规网站。
 
  注:这种方法每一次访问含恶意脚本的页面都会跳转到恶意网站(提醒重新登录),而开放重定向只会提醒用户名密码错误一次,相对而言,开放重定向的无感知效果要好一点。  

   必发365bifa0000 3

源码下载

  倘诺我们想尝试开放重定向的效力,可以去下载代码,把判断本链接的语句Url.IsLocalUrl(returnUrl)注释掉,然后在报到页面加上想要跳转到的页面,如http://xxx.com/Account/LogOn?ReturnUrl=http://www.baidu.com。

  下载地址:https://github.com/ErikXu/OpenRedirection

 

 作品转载自:http://www.cnblogs.com/Erik_Xu/p/5497479.html

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图