ctf的php,CTF中常见的PHP知识点

PHP是一门比较松散的语言,既方便,又容易出现一些问题。本文主要概括一些常见的PHP弱类型,正则表达式函数跟变量覆盖的内容,在CTF这方面也经常出现在代码审计相关的题目中。

一、弱类型

0x01 "=="与"==="的区别

在使用"=="时会自动转换类型,而"==="则是校验类型,而非转换。

1 == '1'; //true

1 == '1abcdef'; //true

0 == 'abcdefg'; //true

0 === 'abcdefg'; //false

0x02 Hash比较

使用"=="时,如果字符串满足0e\d+,解析为科学计数法,否则视为正常字符串。

"0e132456789" == "0e7124511451155" //true

"0e123456abc" == "0e1dddada" //false

"0e1abc"=="0" //true

md5('240610708') == md5('QNKCDZO') //true

0e开头的md5:

QNKCDZO

0e830400451993494058024219903391

s878926199a

0e545993274517709034328855841020

s155964671a

0e342768416822451524974117254469

s214587387a

0e848240448830537924465865611904

s214587387a

0e848240448830537924465865611904

s878926199a

0e545993274517709034328855841020

s1091221200a

0e940624217856561557816327384675

s1885207154a

0e509367213418206700842008763514

0x03 传入数组返回null系列

md5()是不能处理数组的,md5(数组)会返回null,同理的有sha1(),strlen(),eregx()。

$array1[] = array(

"foo" => "bar",

"bar" => "foo",

);

$array2 = array("foo", "bar", "hello", "world");

var_dump(md5($array1)==var_dump($array2)); //true

0x04 十六进制转换

使用"=="时,PHP会将十六进制转换为十进制然后再进行比较

"0x1e240"=="123456" //true

"0x1e240"==123456 //true

"0x1e240"=="1e240" //false

0x05 intval()函数

intval()函数会将从字符串的开始进行转换直到遇到一个非数字的字符。

如果出现无法转换的字符串,intval()不会报错而是返回0。

if(intval($a)>1000) {

mysql_query("select * from news where id=".$a)

}

这个时候$a的值有可能是1002 union…..

0x6 strcmp()函数

strcmp函数比较字符串的本质是将两个变量转换为ascii,然后进行减法运算。

在PHP5.3版本之后使用这个函数比较array跟sring会返回0。

$array=[1,2,3];

var_dump(strcmp($array,'123')); //null,在某种意义上null也就是相当于false。

0x07 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";

}

0x08 in_array(),array_search()函数

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

0x09 is_numeric()函数

当有两个is_numeric判断并用and连接时,and后面的is_numeric可以绕过.

"="优先级比and高。

$a=$_GET['a'];

$b=$_GET['b'];

$c=is_numeric($a) and is_numeric($b);

var_dump(is_numeric($a));

var_dump(is_numeric($b));

var_dump($c); //$b可以不是数字,同样返回true

$test=true and false;

var_dump($test); //返回true

?>

16进制也可以绕过is_numeric()检验,可以用来绕过sql注入里的过滤.

$a = is_numeric ( $_GET ['a'] ) ? $_GET ['a'] : 0;

$con = mysql_connect ( 'localhost', 'root', 'root' );

mysql_select_db ( 'test' );

$sql = 'insert into a values(' . $a . ',"a")';

mysql_query ( $sql );

?>

test.php?a=0x31206f7220313d31时,数据库中成功插入值

0x10 json绕过

输入一个json类型的字符串,json_decode函数解密成一个数组,

判断数组中key的值是否等于 $key的值,但是$key的值我们不知道,

但是可以利用0=="admin"这种形式绕过

最终payload message={"key":0}

if (isset($_POST['message'])) {

$message = json_decode($_POST['message']);

$key ="*********";

if ($message->key == $key) {

echo "flag";

}

else {

echo "fail";

}

}

else{

echo "~~~~";

}

?>

二、正则表达式

0x01 eregi()函数

1. 字符串对比解析,当ereg读取字符串string时,%00后面的字符串不会不会被解析。

#这里 a=abcd%001234,可以绕过

if (ereg ("^[a-zA-Z]+$", $_GET['a']) === FALSE) {

echo 'You password must be alphabet';

}

?>

2. 如果传入数组,ereg返回NULL

0x02 preg_match函数

如果在进行正则表达式匹配的时候,没有限制字符串的开始和结束(^ 和 $),则可以存在绕过的问题.

$ip = '1.1.1.1 abcd'; // 可以绕过

if(!preg_match("/(\d+)\.(\d+)\.(\d+)\.(\d+)/",$ip)) {

die('error');

} else {

// echo('key...')

}

0x03 preg_replace函数

preg_replace() 的第一个参数如果存在 /e 模式修饰符,则允许代码执行。

如果没有 /e 修饰符,可以尝试 %00 截断。

preg_replace("/test/e",$_GET["nac"],"jutst test");

?>

?nac=phpinfo() #可以被执行

三、变量覆盖

0x01 extract()函数

extract() 函数从数组中把变量导入到当前的符号表中。

对于数组中的每个元素,键名用于变量名,键值用于变量值。

$auth = '0';

// 这里可以覆盖$auth的变量值

extract($_GET);

if($auth == 1){

echo "private!";

} else{

echo "public!";

}

?>

0x02 parse_str()函数

parse_str() 的作用是解析字符串,并注册成变量.

与 parse_str() 类似的函数还有 mb_parse_str(),parse_str() 将字符串解析成多个变量,

如果参数 str 是 URL 传递入的查询字符串(query string),则将它解析为变量并设置到当前作用域.

//var.php?var=new

$var='init';

parse_str($_SERVER['QUERY_STRING']);

// $var 会变成 new

echo $var;

0x03 $$的使用

如果把变量本身的 key 也当变量,也就是使用了 $$,就可能存在问题。

// http://127.0.0.1/index.php?_CONFIG=123

$_CONFIG['extraSecure'] = true;

foreach(array('_GET','_POST') as $method) {

foreach($$method as $key=>$value) {

// $key == _CONFIG

// $$key == $_CONFIG

// 这个函数会把 $_CONFIG 变量销毁

unset($$key);

}

}

if ($_CONFIG['extraSecure'] == false) {

echo 'flag {****}';

}

0x04 unset()

unset($bar); 用来销毁指定的变量,如果变量 $bar 包含在请求参数中,

可能出现销毁一些变量而实现程序逻辑绕过。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值