我对此主题的初步理解是,我需要阻止请求中的某些垃圾字符以避免这些攻击。
我决定在使用之前通过每个请求参数的模式匹配来解决这个问题。互联网上提供的关于Null Byte的大多数帖子和给出的例子都显示了文件IO是这次攻击的主要受害者。以下是我的问题
我所指的文章是:
http://projects.webappsec.org/w/page/13246949/Null%20Byte%20Injection
http://www.perlmonks.org/index.pl?node_id=38548
http://hakipedia.com/index.php/Poison_Null_Byte
提前致谢
所以要说得更清楚:
第一篇文章指出了我所谈论的java中的漏洞。 java中允许使用字符串 serverlogs.txt%00.db ,但是当涉及到C / C ++时,这是 serverlogs.txt ,因为在C%00中将被空字节替换导致字符串在serverlogs.txt之后终止。所以我们应该避免这样的角色。这就是我想弄清楚我不应该允许哪些这样的角色。
String fn = request.getParameter("fn");
if (fn.endsWith(".db"))
{
File f = new File(fn);
//read the contents of “f” file
…
}
答案 0 :(得分:4)
你试过吗?我写了这个快速单元测试:
@Test
public void test() throws Exception {
FileOutputStream out = new FileOutputStream("test.txt");
out.write("hello!".getBytes("utf-8"));
out.close();
String badPath = "test.txt\0foo";
File file = new File(badPath);
FileInputStream in = new FileInputStream(file);
System.out.println(StreamUtils.copyToString(in, Charset.forName("utf-8")));
}
现在,如果null字符破坏了字符串,我希望将我的文件内容打印到控制台。相反,我得到一个FileNotFoundException。为了记录,这是在Ubuntu 13.04上使用Java 1.7.0_40。
<强>更新强>
进一步调查显示File#isInvalid
中的此代码:
final boolean isInvalid() {
if (status == null) {
status = (this.path.indexOf('\u0000') < 0) ? PathStatus.CHECKED
: PathStatus.INVALID;
}
return status == PathStatus.INVALID;
}
答案 1 :(得分:3)
这不是一个糟糕的问题。我怀疑这是所有平台上的有效漏洞(例如,我相信Windows在其内核中使用Pascal风格的字符串,而不是以空字符结尾的字符串),但是如果某些平台和JVM,我一点也不会感到惊讶实际上很容易受到这种攻击。
要考虑的关键点是字符串的来源,以及在与字符串交互之前对这些字节所做的操作。 来自远程计算机的任何字节应始终被认为是恶意的,除非另有证明。并且你永远不应该从互联网上获取字符串并尝试将它们转换为本地计算机上的路径。是的像Apache的网络服务器这样做,但这也是他们最容易受到攻击的代码。正确的解决方案是:不要尝试将坏数据列入黑名单(如空字节),只将白名单列入白名单。
答案 2 :(得分:2)
你也可以从另一个角度解决Null字节的问题!
10月10日,Oracle修复了问题:http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8014846因此,升级到Java 8或Java 7u40并且您受到保护。 (是的,我测试了它!),它有效!
如果我个人博客的链接不被视为垃圾邮件,请将其放在此处: http://crocode.blogspot.ru/2015/03/java-null-byte-injections.html
答案 3 :(得分:1)
如果我正确地阅读了您的问题,您希望阻止可执行代码在字符串的终止空字节后注入内存。
Java不是C。
Java不会对其字符串使用终止空字节,因此您无需对此进行保护。