【CTF】PHP漏洞(学习积累中)
1. strcmp字符串比较
strcmp() 函数比较两个字符串,且对大小写敏感
语法:strcmp(string1,string2);
strcmp函数比较字符串的本质是将两个变量转换为ascii,然后进行减法运算,然后根据运算结果来决定返回值。
-
0 - 如果两个字符串相等
-
<0 - 如果 string1 小于 string2
-
>0 - 如果 string1 大于 string2
define('FLAG', 'flag{1}');
if (isset($_GET['flag'])) {
if (strcmp($_GET['flag'], FLAG) == 0) {
echo "success, flag:" . FLAG;
}
}
如果一个数值和字符串进行比较的时候,会将字符串转换成数值,strcmp就会比较出错,返回NULL,NULL==0成立,得到flag
GET传入flag[]=1就能绕过了
2. md5碰撞
define('FLAG', 'flag{2}');
if (isset($_GET['a']) and isset($_GET['b'])) {
if ($_GET['a'] != $_GET['b']
&& md5($_GET['a']) == md5($_GET['b'])) {
echo "success, flag:" . FLAG;
}
}
如果a的值不等于b的值,并且a的md5值要等于b的md5值,PHP在处理哈希字符串时,它把每一个以“0E”开头的哈希值都解释为0,所以如果两个不同的密码经过哈希以后,其哈希值都是以“0E”开头的,那么PHP将会认为他们相同,都是0。
md5('QNKCDZO') ==
'0e830400451993494058024219903391'
md5('240610708') ==
'0e462097431906509019562988736854'
以下值在md5加密后以0E开头
-
QNKCDZO
-
240610708
-
s878926199a
-
s155964671a
-
s214587387a
-
s214587387a
以下值在sha1加密后以0E开头,sha1(str)
-
sha1('aaroZmOk')
-
sha1('aaK1STfY')
-
sha1('aaO8zKZF')
-
sha1('aa3OFF9m')
GET传入a=QNKCDZO&b=240610708就能绕过了
3. md5函数特性
define('FLAG', 'flag{2}');
if (isset($_GET['a']) and isset($_GET['b'])) {
if ($_GET['a'] !== $_GET['b']
&& md5($_GET['a']) === md5($_GET['b'])) {
echo "success, flag:" . FLAG;
}
}
在php中===为完全等于运算,不仅比较值,而且还比较值的类型,只有两者一致才为真。再次使用a=QNKCDZO&b=240610708就不行了,因为a和b类型不同。
PHP中md5的函数特性
md5([1,2,3]) == md5([4,5,6]) == NULL
[1] !== [2] && md5([1]) === md5([2])
所以GET传入a[]=1&b[]=2就能够绕过了
4. json绕过
define('key', 'flag{4}');
if (isset($_POST['a'])) {
$a = json_decode($_POST['a']);
if ($a->key == $key) {
echo "flag" . key;
} else {
echo "不相等";
}
} else{
echo "a不存在";
}
输入一个json类型的字符串,json_decode函数解密成一个数组,判断数组中key的值是否等于key的值我们不知道,但是可以利用0=="string"这种形式绕过。
所以POST传入a={"key":0}就能够绕过了。
如果以后再学习到了就写上来