📜 ⬆️ ⬇️

Protecting Citrix Web Interface against brute-force attacks with CAPTCHA

The Citrix Web Interface software is used for both XenApp and XenDesktop and is a set of web scripts, as well as a management console.
The Web Interface provides secure access to XenApp and XenDesktop resources from anywhere using any device equipped with a browser.

The Web Interface accepts the username and password on the site form and directly transmits the authentication system, in most cases this is the Microsoft Active Directory. At default settings, after several attempts with incorrectly entered password, the user account is blocked for a certain period of time (usually from 10 to 30 minutes), which rather reliably protects against “brute-force” attacks. The problem is different - it turns out that knowing the address of the Web Interface and the name of the user, you can use the usual HTTP requests, repeated every 10-15 minutes, to completely block the account.

The solution to the problem is obviously captcha, but at the moment, Citrix does not provide standard methods for activating captcha on the Web Interface and will have to edit the script code with pens. Fortunately, there is nothing difficult about it.
')


1. Create a script to generate images

file name:
folder: auth (default is C: / inetpub / wwwroot / Citrix / XenApp / auth)
<%@ page language="C#" %> <%@Import Namespace="System.Drawing" %> <script runat="server"> private void Page_Load() { Bitmap objBMP =new System.Drawing.Bitmap(60,20); Graphics objGraphics = System.Drawing.Graphics.FromImage(objBMP); objGraphics.Clear(Color.Green); Font objFont = new Font("Chiller", 11, FontStyle.Bold); string randomStr=""; int[] myIntArray = new int[5] ; int x; Random autoRand = new Random(); for (x=0;x<5;x++) { myIntArray[x] = System.Convert.ToInt32 (autoRand.Next(0,9)); randomStr+= (myIntArray[x].ToString ()); } //Save generated Rnd in a Session Session.Contents["CaptchaStr"]=randomStr; objGraphics.DrawString(randomStr, objFont, Brushes.White, 3, 3); Response.ContentType = "image/GIF"; objBMP.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Gif); objFont.Dispose(); objGraphics.Dispose(); objBMP.Dispose(); } </script> 


To allow non-logged-in users to run this script, it must be added to the list of allowed pages "AUTH: UNPROTECTED_PAGES".
For this:
- Open the web.config file in the root of the site
- Find the line appSettings -> add key = "AUTH: UNPROTECTED_PAGES" and add "" to value.
- It should get something like this-- value = "/ rade.aspx, / auth / style.aspx, / auth /, / auth / javascript.aspx, / auth ...

Next, check whether the image is generated by running the script through a browser. You should have a picture like this:
image

2. Edit the login form code, add a picture and enter a number from the image
Open the loginMainForm.inc file in the include folder (C: / inetpub / wwwroot / Citrix / XenApp / app_data / include) and make the following changes

Immediately before the line <table class = "loginForm"
 <script> document.cookie='captcha=0000'; </script> 

Next, right after} // End Domain

 %> <tr><td align=right>Captcha:</td><td> <img src= border=0 width=60 height=20> <input size=6 type=text id=captcha onKeyUp="document.cookie='captcha='+document.getElementById('captcha').value;" > </td></tr> <% 


After these changes, the login form should look something like this:


3. Edit the login.aspx - first add the verification of the entered code captcha

Edit the login.aspx file in the auth folder (by default, C: / inetpub / wwwroot / Citrix / XenApp / auth) so find the line
layout.PageView = "loginView.ascx";
and immediately after it add the following code:
 string strData =Request.ServerVariables["HTTP_COOKIE"]; if (Session.Contents["CaptchaStr"] == null ) { Session.Contents["CaptchaStr"] = ""; } if ( Session.Contents["CaptchaStr"].ToString().Length != 0 && Request.ServerVariables["HTTP_REFERER"].Contains("login.aspx") ) { string captcha = "0000"; string[] separator = new string[] { ";" }; string[] strSplitArr = strData.Split( separator, StringSplitOptions.RemoveEmptyEntries); foreach (string arrStr in strSplitArr) { string[] arrFind = arrStr.Split(new Char[] {'='}, 3); if (arrFind[0].Contains("captcha") && arrFind[1].Length != 0 ) { captcha = arrFind[1]; } } if( captcha.ToString()== Session.Contents["CaptchaStr"].ToString() ) { Response.Write(captcha+"-"+Session.Contents["CaptchaStr"]); } else { Session.Remove("CaptchaStr"); Response.Redirect("~/html/serverErrorCaptcha.html"); Response.End(); } } 

