Perl 代码中的这个特定路径串联是否可以利用?
假设攻击者控制变量$untrusted_user_supplied_path
。下面的 Perl 代码可以被利用吗?
my $untrusted_user_supplied_path = ...
if ($untrusted_user_supplied_path =~ /\.\./) {
die("Tries to escape homedir.");
}
my $base_path = "/home/username/";
my $full_path = "${base_path}${untrusted_user_supplied_path}";
if (-e $full_path) {
open(FILE, "<", $full_path) || die("File not accessible.");
while (<FILE>) {
# present the content to the user
}
close(FILE);
}
如果攻击者可以选择 $untrusted_user_supplied_path 的值,以便他/她可以读取驻留在不是 $base_path 子目录的目录中的文件,则该代码被定义为可利用的(比如/etc/passwd
)?
您可以假设代码在 Linux 下运行。此外,您可以假设向用户呈现文件的代码中没有引入任何其他缺陷。
请注意,问题是关于代码是否是 可利用,而不是如何使代码更安全。有无数 使代码更安全的方法(想想chroot
等),但那就是 超出了这个问题的范围。只要在你的答案中说明,如果你 相信该代码是否可被利用。当然,请 提供支持性论证。
Assume that an attacker controls the variable $untrusted_user_supplied_path
. Is the following Perl code exploitable?
my $untrusted_user_supplied_path = ...
if ($untrusted_user_supplied_path =~ /\.\./) {
die("Tries to escape homedir.");
}
my $base_path = "/home/username/";
my $full_path = "${base_path}${untrusted_user_supplied_path}";
if (-e $full_path) {
open(FILE, "<", $full_path) || die("File not accessible.");
while (<FILE>) {
# present the content to the user
}
close(FILE);
}
The code is defined as exploitable if an attacker can choose a value of $untrusted_user_supplied_path
such that he/she can read a file that resides in a directory that is not a sub-directory of $base_path
(say /etc/passwd
)?
You can assume that the code is running under Linux. Furthermore, you can assume that no additional flaws are introduced in the code which presents the file to the user.
Please note that the question is about whether or not the code is
exploitable, not how to make the code more secure. There are numerous
ways to make the code more secure (think chroot
, etc.) but that is
beyond the scope of this question. Just state in your answer if you
believe that the code is exploitable or not. And of course, please
provide supporting argumentation.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您询问您的代码是否可被利用。是的。所有代码都是可利用的。你可能不会认为是因为你认为你已经涵盖了你能想到的情况,但对方通常会发现你没有想到的情况。但我总是说所有的枪都已上膛。
安全不仅仅是代码。您必须考虑运行它的环境,用户在运行您的代码之前还可以做什么,等等。
如果您真的担心此代码可能会发生什么,请创建一个风险矩阵。从您担心的部分开始,列出其所有假设。例如,在您的情况下,您可能会这样开始:
perl
我想我是(没有路径攻击在查找可执行文件时)PERL5LIB
、PERL5OPT
或-I
没有预先加载模块加载路径(查找模块时没有路径攻击)等等等等。一旦你提出了所有的假设,你就可以通过锁定这些案例来确保它们是有效的。您还可以找到他们的所有假设,并锁定这些假设,等等。 Perl 的 污点检查 将有助于解决其中的一些问题(我在 < a href="http://oreilly.com/catalog/9780596527242/" rel="nofollow noreferrer">掌握 Perl)。
成功的攻击通常是间接的。例如,我的工作之一是保护一家非常富有且偏执的银行中的一些数据。我们做了所有我们能做的计算机工作,我的一位同事在闲聊中问我们在安装服务器之前他们是如何完成这项任务的。他们说,“哦,数据在某某办公桌上的活页夹上”。尽管我们付出了所有的工作、他们的工资以及每个人的时间和精力,但无论我们对服务器做了什么,任何想要这些数据的内部人员都可以带走它。
现在您已经有了风险矩阵,您就可以开始培养风险承受能力了。没有什么是完美的,你可以努力让宇宙的热寂锁定一切。您不会满足于完美,而是满足于您愿意为代码的每个部分承担多少风险。你要弄清楚如果某个部件受到损害会发生什么,以及这会让你付出多少代价(以美元、声誉等为单位),并算出对你(或你的雇主)来说有多少工作值得。您所做的工作刚好低于您的风险承受能力。
问题是,即使是最优秀的人也会错过一些东西。安全方面的小漏洞可能看起来并不那么重要,但如果你把足够多的东西放在一起,你最终可以引导自己进入一个可利用的境地。安全是整体性的。
You're asking if your code is exploitable. Yes. All code is exploitable. You might not think it is because you think you've covered the situations that you can think about, but the other side typically finds a situation you haven't thought about. But then, I always say all guns are loaded too.
Security is more than just the code. You have to consider the environment it runs it, what else the user was allowed to do before he ran your code, etc. etc.
If you're truly worried about what might happen with this code, create a risk matrix. Start with the part that you're worried about and list all of its assumptions. For instance, in your case you might start with:
perl
I think I am (no path attack in finding executable)PERL5LIB
,PERL5OPT
, or-I
did not front-load module load paths (no path attack in finding modules)And so on and so on. Once you develop all of your assumptions, you ensure that they are valid by locking down those cases. You also find all of their assumptions, and lock down those, and so on. Perl's taint checking will help with some of those (and I talk about it in more depth in Mastering Perl).
Successful attacks are often indirect ones. For instance, I was part of a job to secure some data in a very rich and paranoid bank. We did all the computery stuff we could do, and one of my co-workers, in idle conversation, asked how they did the task before we installed the server. They said, "Oh, the data is on a binder on so-and-so's desk". Despite all of our work, their pay, and everyone's time and effort, anyone on the inside who wanted the data could quite literally walk off with it no matter what we did with the server.
Now that you have your risk matrix, you start developing your risk tolerance. Nothing is ever going to be perfect, and you could work to the heat death of the universe locking everything down. Instead of being perfect, you settle for how much risk you're willing to take on for each part of the code. You figure out what could happen if one part is compromised and how much that would cost you (in dollars, reputation, whatever) and figure out how much work that is worth to you (or your employers). You do just enough work to be below your risk tolerance.
The problem is that even the best people will miss something. Small cracks in security might not seem that important, but if you put enough together you can eventually bootstrap yourself into an exploitable situation. Security is holistic.
如果主目录内存在指向外部某个位置的符号链接,您仍然会遇到麻烦。
If a symlink exists inside the homedir to somewhere outside, you're still in trouble.
在我看来这是合理的,尽管你的测试有点严厉。您可能需要考虑将: 替换
为:
以允许访问包含两个点的文件和目录。它仍然不允许像 dir1/../dir2/filename 这样复杂但可能有效的访问,尽管您可能不太担心这一点。
It looks reasonable to me, although your test is a little draconian. You might want to consider replacing:
with:
to allow access to files and directories containing two dots. It still wouldn't allow convoluted but potentially valid accesses like
dir1/../dir2/filename
, although you might not be too worried about that.我将违反您的入住规则并建议您这样做:
这应该是防水的。不过,它确实要求 $base_path 是规范的。
I'm going to violate your house rules and suggest that you do it like this:
This should be watertight. It does require $base_path to be canonical, though.
它是否可被利用取决于将文件呈现给用户的代码。代码中不一定有“缺陷”,但有机会做你没有想到的事情。
Whether it is exploitable or not depends on the code which presents the file to the user. There don't have to be "flaws" in that code so much as opportunities for doing things you haven't thought of.