0x00 前言

最近在干代码审计,于是就把之前学习的CTF题目中有关变量覆盖的题目结合下进一步研究。

通常将可以用自定义的参数值替换原有变量值的情况称为变量覆盖漏洞。经常导致变量覆盖漏洞场景有:$$使用不当,extract()函数使用不当,parse_str()函数使用不当,import_request_variables()使用不当,开启了全局变量注册等。
本篇收集了几个CTF中的题目作为例子,对$$,extract(),parse_str()的问题进行总结。

0x01 $$导致的变量覆盖问题

$$ 导致的变量覆盖问题在CTF代码审计题目中经常在foreach中出现,如以下的示例代码,使用foreach来遍历数组中的值,然后再将获取到的数组键名作为变量,数组中的键值作为变量的值。因此就产生了变量覆盖漏洞。请求?name=test 会将$name的值覆盖,变为test。

  1. 1 <?php
  2. 2 //?name=test
  3. 3
  4. 4 //output:string(4) “name” string(4) “test” string(4) “test” test
  5. 5
  6. 6 $name="thinking";
  7. 7 foreach ($_GET as $key => $value)
  8. 8 {
  9. 9 $$key = $value;
  10. 10 }
  11. 11 var_dump($key);
  12. 12 var_dump($value);
  13. 13 var_dump($$key);
  14. 14 echo "</br>".$name;
  15. 15 ?>

可见$name的值被覆盖掉了

CTF中$$导致的变量覆盖问题的例题1:
题目源码:

  1. 1 <?php
  2. 2 include "flag.php";
  3. 3 $_403 = "Access Denied";
  4. 4 $_200 = "Welcome Admin";
  5. 5 if ($_SERVER["REQUEST_METHOD"] != "POST")
  6. 6 {
  7. 7 die("BugsBunnyCTF is here :p…");
  8. 8 }
  9. 9 if ( !isset($_POST["flag"]) )
  10. 10 {
  11. 11 die($_403);
  12. 12 }
  13. 13 foreach ($_GET as $key => $value)
  14. 14 {
  15. 15 $$key = $$value;
  16. 16 }
  17. 17 foreach ($_POST as $key => $value)
  18. 18 {
  19. 19 $$key = $value;
  20. 20 }
  21. 21 if ( $_POST["flag"] !== $flag )
  22. 22 {
  23. 23 die($_403);
  24. 24 }
  25. 25 echo "This is your flag : ". $flag . "\n";
  26. 26 die($_200);
  27. 27 ?>

题目分析:
源码包含了flag.php文件,并且需要满足3个if里的条件才能获取flag,题目中使用了两个foreach并且也使用了$$.两个foreach中对 $$key的处理是不一样的,满足条件后会将$flag里面的值打印出来,所以$flag是在flag.php文件文件中的。
但是由于第7,11-14行间的代码会将flag的值给覆盖掉了,所以需要先将flag的值给覆盖掉了,所以需要先将flag的值赋给200或200或_403变量,然后利用die(200)或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

0×02 extract()函数导致的变量覆盖问题

extract() 该函数使用数组键名作为变量名,使用数组键值作为变量值。针对数组中的每个元素,将在当前符号表中创建对应的一个变量。
extract()的用法参考:http://www.runoob.com/php/func-array-extract.html
语法: extract(array,extract_rules,prefix)

CTF中extract()导致的变量覆盖问题的例题1:
题目源码:

  1. 1 <?php
  2. 2 $flag = xxx’;
  3. 3 extract($_GET);
  4. 4 if (isset($gift))
  5. 5 {
  6. 6 $content = trim(file_get_contents($flag));
  7. 7 if ($gift == $content)
  8. 8 {
  9. 9 echo hctf{…}’;
  10. 10 }
  11. 11 else
  12. 12 {
  13. 13 echo Oh..’;
  14. 14 }
  15. 15 }
  16. 16 ?>

