CTF之php变量覆盖漏洞

什么是变量覆盖漏洞

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

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


$$导致的变量覆盖问题

1.$$介绍
$$这种写法称为可变变量
一个可变变量获取了一个普通变量的值作为这个可变变量的变量名。

<?php
$a = "hello";
echo "$a";              //输出hello
$a="world";
echo "$a";              //输出hello
echo "$$a";            //输出word
echo "$a ${$a}";    //输出hello world
echo "$a $hello";  //输出hello world
?>

2.漏洞产生
使用foreach来遍历数组中的值,然后再将获取到的数组键名作为变量,数组中的键值作为变量的值。因此就产生了变量覆盖漏洞。
举例

<?php
foreach ($_GET as $key => $value) {
${$key} = $value;
}
echo $a;
?>

get得到的数据$key和$value,关键第3行,${$key}用get传进来的$key做为新的变量,将get传进来的$value赋值给它。
get ?a=1 第3行回解析为$a=1。就造成了变量覆盖。
3.漏洞重现

include “flag.php”;                                                //包含并运行指定文件
$_403 = “Access Denied”;
$_200 = “Welcome Admin”;
if ($_SERVER["REQUEST_METHOD"] != “POST”)      //返回post的值
**die**(“BugsBunnyCTF is here :p…”);
if ( !isset($_POST["flag"]) )              //检查是否设置
**die**($_403);
//echo "$_GET";
foreach ($_GET as $key => $value)
**$$key = $$value;                      //后面分析**
//echo "$key";
//echo "$$key  $_200";
//echo "$value";
//echo "$$value  $flag";
foreach ($_POST as $key => $value)
**$$key = $value;**
**//echo "$key";**
//echo "$$key";
//echo "$value";
if ( $_POST["flag"] !== $flag )
**die**($_403);
else
{
echo “This is your flag : “. $flag . “\n”;
die($_200);
}
**?>**

题目分析
需要满足三个if 才能够输出flag,很明显$flag在flag.php文件里。
两个foreach 都使用了$$ 修改了$flag变量 我们没办法直接通过echo “This is your flag : “. $flag . “\n”;得到flag。所以利用die($_200),在$_200种储存$flag的值,从而得到flag
解题思路
get ?_200=flag post flag=aaaaaaaaaaaaaa
1.)foreach ($_GET as $key => $value) $$key = $$value;
将_200=flag 变为了 $_200=$flag 此时这个$flag=我们想要的flag
2.) foreach ($_POST as $key => $value)
$$key = $value;
将post过去的flag=aaaaaaaaaaa变为$flag=aaaaaaaaaaaaaaaa


flag=b~


extract()函数使用不当

1.extract()函数介绍
extract() 函数从数组中将变量导入到当前的符号表。
该函数使用数组键名作为变量名,使用数组键值作为变量值。针对数组中的每个元素,将在当前符号表中创建对应的一个变量。
该函数返回成功设置的变量数目。
2.语法
extract(array,extract_rules,prefix)
参数 描述
array必需。 规定要使用的数组。
extract_rules可选。 extract() 函数将检查每个键名是否为合法的变量名,同时也检查和符号表中已存在的变量名是否冲突。对不合法和冲突的键名的处理将根据此参数决定。
可能的值:
EXTR_OVERWRITE - 默认。如果有冲突,则覆盖已有的变量。
EXTR_SKIP - 如果有冲突,不覆盖已有的变量。
EXTR_PREFIX_SAME - 如果有冲突,在变量名前加上前缀 prefix。
EXTR_PREFIX_ALL - 给所有变量名加上前缀 prefix。
EXTR_PREFIX_INVALID -仅在不合法或数字变量名前加上前缀 prefix。
EXTR_IF_EXISTS - 仅在当前符号表中已有同名变量时,覆盖它们的值。其它的都不处理。
EXTR_PREFIX_IF_EXISTS - 仅在当前符号表中已有同名变量时,建立附加了前缀的变量名,其它的都不处理。
EXTR_REFS - 将变量作为引用提取。导入的变量仍然引用了数组参数的值。

prefix可选。 如果 extract_rules 参数的值是 EXTR_PREFIX_SAME、EXTR_PREFIX_ALL、 EXTR_PREFIX_INVALID 或 EXTR_PREFIX_IF_EXISTS,则 prefix 是必需的。
该参数规定了前缀。前缀和数组键名之间会自动加上一个下划线。

