Функциональные функции PHP

Я пытаюсь создать список функций, которые можно использовать для выполнения произвольного кода. Цель состоит не в том, чтобы перечислять функции, которые должны быть внесены в черный список или иным образом запрещены. Скорее, я хотел бы иметь grep -able список ключевых слов с красным флагом, удобный при поиске скомпрометированного сервера для задних дверей.

Идея состоит в том, что если вы хотите создать многоцелевой вредоносный PHP script - например, "веб-оболочку" script, например c99 или r57, вам придется использовать один или несколько относительно небольшого набора функций где-то в файле, чтобы позволить пользователю выполнять произвольный код. Поиск этих функций помогает вам быстрее сузить стог сена десятков тысяч файлов PHP до относительно небольшого набора сценариев, которые требуют более пристального изучения.

Очевидно, что, например, любое из следующего будет считаться вредоносным (или ужасным кодированием):

<? eval($_GET['cmd']); ?>

<? system($_GET['cmd']); ?>

<? preg_replace('/.*/e',$_POST['code']); ?>

и т.д.

Поиск через скомпрометированный веб-сайт на днях я не заметил фрагмента вредоносного кода, потому что я не понимал, что preg_replace может быть опасным с помощью флага /e (что серьезно? это даже там?). Есть ли другие, которые я пропустил?

Вот мой список:

Shell Execute

  • system
  • exec
  • popen
  • backtick operator
  • pcntl_exec

Выполнение PHP

  • eval
  • preg_replace (с модификатором /e)
  • create_function
  • include [_once]/require [_once] (см. комментарий mario для подробностей использования)

Также может быть полезно иметь список функций, способных модифицировать файлы, но я полагаю, что 99% кода эксплойта времени будет содержать хотя бы одну из вышеперечисленных функций. Но если у вас есть список всех функций, способных редактировать или выводить файлы, отправьте его, и я включу его здесь. (И я не считаю mysql_execute, так как эта часть другого класса эксплойта.)

Ответ 1

Чтобы создать этот список, я использовал 2 источника. Исследование в алого и RATS. Я также добавил некоторые из моих собственных в микс, и люди в этой теме помогли.

Изменить: После публикации этого списка я связался с основоположником RIPS и на данный момент это поиск инструментов PHP-код для использования каждой функции в этом списке.

Большинство этих вызовов функций классифицируются как Sinks. Когда зараженная переменная (например, $_REQUEST) передается в функцию приемника, у вас есть уязвимость. Программы, такие как RATS и RIPS используют grep like чтобы идентифицировать все приемники в приложении. Это означает, что программисты должны проявлять особую осторожность при использовании этих функций, но если они будут запрещены, то вы не сможете многое сделать.

"С великой силой приходит большая ответственность".

- Стэн Ли

Выполнение команды

exec           - Returns last line of commands output
passthru       - Passes commands output directly to the browser
system         - Passes commands output directly to the browser and returns last line
shell_exec     - Returns commands output
`` (backticks) - Same as shell_exec()
popen          - Opens read or write pipe to process of a command
proc_open      - Similar to popen() but greater degree of control
pcntl_exec     - Executes a program

Выполнение кода PHP

Помимо eval существуют другие способы выполнения PHP-кода: include/require может использоваться для удаленного выполнения кода в виде Local File Include и Удаленный файл Включить уязвимости.

eval()
assert()  - identical to eval()
preg_replace('/.*/e',...) - /e does an eval() on the match
create_function()
include()
include_once()
require()
require_once()
$_GET['func_name']($_GET['argument']);
$func = new ReflectionFunction($_GET['func_name']); $func->invoke(); or $func->invokeArgs(array());

Список функций, которые принимают обратные вызовы

Эти функции принимают строковый параметр, который можно использовать для вызова функции выбора злоумышленника. В зависимости от функции злоумышленник может или не может иметь возможность передать параметр. В этом случае можно использовать функцию Information Disclosure, такую ​​как phpinfo().

