Автор: @Vespii

Ссылка на таск Codeby:

https://codeby.games/categories/web/fd3f1c50-2c25-4b34-b5c9-f30d71528591

Описание задания

В коробке есть подарок, но получить его, видимо, будет непросто

62.173.140.174:16039

Решение

Вот что мы видим, когда заходим на сайт.

Если ввести “hacker”, то получим ответ “Something went wrong”. Почему так происходит? Давайте разберемся. Скачаем зипку, данную в задании и откроем код.

Объяснение кода

Для начала поймем, что происходит в этом коде.

Эта функция запускает сессию:

session_start();

Следующая функция проверяет наличие сессии. Если сессии нет, то генерируется новый идентификатор и записывается в PHPSESSID, заменяя старый:

if (!isset($_SESSION['PHPSESSID'])) {
 
	session_regenerate_id(true);
	
	$_SESSION['PHPSESSID'] = session_id();
 
}

Данная функция проверяет, чтобы PHPSESSID не был изменен вручную. Если сессия не совпадает с той, которая указана в коде, генерируется новая:

if ($_SESSION['PHPSESSID'] !== session_id()) {
 
	session_regenerate_id(true);
	
	$_SESSION['PHPSESSID'] = session_id();
 
}

Функция zerofunc001() также проверяет наличие сессии и, если она отсутствует, то запускает новую сессию:

if (session_status() == PHP_SESSION_NONE) {
	
	session_start();
	
}

Переменная $sessionId содержит идентификатор сессии, а переменная $pattern определяет диапазон символов:

$sessionId = session_id();
 
$pattern = '/[0-9]/';

Дальше с помощью функции preg_match_all() производится поиск всех символов, соответствующих заданному диапазону в переменной $pattern и результат записывают в переменную $matches.

preg_match_all($pattern, $sessionId, $matches);

Функция zerofunc001() возвращает количество найденных совпадений:

return count($matches[0]);

Вот полный код функции zerofunc001():

function zerofunc001() {
 
	if (session_status() == PHP_SESSION_NONE) {
	
	session_start();
	
	}
	
	$sessionId = session_id();
	
	$pattern = '/[0-9]/';
	
	preg_match_all($pattern, $sessionId, $matches);
	
	return count($matches[0]);
	
}

Функция zerofunc002($number) принимает число и проверяет, делится ли оно без остатка, то есть является ли оно четным:

function zerofunc002($number) {
	
	return $number % 2 == 0;
	
}

Следующая функция получает параметр word через POST и проверяет, что он не пустой.

if (isset($_POST['word']) && !empty($_POST['word']))

Затем значение параметра записывается в переменную $p:

$p0=$_POST[base64_decode('d29yZA==')];

Далее выполняется функция zerofunc001(), и результат записывается в переменную $e1:

$e1=zerofunc001();

После этого переменная $e1 передается в функцию zerofunc002() где происходит проверка условия. Если число четное, результат равен 2. В противном случае результат равен 3:

$x2=(zerofunc002($e1))?2:3;

Затем запускается цикл, который продолжается до тех пор, пока переменная $d3 не станет равной числу $x2. Внутри цикла происходит замена всех вхождений строки “hacker” в переменной $p0 на пустую строку, что фактически удаляет эту подстроку из переменной.

for($d3=0;$d3<$x2;$d3++) {
	
	$p0=str_replace(base64_decode('aGFja2Vy'),'',$p0);
	
} 

Результат цикла записывают в переменную $word

$word = $p0;

Вот так выглядит код полностью:

Теперь должно быть понятно, почему вместо флага получаем “Something went wrong”. Когда пишем hacker.

Обход и получение флага

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

Итак, приступим. Из кода мы уже знаем, что если ввести просто hacker, то он удаляется. Теперь хочу немного наглядно показать это:

Я доработала код, и теперь он показывает, что происходит в цикле:

Для тех, кто не понял. Код удалил “hacker” и остальные итерации остались пустыми. Нам нужно, чтобы к концу итерации остался один “hacker”.

Теперь попробуем “hackehackerr”.

Как видим “hacker” дошел до 0 итерации. Попробуем теперь “hackehackehackerrr”.

Теперь всё прошло так, как нужно. Все итерации были завершены, и в конце остался именно “hacker”, как мы и ожидали.

Теперь сделаем тоже самое на реальном сайте:

Tags:

#codeby#writeup#web#easy