html 怎么让tr的css覆盖td的_通达OA上传漏洞之变量覆盖分析
作者:kw0ng
開始
通達OA上傳到包含漏洞分析的文章已經有很多,本文重點分析,文件上傳處決定路徑信息是否回顯的UPLOAD_MODE參數是怎么傳遞的。
代碼分析
觸發文件上傳點位于/ispirit/im/upload.php中,服務端在接收文件信息的同時還需要幾個參數,如不了解 multipart/form-data類型如何傳遞參數的可以先去學習下,通達OA的PHP代碼采用了Zend54加密,但是我使用兩個不同的工具解密卻得到了不一致的代碼,這也導致了這篇文章差點難產。首先是第一段代碼:
$P = $_POST['P'];if (isset($P) || $P != '') { ob_start(); include_once 'inc/session.php'; //如果P不為空 session_id($P); session_start(); session_write_close();} else { include_once './auth.php';}這段代碼需要一個POST傳參獲取P值,且為空時將會包含auth.php進行重認證,因為我們的POST包需要一個P值且不為空。
$DEST_UID = $_POST['DEST_UID']; $dataBack = array();if ($DEST_UID != '' && !td_verify_ids($ids)) { $dataBack = array('status' => 0, 'content' => '-ERR ' . _('接收方ID無效')); echo json_encode(data2utf8($dataBack)); exit;}if (strpos($DEST_UID, ',') !== false) { } else { $DEST_UID = intval($DEST_UID); }if ($DEST_UID == 0) { if ($UPLOAD_MODE != 2) { $dataBack = array('status' => 0, 'content' => '-ERR ' . _('接收方ID無效')); echo json_encode(data2utf8($dataBack)); exit; }}這段代碼中我們需要提供DEST_UID參數,且如果DEST_UID為0,則觸發判斷UPLOAD_MODE是否等于2,不等于2則報error并退出,因此將DEST_UID不等于0可繞過。
if (1 <= count($_FILES)) { //返回數組中元素的數目: if ($UPLOAD_MODE == '1') { //如果UPLOAD_MODE = 1 if (strlen(urldecode($_FILES['ATTACHMENT']['name'])) != strlen($_FILES['ATTACHMENT']['name'])) { $_FILES['ATTACHMENT']['name'] = urldecode($_FILES['ATTACHMENT']['name']); } } $ATTACHMENTS = upload('ATTACHMENT', $MODULE, false); if (!is_array($ATTACHMENTS)) { $dataBack = array('status' => 0, 'content' => '-ERR ' . $ATTACHMENTS); echo json_encode(data2utf8($dataBack)); exit; } ob_end_clean(); $ATTACHMENT_ID = substr($ATTACHMENTS['ID'], 0, -1); $ATTACHMENT_NAME = substr($ATTACHMENTS['NAME'], 0, -1); if ($TYPE == 'mobile') { $ATTACHMENT_NAME = td_iconv(urldecode($ATTACHMENT_NAME), 'utf-8', MYOA_CHARSET); }} else { $dataBack = array('status' => 0, 'content' => '-ERR ' . _('無文件上傳')); echo json_encode(data2utf8($dataBack)); exit;}判斷1 <= count($FILES) 就是$FILES是否取到上傳數據。
判斷UPLOAD_MODE是否等于1,如果等于1且文件名url解碼后的長度不等于原長度則將文件名url解碼。
調用upload函數$ATTACHMENTS = upload('ATTACHMENT', $MODULE, false);傳入3個參數,$MODULE = 'im';。
使用PHP的$FILES函數來獲取我們上傳的文件信息$FILES['ATTACHMENT']['name'] $_FILES的第一個下標必須是我們的input name值,因此我們的POST包的Content-Disposition: form-data; name="ATTACHMENT"; filename="jpg"中的name必須是'ATTACHMENT'。
本段代碼說明了UPLOAD_MODE等于2或3的時候會返回$CONTENT或$ATTACHMENT_ID變量的值(1也可以),且返回值與最終文件上傳所在的路徑、文件名是相關的。
綜上所述我們得到了3個信息
存在P值且不為空 ($_POST["P"]獲取)
DEST_UID不為0?($POST["DEST_UID"]獲取)
UPLOAD_MODE = 1或2或3?(非$POST["UPLOAD_MODE"]獲取)
Content-Disposition中name值為"ATTACHMENT"
流程圖:
變量覆蓋
由于在upload.php中未找到取UPLOAD_MODE值的方法,但在實際測試中POST的UPLOAD_MODE值可以被正常帶入且影響文件上傳走向,因此判斷接收UPLOAD_MODE值的方法存在于被包含的文件中,在解密后使用搜索工具也僅發現UPLOAD_MODE這個參數名僅存在于upload.php中,開始追溯之旅最后在common.inc.php文件中發現了UPLOAD_MODE的源頭.
具體調用為upload.php -> session.php -> coon.php -> td_config.php -> common.inc.php
漏洞代碼為:
if (0 < count($_POST)) { $arr_html_fields = array(); foreach ($_POST as $s_key => $s_value) { if (substr($s_key, 0, 7) == '_SERVER') { continue; } if (substr($s_key, 0, 15) != 'TD_HTML_EDITOR_') { if (!is_array($s_value)) { $_POST[$s_key] = addslashes(strip_tags($s_value)); } ${$s_key} = $_POST[$s_key]; } else { if ($s_key == 'TD_HTML_EDITOR_FORM_HTML_DATA' || $s_key == 'TD_HTML_EDITOR_PRCS_IN' || $s_key == 'TD_HTML_EDITOR_PRCS_OUT' || $s_key == 'TD_HTML_EDITOR_QTPL_PRCS_SET' || isset($_POST['ACTION_TYPE']) && ($_POST['ACTION_TYPE'] == 'approve_center' || $_POST['ACTION_TYPE'] == 'workflow' || $_POST['ACTION_TYPE'] == 'sms' || $_POST['ACTION_TYPE'] == 'wiki') && ($s_key == 'CONTENT' || $s_key == 'TD_HTML_EDITOR_CONTENT' || $s_key == 'TD_HTML_EDITOR_TPT_CONTENT')) { unset($_POST[$s_key]); $s_key = $s_key == 'CONTENT' ? $s_key : substr($s_key, 15); ${$s_key} = addslashes($s_value); $arr_html_fields[$s_key] = ${$s_key}; } else { $encoding = mb_detect_encoding($s_value, 'GBK,UTF-8'); unset($_POST[$s_key]); $s_key = substr($s_key, 15); ${$s_key} = addslashes(rich_text_clean($s_value, $encoding)); $arr_html_fields[$s_key] = ${$s_key}; } } } reset($_POST); $_POST = array_merge($_POST, $arr_html_fields);}首先一開始對$_POST長度進行了判斷,這里$_POST實際是一個數組,存儲了客戶端傳遞的參數與值,接著使用foreach函數對數組進行遍歷,foreach函數也是CTF變量覆蓋漏洞經常考察的知識點,在這里我們假設$_POST數組中key為"UPLOAD_MODE",value為"2",那么我們將會最終進入這段代碼中:
if (substr($s_key, 0, 15) != 'TD_HTML_EDITOR_') { if (!is_array($s_value)) { $_POST[$s_key] = addslashes(strip_tags($s_value)); } ${$s_key} = $_POST[$s_key];關鍵代碼:
${$s_key}=$_POST[$s_key];方便大家理解我使用IDE將這段代碼運行下.
可以看到最終數組鍵名UPLOAD_MODE成了了變量名,而他的對應鍵值成為了變量值.
這也就是upload.php未直接接收UPLOAD_MODE值,而我們仍可以傳遞此參數影響函數走向的原因.
RCE
在明白了上傳流程后,我們還需要配合本次的包含漏洞來包含我們上傳的代碼實現RCE,文件包含利用點在/ispirit/interface/gateway.php文件中. 首先
if ($P != "") { if (preg_match("/[^a-z0-9;]+/i", $P)) { echo _("非法參數"); exit(); }參數P要為空值.接著
if ($json) { $json = stripcslashes($json); $json = (array) json_decode($json); foreach ($json as $key => $val ) { if ($key == "data") { $val = (array) $val; foreach ($val as $keys => $value ) { $keys = $value; } } if ($key == "url") { $url = $val; } } if ($url != "") { if (substr($url, 0, 1) == "/") { $url = substr($url, 1); } if ((strpos($url, "general/") !== false) || (strpos($url, "ispirit/") !== false) || (strpos($url, "module/") !== false)) { include_once $url; } } exit();}由于存在json_decode($json);因此我們需要構造一個json,以及一個key為url且含有general/或ispirit/或module/的值,讓函數走到include_once $url;處就完成了文件包含,至于$json從哪來,我想看到這你就明白了.
include_once "inc/session.php";include_once?"inc/conn.php"關于我們? ?
蛇獴攻防實驗室成立于2019年11月,專注網絡攻防技術。
地點:吉林·長春
總結
以上是生活随笔為你收集整理的html 怎么让tr的css覆盖td的_通达OA上传漏洞之变量覆盖分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql 时间 设计模式_数据库时间设
- 下一篇: 山东大学继续教育计算机在线作业,山东大学