admin

Bugku-----------------代码审计
Bugku 代码审计1. extract变量覆盖<?php $flag='xxx'; ext...
扫描右侧二维码阅读全文
21
2019/03

Bugku-----------------代码审计

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函数,将数组中的的键当作变量名 值为变量的内容,同时检查变量是否有冲突,在默认的参数下,如果变量冲突则会覆盖原变量

再看下file_get_contents函数

同时可以读取url的HTML源码

定义shiyan变量和覆盖flag变量使得$cotent == $shiyan

index.php?shiyan&flag=

2. strcmp比较字符串

<?php
    $flag = "flag{xxxxx}";
    if (isset($_GET['a'])) {
    if (strcmp($_GET['a'], $flag) == 0)
    die('Flag: '.$flag);
    else
    print 'No';
    }
?>

看下strcmp的官方说明

Note a difference between 5.2 and 5.3 versions
echo (int)strcmp('pending',array());
will output -1 in PHP 5.2.16 (probably in all versions prior 5.3)
but will output 0 in PHP 5.3.3
Of course, you never need to use array as a parameter in string comparisions.

在php 5.2版本之前,利用strcmp函数将数组与字符串进行比较会返回-1,但是从5.3开始,会返回0

只要传入一个数组即可绕过
index.php?a[]=1

3. 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是不区分大小写的正则表达式匹配,上面代码第一步需要传入的id参数不可等于hackerDJ接下来对id进行url解码 再次与字符串hackerDJ进行比较 成功则输出flag

在向服务器发送http请求时会先进行一次url编码,服务器接收到请求后再进行一次url解码
这里只要将hackerDJ进行两次url编码即可%68%61%63%6b%65%72%44%4a

4. 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无法处理数组,在传入数组时会返回NULL 如此只需要传入usernamepassword都为数组,且传入的值不同即可绕过

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';
}
?>

eregstrpos函数中如果参数为数组则返回NULL并产生warning警告,又因为NULL===FALSE为False即两者并不相等

6. 弱类型整数大小比较绕过

