【问题标题】:Why is it allowed to modify argv[0]?为什么允许修改 argv[0]?
【发布时间】:2016-03-04 08:49:50
【问题描述】:

我一直在从事一个项目,该项目使用 PID、/proc 和命令行分析来验证系统上的进程。我的代码必须由安全人员检查,他们设法用一行代码破解它……尴尬!

#!/usr/bin/env perl

$0="I am running wild"; # I had no clue you can do this!

system("cat /proc/$$/cmdline");
print("\n");
system("ps -ef | grep $$");

# do bad stuff here...

我的问题:

  1. 我看到了上面的一些用例,比如隐藏命令行上给出的密码(也是不好的做法),但是当一个人可以隐藏进程和欺骗 cmdline 时,我看到了更多的问题/问题。有理由允许吗?不是系统漏洞吗?

  2. 如何防止或检测到这种情况?我研究了/proc 挂载选项。我也知道可以使用lsof 来识别基于意外行为的欺骗进程,但这在我的情况下不起作用。目前,我正在使用一种简单的方法来检测 cmdline 是否包含至少一个 null (\0) 字符,该字符假定至少存在一个参数。在上面的代码中,需要用空值替换空格以绕过我无法在 Perl 中实现的检查 - 写入到第一个 \0

【问题讨论】:

    标签: linux perl procfs spoof cmdline-args


    【解决方案1】:

    回答1:

    这是因为启动新流程的实际工作方式。

    fork() 生成当前进程的重复实例,然后您 exec() 开始新事物 - 它用“新”进程替换您的 当前 进程,并且作为结果 - 它必须重写$0

    虽然在运行并行代码时这实际上非常有用 - 我在 fork()ing 代码时经常这样做,因为它可以很容易地发现哪个“东西”卡住/运行很热。

    例如:

    use Parallel::ForkManager;
    my $manager = Parallel::ForkManager -> new ( 10 ); 
    
    foreach my $server ( @list_of_servers ) {
        $manager -> start and next;
        $0 = "$0 child: ($server)";
        #do stuff;
        $manager -> finish;
    }
    

    您可以立即在ps 列表中看到正在发生的事情。您会在httpd 等许多多处理服务中看到这种行为。

    但这不是漏洞,除非您假设它不是漏洞(就像您所做的那样)。无论如何,不​​过是能够“mv”一个二进制文件。

    无论如何,回答 2... 预防或检测什么?我的意思是,你不能从命令行知道一个进程在做什么,但无论如何你也不能知道它在做什么(有很多方法可以让一段代码在幕后做一些“奇怪”的事情)。

    答案是 - 相信您的安全模型。不要在特权上下文中运行不受信任的代码,这在很大程度上与他们所说的无关。当然,你可以在进程列表中写粗鲁的信息,但很明显是谁在做的。

    【讨论】:

    • 嗨,Sobrique。我明白你在说什么,我承认我使用cmdline 可能是为了我不应该做的事情(见this one)。我还看到了它在并行处理中的用处。我的第二个问题更多是关于我是否可以检测到 cmdline 已被修改为第一个/原始值以外的其他值
    • 但这就是每个过程。系统上每个进程的“父级”最终都是init。其他一切都从那里进行了分叉和执行 - 在此过程中,更改了名称。文件不知道自己的名称,名称只是目录结构找到特定 inode 的方式。因此,除了将 $0 设置为适当的值之外,进程也不知道自己的名称。
    • 我明白了......有道理......我担心会是这样 - 我接受你的回答,因为你涵盖了这两个问题。您提供的技术信息也非常感谢 - 为之欢呼:)
    猜你喜欢
    • 2011-10-28
    • 2012-03-07
    • 1970-01-01
    • 2022-01-09
    • 2020-07-02
    • 2023-03-07
    • 2011-06-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多