Advantech iView多個不同類型匿名RCE漏洞分享

聲明

出品|且聽安全(ID:QCyber)

以下內(nèi)容珊豹,來自且聽安全公眾號的作者原創(chuàng)鸵荠,由于傳播冕茅,利用此文所提供的信息而造成的任何直接或間接的后果和損失,均由使用者本人負責,長白山攻防實驗室以及文章作者不承擔任何責任姨伤。

漏洞信息

2022.06 ZDI發(fā)布多個Advantech iView漏洞信息CVE-2022-2135&2143&2135 等?:

影響版本為 Advantech iView All versions prior to 5_7_04_6469哨坪。重點關注其中評分為 `9.8` 的高危漏洞,發(fā)現(xiàn)問題主要集中在 `NetworkServlet`? 姜挺,整理的部分漏洞信息如下:

  • ?`findCfgDeviceList` :When parsing the COLUMN and VALUE elements of the findCfgDeviceList action, the process does not properly validate a user-supplied string before using it to construct SQL queries. An attacker can leverage this vulnerability to execute code in the context of SYSTEM.

  • ?`getAllActiveTraps` :When parsing the search_date_to and search_date_from elements of the getAllActiveTraps action, the process does not properly validate a user-supplied string before using it to construct SQL queries. An attacker can leverage this vulnerability to execute code in the context of SYSTEM.

  • ?`performZTPConfig` :When parsing any element of the performZTPConfig action, the process does not properly validate a user-supplied string before using it to construct SQL queries. An attacker can leverage this vulnerability to execute code in the context of SYSTEM.

  • ?`setTaskEditorItem` :When parsing the DESCRIPTION element of the setTaskEditorItem action, the process does not properly validate a user-supplied string before using it to construct SQL queries. An attacker can leverage this vulnerability to execute arbitrary code in the context of SYSTEM.

  • ?`exportDeviceList` :When parsing the filename element of the exportDeviceList action, the process does not properly validate a user-supplied path prior to using it in file operations. An attacker can leverage this vulnerability to execute code in the context of SYSTEM.

  • ?`findCfgDeviceListDetailsExport` :When parsing the filename element of the findCfgDeviceListDetailsExport action, the process does not properly validate a user-supplied path prior to using it in file operations. An attacker can leverage this vulnerability to execute code in the context of SYSTEM.

  • ?`backupDatabase` :When parsing the backup_filename element of the backupDatabase action, the process does not properly validate a user-supplied string before using it to execute a system call. An attacker can leverage this vulnerability to execute code in the context of SYSTEM.

  • ?`runProViewUpgrade` :When parsing the fwfilename element of the runProViewUpgrade action, the process does not properly validate a user-supplied string before using it to execute a system call. An attacker can leverage this vulnerability to execute code in the context of SYSTEM.

  • ?`findSummaryUpdateDeviceList` :When parsing the COLUMN and VALUE elements of the findSummaryUpdateDeviceList action, the process does not properly validate a user-supplied string before using it to construct SQL queries. An attacker can leverage this vulnerability to execute code in the context of SYSTEM.

  • 分析發(fā)現(xiàn)這些漏洞實現(xiàn) RCE 的方式主要是以下三種方式:

  • ?SQL 注入漏洞結(jié)合 `outfile` 實現(xiàn) getshell?

  • ? 直接命令拼接 getshell

  • ? 路徑穿越導致 getshell?

  • 查看 `NetworkServlet` 定義:

    定位?

    `com.imc.iview.network.NetworkServlet#doPost` :

    提取參數(shù) `page_action_type` 齿税,根據(jù)取值調(diào)用不同的函數(shù)。下面就選擇三個不同接口來分析三種不同 getshell 的方法炊豪。

    方式1:SQL注入+outfile getshell

    接口定義:

    提取參數(shù)后凌箕,調(diào)用 `findCfgDeviceList` :

    進入 `getDistinctDeviceTypes` :

    進入 `buildSelectSQL` :

    進行一z列參數(shù)賦值與類型轉(zhuǎn)換后進入 `checkForChassisUpdates` ,

    傳入的參數(shù) `strSegment` 就是 GET 請求攜帶的參數(shù) `segment` :

    private boolean checkForChassisUpdates(String strSegment) {    boolean bReturn = false;    new String();    int nCount = 0;    if (this.initDBServices()) {        String strSQL = "SELECT COUNT(*) UpdateCount FROM device_tree_table as a, device_tree_table as b WHERE b.nDeviceTypeId = 18 AND b.dtBuildDate < '2012-07-09 08:04:00' AND a.nDeviceId = b.nParentId AND a.strDescription = '" + strSegment + "'";        Connection conn = this.getConnection();        try {            Statement stmt = conn.createStatement();            ResultSet resultset;            for(resultset = stmt.executeQuery(strSQL); resultset.next(); nCount = resultset.getInt("UpdateCount")) {            }        ...}

    沒有對參數(shù)進行任何檢查词渤,直接拼接進入了 SQL 查詢語句牵舱,導致出現(xiàn) SQL 注入漏洞:

    因為 Advantech iView 默認集成的 MySQL 數(shù)據(jù)庫版本較低,支持 `outfile` 缺虐,所以可以利用 SQL 注入直接寫入 webshell:

    方式2:mysqldump 命令注入 getshell

    接口定義:

    提取請求參數(shù) `backup_filename` 芜壁,通過 `checkFileNameIncludePath` 和

    `checkSQLInjection` 對進行檢查。

  • ?`checkFileNameIncludePath` 函數(shù)檢查是否存在路徑穿越高氮,并對 `\webapps\` 等進行了過濾慧妄,很顯然 `/webapps/` 就可以繞過。

  • ?`checkSQLInjection` 函數(shù)對插件的 SQL 注入關鍵詞進行了過濾剪芍,也對 `getRuntime().exec` 等命令執(zhí)行常用字符串進行了過濾塞淹,但是沒有過濾 `ProcessBuilder` 等其他可以命令執(zhí)行的函數(shù)。

  • 回到 `backupDatabase` 函數(shù)罪裹,通過過濾檢查后饱普,將調(diào)用 `mysqldump` 進行數(shù)據(jù)庫備份:

    if (!errFile && !sqlInj) {    if (tempDBServices.getMySQLLocation()) {        String strMySQLPath = tempDBServices.getMySQLPath();        if (tempDBServices.retrieveDbSettings()) {            String strUser = tempDBServices.getStrLoginUserID();            String strPassword = tempDBServices.getStrLoginPassword();            if (tempSystemTable.findDbBackupFilePath()) {                String strDbBackupFilePath = tempSystemTable.getDbBackupFilePath();                strDbBackupFilePath = strDbBackupFilePath + strFilename;                if (OsUtils.isWindows()) {                    strExecuteCmd = "\"" + strMySQLPath;                    strExecuteCmd = strExecuteCmd + "bin\\mysqldump\" -hlocalhost -u " + strUser + " -p" + strPassword + " --add-drop-database -B iview -r \"" + strDbBackupFilePath + "\"";                }                try {                    runtimeProcess = Runtime.getRuntime().exec(strExecuteCmd);                    ...

    將請求的參數(shù)直接拼接進入了命令執(zhí)行語句:

    查看 `mysqldump` 支持的參數(shù)列表:

    其中 `-r` 可以指定導出文件的路徑, `-w` 用于設置導出的數(shù)據(jù)條件状共,但其取值也會導出到文件中套耕,所以我們可以用來傳遞 shell 內(nèi)容。最終通過構(gòu)造特殊的 `backup_filename` 參數(shù)實現(xiàn) getshell :

    方式3:路徑穿越可導致 getshell

    接口定義:

    提取參數(shù) `filename` 峡继,傳入 `exportDeviceList` 函數(shù)冯袍,沒有檢查存在路徑穿越風險:

    重點關注 `getExportDevices` 和 `createExportFile` 函數(shù):

  • ?`getExportDevices`

  • StringBuffer strSQL = new StringBuffer("SELECT a.nDeviceId AS \"Device Id\", b.strDescription AS \"Segment\", a.strDeviceTypeId AS \"Device Type\", a.strIPAddress AS \"IP Address\", a.strDNSName AS \"Device Domain Name\", a.strMACAddress AS \"MAC Address\", a.strGetCommunity AS \"Get Community\", a.strSetCommunity AS \"Set Community\", a.strDeviceUser AS \"Device User\", a.strDevicePassword AS \"Device Password\" FROM device_tree_table a, device_tree_table b WHERE a.nParentId = b.nDeviceId");String strColNames = "Device Id, Segment, Device Type, IP Address, Device Domain Name, MAC Address, Get Community, Set Community, Device User, Device Password";

    首先從數(shù)據(jù)表 `device_tree_table` 中查詢符合條件的設備列表 `tempDeviceList` ,然后通過 `setExportList` 賦值給 `m_ExportList` 私有變量碾牌。

  • `createExportFile`

  • 通過 `getExportList` 提取 `m_ExportList`變量并賦值給

    `tempRowOutputList` 颠猴,然后寫入路徑可控文件。

    從上面分析可知小染,如果可以將 shell 寫入 `device_tree_table` 翘瓮,那么結(jié)合路徑穿越可以將 shell 寫入任意目錄。比較幸運的是在 `NetworkServlet` 中可以找到添加設備的接口 `addDevices` :

    組合 `addDevices` 和 `exportDeviceList` 應該就可以實現(xiàn) getshell 裤翩。

    在漏洞復現(xiàn)時發(fā)現(xiàn)资盅, `addDevices` 在多個地方需要通過發(fā)送 udp 廣播包檢查設備的存活性(比如 `Network#updateProViewFunction` 函數(shù)):

    偽造數(shù)據(jù)包肯定可以繞過檢查调榄,有興趣的小伙伴可以自行深入分析協(xié)議解析過程完成構(gòu)造!

    修復方式

    多處增加了SQL注入檢查呵扛,比如`findCfgDeviceList` :

    多處增加了路徑穿越檢查每庆,比如 `exportDeviceList` :

    縫縫補補修復的地方很多,但是對比分析后仍然感覺程序代碼怎一個亂字了得今穿!

    ?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
    • 序言:七十年代末缤灵,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蓝晒,更是在濱河造成了極大的恐慌腮出,老刑警劉巖,帶你破解...
      沈念sama閱讀 219,539評論 6 508
    • 序言:濱河連續(xù)發(fā)生了三起死亡事件芝薇,死亡現(xiàn)場離奇詭異胚嘲,居然都是意外死亡,警方通過查閱死者的電腦和手機洛二,發(fā)現(xiàn)死者居然都...
      沈念sama閱讀 93,594評論 3 396
    • 文/潘曉璐 我一進店門馋劈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人晾嘶,你說我怎么就攤上這事妓雾。” “怎么了垒迂?”我有些...
      開封第一講書人閱讀 165,871評論 0 356
    • 文/不壞的土叔 我叫張陵械姻,是天一觀的道長。 經(jīng)常有香客問我娇斑,道長策添,這世上最難降的妖魔是什么材部? 我笑而不...
      開封第一講書人閱讀 58,963評論 1 295
    • 正文 為了忘掉前任毫缆,我火速辦了婚禮,結(jié)果婚禮上乐导,老公的妹妹穿的比我還像新娘苦丁。我一直安慰自己,他們只是感情好物臂,可當我...
      茶點故事閱讀 67,984評論 6 393
    • 文/花漫 我一把揭開白布旺拉。 她就那樣靜靜地躺著,像睡著了一般棵磷。 火紅的嫁衣襯著肌膚如雪蛾狗。 梳的紋絲不亂的頭發(fā)上,一...
      開封第一講書人閱讀 51,763評論 1 307
    • 那天仪媒,我揣著相機與錄音沉桌,去河邊找鬼。 笑死,一個胖子當著我的面吹牛留凭,可吹牛的內(nèi)容都是我干的佃扼。 我是一名探鬼主播,決...
      沈念sama閱讀 40,468評論 3 420
    • 文/蒼蘭香墨 我猛地睜開眼蔼夜,長吁一口氣:“原來是場噩夢啊……” “哼兼耀!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起求冷,我...
      開封第一講書人閱讀 39,357評論 0 276
    • 序言:老撾萬榮一對情侶失蹤瘤运,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后遵倦,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體尽超,經(jīng)...
      沈念sama閱讀 45,850評論 1 317
    • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
      茶點故事閱讀 38,002評論 3 338
    • 正文 我和宋清朗相戀三年梧躺,在試婚紗的時候發(fā)現(xiàn)自己被綠了似谁。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
      茶點故事閱讀 40,144評論 1 351
    • 序言:一個原本活蹦亂跳的男人離奇死亡掠哥,死狀恐怖巩踏,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情续搀,我是刑警寧澤塞琼,帶...
      沈念sama閱讀 35,823評論 5 346
    • 正文 年R本政府宣布,位于F島的核電站禁舷,受9級特大地震影響彪杉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜牵咙,卻給世界環(huán)境...
      茶點故事閱讀 41,483評論 3 331
    • 文/蒙蒙 一派近、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧洁桌,春花似錦渴丸、人聲如沸。這莊子的主人今日做“春日...
      開封第一講書人閱讀 32,026評論 0 22
    • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至吠谢,卻和暖如春土童,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背工坊。 一陣腳步聲響...
      開封第一講書人閱讀 33,150評論 1 272
    • 我被黑心中介騙來泰國打工献汗, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留错沃,地道東北人。 一個月前我還...
      沈念sama閱讀 48,415評論 3 373
    • 正文 我出身青樓雀瓢,卻偏偏與公主長得像枢析,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子刃麸,可洞房花燭夜當晚...
      茶點故事閱讀 45,092評論 2 355

    推薦閱讀更多精彩內(nèi)容