可利用的 PHP 函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3115559/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 08:43:56  来源:igfitidea点击:

Exploitable PHP functions

phpsecuritygrep

提问by tylerl

I'm trying to build a list of functions that can be used for arbitrary code execution. The purpose isn't to list functions that should be blacklisted or otherwise disallowed. Rather, I'd like to have a grep-able list of red-flagkeywords handy when searching a compromised server for back-doors.

我正在尝试构建可用于任意代码执行的函数列表。目的不是列出应列入黑名单或以其他方式禁止的功能。相反,我希望在搜索受感染的服务器以查找后门时有一个方便的红旗关键字grep列表。

The idea is that if you want to build a multi-purpose malicious PHP script -- such as a "web shell" script like c99 or r57 -- you're going to have to use one or more of a relatively small set of functions somewhere in the file in order to allow the user to execute arbitrary code. Searching for those those functions helps you more quickly narrow down a haystack of tens-of-thousands of PHP files to a relatively small set of scripts that require closer examination.

这个想法是,如果你想构建一个多用途的恶意 PHP 脚本——比如像 c99 或 r57 这样的“web shell”脚本——你将不得不使用一个或多个相对较小的函数集文件中的某处,以允许用户执行任意代码。搜索这些函数可以帮助您更快地将数以万计的 PHP 文件大海捞针缩小为需要仔细检查的相对较小的脚本集。

Clearly, for example, any of the following would be considered malicious (or terrible coding):

很明显,例如,以下任何一项都将被视为恶意(或糟糕的编码):

<? eval($_GET['cmd']); ?>

<? system($_GET['cmd']); ?>

<? preg_replace('/.*/e',$_POST['code']); ?>

and so forth.

等等。

Searching through a compromised website the other day, I didn't notice a piece of malicious code because I didn't realize preg_replacecould be made dangerous by the use of the /eflag (which, seriously? Why is that even there?). Are there any others that I missed?

前几天在一个受感染的网站上搜索时,我没有注意到一段恶意代码,因为我没有意识到preg_replace使用/e标志可能会变得危险(这,说真的?为什么会这样?)。还有其他我错过的吗?

Here's my list so far:

到目前为止,这是我的清单:

Shell Execute

外壳执行

  • system
  • exec
  • popen
  • backtick operator
  • pcntl_exec
  • system
  • exec
  • popen
  • backtick operator
  • pcntl_exec

PHP Execute

