不用ftp做网站,简单的网站php开发教程,东莞我的网站建设,工厂关键词网络推广目录
和
MD5函数
intval
strpos in_array preg_match
str_replace 和
使用 时#xff0c;如果两个比较的操作数类型不同#xff0c;PHP 会尝试将它们转换为相同的类型#xff0c;然后再进行比较。
使用 进行比较时#xff0c;不仅比较值#xff0c;还比较变量…目录
和
MD5函数
intval
strpos in_array preg_match
str_replace 和
使用 时如果两个比较的操作数类型不同PHP 会尝试将它们转换为相同的类型然后再进行比较。
使用 进行比较时不仅比较值还比较变量的类型PHP 不会进行任何类型强制转换。如果两个操作数的类型不同即使它们的值看起来相同比较结果也会为假。 在 PHP 中强制类型转换是一种显式地将一个变量从一种类型转换为另一种类型的方式。当需要将一个变量转换为特定类型时可以使用强制类型转换。以下是 PHP 中常见的强制类型转换规则 转换为布尔值 (bool) 当转换为布尔值时以下值被认为是 false 布尔值 false 本身整数 0浮点数 0.0空字符串 字符串 0没有设置任何值的变量null没有元素的数组特殊类型 null没有任何属性的对象所有其他值都被认为是 true。转换为整数 (int) 当转换为整数时浮点数会被截断为整数部分字符串从开头开始解析直到第一个非数字字符为止。布尔值 true 转换为 1false 转换为 0。null 转换为 0。对象转换为整数时会调用对象的 __toString() 方法如果存在然后将结果转换为整数。转换为浮点数 (float) 当转换为浮点数时字符串从开头开始解析直到第一个非数字字符或字符串结束。布尔值 true 转换为 1.0false 转换为 0.0。null 转换为 0.0。对象转换为浮点数时会调用对象的 __toString() 方法如果存在然后将结果转换为浮点数。转换为字符串 (string) 整数和浮点数会被转换为它们的字符串表示形式。布尔值 true 转换为 1false 转换为 空字符串。数组和对象转换为字符串时会调用它们的 __toString() 方法如果存在。如果不存在则会触发一个警告并返回 null 的字符串表示形式。null 转换为 空字符串。资源类型resource在转换为字符串时通常没有意义除非与特定的资源处理器有关。转换为数组 (array) 转换为数组时对于非数组和对象类型的值将创建一个只包含该值的数组。对于对象如果对象实现了 ArrayAccess 接口它将被视为数组。否则将创建一个包含对象属性的数组。转换为对象 (object) 在 PHP 中将一个值转换为对象通常需要该值是一个已经存在的类名或者一个实现了 __invoke() 方法的对象。如果使用类名将创建一个该类的实例。如果使用实现了 __invoke() 方法的对象将调用该对象的 __invoke() 方法。转换为 null 将一个值设置为 null 是一种特殊的强制类型转换它将变量设置为没有值的状态。 测试代码,参数x用于的测试参数y用于的测试
//1、 缺陷绕过 弱类型对比 还会比较类型
$a1;
if($a$_GET[x]){echo $flag;
}//1.0 1 1a$a1;
if($a$_GET[y]){echo $flag;
}测试用例中传入x1 / x1.0 / x1sfd等都会与变量a相等因为会进行强制转换之后再比较 而使用必须类型一致传入y1.0 / y1 MD5函数
在 PHP 中md5() 函数的一个已知缺陷是所谓的“0e”碰撞。这个问题特定于 PHP 的字符串比较机制而不是 md5() 函数本身。当使用 运算符比较两个字符串时如果字符串以“0e”开头后面跟着一系列数字PHP 会将这些字符串解释为科学记数法表示的浮点数并进行数值比较而不是字符串比较。
//2、MD5函数缺陷绕过 弱对比 强类型对比
if($_GET[name] ! $_GET[password]){if(MD5($_GET[name]) MD5($_GET[password])){echo $flag;}echo ?;
}
根据代码逻辑先判断传入的name和password不相等再判断name和password讲过md5加密后相等才会输出flag否则输出问号
测试用例会用到以下两个字符串 QNKCDZO以MD5加密0e830400451993494058024219903391 240610708以MD5加密0e462097431906509019562988736854 正常情况下如nametestpassword123456md5加密是不相等的 而当我们使用上面两个用例字符串md5加密后php会判断相等 当你尝试对数组使用 md5() 函数时PHP 会发出一个警告告诉你 md5() 期望的是一个字符串而你提供的是一个数组。然后由于无法对数组进行哈希计算它会返回 null。在使用比较时传入两个数组比较等于nullnull返回true
//2、MD5函数缺陷绕过 弱对比 强类型对比
if($_GET[name] ! $_GET[password]){if(MD5($_GET[name]) MD5($_GET[password])){echo $flag;}echo ?;
}
上面解释过产生0e碰撞是因为php当作了科学计数比较而使用 进行字符串比较会同时比较值和类型因此不会受到上述“0e”碰撞问题的影响。
这种情况可以使用传入数组的方式绕过,name[]1和password[]2显然满足两者不相等这个条件而md5不对数组哈希并报Warning返回null所以nullnull返回true intval
intval( $var, $base )是 PHP 中的一个内置函数用于获取变量的整数值默认是十进制。这个函数尝试将给定的变量转换为整数类型。如果变量是字符串那么它会解析字符串直到遇到一个非数字字符为止然后返回该数字。如果字符串开头就是一个非数字字符那么它会返回 0。
当使用 intval() 函数并设置基数base为 0 时它会根据字符串的内容来尝试猜测其原始的数字基数并进行相应的转换。这通常用于处理以特定前缀开头的数字字符串如十六进制以 0x 或 0X 开头或八进制以 0 开头如果字符串不符合这些模式它会被尝试解析为十进制数。
注意如果字符串不是一个有效的八进制或十六进制数即如果它包含除了 0-7 之外的字符对于八进制或者除了 0-9 和 a-f不区分大小写之外的字符对于十六进制那么 intval() 将返回 0。
测试代码
//3、intval缺陷绕过
$i666;
$ii$_GET[n];
if(intval($ii)$i){echo $flag;echo br;
}$i666;
$ii$_GET[n];
if(intval($ii,0)$i){echo $flag;
}
使用666safs两个都能正常输出 都能正常截断后面的字符串但改为十六进制0x29a则只有base等与0的才能正常识别输出 strpos
strpos() 是 PHP 中的一个字符串函数用于查找一个子字符串在另一个字符串中首次出现的位置。 strpos(string $haystack, mixed $needle, int $offset 0): int|false 参数说明
$haystack必需。要搜索的字符串。$needle必需。要查找的字符串。如果该参数不是字符串它会被转换为整数并视为字符的 ASCII 值。$offset可选。从 $haystack 字符串中的哪个位置开始搜索。
返回值
如果找到子字符串则返回其第一次出现的位置的索引基于0的索引。如果没有找到子字符串则返回 false。
测试代码
//4、对于strpos()函数我们可以利用换行进行绕过%0a
$i666;
$ii$_GET[h];
if(strpos($ii,$i,0)){echo $flag;
} 在这段代码中如果h666并不会输出flag因为strpos返回 666 在 $ii 中首次出现的位置的索引而666 是字符串的开始它将返回 00在php同样代表false 可以通过换行进行绕过%0a666
%0a:表示换行 也可以在有必要的条件下使用 数组 返回null
//4、对于strpos()函数我们可以利用换行进行绕过%0a
$i666;
$ii$_GET[h];
if(strpos($ii,$i,0)null){echo $flag;
} in_array
in_array() 是 PHP 中的一个函数用于检查一个值是否存在于数组中。它的基本语法如下 bool in_array ( mixed $search , array $array [, bool $strict FALSE ] ) 参数说明
$search必需。要搜索的值。$array必需。要搜索的数组。$strict可选。如果设置为 TRUE则还会检查 $search 的类型是否和数组中的元素类型相同。默认为 FALSE。(True类似,Flase类似)
返回值
如果在数组中找到值则返回 TRUE否则返回 FALSE。 测试代码
//5、in_array第三个参数安全
$whitelist [1,2,3];
$page$_GET[i];
if (in_array($page, $whitelist)) {echo yes;
} preg_match
preg_match 是 PHP 中的一个函数用于执行一个正则表达式匹配。如果匹配成功它会返回 1如果匹配失败或发生错误它会返回 0如果没有进行匹配它会返回 false。
preg_match只能处理字符串如果不按规定传一个字符串传一个数组进入就会使preg_match失效从而绕过该函数的检测。
测试代码
if(isset($_GET[num])){$num $_GET[num];if(preg_match(/[0-9]/, $num)){die(no no no!);}if(intval($num)){echo $flag;}
}
从代码逻辑看获取并判断num参数值是否为空不为空则判断匹配num值中是否有0-9的字符符合条件执行die输出nonono并杀死程序否则执行下一个条件intval(num)取整操作不为flase输出flag
正常输入数字会杀死程序 当我们传一个数组就能绕过正则的检测 str_replace
str_replace 是 PHP 中的一个函数用于在字符串中查找并替换指定的值。它接受一个或多个搜索值需要被替换的以及对应的替换值并在给定的主字符串中进行替换。
缺陷是无法迭代过滤可以双写绕过
测试代码
//7、str_replace无法迭代过滤
$sql$_GET[s];
$sqlstr_replace(select,,$sql);
echo $sql;这段代码会过滤掉select并替换为空 双写则可以绕过他能过滤多个但是二次合并的无法迭代的过滤 如sselectelect过滤一次后再次合并的select不会被过滤