变量覆盖漏洞
1.extract()变量覆盖
(1)extract()函数能将变量从数组导入当前的符号表,其函数定义如下:
extract(array,extract_rules,prefix)
- array 必需。规定要使用的数组。
- extract_rules 可选。extract() 函数将检查每个键名是否为合法的变量名,同时也检查和符号表中已存在的变量名是否冲突。对不合法和冲突的键名的处理将根据此参数决定。
- 前缀和数组键名之间会自动加上一个下划线。
(2)该函数使用数组键名作为变量名,使用数组键值作为变量值。针对数组中的每个元素,将在当前符号表中创建对应的一个变量。第二个参数 type 用于指定当某个变量已经存在,而数组中又有同名元素时,extract() 函数如何对待这样的冲突。该函数返回成功导入到符号表中的变量数目。
其中,第二个参数指定函数将变量导入符号表是的行为,最常见的两个值是“EXTR_OVERWRITE”和“EXTR_SKIP”。
- EXTR_OVERWRITE - 默认。如果有冲突,则覆盖已有的变量。
- EXTR_SKIP - 如果有冲突,不覆盖已有的变量。
(3)我们来看源代码:
<?php if ($_SERVER["REQUEST_METHOD"] == "POST") { ?>
<?php
extract($_POST);
if ($pass == $thepassword_123) { ?>
<div class="alert alert-success">
<code><?php echo $theflag; ?></code>
</div>
<?php } ?>
<?php } ?>
1.源码分析:
题目要求使用POST提交数据,ectract($_POST)会将数据中的键名和键值转换为变量名和变量值,并且只有当pass和thepassword_123的值相等时,才会输出flag,这个时候我们只需要利用ectract()变量覆盖的bug,将我们自己输入的pass和thepassword_123把原有的值给覆盖掉。
2. payload:pass=521&thepassword_123=521
2.parse_str()变量覆盖
(1)函数定义如下:
parse_str(string,array)
- string 必需。规定要解析的字符串。
- array 可选。规定存储变量的数组的名称。该参数指示变量将被存储到数组中。
(2) parse_str()中如果未设置 array 参数,则由该函数设置的变量将覆盖已存在的同名变量。
下面是我在网上找的源代码:
<?php
error_reporting(0);
if (empty($_GET['id'])) {
show_source(__FILE__);
die();
} 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(‘其实很简单其实并不难!’);
}
}
?>
1.源码分析:
要求我们提交id,然后GET方式获取到参数值,再经过parse_str()函数进行解析,将键名转为变量名,键值转为变量值,然后要输出flag还有一层条件,a[0]的值不能等于QNKCDZO但是要与其经过md5加密之后的值相等,发现QNKCDZO加密之后是以0e开头的,所以只有a[0]的值加密之后能以0e开头,条件就成立,这是利用了md5的一个缺陷
2.payload:
?id=a[0]=s1836677006a
3.import_request_variables()变量覆盖
(1)函数定义如下:
bool import_request_variables ( string $types [, string $prefix ] )
写累了不想多说了,链接在这。。。。
(2)自己搞了段代码,将就着着,因为很菜,只搞了一段重点的。。。能不能运行我也不知道哈(没运行过)
<?php
$a='123';
import_request_variables('G');
if($a==9){
echo "flag:{*******}";
} else {
echo "you are failed";
}
?>
源码分析:
上述代码中,import_request_variables(‘G’)指定导入GET请求中的变量,从而导致变量覆盖
payload:
******/?a=9
差不多了,我累了,就到这吧。。。。
下一篇: Linux基本命令