Path Traversal:
A path traversal attack (also known as directory traversal) aims to access files and directories that are stored outside the webroot folder. By manipulating variables that reference files with “dot-dot-slash (../)” sequences and its variations or by using absolute file paths, it may be possible to access arbitrary files and directories stored on the file system including application source code or configuration and critical system files. It should be noted that access to files is limited by system operational access control (such as in the case of locked or in-use files on the Microsoft Windows operating system).
Description:
In this article, I will explain path traversal vulnerability that can be found in the asp.net core, in the incorrect usage of Path.combine
function.
What is Path.combine
?
This method is intended to concatenate individual strings into a single string that represents a file path.
Combine(String[]):
Combines an array of strings into a path.
public static string Combine (params string[] paths);
This method assumes that the first argument is an absolute path and that the following argument or arguments are relative paths.
Going deep:
Enough talking about the technical details that can be found everywhere on the internet and let’s get into the juicy information that you want.
Whenever you’re doing a code review or even a black-box approach and you find an endpoint for example https://alaa.blog/file.aspx?file=alaa.jpg
in this case, you have to assume, this endpoint might be using Path.combine
.
if it’s just using Path.combine
with no other rules or protection then we can escape the directory and access any other file on the system easily.
let’s see an example.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp3
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Download(@"alaa.txt"));
Console.ReadLine();
}
public static String Download(string fileName)
{
//fileName = Path.GetFileName(fileName);
fileName = Path.Combine(Path.GetTempPath(), fileName);
bool resultx = System.IO.File.Exists(fileName);
return resultx.ToString() + ", file: " + fileName;
}
}
}
This is just a small console application I made using C# to simulate the vulnerable code.
On line 21 we can see the function will combine the temp path with the entry from the parameter from line 14 (alaa.txt).
So the full directory, in this case, will be file: C:\Users\user\AppData\Local\Temp\alaa.txt
Line 22 is boolean to check if the file exists for further testing, you can ignore that.
Now let’s assume that alaa.txt
is the parameter value, let’s change it and try to exploit it.
let’s input C:\alaa.txt
and check if it will bypass the directory.
We can use ../../../../
as well, but let’s test it against DNS SSRF, it will be vulnerable as well.
we will try now to access
\ce0f3fcba9527b7dfa2785f14df.ns.pingb.in\a
it's just another proof of concept, if we got a hit then it's vulnerable as well, this could be used if our path traversal is blind.
The result will be:
Remediation
There are a lot of ways to fix this issue, but I’m gonna talk about one method, on line 20 if you uncomment that line, the vulnerability will be easily patched.
The functionPath.GetFileName(fileName);
will sanitize the fileName
parameter and prevent escaping the path.
I believe this could be one of the best solutions, in this case, I’ve tried many times to bypass it but no luck with that.
References
https://docs.microsoft.com/en-us/dotnet/api/system.io.path.combine?view=net-5.0
Thank you for reading this quick article, if you made it to this point, you can follow me on Twitter for more articles and tips @alaa0x2.
The raw code used above can be found on GitHub path.combine.poc