我试图构建一个可以用于任意代码执行的函数列表。其目的不是列出应该列入黑名单或以其他方式禁止的函数。更确切地说,我希望在搜索受感染的服务器以寻找后门时,有一个易于grep-able的红旗关键字列表。

其思想是,如果您想构建一个多用途的恶意PHP脚本——例如c99或r57这样的“web shell”脚本——您将不得不在文件中的某个位置使用一个或多个相对较小的函数集,以便允许用户执行任意代码。搜索这些函数可以帮助您更快地将数万个PHP文件缩小到需要仔细检查的相对较小的脚本集。

显然,例如,以下任何一种代码都被认为是恶意的(或糟糕的编码):

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

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

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

等等。

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

以下是我目前列出的清单:

Shell执行

系统 执行 popen 撇号操作符 pcntl_exec

PHP执行

eval Preg_replace(带/e修饰符) create_function 包括[_once] /要求[_once](详见mario的回答)

有一个能够修改文件的函数列表可能也很有用,但我想99%的情况下,利用代码将至少包含上述函数之一。但是如果你有一个所有能够编辑或输出文件的函数的列表,把它贴出来,我会把它包括在这里。(我没有计算mysql_execute,因为它是另一类利用的一部分。)


当前回答

我担心我的回答可能有点太消极了,但是……

恕我直言,每一个单独的函数和方法都可以用于邪恶的目的。可以将其视为邪恶的涓滴效应:变量被分配给用户或远程输入,变量被用于函数,函数返回值被用于类属性,类属性被用于文件函数,等等。记住:一个伪造的IP地址或中间人攻击可以利用你的整个网站。

Your best bet is to trace from beginning to end any possible user or remote input, starting with $_SERVER, $_GET, $_POST, $_FILE, $_COOKIE, include(some remote file) (if allow_url_fopen is on), all other functions/classes dealing with remote files, etc. You programatically build a stack-trace profile of each user- or remote-supplied value. This can be done programatically by getting all repeat instances of the assigned variable and functions or methods it's used in, then recursively compiling a list of all occurrences of those functions/methods, and so on. Examine it to ensure it first goes through the proper filtering and validating functions relative to all other functions it touches. This is of course a manual examination, otherwise you'll have a total number of case switches equal to the number of functions and methods in PHP (including user defined).

或者为了只处理用户输入,在所有脚本的开头初始化一个静态控制器类,1)根据允许的目的白名单验证和存储所有用户提供的输入值;2)删除输入源(即$_SERVER = null)。你可以看出这有一点纳粹主义。

其他回答

你必须扫描include($tmp)和require(HTTP_REFERER)以及*_once。如果一个利用脚本可以写入一个临时文件,它可以在以后包含它。基本上是两步计算。

甚至可以隐藏远程代码,比如:

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

此外,如果你的网络服务器已经被入侵,你不会总是看到未编码的邪恶。利用shell通常是gzip编码的。考虑include("zlib:script2.png.gz");这里没有eval,还是一样的效果。

您可以在RIPS /config/sink .php中找到持续更新的敏感接收器(可利用的php函数)及其参数列表,这是一个用于php应用程序漏洞的静态源代码分析器,也可以检测php后门。

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

dotnet_load () 新的COM(“WScript.Shell”) 新的Java(“java.lang.Runtime”) Event_new()—非常最终

而且还有更多的伪装方法:

Proc_open是popen的别名 中的call_user_func_array (exE .chr(99),数组(“/ usr / bin /损害”,“——”)); File_put_contents ("/cgi-bin/ nextinvoke .cgi") && chmod(…) setDefaultStub -检查.phar文件中的代码 runkit_function_rename("exec", "innocent_name")或APD rename_function

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

这允许在某些情况下(糟糕的实现)在PHP中的健康检查可以被愚弄,例如在如下情况下:

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

通过调用script.php?file=somefile%00.php,这可能包括任何文件——不仅仅是以.php结尾的文件

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

有很多PHP漏洞可以通过PHP.ini文件中的设置来禁用。最明显的例子是register_globals,但是根据设置,也可以通过HTTP从远程机器包含或打开文件,如果程序对其include()或文件处理函数使用变量文件名,则可以利用这一点。

PHP还允许通过在变量名后面添加()来调用变量函数——例如$myvariable();将调用变量指定的函数名。这是可利用的;例如,如果攻击者可以让变量包含“eval”这个词,并且可以控制参数,那么他可以做任何他想做的事情,即使程序实际上不包含eval()函数。