약한 유형의 언어는 약한 유형의 정의 언어라고도 합니다. 강력한 형식의 정의와 반대입니다. VB, PHP 등의 언어는 Weakly Types를 사용하여 PHP의 Weak Types에 대한 보안 문제를 자세히 소개합니다.
머리말
PHP가 세계 최고의 언어라는 것은 누구나 알고 있으며, PHP 자체의 문제도 웹 보안의 한 측면으로 볼 수 있다고 생각합니다. PHP의 특징은 약한 유형 지정과 내장 함수에 의한 수신 매개변수의 느슨한 처리입니다.
이 글은 주로 공격형 플랫폼과 방어형 플랫폼에서 겪었던 PHP 함수의 문제점과 PHP의 약한 유형으로 인한 문제점을 기록하기 위한 것입니다. PHP를 배우거나 사용할 때 누구나 참고할 만한 가치가 있습니다. 함께 살펴보겠습니다.
PHP 약한 타이핑 소개
편집자는 PHP가 개발자가 사용할 수 있는 많은 고유한 기능을 제공하기 때문에 PHP가 매우 강력하다고 생각합니다. 그 중 하나는 php 약한 타이핑 메커니즘입니다.
PHP에서는 다음 작업을 수행할 수 있습니다.
$param = 1; $param = array(); $param = "stringg";
약한 유형의 언어에는 변수의 데이터 유형에 제한이 없습니다. 언제든지 다른 유형의 변수에 변수를 할당할 수 있으며 변수는 다른 유형의 데이터로 변환될 수도 있습니다.
형변환 문제
형변환은 피할 수 없는 문제입니다. 예를 들어, GET 또는 POST 매개변수를 int 유형으로 변환해야 하거나 두 변수가 일치하지 않는 경우 PHP는 자동으로 변수를 변환합니다. 그러나 PHP는 약한 유형의 언어이므로 유형 변환을 수행할 때 예상치 못한 많은 문제가 발생합니다.
비교연산자
형변환
$a==$b
$a==$b
的比较中
$a=null;$b=flase ; //true $a='';$b=null; //true
这样的例子还有很多,这种比较都是相等。
使用比较操作符的时候也存在类型转换的问题,如下:
0=='0' //true 0 == 'abcdefg' //true 0 === 'abcdefg' //false 1 == '1abcdef' //true
当不同类型的变量进行比较的时候就会存在变量转换的问题,在转换之后就有可能会存在问题。
Hash比较
除了以上的这种方式之外在进行hash比较的时候也会存在问题。如下:
"0e132456789"=="0e7124511451155" //true "0e123456abc"=="0e1dddada" //false "0e1abc"=="0" //true
在进行比较运算时,如果遇到了0ed+
这种字符串,就会将这种字符串解析为科学计数法。所以上面例子中2个数的值都是0因而就相等了。如果不满足0ed+
这种模式就不会相等。这个题目在攻防平台中的md5 collision就有考到。
十六进制转换
还存在一种十六进制余字符串进行比较运算时的问题。
例子如下:
"0x1e240"=="123456" //true "0x1e240"==123456 //true "0x1e240"=="1e240" //false
当其中的一个字符串是0x开头的时候,PHP会将此字符串解析成为十进制然后再进行比较,0x1240解析成为十进制就是123456,所以与int类型和string类型的123456比较都是相等。攻防平台中的起名字真难就是考察的这个特性。
类型转换
常见的转换主要就是int转换为string,string转换为int。
int转string:
$var = 5; 方式1:$item = (string)$var; 方式2:$item = strval($var);
string转int:intval()
函数。
对于这个函数,可以先看2个例子。
var_dump(intval('2')) //2 var_dump(intval('3abcd')) //3 var_dump(intval('abcd')) //0
说明intval()
转换的时候,会将从字符串的开始进行转换知道遇到一个非数字的字符。即使出现无法转换的字符串,intval()
不会报错而是返回0。
intval()
的这种特性在攻防平台中的MYSQL这道题目中就有考到。
同时,程序员在编程的时候也不应该使用如下的这段代码:
if(intval($a)>1000) { mysql_query("select * from news where id=".$a) }
这个时候$a的值有可能是1002 union…..
内置函数的参数的松散性
内置函数的松散性说的是,调用函数时给函数传递函数无法接受的参数类型。解释起来有点拗口,还是直接通过实际的例子来说明问题,下面会重点介绍几个这种函数。
md5()
$array1[] = array( "foo" => "bar", "bar" => "foo", ); $array2 = array("foo", "bar", "hello", "world"); var_dump(md5($array1)==var_dump($array2)); //true
PHP手册中的md5()函数的描述是string md5 ( string $str [, bool $raw_output = false ] )
,md5()
中的需要是一个string类型的参数。但是当你传递一个array时,md5()
不会报错,知识会无法正确地求出array的md5值,这样就会导致任意2个array的md5值都会相等。这个md5()
$array=[1,2,3]; var_dump(strcmp($array,'123')); //null,在某种意义上null也就是相当于false。
$i ="2abc"; switch ($i) { case 0: case 1: case 2: echo "i is less than 3 but not negative"; break; case 3: echo "i is 3"; }
$array=[0,1,2,'3']; var_dump(in_array('abc', $array)); //true var_dump(in_array('1bc', $array)); //true
0ed+
와 같은 문자열이 발견되면 이 문자열을 과학적 표기법으로 구문 분석합니다. 따라서 위 예에서 두 숫자의 값은 모두 0이며 동일합니다. 0ed+
가 만족되지 않으면 이 패턴은 동일하지 않습니다. 이 질문은 공격 및 방어 플랫폼의 md5 충돌에서 테스트되었습니다. 🎜🎜🎜16진수 변환🎜🎜🎜16진수의 나머지 문자열을 비교할 때도 문제가 있습니다. 🎜🎜예제는 다음과 같습니다. 🎜🎜🎜rrreee🎜🎜🎜문자열 중 하나가 0x로 시작하면 PHP는 문자열을 십진수로 구문 분석한 다음 이를 비교합니다. 0x1240을 십진수로 구문 분석하면 123456입니다. int 유형과 동일하며 문자열 유형의 123456 비교는 모두 동일합니다. 공격 및 방어 플랫폼에서 이름을 지정하기 어려운 것은 이러한 검사 특성 때문입니다. 🎜🎜🎜🎜유형 변환🎜🎜🎜🎜일반적인 변환은 주로 int를 문자열로, 문자열을 int로 변환하는 것입니다. intval()
함수. intval()
이 변환되면 숫자가 아닌 문자를 만날 때까지 문자열의 시작 부분부터 변환됩니다. 변환할 수 없는 문자열이 나타나도 intval()
은 오류를 보고하지 않고 0을 반환합니다. intval()
이 기능은 공격 및 방어 플랫폼의 MYSQL 문제에서 테스트되었습니다. string md5 ( string $str [, bool $raw_output = false ] )
입니다. md5()
에는 문자열 유형 매개변수가 필요합니다. 그러나 배열을 전달하면 md5()
는 오류를 보고하지 않으며 지식은 배열의 md5 값을 올바르게 계산할 수 없게 됩니다. 이로 인해 두 가지의 md5 값이 발생하게 됩니다. 배열이 같아야 합니다. md5()
의 이 기능은 공격 및 방어 플랫폼에서도 다시 우회로 고려됩니다. 🎜🎜🎜strcmp()🎜🎜strcmp()
函数在PHP官方手册中的描述是int strcmp ( string $str1 , string $str2 )
,需要给strcmp()
传递2个string类型的参数。如果str1小于str2,返回-1,相等返回0,否则返回1。strcmp函数比较字符串的本质是将两个变量转换为ascii,然后进行减法运算,然后根据运算结果来决定返回值。
如果传入给出strcmp()
的参数是数字呢?
$array=[1,2,3]; var_dump(strcmp($array,'123')); //null,在某种意义上null也就是相当于false。
strcmp这种特性在攻防平台中的pass check有考到。
switch()
如果switch是数字类型的case的判断时,switch会将其中的参数转换为int类型。如下:
$i ="2abc"; switch ($i) { case 0: case 1: case 2: echo "i is less than 3 but not negative"; break; case 3: echo "i is 3"; }
这个时候程序输出的是i is less than 3 but not negative
,是由于switch()
函数将$i进行了类型转换,转换结果为2。
in_array()
在PHP手册中,in_array()
函数的解释是bool in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] )
,如果strict参数没有提供,那么in_array就会使用松散比较来判断$needle
是否在$haystack
中。当strince的值为true时,in_array()
会比较needls的类型和haystack中的类型是否相同。
$array=[0,1,2,'3']; var_dump(in_array('abc', $array)); //true var_dump(in_array('1bc', $array)); //true
可以看到上面的情况返回的都是true,因为'abc'会转换为0,'1bc'转换为1。
array_search()
与in_array()
也是一样的问题。
相关推荐:
위 내용은 PHP 취약 유형 보안 문제에 대한 자세한 요약의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!