日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

jmeter file upload 变量_通达OA上传漏洞之变量覆盖分析

發(fā)布時(shí)間:2024/7/19 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 jmeter file upload 变量_通达OA上传漏洞之变量覆盖分析 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

作者:kw0ng

開(kāi)始

通達(dá)OA上傳到包含漏洞分析的文章已經(jīng)有很多,本文重點(diǎn)分析,文件上傳處決定路徑信息是否回顯的UPLOAD_MODE參數(shù)是怎么傳遞的。

代碼分析

觸發(fā)文件上傳點(diǎn)位于/ispirit/im/upload.php中,服務(wù)端在接收文件信息的同時(shí)還需要幾個(gè)參數(shù),如不了解 multipart/form-data類(lèi)型如何傳遞參數(shù)的可以先去學(xué)習(xí)下,通達(dá)OA的PHP代碼采用了Zend54加密,但是我使用兩個(gè)不同的工具解密卻得到了不一致的代碼,這也導(dǎo)致了這篇文章差點(diǎn)難產(chǎn)。首先是第一段代碼:

$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';}

這段代碼需要一個(gè)POST傳參獲取P值,且為空時(shí)將會(huì)包含auth.php進(jìn)行重認(rèn)證,因?yàn)槲覀兊腜OST包需要一個(gè)P值且不為空。

$DEST_UID = $_POST['DEST_UID']; $dataBack = array();if ($DEST_UID != '' && !td_verify_ids($ids)) { $dataBack = array('status' => 0, 'content' => '-ERR ' . _('接收方ID無(wú)效')); 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無(wú)效')); echo json_encode(data2utf8($dataBack)); exit; }}

這段代碼中我們需要提供DEST_UID參數(shù),且如果DEST_UID為0,則觸發(fā)判斷UPLOAD_MODE是否等于2,不等于2則報(bào)error并退出,因此將DEST_UID不等于0可繞過(guò)。

if (1 <= count($_FILES)) { //返回?cái)?shù)組中元素的數(shù)目: 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 ' . _('無(wú)文件上傳')); echo json_encode(data2utf8($dataBack)); exit;}
  • 判斷1 <= count($FILES) 就是$FILES是否取到上傳數(shù)據(jù)。

  • 判斷UPLOAD_MODE是否等于1,如果等于1且文件名url解碼后的長(zhǎng)度不等于原長(zhǎng)度則將文件名url解碼。

  • 調(diào)用upload函數(shù)$ATTACHMENTS = upload('ATTACHMENT', $MODULE, false);傳入3個(gè)參數(shù),$MODULE = 'im';。

  • 使用PHP的$FILES函數(shù)來(lái)獲取我們上傳的文件信息$FILES['ATTACHMENT']['name'] $_FILES的第一個(gè)下標(biāo)必須是我們的input name值,因此我們的POST包的Content-Disposition: form-data; name="ATTACHMENT"; filename="jpg"中的name必須是'ATTACHMENT'。

  • else if ($UPLOAD_MODE == "2") { $DURATION = intval($_POST["DURATION"]); $CONTENT = "[vm]" . $ATTACHMENT_ID . "|" . $ATTACHMENT_NAME . "|" . $DURATION . "[/vm]"; $query = "INSERT INTO WEIXUN_SHARE (UID, CONTENT, ADDTIME) VALUES ('" . $_SESSION["LOGIN_UID"] . "', '" . $CONTENT . "', '" . time() . "')"; $cursor = exequery(TD::conn(), $query); echo "+OK " . $CONTENT;}else if ($UPLOAD_MODE == "3") { if (is_thumbable($ATTACHMENT_NAME)) { $FILE_PATH = attach_real_path($ATTACHMENT_ID, $ATTACHMENT_NAME, $MODULE); $THUMB_FILE_PATH = substr($FILE_PATH, 0, strlen($FILE_PATH) - strlen($ATTACHMENT_NAME)) . "thumb_" . $ATTACHMENT_NAME; CreateThumb($FILE_PATH, 320, 240, $THUMB_FILE_PATH); } echo "+OK " . $ATTACHMENT_ID;}

    本段代碼說(shuō)明了UPLOAD_MODE等于2或3的時(shí)候會(huì)返回$CONTENT或$ATTACHMENT_ID變量的值(1也可以),且返回值與最終文件上傳所在的路徑、文件名是相關(guān)的。

    綜上所述我們得到了3個(gè)信息

    • 存在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值的方法,但在實(shí)際測(cè)試中POST的UPLOAD_MODE值可以被正常帶入且影響文件上傳走向,因此判斷接收UPLOAD_MODE值的方法存在于被包含的文件中,在解密后使用搜索工具也僅發(fā)現(xiàn)UPLOAD_MODE這個(gè)參數(shù)名僅存在于upload.php中,開(kāi)始追溯之旅最后在common.inc.php文件中發(fā)現(xiàn)了UPLOAD_MODE的源頭.

    具體調(diào)用為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);}

    首先一開(kāi)始對(duì)$_POST長(zhǎng)度進(jìn)行了判斷,這里$_POST實(shí)際是一個(gè)數(shù)組,存儲(chǔ)了客戶端傳遞的參數(shù)與值,接著使用foreach函數(shù)對(duì)數(shù)組進(jìn)行遍歷,foreach函數(shù)也是CTF變量覆蓋漏洞經(jīng)??疾斓闹R(shí)點(diǎn),在這里我們假設(shè)$_POST數(shù)組中key為"UPLOAD_MODE",value為"2",那么我們將會(huì)最終進(jìn)入這段代碼中:

    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];

    關(guān)鍵代碼:

    ${$s_key}=$_POST[$s_key];

    方便大家理解我使用IDE將這段代碼運(yùn)行下.

    可以看到最終數(shù)組鍵名UPLOAD_MODE成了了變量名,而他的對(duì)應(yīng)鍵值成為了變量值.

    這也就是upload.php未直接接收UPLOAD_MODE值,而我們?nèi)钥梢詡鬟f此參數(shù)影響函數(shù)走向的原因.

    RCE

    在明白了上傳流程后,我們還需要配合本次的包含漏洞來(lái)包含我們上傳的代碼實(shí)現(xiàn)RCE,文件包含利用點(diǎn)在/ispirit/interface/gateway.php文件中. 首先

    if ($P != "") { if (preg_match("/[^a-z0-9;]+/i", $P)) { echo _("非法參數(shù)"); exit(); }

    參數(shù)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);因此我們需要構(gòu)造一個(gè)json,以及一個(gè)key為url且含有g(shù)eneral/或ispirit/或module/的值,讓函數(shù)走到include_once $url;處就完成了文件包含,至于$json從哪來(lái),我想看到這你就明白了.

    include_once "inc/session.php";include_once?"inc/conn.php"

    關(guān)于我們? ?

    蛇獴攻防實(shí)驗(yàn)室成立于2019年11月,專(zhuān)注網(wǎng)絡(luò)攻防技術(shù)。

    地點(diǎn):吉林·長(zhǎng)春

    總結(jié)

    以上是生活随笔為你收集整理的jmeter file upload 变量_通达OA上传漏洞之变量覆盖分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。