Function                     => Position of callback arguments
'ob_start'                   =>  0,
'array_diff_uassoc'          => -1,
'array_diff_ukey'            => -1,
'array_filter'               =>  1,
'array_intersect_uassoc'     => -1,
'array_intersect_ukey'       => -1,
'array_map'                  =>  0,
'array_reduce'               =>  1,
'array_udiff_assoc'          => -1,
'array_udiff_uassoc'         => array(-1, -2),
'array_udiff'                => -1,
'array_uintersect_assoc'     => -1,
'array_uintersect_uassoc'    => array(-1, -2),
'array_uintersect'           => -1,
'array_walk_recursive'       =>  1,
'array_walk'                 =>  1,
'assert_options'             =>  1,
'uasort'                     =>  1,
'uksort'                     =>  1,
'usort'                      =>  1,
'preg_replace_callback'      =>  1,
'spl_autoload_register'      =>  0,
'iterator_apply'             =>  1,
'call_user_func'             =>  0,
'call_user_func_array'       =>  0,
'register_shutdown_function' =>  0,
'register_tick_function'     =>  0,
'set_error_handler'          =>  0,
'set_exception_handler'      =>  0,
'session_set_save_handler'   => array(0, 1, 2, 3, 4, 5),
'sqlite_create_aggregate'    => array(2, 3),
'sqlite_create_function'     =>  2,

Раскрытие информации

Большинство этих вызовов функций не являются приемниками. Но скорее это может быть уязвимость, если какой-либо из возвращаемых данных можно просмотреть злоумышленнику. Если злоумышленник может видеть phpinfo(), это определенно уязвимость.

phpinfo
posix_mkfifo
posix_getlogin
posix_ttyname
getenv
get_current_user
proc_get_status
get_cfg_var
disk_free_space
disk_total_space
diskfreespace
getcwd
getlastmo
getmygid
getmyinode
getmypid
getmyuid

Другие

extract - Opens the door for register_globals attacks (see study in scarlet).
parse_str -  works like extract if only one argument is given.  
putenv
ini_set
mail - has CRLF injection in the 3rd parameter, opens the door for spam. 
header - on old systems CRLF injection could be used for xss or other purposes, now it is still a problem if they do a header("location: ..."); and they do not die();. The script keeps executing after a call to header(), and will still print output normally. This is nasty if you are trying to protect an administrative area. 
proc_nice
proc_terminate
proc_close
pfsockopen
fsockopen
apache_child_terminate
posix_kill
posix_mkfifo
posix_setpgid
posix_setsid
posix_setuid

Функции файловой системы

В соответствии с RATS все функции файловой системы в php являются неприятными. Некоторые из них не очень полезны для злоумышленника. Другие полезнее, чем вы думаете. Например, если allow_url_fopen=On, то URL-адрес может использоваться как путь к файлу, поэтому вызов copy($_GET['s'], $_GET['d']); может быть использован для загрузки PHP скрипт в любом месте системы. Также, если сайт уязвим для отправки запроса через GET, каждый из этих функций файловой системы может злоупотреблять каналом и атаковать другого хоста через ваш сервер.

// open filesystem handler
fopen
tmpfile
bzopen
gzopen
SplFileObject->__construct
// write to filesystem (partially in combination with reading)
chgrp
chmod
chown
copy
file_put_contents
lchgrp
lchown
link
mkdir
move_uploaded_file
rename
rmdir
symlink
tempnam
touch
unlink
imagepng   - 2nd parameter is a path.
imagewbmp  - 2nd parameter is a path. 
image2wbmp - 2nd parameter is a path. 
imagejpeg  - 2nd parameter is a path.
imagexbm   - 2nd parameter is a path.
imagegif   - 2nd parameter is a path.
imagegd    - 2nd parameter is a path.
imagegd2   - 2nd parameter is a path.
iptcembed
ftp_get
ftp_nb_get
// read from filesystem
file_exists
file_get_contents
file
fileatime
filectime
filegroup
fileinode
filemtime
fileowner
fileperms
filesize
filetype
glob
is_dir
is_executable
is_file
is_link
is_readable
is_uploaded_file
is_writable
is_writeable
linkinfo
lstat
parse_ini_file
pathinfo
readfile
readlink
realpath
stat
gzfile
readgzfile
getimagesize
imagecreatefromgif
imagecreatefromjpeg
imagecreatefrompng
imagecreatefromwbmp
imagecreatefromxbm
imagecreatefromxpm
ftp_put
ftp_nb_put
exif_read_data
read_exif_data
exif_thumbnail
exif_imagetype
hash_file
hash_hmac_file
hash_update_file
md5_file
sha1_file
highlight_file
show_source
php_strip_whitespace
get_meta_tags

Ответ 2

Вам нужно будет сканировать для include ($ tmp) и require (HTTP_REFERER) и * _once. Если эксплойт script может записывать во временный файл, он может просто включить это позже. В основном двухэтапная оценка.

