郑州企业网站制作怎么做,公司做网站的费用怎么记账,代理商加盟项目网站,百度推广官网推荐:sk67666漏洞描述
信呼OA办公系统uploadAction存在SQL注入漏洞#xff0c;攻击者可利用该漏洞获取数据库敏感信息。
环境搭建
源码下载地址#xff1a;https://github.com/rainrocka/xinhu 下载后解压到本地网站根目录下#xff0c;配置好数据库#xff0c;然后安装即可 默认密…漏洞描述
信呼OA办公系统uploadAction存在SQL注入漏洞攻击者可利用该漏洞获取数据库敏感信息。
环境搭建
源码下载地址https://github.com/rainrocka/xinhu 下载后解压到本地网站根目录下配置好数据库然后安装即可 默认密码是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))$mindex;
if(!isset($a))$adefault;
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-displayfalse;} if(is_array($actbstr)){echo json_encode($actbstr);$xhrock-displayfalse;} }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-tpltypehtml || $ajaxbool false) $_showbool){ $xhrock-setHtmlData(); $da $xhrock-smartydata; foreach($xhrock-assigndata as $_k$_v)$$_k$_v; include_once($mpathname); $_showbool false;
}这里用get方式会接收mdaajaxbool参数 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下的子目录默认值分别为indexdefault、空字符串。
举例index.php?adelusermimgroupdajaxbooltruegid38sid1
$muser表示请求的是webadmin下的imgroup 目录。$alist表示请求的方法是 deluser。ajaxbooltrue表示这是一个 AJAX 请求
漏洞分析
漏洞的位置在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方法 再跟进 public function record( t a b l e , table, table,array,$where‘’) {$addbool true;if(!$this-isempt($where))$addboolfalse;$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){$sqlinsert into $table set $cont;}else{$where $this-getwhere($where);$sqlupdate $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, $lx0){$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?agetmfilvmupload|apidtaskfileid1fnameMScgYW5kIHNsZWVwKDMpIwpayload解释:漏洞的位置在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编码
成功延时