从以上说明我们可以看到第一个参数是必须的,会不会导致变量覆盖漏洞由第二个参数决定,该函数有三种情况会覆盖已有变量。
举例

<?php
$a = 1;    //原变量值为1
$b = array('a' => '3');
extract($b);    //经过extract()函数对$b处理后
echo $a;    //输出结果为3
?>

3.漏洞重现

"extract($_GET);
if(isset($bdctf))
{
$content=trim(file_get_contents($flag));//file_get_contents—将整个文件读入一个字符串
if($bdctf==$content)                             //trim—去除字符串首尾处的空白字符(或者其他字符)
{ echo'bdctf{**********}'; }
else
{ echo'这不是蓝盾的密码啊'; }
}"

题目分析
题目使用了extract($_GET)接收了GET请求中的数据,并将键名和键值转换为变量名和变量的值,然后再进行两个if 的条件判断,所以可以使用GET提交参数和值,利用extract()对变量进行覆盖,从而满足各个条件。

解题思路
if($bdctf==$content) 输出flag
利用extract($_GET)漏洞,使$bdctf与$content都为空或者不存在就满足 $bdctf==$content
get ?flag=&bdctf= 得到flag


parse_str()函数使用不当

1.parse_str()函数介绍
parse_str() 函数把查询字符串解析到变量中。
注释:如果未设置 array 参数,由该函数设置的变量将覆盖已存在的同名变量。
注释:php.ini 文件中的 magic_quotes_gpc 设置影响该函数的输出。如果已启用,那么在 parse_str() 解析之前,变量会被 addslashes() 转换。
parse_str函数的作用就是解析字符串并注册成变量,在注册变量之前不会验证当前变量是否存在,所以直接覆盖掉已有变量
2.语法
parse_str(string,array)**
参数 描述
string必需。 规定要解析的字符串。
array可选。 规定存储变量的数组名称。该参数指示变量存储到数组中。
举例

<?php
$a = 1;                  //原变量值为1
parse_str('a=2');   //经过parse_str()函数后注册变量$a,重新赋值
print_r($b);          //输出结果为2
?>

漏洞重现

<?php
error_reporting(0);
if(
empty($_GET['id'])) {                    //empty()检查是否为空
show_source(__FILE__);            //highlight_file—语法高亮一个文件
die();                                          //等同于exit—输出一个消息并且退出当前脚本
} else {
include (‘flag.php’);
$a = “www.OPENCTF.com”;
$id = $_GET['id'];
@parse_str($id);
if ($a[0] != ‘QNKCDZO’ && md5($a[0]) == md5(‘QNKCDZO’)) {
echo $flag;
} else {
exit(‘其实很简单其实并不难!’);
}
}
?>

题目分析

**$a[0] != ‘QNKCDZO’ && md5($a[0]) == md5(‘QNKCDZO’)**
**PHP Hash比较存在缺陷**
**md5(‘QNKCDZO’)**的结果是**0e830400451993494058024219903391**

PHP在处理哈希字符串时,会利用”!=”或”==”来对哈希值进行比较,它把每一个以”0E”开头的哈希值都解释为0,所以如果两个不同的密码经过哈希以后,其哈希值都是以”0E”开头的,那么PHP将会认为他们相同,都是0。详细参照 http://www.freebuf.com/news/67007.html
解题思路
md5(s878926199a)=0e545993274517709034328855841020 php解析为0
php处理哈希字符串 http://www.cnblogs.com/Primzahl/p/6018158.html
使用get请求?id=a[0]=s878926199a 得到flag


import_request_variables()使用不当

1.import_request_variables()函数介绍
import_request_variables—将 GET/POST/Cookie 变量导入到全局作用域中
import_request_variables()函数就是把GET、POST、COOKIE的参数注册成变量,用在register_globals被禁止的时候

2.语法
bool import_request_variables(string$types[,string$prefix] )
$type代表要注册的变量,G代表GET,P代表POST,C代表COOKIE,第二个参数为要注册变量的前缀
举例

<?php
$auth='0';
import_request_variables('G');
if($auth== 1){
echo"private!";
}else{
echo"public!";
}
?>

get auth=1时,网页上会输出private!
import_request_variables('G')指定导入GET请求中的变量,从而导致变量覆盖

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容