没打0ctf, 但是在看大佬们的writeup的时候发现了这道题。
当时就觉得这个绕过莫名其妙, 不知道是怎么写的过滤。
看了几个博客, 好像都不太清楚绕过的原理,就这样测了下就绕过去了。
不过,当看到这题的flag之后,就大概知道为什么在payload之间插入%00这种可以绕过了。flag是flag{W4f_bY_paSS_FOR_CI} 也就是waf bypass for ci, 也就是用了ci框架清除一些字符的特性来bypass了waf.
在system/core/Input.php的构造方法中
1
2
3
4
|
public
function __construct()
{
省略
$this->_sanitize_globals();
//净化全局变量,
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
protected
function _sanitize_globals()
{
// Is $_GET data allowed? If not we'll set the $_GET to an empty array
if (
$this->_allow_get_array ===
FALSE)
{
$_GET =
array();
}
elseif (is_array($_GET))
{
foreach ($_GET
as $key => $val)
{
$_GET[
$this->_clean_input_keys($key)] =
$this->_clean_input_data($val);
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
protected
function _clean_input_data($str)
{
if (is_array($str))
{
$new_array =
array();
foreach (array_keys($str)
as $key)
{
$new_array[
$this->_clean_input_keys($key)] =
$this->_clean_input_data($str[$key]);
}
return $new_array;
}
/* We strip slashes if magic quotes is on to keep things consistent
NOTE: In PHP 5.4 get_magic_quotes_gpc() will always return 0 and
it will probably not exist in future versions at all.
*/
if ( ! is_php(
'5.4') && get_magic_quotes_gpc())
{
$str = stripslashes($str);
}
// Clean UTF-8 if supported
if (UTF8_ENABLED ===
TRUE)
{
$str =
$this->uni->clean_string($str);
}
// Remove control characters
$str = remove_invisible_characters($str,
FALSE);
|
这里看注释就能大概看出来清掉了哪些啦。
Clean UTF-8 if supported、Remove control characters
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
function remove_invisible_characters($str, $url_encoded = TRUE)
{
$non_displayables =
array();
// every control character except newline (dec 10),
// carriage return (dec 13) and horizontal tab (dec 09)
if ($url_encoded)
{
$non_displayables[] =
'/%0[0-8bcef]/i';
// url encoded 00-08, 11, 12, 14, 15
$non_displayables[] =
'/%1[0-9a-f]/i';
// url encoded 16-31
$non_displayables[] =
'/%7f/i';
// url encoded 127
}
$non_displayables[] =
'/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S';
// 00-08, 11, 12, 14-31, 127
do
{
$str = preg_replace($non_displayables,
'', $str,
-1, $count);
}
while ($count);
return $str;
}
|
这里应该是在清空这些字符之前就检测了字符,
所以呢 这里不止%00能绕过, %12, %80-%99之类的不少字符都能绕过。
后面一开始也在想, 这题都没用ci框架那种常见的url route, 也没看到啥明显的特征提示是ci框架,大家怎么能想到是利用ci框架的这个特性来绕过呢,不过后面发现在404页面中使用的是熟悉的ci框架的404页面, 那么也就很简单了。