攻防世界-WEB-filemanager

攻防世界-WEB-filemanager

码农世界 2024-06-05 前端 114 次浏览 0个评论

前言

人道是,

我心错付情深处,以为两情皆如初。

奈何春风扶柳意,独我梦中空自舞。

许久未见诸位,这段时间由于学业与其他事情,便没再继续写下去(其实很大一部分归咎于自己的懒惰//DOGE)

这次带来一道开胃小菜,希望能够帮到各位师傅们,也希望得到大家的指点


正文

主页面

信息收集

www.tar.gz的内容

因锤死听

代码审计

upload.php

quote($path_parts["filename"]);
		// Fix
        //这里使用了addslashes以转义字符,目的是减少SQL注入风险,不过个人认为没啥卵用
		$path_parts['filename'] = addslashes($path_parts['filename']);
        //这一段用于查询是否存在同名的文件
		$sql = "select * from `file` where `filename`='{$path_parts['filename']}' and `extension`='{$path_parts['extension']}'";
		$fetch = $db->query($sql);
		if ($fetch->num_rows > 0) {
			exit("file is exists");//这个就不用解释了
		}
        //将临时上传的文件从临时目录中移动到指定目录中
		if (move_uploaded_file($file["tmp_name"], UPLOAD_DIR . $name)) {
          
			$sql = "insert into `file` ( `filename`, `view`, `extension`) values( '{$path_parts['filename']}', 0, '{$path_parts['extension']}')";
			$re = $db->query($sql);
			if (!$re) {
				print_r($db->error);
				exit;
			}
			$url = "/" . UPLOAD_DIR . $name;
			echo "Your file is upload, url:
                {$url}
go back";//上传成功后生成url供用户访问上传后的文件 } else { exit("upload error"); } } else { print_r(error_get_last()); exit; } }

rename.php

query("select * from `file` where `filename`='{$req['oldname']}'");
    if ($result->num_rows > 0) {
       $result = $result->fetch_assoc();
    } else {
       exit("old file doesn't exists!");
    }
    if ($result) {
        
       $req['newname'] = basename($req['newname']);//使用basename()确保newname不包含路径信息,保留文件名部分
       $re = $db->query("update `file` set `filename`='{$req['newname']}', `oldname`='{$result['filename']}' where `fid`={$result['fid']}");//数据库更新操作,失败返回error
       if (!$re) {
          print_r($db->error);
          exit;
       }
        //构造旧文件路径和新文件路径
       $oldname = UPLOAD_DIR . $result["filename"] . $result["extension"];
       $newname = UPLOAD_DIR . $req["newname"] . $result["extension"];
       if (file_exists($oldname)) {
          rename($oldname, $newname);
       }
       $url = "/" . $newname;
       echo "Your file is rename, url:
                {$url}
go back"; //这里和上一个php一样 } } ?> file manage

Rename

old filename(exclude extension):

new filename(exclude extension):

delete.php

query("select * from `file` where `filename`='{$req['filename']}'");//根据提供的filename查询数据库中的文件记录
    if ($result->num_rows>0){//查询结果存在获取第一条记录
        $result = $result->fetch_assoc();
    }
    $filename = UPLOAD_DIR . $result["filename"] . $result["extension"];
    if ($result && file_exists($filename)) {
        $db->query('delete from `file` where `fid`=' . $result["fid"]);
        unlink($filename);
        redirect("/");//调用redirect("/")函数重定向到首页
    }
}
?>



    file manage
    
    

Delete file

delete filename(exclude extension):

common.inc.php

 "127.0.0.1",
    "username" => "root",
    "password" => "ayshbdfuybwayfgby",
    "dbname" => "xdctf",
);
$db = new mysqli($DATABASE['host'], $DATABASE['username'], $DATABASE['password'], $DATABASE['dbname']);
$req = array();//定义空数组用于收集参数
foreach (array($_GET, $_POST, $_COOKIE) as $global_var) {
    foreach ($global_var as $key => $value) {
       is_string($value) && $req[$key] = addslashes($value);
    }//简单来说就是放sql注入的
}
define("UPLOAD_DIR", "upload/");
//定义了一个名为redirect的函数,用于重定向到指定的URL。它发送HTTP重定向头,并退出脚本执行
function redirect($location) {
    header("Location: {$location}");
    exit;
}

xdctf.sql

#配置文件,没啥分析的
SET NAMES utf8;
SET FOREIGN_KEY_CHECKS = 0;
DROP DATABASE IF EXISTS `xdctf`;
CREATE DATABASE xdctf;
USE xdctf;
DROP TABLE IF EXISTS `file`;
CREATE TABLE `file` (
  `fid` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `filename` varchar(256) NOT NULL,
  `oldname` varchar(256) DEFAULT NULL,
  `view` int(11) DEFAULT NULL,
  `extension` varchar(32) DEFAULT NULL,
  PRIMARY KEY (`fid`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;
SET FOREIGN_KEY_CHECKS = 1;

还有一个完全不需要分析的index.php





    file manage
    
    


    

Control

  • Delete file
  • Rename file

Content

其实不难发现,最有可能出问题的在rename.php中,我们来看这一段

	if ($result) {
		$req['newname'] = basename($req['newname']);
		$re = $db->query("update `file` set `filename`='{$req['newname']}', `oldname`='{$result['filename']}' where `fid`={$result['fid']}");
		if (!$re) {
			print_r($db->error);
			exit;
		}

代码看着好像没问题,实则细心的师傅不难发现,它并没有对newname进行过滤,也就意味着我们可以构造恶意代码进行漏洞利用

--------------------------------------------------------

还有就是upload.php

它对传入的文件后缀进行验证,也对传入的filename做了转义

$path_parts['filename'] = addslashes($path_parts['filename']);
$sql = "select * from `file` where `filename`='{$path_parts['filename']}' and `extension`='{$path_parts['extension']}'";

但是这还不够,照样能够被利用

当我们传入这样一个值: ',extension='.jpg

由于upload.php并未对传入的文件名做任何的限制(如不能使用'\@*等等),所以能够被成功上传

其次又由于传入的',extension='.jpg中的后缀.jpg符合白名单规则,所以能够被成功上传

我们来进行实践

--------------------------------------------------------

实践

验证成功

--------------------------------------------------------

接下来需要利用rename.php

old filename得这么写,不然',extension='.jpg无法被识别

重命名成功

这样rename.php中的

update `file` set `filename`='{$req['newname']}', `oldname`='{$result['filename']}' where `fid`={$result['fid']}

就变成了

update `file` set `filename`='MQ4.jpg',`oldname`='',extension='' where `fid`={$result['fid']}"

--------------------------------------------------------

接下来上传一个MQ4.jpg的马

--------------------------------------------------------

然后回到rename.php

--------------------------------------------------------

连接我们的小马

连接成功

成功获取flag


结尾

CTF是一个经验积累的过程,多做题,你就能找到其中的奥秘于快乐.

也祝各位六一儿童节快乐!!!!

求赞求关注,感谢!!!!!!!!!!!

转载请注明来自码农世界,本文标题:《攻防世界-WEB-filemanager》

百度分享代码,如果开启HTTPS请参考李洋个人博客
每一天,每一秒,你所做的决定都会改变你的人生!

发表评论

快捷回复:

评论列表 (暂无评论,114人围观)参与讨论

还没有评论,来说两句吧...

Top