题目: http://ctf.nuptsast.com/challenges#/x00
view-source:
if (isset ($_GET['nctf'])) { // if (@ereg ("^[1-9]+$", $_GET['nctf']) === FALSE) echo '必须输入数字才行'; else if (strpos ($_GET['nctf'], '#biubiubiu') !== FALSE) die('Flag: '.$flag); else echo '骚年,继续努力吧啊~'; }
代码的意思就是,输入一个值,满足是数字的同时还要含有字符串“#biubiubiu”,既是数字又是字符串是不可能的。
isset函数是检测变量是否设置。
格式:bool isset( mixed var [, mixed var [, ...]] )
返回值:
若变量不存在则返回FALSE
若变量存在且其值为NULL,也返回FALSE
若变量存在且值不为NULL,则返回TURE
同时检查多个变量时,每个单项都符号上一条要求时才返回TRUE,否则结果为FALSE
如果已经使用unset()释放了一个变量之后,它将不再是isset()。若使用isset()测试一个被设置成NULL的变量,将返回FALSE。同时要注意的是一个NULL字节("\0")并不等同于PHP的NULL常数。
警告:isset()只能用于变量,因为传递任何其它参数都将造成解析错误。若想检测常量是否已设置,可使用defined()函数。
查找 "php" 在字符串中第一次出现的位置。
所以改题目有两种思路:
1 利用%00截断,这个也是ereg函数一个漏洞,类似于0x00截断,都是因为这些函数遇到ASCII码为0的字符时,会自动默认到了结尾而停止;这里有一个需要注意的:我们构造的flag是需要一层url解码的,#
在url中是特殊字符,因此我们需要先将#
编码为%23
2 利用ereg和strpos函数处理数组的特性
当ereg函数处理数组时,会直接返回NULL,而===又是强判断,NULL自然不等于FALSE,因此绕过第一个条件;strpos函数也无法处理数组,直接返回NULL;因此构造?nctf[]=%23biubiubiu即可得到flag:
参考链接:https://blog.youkuaiyun.com/destiny1507/article/details/86629434
-------------------------------------------------------------------
知识点:
isset() ,ereg(),strpos()
url解码 例如%23解码为#
因为ereg()函数存在NULL截断漏洞,导致正则过滤被绕过,所以可以用%00来截断正则匹配。
ereg()处理数组返回null,strpos()处理数组返回null。
PHP ===
是强判断。