PHP exec() 是否将执行的命令存储在任何地方?

PHP exec() 是否将执行的命令存储在任何地方?

假设我在 PHP Web 应用程序中有以下代码。

$encrypt ? $password = generatePassword($passwordstrength): $password="";
$estring = "7z a -p$password -mx0 packFoo.aes.7z mydir/foo";
if($encrypt) {
    exec($estring);
}
mailuser($password);//uses standard PHP mail function

密码由使用 PHP rand() 的函数随机生成。

我没有在 /var/logs 中找到密码,也没有在 .bash_history 中找到密码。

我需要知道如果服务器受到威胁,是否可以从服务器恢复 $password 的值。最终,我可以声称 $password 的值没有存储在服务器上吗?

答案1

作为Mat 在评论中指出,除非您专门设置审核,否则不太可能命令本身故意存储在任何地方并以可直接访问的形式保存。grep -lR ... /因为 root 可能是一种启发性的体验(您可能想noatime先重新安装所有内容......)。

然而,总有一个“但是”。在这种情况下,我可以看到的一个明显的可能性(特别是当您没有安全地清除所显示的代码中的 $password 或 $estring 变量时)是这些内容可能会被写出到交换空间。这意味着即使在没有主动攻击者存在的情况下,它们也至少在一段时间内致力于永久存储。这可以通过完全禁用交换或运行使用随机加密密钥加密的交换来很大程度上缓解,这使得交换在重新启动后无法访问(因为当系统 RAM 被清除时,理解它所需的解密密钥就会丢失)。

我会想象7zip 的表现足以快速从其命令行中清除密码,然后在不再需要时立即从其内部变量中清除密码,但扩展密钥计划之类的内容可能会保留较长时间,从而增加他们被替换的可能性。这些不一定允许恢复密码,但它们很可能允许从加密存档中恢复明文。在适当的时候发出的简单命令ps axw将显示从命令行以纯文本形式登录密码的人,但事实并非如此已存储而且机会之窗很小。

当您发送电子邮件时,我认为它包含明文形式的密码(或者很容易导出为相应明文的内容,例如 Base64 编码的消息正文)。那封电子邮件几乎肯定是将要暂时写入系统的邮件队列,这意味着密码最终会存储在磁盘上(除非您在 RAM 磁盘上拥有邮件队列目录,除了邮件队列应该位于持久存储上之外,这在操作上也会带来一系列问题)。特别是如果您正在运行智能主机设置,队列文件可能很快就会被删除,但由于它已被写入磁盘,可以说“损坏已经完成”。strings /dev/sd?在邮件经过的任何服务器上,类似的东西可能会将密码恢复给任何知道要查找什么的人,除非您采取特定步骤来减轻这种威胁。

当然,电子邮件最初的设计并不是完全安全的。通过 SMTP 发送电子邮件获得合理保密性保证的唯一方法(即使您使用的是基于 SSL 的 SMTP 或 STARTTLS)贯穿整个链条邮件服务器)是端到端加密,如 S/MIME 或 OpenPGP。

长话短说:您的网络应用程序大概不会故意将命令(包括密码)或密码本身存储在任何地方,但它所依赖的其他组件可能会在正常操作过程中存储。

答案2

首先,请注意您有一个更大的安全问题:rand()不适合生成密码。它使用快速、可预测的伪随机数生成器。使用openssl_random_pseudo_bytes()相反,正如在文档


记录命令的名称很常见,但记录它们的参数并不常见。因此,密码不会最终出现在系统日志中,除非该服务器已配置为异常数量的日志记录。

命令行可以被任何同时运行的进程监听7z,它所要做的就是运行ps

-p您可以通过仅传递( 7z a -p -mx0 packFoo.aes.7z mydir/foo);来避免将密码放在命令行上。在这种情况下你需要使用预计将密码(两次)发送到7z,因为它坚持要求密码来自终端并输入两次。这里与 ssh 类似的例子。

另一方面,密码将在文件系统中存储一段时间。它肯定会存储在邮件后台的临时文件中。发送邮件后,临时文件将被删除,但密码仍可以由以 root 身份运行的进程访问,该进程直接访问磁盘以读取可用空间。密码也可能在某个时候被替换。

相关内容