Prev Предыдущее сообщение   Следующее сообщение Next
Старый 30.07.2014, 22:58   #1
dharrya
 
Аватар для dharrya
 
Регистрация: 13.12.2011
Сообщений: 21
Репутация: 20
По умолчанию SSRF + фильтрация портов в fsockopen

Наткнулся на проект с SSRFиной и перегруженной функцией fsockopen с предварительной фильтрацией нежелательных портов, таких как 11211. Да, затея достаточно плохая, но что поделать...
Нашел пару способов обогнуть, но чувствую что есть еще хитрости:-) Для простоты и удобства, примеры фильтрации буду писать на PHP.
И так, что я смог придумать:
1. Сначала проверялся только второй аргумент функции, т.е. только порт:
PHP код:
function connect($host$port) {
    if (
$port == 11211)
        return;

    return 
fsockopen($host$port);

В общем, не правильно совсем. Т.к. php_stream_xport_create принимает только один аргумент (протокол + хост + порт) и потом парсит, то fsockopen делает конкатенацию:
PHP код:
if (port 0) {
    
hostname_len spprintf(&hostname0"%s:%ld"hostport);
} else {
    
hostname_len host_len;
    
hostname host;

Таким образом, достаточно было передать нужный порт и фейковый:
PHP код:
function connect($host$port) {
    if (
$port == 11211)
        return;

    return 
fsockopen($host$port);
}

var_dump(connect("target:11211blahblah"80)); 
2. Это быстренько учли и добавили валидацию, скопипастив логику из PHP. Присмотрелся к php_tcp_sockop_connect, и заметил что порт парсится в int и затем приводится к unsigned short. Получился очень простой вариант обхода:
PHP код:
function connect($host$port) {
    if (
$port == 11211)
        return;

       
// Условная проверка, что порт не будет передан в хосте. Убьет IPv6, ну да и фиг с ним
    
if (!preg_match("#^(?:[a-z0-9+.-]+?://)?[a-z0-9._-]+$#iD"$host))
        return;

    return 
fsockopen($host$port);
}

var_dump(connect("target"11211 65536)); 

Увы, это все на что меня хватило:-(
Окончательная фильтрация порта работает так:
1. Сначала делается конкатенация, потом парсится. Сделано копипастой из php, не подкопаться.
2. Проверяются границы port > 0 && port < 65535
3. Порт сверяется со списком запрещенных

Может у вас есть еще какие-нибудь варианты обхода подобных фильтраций порта или знаете какие особенности fsockopen? Может через какой-то хитрый протокол (я не нашел увы ничего походящего)?

Последний раз редактировалось dharrya; 30.07.2014 в 23:47..
dharrya вне форума   Ответить с цитированием
 

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход



Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd. Перевод: zCarot