$temp = $_GET['password'];
is_numeric($temp)?die("no numeric"):NULL;
if($temp>1336){
echo $flag;

这里有两种解法:
1 . 在php中两种数据类型不同的变量比较时有不同结果 具体看PHP手册 http://php.net/manual/zh/language.operators.comparison.php

所以我们这里只要传入一个数组即可

2 . 利用is_numeric函数的缺陷
is_numeric检测变量是否为数字或数字字符 同时接受16进制、科学计数法、双精度浮点小数
不过is_numeric对于空字符%00,无论是%00放在前后都可以判断为非数值,而%20空格字符只能放在数值后。所以,查看函数发现该函数对对于第一个空格字符会跳过空格字符判断,接着后面的判断

payload: 22.php?password=123452%001

7. sha()函数比较绕过

<?php
$flag = "flag";
if (isset($_GET['name']) and isset($_GET['password']))
{
var_dump($_GET['name']);
echo "
";
var_dump($_GET['password']);
var_dump(sha1($_GET['name']));
var_dump(sha1($_GET['password']));
if ($_GET['name'] == $_GET['password'])
echo '

Your password can not be your name!

';
else if (sha1($_GET['name']) === sha1($_GET['password']))
die('Flag: '.$flag);
else
echo '
Invalid password.

';
}
else
echo '
Login first!

';
?>

sha1()在加密数组时会返回NULL 所以只要传入两个不同的数组即可满足要求

payLoad:http://123.206.87.240:9009/7.php?name[]=1&password[]=2

8. md5加密相等绕过

<?php
$md51 = md5('QNKCDZO');
$a = @$_GET['a'];
$md52 = @md5($a);
if(isset($a)){
    if ($a != 'QNKCDZO' && $md51 == $md52) 
    { echo "flag{*}";} 
    else { 
    echo "false!!!";}}else{echo "please input a";
    }
?>

PHP在处理哈希字符串时,会利用”!=”或”==”来对哈希值进行比较,它把每一个以”0E”开头的哈希值都解释为0,所以如果两个不同的密码经过哈希以后,其哈希值都是以”0E”开头的,那么PHP将会认为他们相同,都是0

所以只要提交一个字符串的MD5值是以0e开头的即可,这里选择s878926199a md5值:0e545993274517709034328855841020

9. 十六进制与数字比较

<?php
error_reporting(0);
function noother_says_correct($temp) {
    $flag = 'flag{test}';
    $one = ord('1'); //ord — 返回字符的 ASCII 码值
    $nine = ord('9'); //ord — 返回字符的 ASCII 码值
    $number = '3735929054'; // Check all the input characters!
    for ($i = 0;$i < strlen($number);$i++) { // Disallow all the digits!
        $digit = ord($temp{$i});
        if (($digit >= $one) && ($digit <= $nine)) {
            return "flase";
        }
    }
    if ($number == $temp) return $flag;
}
$temp = $_GET['password'];
echo noother_says_correct($temp);
?>

题目要求传入的参数和$number相等即$temp =3735929054 并且满足$temp中的每个字符串都要在1-9之内,php在字符串的比较时会自行将16进制转码为10进制 所以这里只要传入3735929054的16进制即可

10 ereg正则%00截断

<?php
$flag = "xxx";
if (isset ($_GET['password']))
{
if (ereg ("^[a-zA-Z0-9]+$", $_GET['password']) === FALSE)
{
echo '

You password must be alphanumeric

';
}
else if (strlen($_GET['password']) < 8 && $_GET['password'] > 9999999)
{
if (strpos ($_GET['password'], '-') !== FALSE) //strpos — 查找字符串首次出现的位置
{
die('Flag: ' . $flag);
}
else
{
echo('
- have not been found

');
}
}
else
{
echo '
Invalid password

';
}
}
?>

ereg读到%00的时候,就截止了所以这里只要传入的参数满足
1.长度小于8
2.数值大于9999999
3.参数中含有*-*
前两个条件可以通过科学计数法满足要求
payload:1e9%00*-*

11 strops 数组绕过

<?php
$flag = "flag";
if (isset ($_GET['ctf'])) {
if (@ereg ("^[1-9]+$", $_GET['ctf']) === FALSE)
echo '必须输入数字才行';
else if (strpos ($_GET['ctf'], '#biubiubiu') !== FALSE)
die('Flag: '.$flag);
else
echo '骚年,继续努力吧啊~';
}

先判断了传入的参数必须为1-9之间的数字然后判断字符#biubiubiu是否存在
ereg和strpos在处理数组会返回NULL
所以传入:ctf[]=1
或者使用%00截断:ctf=111%00%23biubiubiu

数字验证正则绕过

<?php
error_reporting(0);
$flag = 'flag{test}';
if ("POST" == $_SERVER['REQUEST_METHOD'])
{
$password = $_POST['password'];
if (0 >= preg_match('/^[[:graph:]]{12,}$/', $password)) //preg_match — 执行一个正则表达式匹配 
{
echo 'flag';
exit;
}
while (TRUE)
{
$reg = '/([[:punct:]]+|[[:digit:]]+|[[:upper:]]+|[[:lower:]]+)/';
if (6 > preg_match_all($reg, $password, $arr))
break;
$c = 0;
$ps = array('punct', 'digit', 'upper', 'lower'); //[[:punct:]] 任何标点符号 [[:digit:]] 任何数字 [[:upper:]] 任何大写字母 [[:lower:]] 任何小写字母
foreach ($ps as $pt)
{
if (preg_match("/[[:$pt:]]+/", $password))
$c += 1;
}
if ($c < 3) break;
//>=3,必须包含四种类型三种与三种以上
if ("42" == $password) echo $flag;
else echo 'Wrong password';
exit;
}
}

首先传入的参数要大于12个字符,必须是非空格非TAB之外的内容,password要有大小写数字,字符内容,而且匹配到的次数要大于6次,最后password要等于42

要满足上面的条件 要么是16进制要么是科学计数法
所以payload:42.000000000e+0

Last modification:March 21st, 2019 at 05:16 pm
If you think my article is useful to you, please feel free to appreciate

Leave a Comment