0×00 背景

近期在研究学习变量覆盖漏洞的问题,于是就把之前学习的和近期看到的CTF题目中有关变量覆盖的题目结合下进一步研究。

通常将可以用自定义的参数值替换原有变量值的情况称为变量覆盖漏洞。经常导致变量覆盖漏洞场景有:$$使用不当,extract()函数使用不当,parse_str()函数使用不当,import_request_variables()使用不当,开启了全局变量注册等。

本篇收集了几个CTF中的题目作为例子,对$$,extract(),parse_str()的问题进行总结。

0×01 $$导致的变量覆盖问题

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

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

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

题目源码:

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

题目分析: 

源码包含了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

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

extract() 该函数使用数组键名作为变量名,使用数组键值作为变量值。针对数组中的每个元素,将在当前符号表中创建对应的一个变量。

extract()的用法参考:http://www.runoob.com/php/func-array-extract.html

语法: extract(array,extract_rules,prefix)

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

题目源码:

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

题目分析: 

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

解题方法: 

GET请求 ?flag=&gift=,extract()会将$flag和$gift的值覆盖了,将变量的值设置为空或者不存在的文件就满足$gift == $content。

最终PAYLOAD:

GET DATA: ?flag=&gift=

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

题目源码:

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

题目分析: 

题目要求使用POST提交数据,extract($_POST)会将POST的数据中的键名和键值转换为相应的变量名和变量值,利用这个覆盖$pass$thepassword_123变量的值,从而满足$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. <?php
  2.  
  3. error_reporting(0);
  4.  
  5. if (empty($_GET['id']))
  6. {
  7. show_source(__FILE__);
  8. die();
  9. }
  10. else
  11. {
  12. include (‘flag.php’);
  13. $a = www.OPENCTF.com
  14. $id = $_GET['id'];
  15. @parse_str($id);
  16. if ($a[0] != QNKCDZO && md5($a[0]) == md5(‘QNKCDZO’))
  17. {
  18. echo $flag;
  19. }
  20. else
  21. {
  22. exit(‘其实很简单其实并不难!’);
  23. }
  24.  
  25. }
  26.  
  27. ?>

题目分析: 

首先要求使用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

 

0×04 小总结

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

---恢复内容结束---

7. 由一道ctf学习变量覆盖漏洞的更多相关文章

  1. ctf变量覆盖漏洞:

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

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

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

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

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

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

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

  5. PHP代码审计笔记--变量覆盖漏洞

    变量覆盖指的是用我们自定义的参数值替换程序原有的变量值,一般变量覆盖漏洞需要结合程序的其它功能来实现完整的攻击. 经常导致变量覆盖漏洞场景有:$$,extract()函数,parse_str()函数, ...

  6. php之变量覆盖漏洞讲解

    1.变量没有初始化的问题(1): wooyun连接1:[link href="WooYun: PHPCMS V9 member表内容随意修改漏洞"]tenzy[/link] $up ...

  7. 代码审计-MetInfo CMS变量覆盖漏洞

    0x01 代码分析 安装好后是这样的 漏洞文件地址\include\common.inc.php 首先是在这个文件发现存在变量覆盖的漏洞 foreach(array('_COOKIE', '_POST ...

  8. 2020/2/1 PHP代码审计之变量覆盖漏洞

    0x00 变量覆盖简介 变量覆盖是指变量未被初始化,我们自定义的参数值可以替换程序原有的变量值. 0x01 漏洞危害 通常结合程序的其他漏洞实现完整的攻击,比如文件上传页面,覆盖掉原来白名单的列表,导 ...

  9. PHP变量覆盖漏洞小结

    前言 变量覆盖漏洞是需要我们需要值得注意的一个漏洞,下面就对变量覆盖漏洞进行一个小总结. 变量覆盖概述 变量覆盖指的是可以用我们自定义的参数值替换程序原有的变量值,通常需要结合程序的其他功能来实现完整 ...

随机推荐

  1. 在docker中运行elasticsearch时go程序无法连接到节点

    错误信息: panic: no active connection found: no Elasticsearch node available 在docker中运行es时,默认启动sniffing  ...

  2. (补题 杭电 1008)Elevator

    Elevator Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submi ...

  3. 复数 一级ADT实现

    COMPLEX.h /* typedef struct { float RE; //实部 float IM; //虚部 }Complex; */ typedef struct complex * Co ...

  4. 20155209林虹宇虚拟机的安装及一点Linux的学习

    预备作业3 虚拟机的安装 首先,我先了解了一下Linux和安装虚拟机的有关常识. Linux:Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UNIX的多用户.多任务.支 ...

  5. 20155319 实验二 Java面向对象程序设计

    20155319 实验二 Java面向对象程序设计 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 了解设计模式 (一) ...

  6. 20155325 实验三 敏捷开发与XP实践

    实验三 敏捷开发与XP实践-1 http://www.cnblogs.com/rocedu/p/4795776.html, Eclipse的内容替换成IDEA 在IDEA中使用工具(Code-> ...

  7. 深入解析QML引擎, 第4部分: 自定义解析器

    原文 QML Engine Internals, Part 4: Custom Parsers ——————————————————————————————————————————— 上一篇 绑定类型 ...

  8. async+await 让界面飞,让双手爽

    .net 4.5已经发布很久了,但是一直也没有静下心来好好的研究微软给开发者带来的喜悦. 今天我将简单的介绍下 async + await 这对搭档的出现,如何让频繁假死的界面飞起来(其实只是不再阻塞 ...

  9. ffmpeg 踩坑实录 近期使用总结(三)

    一.背景介绍 将ffmpeg运用到项目上已经有一段时间了,趁现在有空赶紧记下来. 二.技术点总结    2.1 实现方式 项目里面主要运用的形式是,在java端,调用操作系统的方法,并执行切片命令. ...

  10. cookie,session傻傻分不清楚?

    做了这么多年测试,还是分不清什么是cookie,什么是session?很正常,很多初级开发工程师可能到现在都搞不清什么是session,cookie相对来说会简单很多. 下面这篇文章希望能够帮助大家分 ...