After editing, login.aspx should look like

login.aspx
 <%@ Register TagPrefix="wi" TagName="Layout" Src="~/app_data/include/layout.ascx" %> <% // login.aspx // Copyright (c) 2002 - 2010 Citrix Systems, Inc. All Rights Reserved. // Web Interface 5.3.0.0 %> <%@ Import Namespace="com.citrix.wi.clientdetect" %> <!--#include file="~/app_data/serverscripts/include.aspxf"--> <script runat="server"> void Page_Load(object sender, System.EventArgs e) { layout.PageClientScript = "~/auth/clientscripts/loginClientScript.ascx"; layout.PageView = "loginView.ascx"; string strData =Request.ServerVariables["HTTP_COOKIE"]; if (Session.Contents["CaptchaStr"] == null ) { Session.Contents["CaptchaStr"] = ""; } if ( Session.Contents["CaptchaStr"].ToString().Length != 0 && Request.ServerVariables["HTTP_REFERER"].Contains("login.aspx") ) { string captcha = "0000"; string[] separator = new string[] { ";" }; string[] strSplitArr = strData.Split( separator, StringSplitOptions.RemoveEmptyEntries); foreach (string arrStr in strSplitArr) { string[] arrFind = arrStr.Split(new Char[] {'='}, 3); if (arrFind[0].Contains("captcha") && arrFind[1].Length != 0 ) { captcha = arrFind[1]; } } if( captcha.ToString()== Session.Contents["CaptchaStr"].ToString() ) { Response.Write(captcha+"-"+Session.Contents["CaptchaStr"]); } else { Session.Remove("CaptchaStr"); Response.Redirect("~/html/serverErrorCaptcha.html"); Response.End(); } } } </script> <% if(new com.citrix.wi.pages.auth.LoginASP(wiContext).perform()) { %> <wi:Layout id="layout" runat="server" /> <% } %> 



4. Input Error Page
If the captcha code is incorrectly entered, the script relocates to the ~ / html / serverErrorCaptcha.html page. Do not forget to create the corresponding file in the folder C: / inetpub / wwwroot / Citrix / XenApp / html /. Can use example

~ / html / serverErrorCaptcha.html
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <!-- serverError.html Copyright (c) 2002 - 2010 Citrix Systems, Inc. All Rights Reserved. Web Interface 5.3.0.0 --> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="REFRESH" content="2; URL=../auth/login.aspx"> <meta name="ROBOTS" content="NOINDEX, NOFOLLOW, NOARCHIVE"> <meta http-equiv="X-UA-Compatible" content="IE=7"> <title>Internal Error</title> <script> document.cookie='captcha=0000'; </script> <script type="text/javascript"> <!-- var names = new Array( 'timeoutFrameWI_', 'reconnectFrameWI_', 'retryPopulatorFrameWI_', 'launchFrameWI_' ); function getTopFrame(w) { for (var n in names) { if(w.name.indexOf(names[n]) == 0) { if(w.parent) { return w.parent; } } } return null; } function redirectTop() { var topFr = getTopFrame(window); if (topFr != null) { topFr.location.href = window.location.href; } } // --> </script> <link rel="stylesheet" type="text/css" href="../html/styles/basicStyle.css"> </head> <body onLoad="redirectTop()" dir="ltr"> <div id="overallWrapper"> <div id="leftShadow"> <div id="rightShadow"> <div id="pageContent"> <div id="header"> <img src="../media/CitrixLogoHeader.gif" alt="Heading image"> </div> <div class="mainPane"> <div id="commonBoxTop"><!-- --></div> <div id="commonBox"> <h3 class="error">Wrong security code</h3> <p>Enter the code shown on the image </p> </div> <div id="commonBoxFoot"><!-- --></div> </div> </div> </div> </div> </div> </body> </html> 



That's basically it. After all the modifications described above, on your WI site, captcha protection should work. Please note that the captcha check is performed first, and without a correctly entered code, no access to the authentication system is performed, which results in the absence of a risk of lockout

Source: https://habr.com/ru/post/178489/


All Articles