PHP 执行

  • eval
  • preg_replace(with /emodifier)
  • create_function
  • include[_once] / require[_once] (see mario's answerfor exploit details)
  • eval
  • preg_replace(带/e修饰符)
  • create_function
  • include[ _once] / require[ _once](有关漏洞利用详情,请参阅 mario 的回答

It might also be useful to have a list of functions that are capable of modifying files, but I imagine 99% of the time exploit code will contain at least one of the functions above. But if you have a list of all the functions capable of editing or outputting files, post it and I'll include it here. (And I'm not counting mysql_execute, since that's part of another class of exploit.)

拥有一个能够修改文件的函数列表也可能很有用,但我想 99% 的漏洞利用代码将至少包含上述函数之一。但是,如果您有能够编辑或输出文件的所有功能的列表,请将其发布,我会将其包含在此处。(而且我没有计算在内mysql_execute,因为这是另一类漏洞利用的一部分。)

采纳答案by rook

To build this list I used 2 sources. A Study In Scarletand RATS. I have also added some of my own to the mix and people on this thread have helped out.

为了建立这个列表,我使用了 2 个来源。 猩红色老鼠的研究。我还添加了一些我自己的组合,这个线程上的人提供了帮助。

Edit:After posting this list I contacted the founder of RIPSand as of now this tools searches PHP code for the use of every function in this list.

编辑:发布此列表后,我联系了RIPS的创始人,截至目前,此工具会搜索 PHP 代码以使用此列表中的每个函数。

Most of these function calls are classified as Sinks. When a tainted variable (like $_REQUEST) is passed to a sink function, then you have a vulnerability. Programs like RATSand RIPSuse grep like functionality to identify all sinks in an application. This means that programmers should take extra care when using these functions, but if they where all banned then you wouldn't be able to get much done.

大多数这些函数调用被归类为接收器。当一个受污染的变量(如 $_REQUEST)被传递给一个接收器函数时,你就有了一个漏洞。RATSRIPS等程序使用类似 grep 的功能来识别应用程序中的所有接收器。这意味着程序员在使用这些功能时应该格外小心,但如果它们都被禁止,那么你将无法完成很多工作。

"With great power comes great responsibility."

能力越大,责任越大。

--Stan Lee

——斯坦·李

Command Execution

命令执行

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 Code Execution

PHP代码执行

Apart from evalthere are other ways to execute PHP code: include/requirecan be used for remote code execution in the form of Local File Includeand Remote File Includevulnerabilities.

除了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());

List of functions which accept callbacks

接受回调的函数列表

These functions accept a string parameter which could be used to call a function of the attacker's choice. Depending on the function the attacker may or may not have the ability to pass a parameter. In that case an Information Disclosurefunction like phpinfo()could be used.

这些函数接受一个字符串参数,该参数可用于调用攻击者选择的函数。根据函数的不同,攻击者可能有也可能没有能力传递参数。在这种情况下,可以使用Information Disclosure类似的功能phpinfo()

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,

Information Disclosure

信息披露

Most of these function calls are not sinks. But rather it maybe a vulnerability if any of the data returned is viewable to an attacker. If an attacker can see phpinfo()it is definitely a vulnerability.

大多数这些函数调用都不是接收器。但是,如果攻击者可以查看返回的任何数据,则它可能是一个漏洞。如果攻击者可以看到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

Other

其他

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

Filesystem Functions

文件系统函数

According to RATS all filesystem functionsin php are nasty. Some of these don't seem very useful to the attacker. Others are more useful than you might think. For instance if allow_url_fopen=Onthen a url can be used as a file path, so a call to copy($_GET['s'], $_GET['d']);can be used to upload a PHP script anywhere on the system. Also if a site is vulnerable to a request send via GET everyone of those file system functions can be abused to channel and attack to another host through your server.

根据 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

回答by mario

You'd have to scan for include($tmp) and require(HTTP_REFERER) and *_once as well. If an exploit script can write to a temporary file, it could just include that later. Basically a two-step eval.

您还必须扫描 include($tmp) 和 require(HTTP_REFERER) 以及 *_once 。如果漏洞利用脚本可以写入临时文件,它可以稍后包含该文件。基本上是一个两步评估。

And it's even possible to hide remote code with workarounds like:

甚至可以使用以下解决方法隐藏远程代码:

 include("data:text/plain;base64,$_GET[code]");

Also, if your webserver has already been compromised you will not always see unencoded evil. Often the exploit shell is gzip-encoded. Think of include("zlib:script2.png.gz");No eval here, still same effect.

此外,如果您的网络服务器已经受到攻击,您将不会总是看到未编码的邪恶。漏洞利用外壳通常是 gzip 编码的。想想include("zlib:script2.png.gz");这里没有 eval,还是一样的效果。

回答by Aillyn

This is not an answer per se, but here's something interesting:

这本身并不是一个答案,但这里有一些有趣的事情:

$y = str_replace('z', 'e', 'zxzc');
$y("malicious code");

In the same spirit, call_user_func_array()can be used to execute obfuscated functions.

本着同样的精神,call_user_func_array()可用于执行混淆功能。

回答by Bill Karwin

I'm surprised no one has mentioned echoand printas points of security exploitation.

我很惊讶没有人提到echoprint作为安全利用点。

Cross-Site Scripting (XSS)is a serious security exploit, because it's even more common than server-side code execution exploits.

跨站点脚本 (XSS)是一种严重的安全漏洞,因为它比服务器端代码执行漏洞更常见。

回答by Cheekysoft

i'd particularly want to add unserialize() to this list. It has had a long history of various vulnerabilities including arbitrary code execution, denial of service and memory information leakage. It should never be called on user-supplied data. Many of these vuls have been fixed in releases over the last dew years, but it still retains a couple of nasty vuls at the current time of writing.

我特别想将 unserialize() 添加到此列表中。它长期以来一直存在各种漏洞,包括任意代码执行、拒绝服务和内存信息泄漏。永远不应该在用户提供的数据上调用它。在过去的露年中,其中许多 vuls 已在版本中得到修复,但在撰写本文时,它仍然保留了一些令人讨厌的 vuls。

For other information about dodgy php functions/usage look around the Hardened PHP Projectand its advisories. Also the recent Month of PHP Securityand 2007's Month of PHP Bugsprojects

有关狡猾的 php 函数/用法的其他信息,请查看Hardened PHP Project及其建议。还有最近的 PHP 安全月和 2007 年的PHP Bugs项目

Also note that, by design, unserializing an object will cause the constructor and destructor functions to execute; another reason not to call it on user-supplied data.

另请注意,按照设计,反序列化对象将导致执行构造函数和析构函数;不在用户提供的数据上调用它的另一个原因。

回答by Josh

My VPS is set to disable the following functions:

我的 VPS 设置为禁用以下功能:

root@vps [~]# grep disable_functions /usr/local/lib/php.ini
disable_functions = dl, exec, shell_exec, system, passthru, popen, pclose, proc_open, proc_nice, proc_terminate, proc_get_status, proc_close, pfsockopen, leak, apache_child_terminate, posix_kill, posix_mkfifo, posix_setpgid, posix_setsid, posix_setuid

PHP has enough potentially destructible functions that your list might be too big to grep for. For example, PHP has chmod and chown, which could be used to simply deactivate a website.

PHP 有足够多的潜在可破坏函数,您的列表可能太大而无法 grep。例如,PHP 有 chmod 和 chown,它们可以用来简单地停用网站。

EDIT: Perhaps you may want to build a bash script that searches for a file for an array of functions grouped by danger (functions that are bad, functions that are worse, functions that should never be used), and then calculate the relativity of danger that the file imposes into a percentage. Then output this to a tree of the directory with the percentages tagged next to each file, if greater than a threshold of say, 30% danger.

编辑:也许您可能想要构建一个 bash 脚本,该脚本搜索按危险分组的函数数组的文件(不好的函数、更糟的函数、不应该使用的函数),然后计算危险的相对性该文件强加到一个百分比。然后将其输出到目录树,并在每个文件旁边标记百分比,如果大于阈值,例如 30% 危险。

回答by Cheekysoft

Also be aware of the class of "interruption vulnerabilities" that allow arbitrary memory locations to be read and written!

还要注意允许读取和写入任意内存位置的“中断漏洞”类别!

These affect functions such as trim(), rtrim(), ltrim(), explode(), strchr(), strstr(), substr(), chunk_split(), strtok(), addcslashes(), str_repeat() and more. This is largely, but not exclusively, due to the call-time pass-by-reference feature of the language that has been deprecated for 10 years but not disabled.

这些会影响诸如 trim()、rtrim()、ltrim()、explode()、strchr()、strstr()、substr()、chunk_split()、strtok()、addcslashes()、str_repeat() 等函数. 这在很大程度上(但并非唯一)是由于该语言的调用时传递引用功能已被弃用 10 年但并未被禁用。

Fore more info, see Stefan Esser's talk about interruption vulnerabilities and other lower-level PHP issues at BlackHat USA 2009 SlidesPaper

有关更多信息,请参阅 Stefan Esser 在 BlackHat USA 2009 Slides Paper 上关于中断漏洞和其他低级别 PHP 问题的讨论

This paper/presentation also shows how dl() can be used to execute arbitrary system code.

这篇论文/演示文稿还展示了如何使用 dl() 来执行任意系统代码。

回答by mario

Plattform-specific, but also theoretical exec vectors:

特定于平台的,但也是理论上的执行向量:

  • dotnet_load()
  • new COM("WScript.Shell")
  • new Java("java.lang.Runtime")
  • event_new() - very eventually
  • dotnet_load()
  • new COM("WScript.Shell")
  • new Java("java.lang.Runtime")
  • event_new() - 最终

And there are many more disguising methods:

还有更多的伪装方法:

  • proc_open is an alias for popen
  • call_user_func_array("exE".chr(99), array("/usr/bin/damage", "--all"));
  • file_put_contents("/cgi-bin/nextinvocation.cgi") && chmod(...)
  • PharData::setDefaultStub - some more work to examine code in .phar files
  • runkit_function_rename("exec", "innocent_name") or APD rename_function
  • proc_open 是 popen 的别名
  • call_user_func_array("exE".chr(99), array("/usr/bin/damage", "--all"));
  • file_put_contents("/cgi-bin/nextinvocation.cgi") && chmod(...)
  • PharData::setDefaultStub - 检查 .phar 文件中的代码的更多工作
  • runkit_function_rename("exec", "innocent_name") 或 APD rename_function

回答by NikiC

Apart from the evallanguage construct there is another function which allows arbitrary code execution: assert

除了eval语言结构之外,还有另一个允许任意代码执行的函数:assert

assert('ex' . 'ec("kill --bill")');

回答by mvds

One source of interesting exploits has not been mentioned. PHP allows strings to have 0x00bytes in them. Underlying (libc) functions treat this as the end of a string.

没有提到有趣的漏洞利用的一个来源。PHP 允许字符串中包含0x00字节。底层 (libc) 函数将此视为字符串的结尾。

This allows for situations where (poorly implemented) sanity-checking in PHP can be fooled, e.g. in a situation like:

这允许在 PHP 中(实施不佳)健全性检查可能被愚弄的情况,例如在以下情况下:

/// note: proof of principle code, don't use
$include = $_GET['file'];
if ( preg_match("/\.php$/",$include) ) include($include);

This might include any file - not just those ending in .php- by calling script.php?file=somefile%00.php

这可能包括任何文件 - 不仅仅是那些结尾.php- 通过调用script.php?file=somefile%00.php

So any function that will not obey PHP's string length may lead to some vulnerability.

所以任何不遵守 PHP 字符串长度的函数都可能导致一些漏洞。