Bugku代码审计

Bugku代码审计

0x01. extrack 变量覆盖

<?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() 函数从数组中将变量导入到当前的符号表。
该函数使用数组键名作为变量名,使用数组键值作为变量值。针对数组中的每个元素,将在当前符号表中创建对应的一个变量。
第二个餐数 type 用于指定当某个变量已经存在,而数组中又有同名元素时,extract() 函数如何和对待这样的冲突。该函数返回成功导入到符号表中的变量数目。

file_get_contents() 函数把整个文件读入一个字符串中。和file()一样,不同的是file_get_contents()把文件读入一个字符串。
file_get_contents() 函数适用于将文件的内容读入到一个字符串中的首选方法。如果操作系统支持,还会使用内存映射技术来曾强性能。

trim()函数

trim() 函数移除字符串两侧的空白字符或其他预定义字符。

trim(string,charlist)
参数描述
string必需。规定要检查的字符串。
charlist可选。规定从字符串中删除哪些字符。如果被省略,则移除以下所有字符:"\0" - NULL"\t" - 制表符"\n" - 换行"\x0B" - 垂直制表符"\r" - 回车" " - 空格"\0" - NULL

“\0” - NULL
“\t” - 制表符
“\n” - 换行
“\x0B” - 垂直制表符
“\r” - 回车
" " - 空格

payload
?shiyan		或者		?shiyan=&content=		或者		?shiyan=&flag=

利用extract()函数漏洞,当$ shiyan和$ content为空时,满足 $ shiyan==$ content

0x02. 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';
}
?>
strcmp()函数

strcmp ( string str1,stringstr1,stringstr2 )
str1是第一个字符串,str2是第二个字符串。如果 str1 小于 str2 返回 < 0; 如果 str1 大于 str2 返回 > 0;如果两者相等,返回 0。
但是如果我们传入非字符串类型的数据的时候,这个函数将发生错误,在5.3之前的php中,显示了报错的警告信息后,将return 0 ! 也就是虽然报了错,但却判定其相等了。
因此,解这道题,就只要传入一个非字符串类型的变量即可,一般情况下,我们我们传数组,所以payload为:?a[]=123

0x03. 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()函数

语法

int eregi(string pattern, string string, [array regs]);

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

可选的输入参数规则包含一个数组的所有匹配表达式,他们被正则表达式的括号分组。

返回值
如果匹配成功返回true,否则,则返回false

payload

url二次编码绕过,第一次被浏览器解码,第二次被urldecode解码
在这里插入图片描述
所以构造payload
可以只url二次编码其中一个字符,也可以编码全部

?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

或者

?id=hackerD%4A

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

有两种方法绕过:

1,md5()函数无法处理数组,如果传入的为数组,会返回NULL,所以两个数组经过加密后得到的都是NULL,也就是相等的。

2,利用==比较漏洞

如果两个字符经MD5加密后的值为 0exxxxx形式,就会被认为是科学计数法,且表示的是0*10的xxxx次方,还是零,都是相等的。

下列的字符串的MD5值都是0e开头的:

QNKCDZO

240610708

s878926199a

s155964671a

s214587387a

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

这个题目用第一种方法即可成功绕过,第二种方法不行

0x05. 数组返回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';
}
?>

ereg()函数用指定的模式搜索一个字符串中指定的字符串,如果匹配成功返回true,否则,则返回false。搜索字母的字符是大小写敏感的, 我们可以用%00来截断,在%00之后的数值函数无法识别

倘若函数的参数不符合其函数要求的时候返回的是null值, 所以也可传入password为数组类型

payload
?password=1%00--

或者

?password[]=1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值