可开发的PHP函数
我试图建立一个可用于任意代码执行的函数列表。 目的不是要列出应被列入黑名单或不允许的功能。 相反,我希望在搜索受感染服务器的后门时方便地使用grep
-able的红旗关键字列表。
这个想法是,如果你想构建一个多用途的恶意PHP脚本 - 比如像c99或r57这样的“web shell”脚本 - 你将不得不使用一个或多个相对较小的一组函数在文件的某处,以便允许用户执行任意代码。 搜索这些函数可以帮助您更快速地将数以万计的PHP文件的大堆缩小到需要更仔细检查的相对较小的脚本集。
显然,例如,以下任何一项都将被视为恶意(或可怕的编码):
<? eval($_GET['cmd']); ?>
<? system($_GET['cmd']); ?>
<? preg_replace('/.*/e',$_POST['code']); ?>
等等。
有一天我在一个受到攻击的网站上搜索,我没有注意到一段恶意代码,因为我没有意识到preg_replace
可能会因使用/e
标志而变得危险(这很严重,那为什么呢?) 。 还有其他我错过了吗?
这是我的列表到目前为止:
外壳执行
system
exec
popen
backtick operator
pcntl_exec
PHP执行
eval
preg_replace
(带/e
修饰符) create_function
include
[ _once
] / require
[ _once
](请参阅mario的漏洞利用细节答案) 有一个能够修改文件的函数列表也许是有用的,但我想99%的时间利用代码将至少包含上面的一个函数。 但是,如果您有能够编辑或输出文件的所有功能的列表,请将其张贴出来,然后我将其添加到此处。 (而且我不计算mysql_execute
,因为这是另一类漏洞利用的一部分。)
为了建立这个清单,我使用了2个来源。 在猩红和RATS研究。 我还添加了一些我自己的组合,并且此线程中的人员已经帮助完成了。
编辑:发布此列表后,我联系了RIPS的创始人,截至目前,此工具搜索PHP代码以使用此列表中的每个函数。
大多数这些函数调用都被分类为接收器。 当一个受污染的变量(如$ _REQUEST)被传递给一个接收函数时,那么你就有一个漏洞。 RATS和RIPS等程序使用grep like功能来识别应用程序中的所有接收器。 这意味着程序员在使用这些函数时应该格外小心,但是如果他们全部被禁止了,那么你将无法完成很多任务。
“拥有权利的同时也被赋予了重大的责任。”
- 史坦利
命令执行
exec - Returns last line of commands output
passthru - Passes commands output directly to the browser
system - Passes commands output directly to the browser and returns last line
shell_exec - Returns commands output
`` (backticks) - Same as shell_exec()
popen - Opens read or write pipe to process of a command
proc_open - Similar to popen() but greater degree of control
pcntl_exec - Executes a program
PHP代码执行
除了eval
之外,还有其他一些方法可以执行PHP代码: include
/ require
可以以本地文件包含和远程文件包含漏洞的形式用于远程代码执行。
eval()
assert() - identical to eval()
preg_replace('/.*/e',...) - /e does an eval() on the match
create_function()
include()
include_once()
require()
require_once()
$_GET['func_name']($_GET['argument']);
$func = new ReflectionFunction($_GET['func_name']); $func->invoke(); or $func->invokeArgs(array());
接受回调的函数列表
这些函数接受一个字符串参数,可以用来调用攻击者选择的函数。 攻击者可能或可能不具备传递参数的功能,具体取决于功能。 在这种情况下,可以使用像phpinfo()
这样的Information Disclosure
功能。
Function => Position of callback arguments
'ob_start' => 0,
'array_diff_uassoc' => -1,
'array_diff_ukey' => -1,
'array_filter' => 1,
'array_intersect_uassoc' => -1,
'array_intersect_ukey' => -1,
'array_map' => 0,
'array_reduce' => 1,
'array_udiff_assoc' => -1,
'array_udiff_uassoc' => array(-1, -2),
'array_udiff' => -1,
'array_uintersect_assoc' => -1,
'array_uintersect_uassoc' => array(-1, -2),
'array_uintersect' => -1,
'array_walk_recursive' => 1,
'array_walk' => 1,
'assert_options' => 1,
'uasort' => 1,
'uksort' => 1,
'usort' => 1,
'preg_replace_callback' => 1,
'spl_autoload_register' => 0,
'iterator_apply' => 1,
'call_user_func' => 0,
'call_user_func_array' => 0,
'register_shutdown_function' => 0,
'register_tick_function' => 0,
'set_error_handler' => 0,
'set_exception_handler' => 0,
'session_set_save_handler' => array(0, 1, 2, 3, 4, 5),
'sqlite_create_aggregate' => array(2, 3),
'sqlite_create_function' => 2,
信息披露
大多数这些函数调用不是汇。 但是,如果任何返回的数据可以被攻击者查看,它可能就是一个漏洞。 如果攻击者能够看到phpinfo()
那肯定是一个漏洞。
phpinfo
posix_mkfifo
posix_getlogin
posix_ttyname
getenv
get_current_user
proc_get_status
get_cfg_var
disk_free_space
disk_total_space
diskfreespace
getcwd
getlastmo
getmygid
getmyinode
getmypid
getmyuid
其他
extract - Opens the door for register_globals attacks (see study in scarlet).
parse_str - works like extract if only one argument is given.
putenv
ini_set
mail - has CRLF injection in the 3rd parameter, opens the door for spam.
header - on old systems CRLF injection could be used for xss or other purposes, now it is still a problem if they do a header("location: ..."); and they do not die();. The script keeps executing after a call to header(), and will still print output normally. This is nasty if you are trying to protect an administrative area.
proc_nice
proc_terminate
proc_close
pfsockopen
fsockopen
apache_child_terminate
posix_kill
posix_mkfifo
posix_setpgid
posix_setsid
posix_setuid
文件系统功能
根据RATS,php中的所有文件系统功能都很糟糕。 其中一些对攻击者来说似乎不是很有用。 其他人比你想象的更有用。 例如,如果allow_url_fopen=On
那么url可以用作文件路径,所以调用copy($_GET['s'], $_GET['d']);
可以用来上传系统上任何地方的PHP脚本。 另外,如果某个站点容易受到通过GET发送的请求,则可能会滥用这些文件系统的所有功能,从而通过您的服务器对另一台主机进行频道和攻击。
// open filesystem handler
fopen
tmpfile
bzopen
gzopen
SplFileObject->__construct
// write to filesystem (partially in combination with reading)
chgrp
chmod
chown
copy
file_put_contents
lchgrp
lchown
link
mkdir
move_uploaded_file
rename
rmdir
symlink
tempnam
touch
unlink
imagepng - 2nd parameter is a path.
imagewbmp - 2nd parameter is a path.
image2wbmp - 2nd parameter is a path.
imagejpeg - 2nd parameter is a path.
imagexbm - 2nd parameter is a path.
imagegif - 2nd parameter is a path.
imagegd - 2nd parameter is a path.
imagegd2 - 2nd parameter is a path.
iptcembed
ftp_get
ftp_nb_get
// read from filesystem
file_exists
file_get_contents
file
fileatime
filectime
filegroup
fileinode
filemtime
fileowner
fileperms
filesize
filetype
glob
is_dir
is_executable
is_file
is_link
is_readable
is_uploaded_file
is_writable
is_writeable
linkinfo
lstat
parse_ini_file
pathinfo
readfile
readlink
realpath
stat
gzfile
readgzfile
getimagesize
imagecreatefromgif
imagecreatefromjpeg
imagecreatefrompng
imagecreatefromwbmp
imagecreatefromxbm
imagecreatefromxpm
ftp_put
ftp_nb_put
exif_read_data
read_exif_data
exif_thumbnail
exif_imagetype
hash_file
hash_hmac_file
hash_update_file
md5_file
sha1_file
highlight_file
show_source
php_strip_whitespace
get_meta_tags
你必须扫描include($ tmp)并且需要(HTTP_REFERER)和* _once。 如果攻击脚本可以写入临时文件,则可以稍后将其包含在内。 基本上是一个两步评估。
而且甚至可以使用以下解决方法来隐藏远程代码:
include("data:text/plain;base64,$_GET[code]");
另外,如果你的网络服务器已经被破坏,你不会总是看到未编码的恶意。 通常攻击外壳是gzip编码的。 想想include("zlib:script2.png.gz");
这里没有评价,效果仍然相同。
这本身并不是一个答案,但是这里有一些有趣的东西:
$y = str_replace('z', 'e', 'zxzc');
$y("malicious code");
同样的精神, call_user_func_array()
可以用来执行混淆函数。