首页 文章

可利用的PHP功能

提问于
浏览
277

我列出了应列入黑名单或不允许的功能 . 相反,我希望在搜索受感染的后台服务器时,有一个 grep -可用的红旗关键字列表 .

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

显然,例如,以下任何一种都被视为恶意(或可怕的编码):

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

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

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

等等 .

前几天通过一个被入侵的网站搜索,我没有意识到 preg_replace 可能因使用 /e 标志而变得危险(严重的是,为什么即使那样?) . 还有其他我错过的吗?

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

Shell Execute

  • system

  • exec

  • popen

  • backtick operator

  • pcntl_exec

PHP Execute

  • eval

  • preg_replace (带 /e 修饰符)

  • create_function

  • include [ _once ] / require [ _once ](有关漏洞利用详情,请参阅mario的回答)

拥有一个能够修改文件的函数列表可能也很有用,但我想99%的时间漏洞利用代码将包含至少一个上述函数 . 但是如果你有一个能够编辑或输出文件的所有函数的列表,那么发布它并且我不计算 mysql_execute ,因为这是另一类漏洞利用的一部分 . )

23 回答

  • 14

    我特别想在这个列表中添加unserialize() . 它有各种各样的漏洞,包括任意代码执行,拒绝服务和内存信息泄漏 . 永远不应该在用户提供的数据上调用它 . 许多这些vuls在最近的露水年份已被修复,但在目前的写作时间仍然保留了几个讨厌的vuls .

    有关狡猾的PHP函数/用法的其他信息,请查看Hardened PHP Project及其建议 . 最近的Month of PHP Security和2007年的Month of PHP Bugs项目

    还要注意,通过设计,反序列化对象将导致构造函数和析构函数执行;另一个原因是不在用户提供的数据上调用它 .

  • 5

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

    PHP还允许通过在变量名的末尾添加()来调用变量函数 - 例如 $myvariable(); 将调用变量指定的函数名 . 这是可以利用的;例如,如果攻击者可以获取变量以包含单词'eval',并且可以控制参数,那么即使程序实际上不包含eval()函数,他也可以执行任何他想要的操作 .

  • 5

    为了构建这个列表,我使用了两个来源 . A Study In ScarletRATS . 我也添加了一些我自己的混合,这个线程上的人已经帮了忙 .

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

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

    "With great power comes great responsibility."

    • 李斯坦

    命令执行

    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 可用于以Local File IncludeRemote File Include漏洞的形式执行远程代码 .

    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所有filesystem functions在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
    
  • 59

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

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

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

    此外,如果您的网络服务器已被盗用,您将不会总是看到未编码的邪恶 . 漏洞利用shell通常是gzip编码的 . 想想 include("zlib:script2.png.gz"); 这里没有评价,效果仍然相同 .

  • 9

    这本身不是答案,但这里有一些有趣的东西:

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

    本着同样的精神, call_user_func_array() 可用于执行混淆函数 .

  • 19

    我很惊讶没有人提到 echoprint 作为安全漏洞 .

    Cross-Site Scripting (XSS)是一个严重的安全漏洞,因为它比服务器端代码执行漏洞更常见 .

  • 17

    我的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有足够的潜在可破坏功能,你的列表可能太大而无法访问 . 例如,PHP具有chmod和chown,可用于简单地停用网站 .

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

  • 15

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

    这些影响函数,如trim(),rtrim(),ltrim(),explode(),strchr(),strstr(),substr(),chunk_split(),strtok(),addcslashes(),str_repeat()等等 . 这主要是(但不是唯一的)由于该语言的调用时间传递引用功能已被弃用了10年但未被禁用 .

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

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

  • 205

    Plattform特定的,但也是理论exec向量:

    • dotnet_load()

    • 新COM("WScript.Shell")

    • 新Java("java.lang.Runtime")

    • event_new() - 最终

    还有更多的伪装方法:

    • 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

  • 5

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

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

    尚未提及有趣漏洞的一个来源 . PHP允许字符串中包含 0x00 个字节 . 底层(libc)函数将此视为字符串的结尾 .

    这允许PHP中的(执行不良)健全性检查被欺骗的情况,例如,在这种情况下:

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

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

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

  • 48

    危险的句法元素呢?

    variable variable”( $$var )将在当前范围内找到名为$ var的变量 . 如果使用错误,远程用户可以修改或读取当前范围中的任何变量 . 基本上是一个较弱的 eval .

    例如:您编写了一些代码 $$uservar = 1; ,然后远程用户将 $uservar 设置为"admin",导致 $admin 在当前范围内设置为 1 .

  • 13

    我想你将无法通过解析源文件找到所有可能的漏洞 .

    • 如果这里提供了很好的列表,你可以错过一个可以被利用的功能

    • 仍然可能存在这样的“隐藏”邪恶代码

    $ myEvilRegex = base64_decode('Ly4qL2U ='); preg_replace($ myEvilRegex,$ _POST ['code']);

    • 你现在可以说,我只是扩展我的脚本也匹配这个

    • 然后你会有那可能是“可能是邪恶的代码”,这也是它的背景

    • 所以要(伪)安全,你自己应该 write good coderead all existing code

  • 4

    反引号运算符Backtick on php manual

  • 6

    我知道 move_uploaded_file 已被提及,但文件上传一般非常危险 . 只是 $_FILES 的存在应引起一些关注 .

    将PHP代码嵌入到任何类型的文件中都是非常有可能的 . 图像可能特别容易受到文本注释的影响 . 如果代码按原样接受 $_FILES 数据中找到的扩展名,则问题尤其麻烦 .

    例如,用户可以将嵌入了PHP代码的有效PNG文件上传为“foo.php” . 如果脚本特别天真,它实际上可能将文件复制为“/uploads/foo.php” . 如果服务器配置为允许在用户上载目录中执行脚本(通常是这种情况,以及可怕的疏忽),那么您可以立即运行任意PHP代码 . (即使图像保存为.png,也可能通过其他安全漏洞获取代码 . )

    A(非详尽)要上传的内容列表:

    • 确保分析内容以确保上传是它声称的类型

    • 使用不会执行的已知安全文件扩展名保存文件

    • 确保在用户上载目录中禁用PHP(以及任何其他代码执行)

  • 20

    让我们将 pcntl_signalpcntl_alarm 添加到列表中 .

    借助这些函数,您可以解决在php.ini或脚本中创建的任何set_time_limit限制 .

    例如,该脚本将运行10秒,尽管 set_time_limit(1);

    (归功于Sebastian Bergmanns tweetgist

    <?php
    declare(ticks = 1);
    
    set_time_limit(1);
    
    function foo() {
        for (;;) {}
    }
    
    class Invoker_TimeoutException extends RuntimeException {}
    
    class Invoker
    {
        public function invoke($callable, $timeout)
        {
            pcntl_signal(SIGALRM, function() { throw new Invoker_TimeoutException; }, TRUE);
            pcntl_alarm($timeout);
            call_user_func($callable);
        }
    }
    
    try {
        $invoker = new Invoker;
        $invoker->invoke('foo', 1);
    } catch (Exception $e) {
        sleep(10);
        echo "Still running despite of the timelimit";
    }
    
  • 2

    这些功能也可能有一些令人讨厌的影响 .

    • str_repeat()

    • unserialize()

    • register_tick_function()

    • register_shutdown_function()

    前两个可以耗尽所有可用的内存,后者可以耗尽...

  • 10

    最近在security.stackexchange.com上对此进行了一些讨论

    可用于任意代码执行的函数

    好吧,这缩小了范围 - 但由于'print'可以用于注入javascript(因此窃取会话等),它仍然有点武断 .

    不列出应列入黑名单或不允许的功能 . 相反,我想要一个grep-able列表

    这是一种明智的做法 .

    考虑编写自己的解析器 - 很快你会发现基于grep的方法失控(awk会好一点) . 很快你也会开始希望你也实现了白名单!

    除了显而易见的,我建议标记任何包含除了字符串文字以外的任何参数的东西 . 注意__autoload() .

  • 2

    我担心我的回答可能有点过于消极,但......

    恕我直言,那里的每一个功能和方法都可以用于恶意目的 . 可以把它想象成邪恶的涓滴效应:变量被分配给用户或远程输入,变量用于函数,函数返回值用于类属性,类属性用于文件函数,等等 . 请记住:伪造的IP地址或中间人攻击可以利用您的整个网站 .

    最好的办法是从开始跟踪到结束的任何可能的用户或远程输入,从 $_SERVER$_GET$_POST$_FILE$_COOKIEinclude(some remote file) (如果 allow_url_fopen 是),所有其他功能/类处理远程文件,等你以编程方式构建每个用户或远程提供的值的堆栈跟踪配置文件 . 这可以通过获取所分配的变量的所有重复实例以及函数或方法来以编程方式完成,它使 case 开关的总数等于PHP中的函数和方法的数量(包括用户定义的) .

    或者仅用于处理用户输入,在所有脚本的开头初始化一个静态控制器类,1)验证并将所有用户提供的输入值存储在允许目的的白名单中; 2)擦除输入源(即 $_SERVER = null ) . 你可以看到这里有一点Naziesque .

  • 1

    以下是我的提供程序为安全目的禁用的函数列表:

    • exec

    • dl

    • show_source

    • apache_note

    • apache_setenv

    • closelog

    • debugger_off

    • debugger_on

    • define_syslog_variables

    • escapeshellarg

    • escapeshellcmd

    • ini_restore

    • openlog

    • passthru

    • pclose

    • pcntl_exec

    • popen

    • proc_close

    • proc_get_status

    • proc_nice

    • proc_open

    • proc_terminate

    • shell_exec

    • syslog

    • 系统

    • url_exec

  • 1

    代码中的大多数攻击都使用多个访问源,或者自己执行多个步骤 . 我不仅会搜索代码或具有恶意代码的方法,还会搜索所有方法,执行或调用它 . 最好的安全性还包括在进出时对表单数据进行编码和验证 .

    还要注意定义系统变量,然后可以从代码中的任何函数或方法调用它们 .

  • 0

    使用解释文本的4位字符函数发现了几个缓冲区溢出 . ヶ辆()用htmlspecialchars()

    在顶部,一个很好的防御是使用mb_convert_encoding()在解释之前转换为单个编码 .

  • 0

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

相关问题