题目分析:
题目使用了extract($_GET)接收了GET请求中的数据,并将键名和键值转换为变量名和变量的值,然后再进行两个if 的条件判断,所以可以使用GET提交参数和值,利用extract()对变量进行覆盖,从而满足各个条件。
解题方法:
GET请求 ?flag=&gift=,extract()会将flag和flag和gift的值覆盖了,将变量的值设置为空或者不存在的文件就满足gift==gift==content。
最终PAYLOAD:
GET DATA: ?flag=&gift=

CTF中extract()导致的变量覆盖问题的例题2:
题目源码:

  1. 1 <?php
  2. 2 if ($_SERVER["REQUEST_METHOD"] == POST”)
  3. 3 {
  4. 4 extract($_POST);
  5. 5
  6. 6 if ($pass == $thepassword_123)
  7. 7 {
  8. 8 <div class=”alert alert-success”>
  9. 9 <code><?php echo $theflag; ?></code>
  10. 10 </div>
  11. 11 }
  12. 12 }
  13. 13 ?>

题目分析:
题目要求使用POST提交数据,extract($_POST)会将POST的数据中的键名和键值转换为相应的变量名和变量值,利用这个覆盖$pass和$thepassword_123变量的值,从而满足pass==pass==thepassword_123这个条件。
解题方法:
使用POST请求提交pass=&thepassword_123=, 然后extract()会将接收到的数据将$pass和$thepassword_123变量的值覆盖为空,便满足条件了。
最终PAYLOAD:
POST DATA:pass=&thepassword_123=

0×03 parse_str函数导致的变量覆盖问题

parse_str() 函数用于把查询字符串解析到变量中,如果没有array 参数,则由该函数设置的变量将覆盖已存在的同名变量。
语法:parse_str(string,array)

parse_str() 用法参考:http://php.net/parse_str
CTF中parse_str()导致的变量覆盖问题的例题1:
题目源码:

  1. 1 <?php
  2. 2 error_reporting(0);
  3. 3 if (empty($_GET['id']))
  4. 4 {
  5. 5 show_source(__FILE__);
  6. 6 die();
  7. 7 }
  8. 8 else
  9. 9 {
  10. 10 include ('flag.php');
  11. 11 $a = "www.OPENCTF.com";
  12. 12 $id = $_GET['id'];
  13. 13 @parse_str($id);
  14. 14 if ($a[0] != "QNKCDZO" && md5($a[0]) == md5("QNKCDZO"))
  15. 15 {
  16. 16 echo $flag;
  17. 17 }
  18. 18 else
  19. 19 {
  20. 20 exit("其实很简单其实并不难!");
  21. 21 }
  22. 22 }
  23. 23 ?>