И даже можно скрыть удаленный код с обходными методами, например:

 include("data:text/plain;base64,$_GET[code]");

Кроме того, если ваш веб-сервер уже скомпрометирован, вы не всегда увидите незарегистрированное зло. Часто оболочка эксплойта кодируется gzip. Подумайте о include("zlib:script2.png.gz"); Здесь нет eval, все тот же эффект.

Ответ 3

Это не ответ как таковой, но здесь что-то интересное:

$y = str_replace('z', 'e', 'zxzc');
$y("malicious code");

В том же духе call_user_func_array() может использоваться для выполнения запутанных функций.

Ответ 4

Я удивлен, что никто не упомянул echo и print как точки безопасности.

Скрипты между сайтами (XSS) - это серьезный эксплойт безопасности, поскольку он даже более распространен, чем эксплойты выполнения на стороне сервера.

Ответ 5

В частности, я хочу добавить unserialize() в этот список. Он имел долгую историю различных уязвимостей, включая произвольное выполнение кода, отказ в обслуживании и утечку информации о памяти. Его никогда не следует вызывать по предоставленным пользователем данным. Многие из этих vuls были зафиксированы в релизах в течение последних лет росы, но в настоящее время все еще сохраняется пара неприятных ударов в настоящее время.

Для получения дополнительной информации об уродливых функциях/использовании php смотрите Закаленный PHP-проект и его советы. Также недавний Месяц безопасности PHP и 2007 Месяц ошибок PHP проекты

Также обратите внимание, что при проектировании неэтериализация объекта приведет к выполнению функций конструктора и деструктора; еще одна причина не называть его предоставленными пользователем данными.

Ответ 6

Мой VPS установлен для отключения следующих функций:

[email protected] [~]# grep disable_functions /usr/local/lib/php.ini
disable_functions = dl, exec, shell_exec, system, passthru, popen, pclose, proc_open, proc_nice, proc_terminate, proc_get_status, proc_close, pfsockopen, leak, apache_child_terminate, posix_kill, posix_mkfifo, posix_setpgid, posix_setsid, posix_setuid

PHP имеет достаточно потенциально разрушаемых функций, которые могут быть слишком большими для вашего списка. Например, PHP имеет chmod и chown, которые могут быть использованы для простого деактивации веб-сайта.

EDIT: возможно, вам захочется создать bash script, который ищет файл для массива функций, сгруппированных по опасностям (функции, которые плохи, функции, которые хуже, функции, которые никогда не должны использоваться) а затем вычислить относительность опасности, которую файл накладывает на процент. Затем выведите это в дерево каталога с процентами, помеченными рядом с каждым файлом, если это превышает 30% опасности.

Ответ 7

Также имейте в виду класс "уязвимостей прерывания", которые позволяют читать и записывать произвольные ячейки памяти!

Они влияют на такие функции, как trim(), rtrim(), ltrim(), explode(), strchr(), strstr(), substr(), chunk_split(), strtok(), addcslashes(), str_repeat ( ) и более. Это в значительной степени, но не исключительно, из-за функции переадресации вызова по времени на языке, который устарел на 10 лет, но не отключен.

Для получения дополнительной информации см. статью Стефана Эссерса об уязвимостях прерывания и других проблемах с низким уровнем PHP в BlackHat USA 2009 Slides Paper

В этой статье/презентации также показано, как dl() может использоваться для выполнения произвольного системного кода.

Ответ 8

Специфичные по Plattform, но и теоретические векторы exec:

  • dotnet_load()
  • новый COM ( "WScript.Shell" )
  • новая Java ( "java.lang.Runtime" )
  • event_new() - в конечном итоге

И есть еще много методов маскировки:

  • proc_open является псевдонимом для popen
  • call_user_func_array ( "exE".chr(99), array ( "/usr/bin/damage", "--all" ));
  • file_put_contents ( "/cgi-bin/nextinvocation.cgi" ) && & & CHMOD (...)
  • PharData:: setDefaultStub - еще одна работа по проверке кода в файлах .phar
  • runkit_function_rename ( "exec", "innocent_name" ) или APD rename_function

Ответ 9

Помимо конструкции языка eval существует еще одна функция, которая позволяет выполнять произвольный код: assert

assert('ex' . 'ec("kill --bill")');

Ответ 10

Один источник интересных эксплойтов не упоминался. PHP позволяет содержать строки 0x00. Базовые (libc) функции рассматривают это как конец строки.

