PHP弱类型产生的安全问题
简介
PHP作为一种弱类型编程语言,在定义变量时无需像C++等强类型时定义数据类型。
1
2
3
4
5<?php
$a = 1;
$a = "hello";
$a = [];
?>1
2
3
4<?php
$a = '1'; //a现在是字符串'1'
$a *= 2; //a现在是整数2
?>
简介
PHP有这些比较运算符 1
2
3
4
5
6
7
8
9
10
11
12
13<?php
$a == $b; //相等
$a === $b; //全等
$a != $b; //不等
$a <> $b; //不等
$a !== $b; //不全等
$a < $b; //小于
$a > $b; //大于
$a <= $b; //小于等于
$a >= $b; //大于等于
$a <==> $b; //太空船运算符:当$a小于、等于、大于$b时分别返回一个小于、等于、大于0的integer 值。 PHP7开始提供.
$a ?? $b ?? $c; //NULL 合并操作符 从左往右第一个存在且不为 NULL 的操作数。如果都没有定义且不为 NULL,则返回 NULL。PHP7开始提供。
?>
下面看一段从PHP手册中摘的一段: >如果该字符串没有包含 '.','e' 或 'E' 并且其数字值在整型的范围之内(由 PHP_INT_MAX 所定义),该字符串将被当成 integer 来取值。其它所有情况下都被作为 float 来取值。
1 |
|
可以看到字符串中如果有'.'或者e(E),字符串将会被解析为整数或者浮点数。这些特性在处理Hash字符串时会产生一些安全问题。
1 |
|
若Hash字符串以0e开头,在进行!=或者==运算时将会被解析为科学记数法,即0的次方。 或字符串为0x开头,将会被当作十六进制的数。
下面给出几个以0e开头的MD5加密之后的密文。 1
2
3
4
5
6
7
8
9
10
11
12
13
14QNKCDZO
0e830400451993494058024219903391
s1885207154a
0e509367213418206700842008763514
s1836677006a
0e481036490867661113260034900752
s155964671a
0e342768416822451524974117254469
s1184209335a
0e072485820392773389523109082030
具体函数
md5()
1 |
|
要求输入的username为字母,password为数字,并且两个变量的MD5必须一样,这时就可以考虑以0e开头的MD5密文。md5('240610708') == md5('QNKCDZO') 可以成功得到flag。
sha1()
1 |
|
sha1函数需要传入的数据类型为字符串类型,如果传入数组类型则会返回NULL
1 |
|
因此传入name[]=1&password[]=2 即可成功绕过
strcmp() php version < 5.3
1 |
|
和sha1()函数一样,strcmp()是字符串处理函数,如果给strcmp()函数传入数组,无论数据是否相等都会返回0,当然这只存在与PHP版本小于5.3之中。
intval()
1 |
|
intval()函数获取变量的整数值,程序要求从浏览器获得的id值不为1024,因此输入1024.1即可获得flag。
json_decode()
1 |
|
需要POST的message中的key值等于程序中的key值,如果传入的key为整数0,那么在比较运算符==的运算下,将会判定字符串为整数0,那么只需要传入数据:message={"key":0}
array_search() 和 in_array()
上面两个函数和前面d额是一样的问题,会存在下面的一些转换为题: > "admin" == 0; //true > "1admin" == 1; //true
总结
熬夜写文章已经很晚了,就懒得再写总结了。以后每周总结一篇关于代码审计的小知识点。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!