题目分析:
首先要求使用GET提交id参数,然后parse_str($id)对id参数的数据进行处理,再使用判断a[0] != ‘QNKCDZO’ && md5(a[0] != ‘QNKCDZO’ && md5(a[0]) == md5(‘QNKCDZO’)的结果是否为真,为真就返回flag,md5(‘QNKCDZO’)的结果是0e830400451993494058024219903391由于此次要满足a[0] != ‘QNKCDZO’ && md5(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

0×04 小总结

变量覆盖漏洞在PHP代码审计中会以比较隐晦的方式存在,所以需要更加仔细的阅读源码找出漏洞的点,在CTF里面经常是以比较直接方式展示,所以可以先通过学习CTF各种变量覆盖的题目,然后掌握后再去审计cms,这样可以更加通透的理解掌握和挖掘变量覆盖漏洞。

CTF中的变量覆盖问题的更多相关文章

  1. CTF中的变量覆盖漏洞

    https://www.cnblogs.com/bmjoker/p/9025351.html 原   作 者:bmjoker出 处:https://www.cnblogs.com/bmjoker/p/ ...

  2. PHP中的变量覆盖漏洞

    简介 今天利用周六整理了一下 php覆盖的漏洞 榆林学院的同学可以使用协会内部实验平台进行实验操作. 1.extract()变量覆盖 1.extract() extract() 函数从数组中将变量导入 ...

  3. CTF——代码审计之变量覆盖漏洞writeup【2】

    题目: 基础: 所需基础知识见变量覆盖漏洞[1]  分析: 现在的$a=’hi’,而下面的函数需满足$a=’jaivy’才可以输出flag,那么需要做的事就是想办法覆盖掉$a原来的值. 那么出现的提示 ...

  4. CTF——代码审计之变量覆盖漏洞writeup【1】

    题目: 所需基础知识: 分析: 思路:由于目的是要拿$flag的值,所以可以得出最终会输出两个变量,而$flag的值在红框那行,被我们自己post的值给覆盖,所以flag值肯定不会在这出来,那么只剩下 ...

  5. 7. 由一道ctf学习变量覆盖漏洞

    0×00 背景 近期在研究学习变量覆盖漏洞的问题,于是就把之前学习的和近期看到的CTF题目中有关变量覆盖的题目结合下进一步研究. 通常将可以用自定义的参数值替换原有变量值的情况称为变量覆盖漏洞.经常导 ...

  6. ctf变量覆盖漏洞:

    1.变量覆盖: ①:针对extract函数的变量覆盖漏洞: <?php @error_reporting(E_ALL^E_NOTICE); require('config.php'); if($ ...

  7. 变量覆盖漏洞学习及在webshell中的运用

    一.发生条件: 函数使用不当($$.extract().parse_str().import_request_variables()等) 开启全局变量 二.基础了解: 1.$$定义 $$代表可变变量, ...

  8. 【技巧总结】Penetration Test Engineer[3]-Web-Security(SQL注入、XXS、代码注入、命令执行、变量覆盖、XSS)

    3.Web安全基础 3.1.HTTP协议 1)TCP/IP协议-HTTP 应用层:HTTP.FTP.TELNET.DNS.POP3 传输层:TCP.UDP 网络层:IP.ICMP.ARP 2)常用方法 ...

  9. Web安全之变量覆盖漏洞

    通常将可以用自定义的参数值替换原有变量值的情况称为变量覆盖漏洞.经常导致变量覆盖漏洞场景有:$$使用不当,extract()函数使用不当,parse_str()函数使用不当,import_reques ...

随机推荐

  1. Spring MVC环境搭建和配置

    1. 创建Dynamic web project 2. 修改WEB-INF/web.xml,内容如下: <?xml version="1.0" encoding=" ...

  2. 在React中使用 react-router-dom 编程式路由导航的正确姿势【含V5.x、V6.x】

    ## react-router-dom 编程式路由导航 (v5) ###### 1.push跳转+携带params参数 ```jsx props.history.push(`/b/child1/${i ...

  3. ACwing895. 最长上升子序列

    题目: 给定一个长度为N的数列,求数值严格单调递增的子序列的长度最长是多少. 输入格式: 第一行包含整数N. 第二行包含N个整数,表示完整序列. 输出格式: 输出一个整数,表示最大长度. 数据范围: ...

  4. layDate设置开始日期选择框和结束日期选择框 之间的相互验证方法

    var startDate = laydate.render({ elem: '#_select_start_date', //结束日期框的ID type: 'date', done: functio ...

  5. ubuntu无法找到ifconfig(command not found: ifconfig)

    演示环境 $ uname -a Linux xxxxx-xxxxx-xxxx5.4.0-47-generic #51-Ubuntu SMP Fri Sep 4 19:50:52 UTC 2020 x8 ...

  6. 【LeetCode】1432. 改变一个整数能得到的最大差值 Max Difference You Can Get From Changing an Integer

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 暴力 日期 题目地址:https://leetcode ...

  7. 【LeetCode】967. Numbers With Same Consecutive Differences 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 DFS 日期 题目地址:https://leetco ...

  8. 【LeetCode】953. Verifying an Alien Dictionary 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...

  9. 【LeetCode】886. Possible Bipartition 解题报告(Python)

    [LeetCode]886. Possible Bipartition 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu ...

  10. 第三十五个知识点:给针对ECDLP问题的Pollard rho,Pollard "Kangaroo",parallel Pollard rho攻击的一个粗略的描述

    第三十五个知识点:给针对ECDLP问题的Pollard rho,Pollard "Kangaroo",parallel Pollard rho攻击的一个粗略的描述 我们的目标是对任 ...