CTF——PHP审计——变量覆盖
一,变量覆盖漏洞
参考:https://www.cnblogs.com/xiaozi/p/7768580.html
通常将可以用自定义的参数值替换原有变量值的情况称为变量覆盖漏洞。经常导致变量覆盖漏洞场景有:
1,$$使用不当,
2,extract()函数使用不当,
3,parse_str()函数使用不当,
4,import_request_variables()使用不当,
5,开启了全局变量注册等。
1,$$使用不当
$key='text'; $$key =200 的意思是 将 $key 的值作为变量 并赋值为 200
$$ 导致的变量覆盖问题在CTF代码审计题目中经常在foreach中出现,如以下的示例代码,使用foreach来遍历数组中的值,然后再将获取到的数组键名作为变量,数组中的键值作为变量的值。因此就产生了变量覆盖漏洞。请求?name=test 会将$name的值覆盖,变为test。
<?php$name=’thinking’;foreach ($_GET as $key => $value)$$key = $value;var_dump($key);var_dump($value);var_dump($$key);echo $name;?>
//?name=test
//output:string(4) “name” string(4) “test” string(4) “test” test
例题一:
<?phpinclude “flag.php”;$_403 = “Access Denied”;$_200 = “Welcome Admin”;if ($_SERVER["REQUEST_METHOD"] != “POST”)die(“BugsBunnyCTF is here :p…”);if ( !isset($_POST["flag"]) )die($_403);foreach ($_GET as $key => $value)$$key = $$value;
foreach ($_POST as $key => $value)$$key = $value;if ( $_POST["flag"] !== $flag )die($_403);15.echo “This is your flag : “. $flag . “\n”;16.die($_200);17.?>
题目分析:
源码包含了flag.php文件,并且需要满足3个if里的条件才能获取flag,题目中使用了两个foreach并且也使用了$$.两个foreach中对 $$key的处理是不一样的,满足条件后会将$flag里面的值打印出来,所以$flag是在flag.php文件文件中的。
但是由于第7,11-14行间的代码会将$flag的值给覆盖掉了,所以需要先将$flag的值赋给$_200或$_403变量,然后利用die($_200)或 die($_403)将flag打印出来。
解题方法:
由于第7,11-14行间的代码会将$flag的值给覆盖掉,所以只能利用第一个foreach先将$flag的值赋给$_200,然后利用die($_200)将原本的flag值打印出来。
最终PAYLOAD:
本地复现,所以flag与原题不一样
GET DATA:?_200=flag
POST DATA:flag=aaaaaaaaaaaaaaaaaaaaa
2,extract()函数使用不当
extract(array,extract_rules,prefix)
定义和用法
extract() 函数从数组中将变量导入到当前的符号表。
该函数使用数组键名作为变量名,使用数组键值作为变量值。针对数组中的每个元素,将在当前符号表中创建对应的一个变量。
第二个参数 type 用于指定当某个变量已经存在,而数组中又有同名元素时,extract() 函数如何对待这样的冲突。
该函数返回成功导入到符号表中的变量数目。
<?php
$a = "Original";
$my_array = array("a" => "Cat","b" => "Dog", "c" => "Horse");
extract($my_array);
echo "\$a = $a; \$b = $b; \$c = $c";
?>
$a = Cat; $b = Dog; $c = Horse
例题一:
<?php
$flag='xxx';
extract($_GET); if(isset($shiyan)) { $content=trim(file_get_contents($flag)); if($shiyan==$content) { echo'flag{xxx}'; }else { echo'Oh.no'; }
}
?>
题目分析:URL 通过 get 的方式传参,传输的数据以数组的形式被封装在$_GET 中;extract()函数从数组中将变量导入到当前的符号表,该函数使用数组键名作为变量名,使用数组键值作为变量值;isset()函数判断是否存在变量$shiyan
;trim()函数移除字符串两侧的空白字符或其他预定义字符 ,这里是移除字符串两侧的空格;file_get_contents()函数将整个文件读入一个字符串;假如$shiyan
的值等于文件的内容($content
)时,就打印出flag
同时传入 shiyan 和 flag 了使 读取文件错误 就会试 $content 的值为 布尔的0
?shiyan=&flag=
例题二:
<?php if ($_SERVER["REQUEST_METHOD"] == “POST”) { ?><?phpextract($_POST);if ($pass == $thepassword_123) { ?><div class=”alert alert-success”><code><?php echo $theflag; ?></code></div><?php } ?><?php } ?>
题目分析:
题目要求使用POST提交数据,extract($_POST)会将POST的数据中的键名和键值转换为相应的变量名和变量值,利用这个覆盖$pass和$thepassword_123变量的值,从而满足$pass == $thepassword_123这个条件。
解题方法:
使用POST请求提交pass=&thepassword_123=, 然后extract()会将接收到的数据将$pass和$thepassword_123变量的值覆盖为空,便满足条件了。
最终PAYLOAD:
POST DATA:pass=&thepassword_123=
3,parse_str()函数使用不当
parse_str() 函数把查询字符串解析到变量中。
注释:如果未设置 array 参数,则由该函数设置的变量将覆盖已存在的同名变量。
parse_str(string,array)
参数 | 描述 |
---|---|
string | 必需。规定要解析的字符串。 |
array | 可选。规定存储变量的数组的名称。该参数指示变量将被存储到数组中。 |
<!DOCTYPE html>
<html>
<body><?php
parse_str("name=Bill&age=60",$myArray);
print_r($myArray);
?></body>
</html>
Array ( [name] => Bill [age] => 60 )
例题一:
<?phperror_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(‘其实很简单其实并不难!’);}}?>
题目分析:
首先要求使用GET提交id参数,然后parse_str($id)对id参数的数据进行处理,再使用判断$a[0] != ‘QNKCDZO’ && md5($a[0]) == md5(‘QNKCDZO’)的结果是否为真,为真就返回flag,md5(‘QNKCDZO’)的结果是0e830400451993494058024219903391由于此次要满足$a[0] != ‘QNKCDZO’ && md5($a[0]) == md5(‘QNKCDZO’)所以要利用php弱语言特性,0e123会被当做科学计数法,0 * 10 x 123。所以需要找到一个字符串md5后的结果是0e开头后面都是数字的,如,240610708,s878926199a
PHP处理0e开头md5哈希字符串缺陷/bug 参考:http://www.cnblogs.com/Primzahl/p/6018158.html
解题方法:
使用GET请求id=a[0]=240610708,这样会将a[0]的值覆盖为240610708,然后经过md5后得到0e462097431906509019562988736854与md5(‘QNKCDZO’)的结果0e830400451993494058024219903391比较都是0 所以相等,满足条件,得打flag。
最终PAYLOAD:
GET DATA:
?id=a[0]=s878926199a
or
?id=a[0]=240610708
4,import_request_variables()使用不当
import_request_variables() 函数将 get/post/cookie 变量导入到全局作用域中。该函数在最新版本的 php 中已经不支持
import_request_variables() 函数将 get/post/cookie 变量导入到全局作用域中。如果你禁止了 register_globals,但又想用到一些全局变量,那么此函数就很有用。
bool import_request_variables ( string $types [, string $prefix ] )
$types:指定需要导入的变量,可以〖can〗用字母 g、p 和 c 分别表示 get、post 和 cookie,这些字母不区分大小写,所以你可以〖can〗使用 g 、 p 和 c 的任何组合。post 包含了通过 post 方法上传的文件信息。注意这些字母的顺序,当使用 gp 时,post 变量将使用相同的名字覆盖 get 变量。任何 gpc 以外的字母都将被忽略。
$prefix: 变量名的前缀,置于所有〖all〗被导入到全局作用域的变量之前。所以如果你有个名为 userid 的 get 变量,同时提供了 pref_ 作为前缀,那么你将获得一个名为 $pref_userid 的全局变量。虽然 prefix 参数是可选的,但如果不指定前缀,或者指定一个空字符串作为前缀,你将获得一个 e_notice 级别的错误。
例题一:
<?php
$auth='0';
import_request_variables('G');
if($auth== 1){
echo"private!";
}else{
echo"public!";
}
?>
get auth=1时,网页上会输出private!
例题二:
<?php
$yml = "happy";
echo "out0:".$yml;
echo "<br>";
import_request_variables('P');
echo "out1:".$yml;
?>
5,全局变量注册开关问题
register_globals的意思就是注册为全局变量,所以当On的时候,传递过来的值会被直接的注册为全局变量直接使用,而Off的时候,我们需要到特定的数组里去得到它。
代码示例1:
<?php
//?id=1
echo "Register_globals: ".(int)ini_get("register_globals")."<br/>";
echo '$_GET["id"] :'.$_GET['id']."<br/>";
echo '$id :'.$id;
?>
当register_globals=Off的时候,下一个程序接收的时候应该用$_GET['id']来接受传递过来的值;
当register_globals=On的时候,下一个程序可以直接使用$id来接受值,也可以用$_GET['id']来接受传递过来的值。
tips:如果上面的代码中,已经对变量$id赋了初始值,比如$id=0,那么即使在URL中有/test.php?id=1,也不会将变量覆盖,id值为0
代码示例2:
<?php
echo "Register_globals: ".(int)ini_get("register_globals")."<br/>";
if (ini_get('register_globals'))
foreach($_REQUEST as $k=>$v) unset(${$k});
print $a."<br/>";
print $_GET[b];
?>
在register_globals=ON时,
提交/test.php?a=1&b=2 , 变量$a未初始化,$_GET[b]=2
提交/test.php??GLOBALS[a]=1&b=2,$a=1,$_GET[b]=2
tips: 从 PHP » 4.2.0 版开始配置文件中 PHP 指令 register_globals 的默认值从 on 改为 off 了,自 PHP 5.3.0 起废弃并将自 PHP 5.4.0 起移除。
CTF——PHP审计——变量覆盖相关推荐
- PHP-代码审计-变量覆盖
当你的才华 还撑不起你的野心时 那你就应该静下心来学习 代码审计学习线上实验,都是CE一边实操,一边整理的笔记,方便以后翻看时,可快速查阅. 目录 变量覆盖漏洞 一.简介 • extract()函数 ...
- php之变量覆盖漏洞讲解,PHP中的变量覆盖漏洞代码深入解析
2.CTF中extract()导致的变量覆盖 我们大致分析是要求我们GET传参进去值会经过extract()函数下来会有两个if 第一个if判断 ceshi这个变量是否存在 存在则继续执行if里面的 ...
- jmeter file upload 变量_通达OA上传漏洞之变量覆盖分析
作者:kw0ng 开始 通达OA上传到包含漏洞分析的文章已经有很多,本文重点分析,文件上传处决定路径信息是否回显的UPLOAD_MODE参数是怎么传递的. 代码分析 触发文件上传点位于/ispirit ...
- html 怎么让tr的css覆盖td的_通达OA上传漏洞之变量覆盖分析
作者:kw0ng 开始 通达OA上传到包含漏洞分析的文章已经有很多,本文重点分析,文件上传处决定路径信息是否回显的UPLOAD_MODE参数是怎么传递的. 代码分析 触发文件上传点位于/ispirit ...
- 浅显易懂 Makefile 入门 (02)— 普通变量和自动变量定义、使用($@、$^、$< 作用)、变量覆盖 override、变量的来源 origin
1. 变量的定义 Makefile 文件中定义变量的基本语法如下: 变量的名称=值列表 变量的名称可以由大小写字母.阿拉伯数字和下划线构成.等号左右的空白符没有明确的要求,因为在执行 make 的时候 ...
- filter执行先后问题_Thinkphp5框架变量覆盖导致远程代码执行
Thinkphp5.0.x框架对输入数据过滤不严,导致Request类成员存在变量覆盖问题,在一定情况下能导致远程代码执行漏洞. 介绍 Thinkphp框架官方提供核心版和完整版两种: 核心版因默认缺 ...
- php extract 变量覆盖,extract变量覆盖
Bugkuctf题库中的一道代码审计题,通过巧妙利用file_get_contents函数特性来绕过extract变量覆盖 源代码如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 1 ...
- csrf漏洞防御方案_变量覆盖漏洞利用及防御方案
一.漏洞简介 变量覆盖漏洞是指攻击者使用自定义的变量去覆盖源代码中的变量,从而改变代码逻辑,实现攻击目的的一种漏洞.通常来说,单独的变量覆盖漏洞很难有利用价值,但是在与其他应用代码或漏洞结合后,其造成 ...
- php之变量覆盖漏洞讲解
1.变量没有初始化的问题(1): wooyun连接1:[link href="WooYun: PHPCMS V9 member表内容随意修改漏洞"]tenzy[/link] $up ...
最新文章
- 浅析ASP.NET应用ViewState技术
- 函数-函数进阶-装饰器流程分析
- 从青铜到王者的路线,java枚举类使用场景
- portainer容器可视化管理部署简要笔记
- Ubuntu安装JDK教程
- 网吧服务器常用设置维护工具,某某网吧专用维护工具
- 【脱壳-寻找OEP】通过堆栈平衡法找到OEP(ESP定律)
- 四步实现Grub4DOS引导img文件打造启动U盘
- phpstudy php redis,phpstudy拓展redis
- Apache和Apache Tomcat的区别是什么?
- 手机邮箱无法显示加密邮件_电子邮件可能无法加密
- linux spec cpu,SPEC CPU2006的安装和使用
- 根文件系统(rootfs)理解
- 平安科技美国研究院院长韩玫:AI赋能传统行业,要知其然也知其所以然
- App Inventor 2能编译出苹果iOS版App吗?
- java的幂等性处理
- 北京华联BHG Mall持续发力,BHG DAY引领城市消费新热潮
- stegano(图片隐写、摩斯密码)
- 微信小程序商品展示页面(仿咸鱼)
- 内网中设备通过一台主机做端口转发联通外网( TPLink路由映射,端口转发,windows自带端口转发netsh interface portproxy)
热门文章
- android 简单的音乐播放器实现播放模式的切换
- 在PPT的时候,发现用Python十几行代码就可以实现Logo换色
- linux配置usb主从_一种Linux下USB设备主从切换的实现
- 博士申请 | 佐治亚理工学院陈永昕教授招收机器学习理论方向博士生
- CVPR 2021 | 从理论和实验角度深入剖析对比损失中的温度超参数
- 最新综述 | 强化学习中从仿真器到现实环境的迁移
- 【天池赛事】零基础入门语义分割-地表建筑物识别 Task2:数据扩增方法
- POJ1703 Find them, Catch them 并查集
- 接口本地正常服务器报500_运维该如何解决服务器底层维护难题?
- python数字转汉字-Python转换数字到中文大写格式