GB/T 34944-2017 《Java语言源代码漏洞测试规范》是2017年发布实施的针对源代码安全漏洞进行测试的规范,包括9类43种安全漏洞类型,测评机构可以单独申请CNAS源代码测试资质。
本次我们重点讲解其中两种安全漏洞类型,绝对路径遍历和相对路径遍历,是路径遍历安全漏洞类型的两个细分分类。下面我们先看一下,国标中对这两种细化漏洞的描述。
相对路径遍历:
漏洞描述:路径名受外部控制的输入数据影响,且程序没有使能够解析到目录外位置的字符序列(如“..”失效)
漏洞风险:攻击者可以通过输入能够解析到目录外位置的字符序列来访问限制目录之外的文件或目录。
修复或规避建议:在构建路径名前对输入数据进行验证,确保外部输入仅包含允许的构成路径名的字符。
示例1:不规范用法
import java.io.*; public class Example{ private String dataPath; //本例中允许访问的目录 public void exampleFun(String filename) { //filename为用户的输入数据,不超过10个字符 //filename可能包含".."字符序列导致访问dataPath目录之外的文件; String path = dataPath + filename; try { File file = new File(path); if(file.exists()) { file.open(); //其它语句 } //其它语句 } catch (...) { //其它语句 }
} } |
相对路径遍历是一个比较容易实现的攻击行为,只要攻击者能够输入路径,可能会试探通过增加../改变路径,从而可以访问到其它非授权路径,所以还是要进行控制。
示例2:规范用法
import java.io.*; public class Example{ private String dataPath; //本例中允许访问的目录 public void exampleFun(String filename) { //filename为用户的输入数据,不超过10个字符 String regex ="-[A-Za-z0-9]+\.[a-z]+$"; //对文件名进行合法性校验的正则表达式 //filename转入的文件名称可能存在漏洞,现通过正则表达式regex校验文件名filename的合法性 //校验通过则访问文件 if(filename.matches(regex)) { //如果文件名合法,则交路径和文件名组合成完整的文件访问路径 String path = dataPath + filename; try { //访问文件,这里的path已经是合法的,安全的文件路径,不存在漏洞 File file = new File(path); if(file.exists()) { file.open(); //其它语句 } //其它语句 } catch (...) { //其它语句 } } } } |
通过正则表示式对用户输入的路径和文件名进行处理。
绝对路径遍历:
漏洞描述:路径名由外部控制的输入数据决定,且程序没有限制路径名允许访问的目录
漏洞风险:攻击者可以通过输入路径名来访问任意的文件或目录
修复或规避建议:在程序中指定允许访问的文件或目录,在访问文件或目录前对路径名进行验,确保仅允许访问指定的文件或目录。
示例3:不规范用法
import java.io.*; public class Example{ public void exampleFun(String absolutePath) { //absolutePath为用户的输入数据 try { File file = new File(absolutePath); //没有限制absolutePath访问的目录 if(file.exists()) { file.open(); //其它语句 } //其它语句 } catch (...) { //其它语句 } } } |
绝对路径遍历需要程序员对用户输入的路径,许可进行检查。
import java.io.*; public class Example{ public void exampleFun(String absolutePath) { //absolutePath为用户的输入数据 String regex = "^C:\\data\\[A-Za-z0-9]+\.[a-z]+$"; //用正则表达式设置限制访问的目录 //验证absolutePath是否仅能解析到受限制的目录内 if(absolutePath != null && absolutePath.matches(regex)) { try { File file = new File(absolutePath); //没有限制absolutePath访问的目录 if(file.exists()) { file.open(); //其它语句 } //其它语句 } catch (...) { //其它语句 } } //其它语句 } } |
例4:规范用法
同样需要对用户输入的路径和文件名进行正则表示式判断。
路径遍历攻击旨在访问存储在Web根目录之外的文件和目录。通过操纵带有“点-斜线(./…/)”序列及其变化的文件或使用绝对文件路径来引用文件的遍历,可以访问存储在文件系统上的任意文件和目录,包括应用程序源代码、配置和关键系统文件等,也可以与其它漏洞综合利用,用来提升权限。有的资料上也称为“点- 点斜线”、“目录遍历”、“目录爬升”和“回溯”等。最常见的特殊元素之一是“ ../”,在大多数现代操作系统中,该元素被解释为当前位置的父目录,这称为相对路径遍历。
路径遍历还包括使用绝对路径名,例如“ /usr/local/ bin”,这在访问意外文件时也可能有用,这称为绝对路径遍历。
绝对路径:绝对路径就是你的主页上的文件或目录在硬盘上真正的路径,(URL和物理路径),例如:C:\xyz\test.txt 代表了test.txt文件的绝对路径。例如:在Servlet中,“/”代表Web应用的根目录。和物理路径的相对表示,例如:“./” 代表当前目录, “../”代表上级目录,这种类似的表示,属于相对路径。
下面使用Benchmark 1.2b中的例子进行说明。Benchmark是OWASP给出的用于评价SAST工具约登指数的一组案例集,一共真假漏洞示例2740个。
下面举一个Benchmark中的例子,存在相对路径遍历安全漏洞。
1. 选择BenchmarkTest00001。
2. 使用页面中现有的值提交,查看结果进行分析。
3. 根据界面路径找到FileName文件查看文件内容。
4. 在Value文本框中输入:..\conf\logging.properties。
5. 点击“Generate cookie”按钮,点击“Test it”按钮。
这个漏洞例子中,主要是在第4步完成了到当前路径的上层路径下的conf目录中打开logging.properties文件,显示该文件中的内容,完成一个相对路径遍历漏洞的攻击利用。通过源代码缺陷检测工具,可以检测出存在目录遍历漏洞。对应找到在BenchmarkTest00001文件的第62行,org.owasp.benchmark.helpers.Utils.testfileDir + param拼接后的值赋给了filename,在63行中也是直接使用了filename,未对其进行任何过滤或转义操作。存在路径遍历漏洞。如图。
下面一个例子是绝对路径遍历。
1. 选择BenchmarkTest00011。
2. 使用页面中现有的值提交查看结果,进行分析。
3. 在C:\logs目录下创建Test.txt文件,然后在界面value文本框中输入C:\logs。
4. 点击“Login”按钮。
该例子是在输入时使用绝对路径,在输入的路径下创建test.txt文件。从源代码上分析:
45-50行,request.getHeaders(“vector”),获取浏览器界面界面中输入的值,并将其赋给param。
53行,java.io.File(param, “/Test.txt”),是根据文件路径获取文件流,有了文件流就可以取到文件的相关信息。
使用源代码缺陷检测工具,可以检测出该漏洞,查看检测结果,如下图。
(结束)