array(2) { ["docs"]=> array(10) { [0]=> array(10) { ["id"]=> string(3) "428" ["text"]=> string(77) "Visual Studio 2017 单独启动MSDN帮助(Microsoft Help Viewer)的方法" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(8) "DonetRen" ["tagsname"]=> string(55) "Visual Studio 2017|MSDN帮助|C#程序|.NET|Help Viewer" ["tagsid"]=> string(23) "[401,402,403,"300",404]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400964" ["_id"]=> string(3) "428" } [1]=> array(10) { ["id"]=> string(3) "427" ["text"]=> string(42) "npm -v;报错 cannot find module "wrapp"" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "zzty" ["tagsname"]=> string(50) "node.js|npm|cannot find module "wrapp“|node" ["tagsid"]=> string(19) "[398,"239",399,400]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400760" ["_id"]=> string(3) "427" } [2]=> array(10) { ["id"]=> string(3) "426" ["text"]=> string(54) "说说css中pt、px、em、rem都扮演了什么角色" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(12) "zhengqiaoyin" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400640" ["_id"]=> string(3) "426" } [3]=> array(10) { ["id"]=> string(3) "425" ["text"]=> string(83) "深入学习JS执行--创建执行上下文(变量对象,作用域链,this)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "Ry-yuan" ["tagsname"]=> string(33) "Javascript|Javascript执行过程" ["tagsid"]=> string(13) "["169","191"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511399901" ["_id"]=> string(3) "425" } [4]=> array(10) { ["id"]=> string(3) "424" ["text"]=> string(30) "C# 排序技术研究与对比" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "vveiliang" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(8) ".Net Dev" ["catesid"]=> string(5) "[199]" ["createtime"]=> string(10) "1511399150" ["_id"]=> string(3) "424" } [5]=> array(10) { ["id"]=> string(3) "423" ["text"]=> string(72) "【算法】小白的算法笔记:快速排序算法的编码和优化" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "penghuwan" ["tagsname"]=> string(6) "算法" ["tagsid"]=> string(7) "["344"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511398109" ["_id"]=> string(3) "423" } [6]=> array(10) { ["id"]=> string(3) "422" ["text"]=> string(64) "JavaScript数据可视化编程学习(二)Flotr2,雷达图" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "chengxs" ["tagsname"]=> string(28) "数据可视化|前端学习" ["tagsid"]=> string(9) "[396,397]" ["catesname"]=> string(18) "前端基本知识" ["catesid"]=> string(5) "[198]" ["createtime"]=> string(10) "1511397800" ["_id"]=> string(3) "422" } [7]=> array(10) { ["id"]=> string(3) "421" ["text"]=> string(36) "C#表达式目录树(Expression)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "wwym" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(4) ".NET" ["catesid"]=> string(7) "["119"]" ["createtime"]=> string(10) "1511397474" ["_id"]=> string(3) "421" } [8]=> array(10) { ["id"]=> string(3) "420" ["text"]=> string(47) "数据结构 队列_队列实例:事件处理" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "idreamo" ["tagsname"]=> string(40) "C语言|数据结构|队列|事件处理" ["tagsid"]=> string(23) "["246","247","248",395]" ["catesname"]=> string(12) "数据结构" ["catesid"]=> string(7) "["133"]" ["createtime"]=> string(10) "1511397279" ["_id"]=> string(3) "420" } [9]=> array(10) { ["id"]=> string(3) "419" ["text"]=> string(47) "久等了,博客园官方Android客户端发布" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(3) "cmt" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511396549" ["_id"]=> string(3) "419" } } ["count"]=> int(200) } 222 PHP 变量覆盖漏洞 - 爱码网

参考文章

PHP中的变量覆盖漏洞

简介

变量覆盖----自定义的参数值替换原有变量值的情况称为变量覆盖漏洞

经常导致变量覆盖漏洞场景有:开启了全局变量注册、$$ 使用不当、extract() 函数使用不当、parse_str() 函数使用不当、import_request_variables() 使用不当等。

具体

全局变量注册

  • register_globals

PHP 变量覆盖漏洞

在 PHP5.3 之前,默认开启;PHP5.3 默认关闭,PHP5.6 及 5.7 已经被移除

PHP 变量覆盖漏洞

register_globals 全局变量设置开启时,传递过来的值(POST/GET/Cookie)会被直接注册为全局变量而使用,这会造成全局变量覆盖

小例子:

<?php
if ($_GET["username"] == "1ndex" and $_GET["password"] == "1ndex"){
$authorized = true;
}

if(!$authorized){
echo "Failed";
}
else{
echo "Success";
}
?>

register_globals=Off时,只能通过提交正确的账号密码才可成功登陆,也就是http://127.0.0.1/blfg.php?username=1ndex&password=1ndex

register_globals=On时,可以无需账号密码通过验证,只需要将变量authorized设置为即可,可为http://127.0.0.1/blfg.php?authorized=1或者http://127.0.0.1/blfg.php?GLOBALS[authorized]=1
register_globals=Off时,该方法无效
PHP 变量覆盖漏洞

$$ -- 动态变量覆盖

首先看到这里:

<?php

$a = "test";
$test = "who am i";
echo($$a);
?>

最终输出结果是什么?? -- who am i
$$a 也可以写成 ${$a},解析后就是 $test 也就是最终结果 who am i

看到这样一个题:

<?php
foreach (array('_POST','_GET') as $_request)  
{
    foreach ($$_request as $_key=>$_value)  
    {
        $$_key = $_value;
    }
}
$id = isset($id) ? $id : 2;
if($id == 1) {
    include(./flag);
    die();
}
?>

我们怎么样取得flag?很显然,需要包含 flag 文件
直接 get/post 传参 id=1 即可,当执行 $$_key = $_value; 时,$_key="id"$$_key 等价于 $id,就终结果也就是 $id = 1,定义了 id 参数,并赋值为 1,也就导致了包含flag文件
PHP 变量覆盖漏洞

extract()

extract() 函数从数组中将变量导入到当前的变量表。该函数使用数组键名作为变量名,使用数组键值作为变量值。
小例子:

<?php
$a = array('nickname' => '1ndex');
extract($a);
echo $nickname;
?>
//运行结果为输出 1ndex

extract(array[,flag][,prefix])三个参数:

  • array
    一个关联数组(必需)。此函数会将键名当作变量名,值作为变量的值。 对每个键/值对都会在当前的符号表中建立变量,并受到 flagsprefix 参数的影响。
    必须使用关联数组,数字索引的数组将不会产生结果,除非用了 EXTR_PREFIX_ALL 或者 EXTR_PREFIX_INVALID

  • flags
    对待非法/数字和冲突的键名的方法将根据取出标记 flags 参数决定。可以是以下值之一:

    • EXTR_OVERWRITE
      如果有冲突,覆盖已有的变量。(默认)
    • EXTR_SKIP
      如果有冲突,不覆盖已有的变量。
    • EXTR_PREFIX_SAME
      如果有冲突,在变量名前加上前缀 prefix
    • EXTR_PREFIX_ALL
      给所有变量名加上前缀 prefix。
    • EXTR_PREFIX_INVALID
      仅在非法/数字的变量名前加上前缀 prefix
    • EXTR_IF_EXISTS
      仅在当前符号表中已有同名变量时,覆盖它们的值。其它的都不处理。 举个例子,以下情况非常有用:定义一些有效变量,然后从 $_REQUEST 中仅导入这些已定义的变量。
    • EXTR_PREFIX_IF_EXISTS
      仅在当前符号表中已有同名变量时,建立附加了前缀的变量名,其它的都不处理。
    • EXTR_REFS
      将变量作为引用提取。这有力地表明了导入的变量仍然引用了 array 参数的值。可以单独使用这个标志或者在 flags 中用 OR 与其它任何标志结合使用。
  • prefix
    注意 prefix 仅在 flags 的值是 EXTR_PREFIX_SAME,EXTR_PREFIX_ALL,EXTR_PREFIX_INVALID 或 EXTR_PREFIX_IF_EXISTS 时需要。 如果附加了前缀后的结果不是合法的变量名,将不会导入到符号表中。前缀和数组键名之间会自动加上一个下划线。

flags 参数默认为 EXTR_OVERWRITE,即如果有冲突,覆盖已有的变量

小题目:

<?php
extract($_GET);  
if(isset($mypwd))
{
if($mypwd==$pwd)
{
    include("./flag");
}
}
?>

答案:http://127.0.0.1/blfg.php?pwd=1&mypwd=1

parse_str()

parse_str() 函数把字符串解析成多个变量。其作用就是解析字符串并注册成变量,在注册变量之前不会验证当前变量是否存在,所以直接覆盖掉已有变量
注意:当 magic_quotes_gpc = On,那么在 parse_str() 解析之前,变量会被 addslashes() 转换(也就是会被转义,加反斜线)。

parse_str(string[,array]),两个参数分别为:

  • string
    输入的字符串。如果 strURL 传递入的查询字符串(query string),则将它解析为变量并设置到当前作用域(如果提供了 array 则会设置到该数组里)
    注意,php >= 7.2,如果不设置该参数,该函数将失效

  • array
    一个数组,如果设置该参数, 变量将会以数组元素的形式存入到这个数组,作为替代

小例子:

<?php
$str = "first=value&arr[]=foo+bar&arr[]=baz";

parse_str($str, $output);
echo $output['first'];  // value
echo $output['arr'][0]; // foo bar
echo $output['arr'][1]; // baz
?>

小题目:

<?php
error_reporting(0);
if(
empty($_GET['id'])) {                    
show_source(__FILE__);           
die();                                       
} else {
include (‘./flag.php’);
$a = “https://www.cnblogs.com/wjrblogs/”;
$id = $_GET['id'];
@parse_str($id);
if ($a[0] != ‘QNKCDZO’ && md5($a[0]) == md5(‘QNKCDZO’)) {
echo $flag;
} else {
exit(‘其实很简单其实并不难!’);
}
}
?>

利用 phphash 比较缺陷(PHP 在处理哈希字符串时,会利用!===来对哈希值进行比较,它把每一个以0E开头的哈希值都解释为 0,所以如果两个不同的密码经过哈希以后,其哈希值都是以0E开头的,那么PHP将会认为他们相同,都是 0),所以,只需要找一个字符串哈希后以 OE 开头即可。

最终答案:127.0.0.1/blfg.php?id=a[0]=s878926199a

import_request_variables()

import_request_variables()函数将 GET/POST/Cookie 变量导入到全局作用域中,当禁止了 register_globals,但又想用到一些全局变量,那么此函数就很有用

import_request_variables(string[,prefix]),两个参数分别为:

  • string
    指定导入哪些变量为全局变量,可以用字母 GPC 分别表示导入 GETPOSTCookie 中的变量。这些字母不区分大小写,所以你可以使用 gpc 的任何组合。POST 包含了通过 POST 方法上传的文件信息。注意这些字母的顺序,当使用 gp 时,POST 变量将使用相同的名字覆盖 GET 变量。任何 GPC 以外的字母都将被忽略

  • prefix
    prefix 参数作为变量名的前缀,置于所有被导入到全局作用域的变量之前

小例子:

<?php
$auth='0';
import_request_variables('G');
if($auth== 1){
echo"登陆成功";
}else{
echo"登陆失败";
}
?>

答案:127.0.0.1/blfg.php?auth=1

相关文章: