dotnet中的Path Traversal
主要针对asp.net core
中的Path.combine
函数
在ASP.NET Core中,
Path.Combine
函数是用来将多个路径片段组合成一个完整路径的工具方法。这个函数的作用是确保路径的各个部分正确地拼接在一起,特别是在处理文件系统路径时,它可以避免因操作系统不同(如Windows和Linux)而导致的斜杠方向问题(Windows使用反斜杠,而Linux使用正斜杠
/
)。
Path.Combine
函数会自动处理路径分隔符,确保生成的路径在当前操作系统上是有效的。如果其中一个路径片段已经是绝对路径,那么之前的所有路径片段都会被忽略,函数会从这个绝对路径开始构建新的路径。例如,在Windows系统上,
Path.Combine("C:\folder1", "folder2", "file.txt")
会返回"C:\folder1\folder2\file.txt"
。在Linux系统上,Path.Combine("/home/user", "documents", "file.txt")
会返回"/home/user/documents/file.txt"
。
Demo
using System;
usingSystem.Collections.Generic;
usingSystem.IO;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
namespacepath_traversal_demo
{
classProgram
{
static void Main(string[] args)
{
Console.WriteLine(Download(@"wulala.txt"));
Console.ReadLine();
}
public static String Download(string fileName)
{
fileName =Path.Combine(Path.GetTempPath(), fileName);
bool resultx =System.IO.File.Exists(fileName);
return resultx.ToString()+", file: "+ fileName;
}
}
}
尝试让payload部分,为/wulala
、../../../../windows/win.ini
还有c:/windows/win.ini
利用方面
\.PhysicalDrive<drivenumber> #可以读取原始磁盘数据。需要管理员权限
\.PhysicalDrive1
\.GLOBALROOTdeviceharddisk0dr0
如果存在写入权限,还可以使用“CONOUT$”将数据写入控制台输出。
CONIN: \.GlOBALROOTDeviceConDrvCurrentIn
CONOUT: \.GlOBALROOTDeviceConDrvCurrentOut
检测正在运行的服务
Default Windows pipeline: \.pipeInitShutdown
SQLExpress \.pipeSQLLocalSQLEXPRESS 3 -1
SQLExpress \.pipeMSSQL$SQLEXPRESSsqlquery
SQL server \.pipesqlquery
Docker \.pipedocker_engine
利用NTFS streams
一些文件可以具有备用数据流。
常见的替代数据流是“: Zone.Identifier:$DATA”。此备用数据流在下载时添加到文件中,并包含下载位置。
http://xxx.com/xxx?filename= myfile.txt: Zone.Identifier:$DATA
Network folders
不仅本地文件是可读的,而且远程文件也可以访问。
\<ip>c$windowswin.ini
WSL
https://learn.microsoft.com/zh-cn/windows/wsl/basic-commands
如果windows上开了linux的话
还可以通过目录遍历攻击读取 WSL 上已安装的 linux 发行版。
\wsl.localhost<distroname>
\wsl.localhostUbuntu-22.04etcpasswd
我安装的是Ubuntu-22.04
bypass
windows不区分大小写,可以加入一些。
../
替换 ../
..//
替换 ../
/
替换
\.UNClocalhostC$windowswin.ini
\localhostc$windowswin.ini
\.GLOBALROOTDeviceHarddiskVolume3windowswin.ini
\?C:windowswin.ini
\.GLOBALROOTDeviceHarddisk0Partition0windowswin.ini
\.C:windowswin.ini
//./c:/windows/win.ini
windows不区分大小写,可以加入一些。
如何修复
用Path.GetFileName修复
增加一行fileName = Path.GetFileName(fileName);
解决
Path.GetFileName
是 .NET Framework 和 .NET Core 中的一个静态方法,它属于System.IO.Path
类。这个方法的主要作用是从一个完整路径字符串中提取文件名和扩展名部分。具体来说,
Path.GetFileName
方法会返回指定路径字符串的最后一部分,这通常是文件名,包括文件的扩展名。
OK , 这样就固定了。根目录,但是缺点也很明显,只能是文件名,比如这个目录下,其他的文件夹此时是无法取到的。
增加一些判断,完善
if (path.EndsWith("..")|| path.Contains("../")|| path.Contains("..\"))
{
thrownewArgumentException("Path contains invalid characters: "+ path);
}
if(!combinePath.StartsWith(Path.GetFullPath(parentPath)))
{
thrownewArgumentException("Path contains invalid characters: "+string.Join(", ", paths));
}
正常下就会正常添加,携带子路径。
当存在异常的时候
其余的情况就会alert报错。
目前看都OK,过滤中,没有验证.
这个字符,因为它表示当前路径。不会造成问题。
其次当使用其他payload的时候
.UNClocalhostC$windowswin.ini
以上~
原文始发于微信公众号(wulala520):dotnet中的Path Traversal
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论