『PHP代码审计』PHPOK存在命令执行漏洞

文章目录

  • 前言
  • 一、漏洞演示
  • 二、漏洞分析
  • 三、利用
  • 四、修复
  • 五、总结

前言

作者:Ho1aAs

博客:https://blog.csdn.net/Xxy605

记一下自己挖到的第一个漏洞,写的不太好,师傅们多多包涵

一、漏洞演示

访问PHPOK CMS的后台,选择左侧的文件管理,页面提示需要输入管理员二次密码进行验证才能进入界面

『PHP代码审计』PHPOK存在命令执行漏洞_第1张图片

选择右上角管理员头像,打开修改密码界面

『PHP代码审计』PHPOK存在命令执行漏洞_第2张图片

在管理员密码修改界面,发现可以随意更改二次密码,而无需验证

那么可以随意更改、覆盖原二次密码,就绕过了二次密码验证,从而得以进入文件管理

『PHP代码审计』PHPOK存在命令执行漏洞_第3张图片

『PHP代码审计』PHPOK存在命令执行漏洞_第4张图片

输入二次密码,通过验证,进入文件管理

点击右上的创建文件,新建一个空的php文件

『PHP代码审计』PHPOK存在命令执行漏洞_第5张图片
『PHP代码审计』PHPOK存在命令执行漏洞_第6张图片

写入命令
『PHP代码审计』PHPOK存在命令执行漏洞_第7张图片

php直接上传到了根目录,访问即可执行

『PHP代码审计』PHPOK存在命令执行漏洞_第8张图片

二、漏洞分析

文件管理功能在_app/filemanage/admin_control.php,该功能只要通过二次密码验证就能使用,并且对新建的文件、文件的内容没有任何过滤

	/**
	 * 内容编辑器
	**/
	public function edit_f()
	{
     
    	# 验证编辑权限
		if(!$this->session->val('admin_id_checked')){
     
			$this->display('admin_vcode');
		}
		if(!$this->popedom["edit"]){
     
			$this->error(P_Lang('您没有权限执行此操作'));
		}
    	# 根目录
		$folder = $this->get("folder");
		if(!$folder){
     
			$folder = "/";
		}
		if(substr($folder,-1) != '/'){
     
			$folder .= "/";
		}
    	# 获取文件名
		$title = $this->get("title");
		$file = $this->dir_root.$folder.$title;
		if(!file_exists($file)){
     
			$this->error(P_Lang('文件不存在'));
		}
		$is_edit = true;
		if(!is_writable($file)){
     
			$tips = P_Lang('文件无法写入,不支持在线编辑');
			$this->assign('tips',$tips);
			$is_edit = false;
		}
		$this->assign('is_edit',$is_edit);
		# 这里对写入内容进行了处理
    	# 只是过滤替换了某些字符,并没有对危险字符(串)处理
		$content = $this->lib('file')->cat($file);
		$content = str_replace(array("<",'>'),array("&lt;","&gt;"),$content);
		$content = str_replace(array('<','>'),array('<','>'),$content);
		$this->assign("content",$content);
		$this->assign("folder",$folder);
		$this->assign("title",$title);
		//加载编辑器
		$this->addcss("static/codemirror/lib/codemirror.css");
		$this->addjs("static/codemirror/lib/codemirror.js");
		$this->addjs('static/codemirror/mode/css/css.js');
		$this->addjs('static/codemirror/mode/javascript/javascript.js');
		$this->addjs('static/codemirror/mode/htmlmixed/htmlmixed.js');
		$this->addjs('static/codemirror/mode/php/php.js');
		$this->addjs('static/codemirror/mode/xml/xml.js');
		$istpl = strpos($folder,'tpl/') !== false ? true : false;
		$this->assign('istpl',$istpl);
		if($istpl){
     
			$oklist = $this->model('call')->get_list("ok.status=1",0,999);
			$this->assign('oklist',$oklist);
			$this->assign('ishtml',true);
		}else{
     
			$tmp = strtolower($title);
			$ishtml = strpos($tmp,'.htm') !== false ? true : false;
			$this->assign('ishtml',$ishtml);
			$isphp = strpos($tmp,'.php') !== false ? true : false;
			$this->assign('isphp',$isphp);
		}
		$this->display("admin_edit");
	}

	public function save_f()
	{
     
    	# 验证保存权限
		if(!$this->session->val('admin_id_checked')){
     
			$this->error(P_Lang('未经过二次密码确认,不能执行此操作'));
		}
		if(!$this->popedom["edit"]){
     
			$this->error(P_Lang('您没有权限执行此操作'));
		}
    	# 根目录
		$folder = $this->get("folder");
		if(!$folder){
     
			$folder = "/";
		}
		if(substr($folder,-1) != '/'){
     
			$folder .= "/";
		}
    	# 获取文件名
		$title = $this->get("title");
		$file = $this->dir_root.$folder.$title;
		if(!file_exists($file)){
     
			$this->error(P_Lang('文件不存在'));
		}
		if(!is_writable($file)){
     
			$this->error(P_Lang('文件无法写入,不支持在线编辑'));
		}
    	# 将修改后的内容写入文件
		$content = $this->get("content","html_js");
		$this->lib('file')->vim($content,$file);
		$this->success();
	}

三、利用

新建PHP文件调用PHP命令执行函数

四、修复

建议修改二次密码时添加验证原密码

五、总结

由于以下问题导致该漏洞的产生:

  • 随意修改二次密码、缺乏修改时对二次密码原密码的验证
  • 文件管理功能对输入文件没有任何过滤、随意操纵网站的根目录,能够写入命令

你可能感兴趣的:(#,代码审计,php,代码审计,cms,web安全,命令执行)