Это позволяет использовать ситуации, когда (плохо реализовано) проверка работоспособности в PHP может быть обманута, например. в ситуации вроде:

/// note: proof of principle code, don't use
$include = $_GET['file'];
if ( preg_match("/\\.php$/",$include) ) include($include);

Это может включать любой файл, а не только те, которые заканчиваются на .php, путем вызова script.php?file=somefile%00.php

Таким образом, любая функция, которая не будет соответствовать длине строки PHP, может привести к некоторой уязвимости.

Ответ 11

Как насчет опасных синтаксических элементов?

" variable variable" ($$var) найдет переменную в текущей области по имени $var. При неправильном использовании удаленный пользователь может изменить или прочитать любую переменную в текущей области. В основном слабее eval.

Ex: вы пишете код $$uservar = 1;, тогда удаленный пользователь устанавливает $uservar в "admin", в результате чего $admin будет установлено в 1 в текущей области.

Ответ 12

Думаю, вы не сможете найти все возможные эксплойты, проанализировав исходные файлы.

  • Также, если есть действительно большие списки, представленные здесь, вы можете пропустить функцию, которая может быть использована

  • там все еще может быть "скрытый" злой код, подобный этому

$myEvilRegex = base64_decode ('Ly4qL2U =');

preg_replace ($ myEvilRegex, $_POST ['code']);

  • Теперь вы можете сказать, я просто расширяю свой script, чтобы также соответствовать этому

  • но тогда у вас будет этот mayn "возможно, злой код", который, кроме того, вне контекста

  • чтобы быть (псевдо) безопасным, вы действительно должны писать хороший код и читать весь существующий код самостоятельно

Ответ 14

Я знаю, что move_uploaded_file упоминается, но загрузка файлов в целом очень опасна. Просто наличие $_FILES должно вызвать некоторую озабоченность.

Вполне возможно встроить PHP-код в любой тип файла. Изображения могут быть особенно уязвимы с текстовыми комментариями. Проблема особенно затруднительна, если код принимает расширение, найденное в $_FILES данных как есть.

Например, пользователь может загрузить действительный файл PNG со встроенным PHP-кодом как "foo.php". Если script является особенно наивным, он может фактически скопировать файл как "/uploads/foo.php". Если сервер настроен на выполнение script исполнения в каталогах загрузки пользователей (часто это случается и ужасный надзор), вы сразу можете запускать любой произвольный PHP-код. (Даже если изображение сохранено как .png, возможно, код будет выполнен с помощью других недостатков безопасности.)

A (неисчерпывающий) список вещей, которые нужно проверить при загрузке:

  • Обязательно проанализируйте содержимое, чтобы убедиться, что загрузка является типом, который, по его утверждению, является
  • Сохраните файл с известным безопасным расширением файла, который никогда не будет выполнен
  • Убедитесь, что PHP (и любое другое исполнение кода) отключено в каталогах загрузки пользователей

Ответ 15

Добавьте в список pcntl_signal и pcntl_alarm.

С помощью этих функций вы можете обойти любое ограничение set_time_limit, созданное int php.ini или в script.

Этот script, например, будет работать в течение 10 секунд, несмотря на set_time_limit(1);

(Кредит принадлежит Себастьяну Бергманнсу твит и gist:

<?php
declare(ticks = 1);

set_time_limit(1);

function foo() {
    for (;;) {}
}

class Invoker_TimeoutException extends RuntimeException {}

class Invoker
{
    public function invoke($callable, $timeout)
    {
        pcntl_signal(SIGALRM, function() { throw new Invoker_TimeoutException; }, TRUE);
        pcntl_alarm($timeout);
        call_user_func($callable);
    }
}

try {
    $invoker = new Invoker;
    $invoker->invoke('foo', 1);
} catch (Exception $e) {
    sleep(10);
    echo "Still running despite of the timelimit";
}

Ответ 16

Существует множество эксплойтов PHP, которые могут быть отключены настройками в файле PHP.ini. Очевидным примером является register_globals, но в зависимости от настроек также возможно включать или открывать файлы с удаленных компьютеров через HTTP, которые могут быть использованы, если программа использует имена файлов переменных для любой из функций include() или обработки файлов.

PHP также допускает вызов функции переменной путем добавления() в конец имени переменной - например, $myvariable(); будет вызывать имя функции, указанное переменной. Это можно использовать; например, если злоумышленник может заставить переменную содержать слово "eval" и может управлять параметром, тогда он может делать все, что захочет, хотя программа фактически не содержит функцию eval().

Ответ 17

Эти функции также могут иметь некоторые неприятные эффекты.

  • str_repeat()
  • unserialize()
  • register_tick_function()
  • register_shutdown_function()

Первые два могут исчерпать всю доступную память, а последние сохраняют усталость...

Ответ 18

Недавно было обсуждено это на security.stackexchange.com

которые могут использоваться для выполнения произвольного кода

Ну, это немного уменьшает область видимости, но поскольку "печать" может быть использована для ввода javascript (и, следовательно, воровских сессий и т.д.), она все еще несколько произвольна.

не следует перечислять функции, которые должны быть внесены в черный список или иным образом запрещены. Скорее, я хотел бы иметь список grep-able

Это разумный подход.

Подумайте о том, чтобы написать собственный синтаксический анализатор, хотя очень скоро вы поймете, что подход на основе grep выходит из-под контроля (awk будет немного лучше). Довольно скоро вы тоже начнете желать, чтобы вы внедрили белый список!

В дополнение к очевидным, я бы рекомендовал помечать все, что включает include, с аргументом чего-либо, кроме строкового литерала. Следите за __autoload() тоже.

Ответ 19

Я боюсь, что мой ответ может быть слишком негативным, но...

ИМХО, каждая отдельная функция и метод там могут использоваться для гнусных целей. Подумайте об этом как о влиянии нецензурности: переменная присваивается пользователю или удаленному вводу, переменная используется в функции, возвращаемое значение функции, используемое в свойстве класса, свойство класса, используемое в файловой функции, и так далее. Помните: поддельный IP-адрес или атака "человек-в-середине" могут использовать весь ваш сайт.

Лучше всего трассировать от начала до конца любой возможный пользовательский или удаленный вход, начиная с $_SERVER, $_GET, $_POST, $_FILE, $_COOKIE, include(some remote file) (if allow_url_fopen включен), все другие функции/классы, относящиеся к удаленным файлам и т.д. Вы программно создаете профиль трассировки стека для каждого пользовательского или удаленного значения. Это можно сделать программно, получив все повторяющиеся экземпляры назначенной переменной, а также функции или методы, в которых она используется, а затем рекурсивно компилирует список всех вхождений этих функций/методов и т.д. Изучите его, чтобы убедиться, что он сначала проходит надлежащую фильтрацию и проверку функций по отношению ко всем другим функциям, которые он затрагивает. Это, конечно, ручное исследование, в противном случае у вас будет общее количество переключателей case, равное числу функций и методов в PHP (включая определенные пользователем).

В качестве альтернативы для обработки только пользовательского ввода, статический класс контроллера инициализируется в начале всех сценариев, которые 1) проверяют и сохраняют все введенные пользователем входные значения в виде белого списка разрешенных целей; 2) стирает этот входной источник (т.е. $_SERVER = null). Вы можете видеть, где это получает немного Назиске.

Ответ 20

Вот список функций, которые мой провайдер отключает для целей безопасности:

  • Exec
  • дл
  • show_source
  • apache_note
  • apache_setenv
  • closelog
  • debugger_off
  • debugger_on
  • define_syslog_variables
  • escapeshellarg
  • EscapeShellCmd
  • ini_restore
  • openlog
  • PassThru
  • pclose
  • pcntl_exec
  • POPEN
  • proc_close
  • proc_get_status
  • proc_nice
  • proc_open
  • proc_terminate
  • shell_exec
  • Syslog
  • система
  • url_exec

Ответ 21

Большинство атак в коде используют несколько источников доступа или несколько шагов для выполнения. Я бы искал не только код, либо метод с вредоносным кодом, но и все методы, выполнение функции или ее вызов. Наилучшая безопасность также будет включать в себя кодирование и проверку данных формы, когда она приходит и выходит.

Следите также за тем, чтобы определить системные переменные, после чего они могут быть вызваны из любой функции или метода в коде.

Ответ 22

Несколько переполнений буфера были обнаружены с использованием 4-битного символов, которые интерпретируют текст. htmlentities() htmlspecialchars()

были наверху, хорошая защита - использовать mb_convert_encoding() для преобразования в одиночный кодирование до интерпретации.

Ответ 23

Вы можете найти постоянно обновляемый список чувствительных приемников (эксплуатационные функции php) и их параметры в RIPS/config/sinks.php, a статический анализатор исходного кода для уязвимостей в PHP-приложениях, которые также обнаруживают PHP backdoor.