Function hijaking

Перехват функций – архиполезная штука. Если нет возможности изобрести пяттиколесный велосопед, поймать опасную функцию (системную команду) за хвост можно с помощью модуля Baxtep (спасибо Андрею).

Baxtep – PHP security extension to intercept execution of system commands.

Для сборки модуля понадобятся пара прямых рук и такие команды:

# скачиваем с репозитория
svn checkout https://baxtep.googlecode.com/svn/trunk/ baxtep

# переходим в каталог
cd baxtep

# собираем:
phpize
# если у вас PHP в нестандартном каталоге, укажите полный путь:
# /usr/local/php5-fcgi/bin/phpize
./configure
make

# закиньте модуль в папку с модулями:
cp .libs/baxtep.so /usr/local/php5-fcgi/lib/php/extensions/no-debug-non-zts-20060613/baxtep.so

# каталог с модулями можно определить командой
php -i | grep extension_
# или по полному пути:
# /usr/local/php53-fcgi/bin/php -i | grep extension_

# php.ini можно найти тоже через php -i, добавьте туда:
baxtep.logfile = "/tmp/baxtep_messages"
# или укажите другой путь, куда удобнее. я добавил строчку перед
# [Zend]

Все, перезапускайте Apache/PHP, в зависимости от того, что вам нужно перезапустить, чтобы модуль подгрузился. Вахтер послушно запишет в лог-файл все системные вызовы, например:

2012-02-25 19:35:39 BAXTEP: proc_open CMDLINE: `php` FILE: /path/to/file/1.php on line 11 URI: /1.php
2012-02-25 19:35:39 BAXTEP: shell_exec CMDLINE: `date` FILE: - on line 1 URI: (null)

Среди опасных, есть еще функция proc_open, чтобы ее перехватывать, нужно добавить в файл baxtep.c строчку:

php_baxtep_substitute_function("proc_open" TSRMLS_CC);

и пересобрать/переподгрузить модуль.

Список функций, которые я блокирую, если в них нет острой необходимости (php.ini):

disable_functions = exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec

Скрытие кода, метод 6: ionCube HTML obfuscator

На сайте ionCube случайно заметил бесплатную плюшку – Free Obfuscating HTML Encoder. Захотелось посмотреть и раскодировать)

Закодированная страница в примере на сайте выглядит следующим образом:

<script language=javascript>
c="e66x75...Y7dF7d"; // [1] first long string
eval(unescape("%64%3d...%22%3b")); // [2] second long string
x("C3Bomk...4ApQkS"); // [3] third long string
</script>

В оригинале весь код располагается в одну строку. В строке #4 вызов неизвестной функции, по всей видимости, она находится в блоке с eval и ее нужно раскрыть. Логично предположить, что тело страницы (контент) находится непосредственно в строке, передаваемой этой функции.

1. Убираем eval и помещаем все в textarea или смотрим через alert:

document.write( "<textarea>" );
document.write( unescape("%64%3d...%22%3b") );
document.write( "</textarea>" );
Читать далее

Microsoft Facepalm 2012

Майкрософт такой Майкрософт. Ну вот нахрена им люди в техподдержке, если на вопросы живых людей они отвечают как роботы-имбецилы? Задал 4 вопроса, ответили куском текста с сайта, ну не ептель? Нахрена вообще такая “техподдержка”? Маразм крепчает…

VMWare + physical drive vs Android

Некоторое время назад я описывал способ лечения VMWare, которая отказывалась открывать физический диск. С того времени еще не раз сталкивался с прекрасным.

Bug #2

Второй баг обнаружился вот просто только что. Перезагрузил Виндовс после установки обновлений и VMWare выдала свое феерическое:

The physical disk is already in use (73).

Проклиная VMWare Не понимая, что происходит, стал пытаться смотреть какая скотина кто использует без спроса жесткий диск, но потом пошел другим путем, как оказалось – более правильным. Стал искать что же изменилось в физическом окружении между запусками VMWare.

Перед ребутом я подключил телефон HTC Wildfire S, чтобы немного подзарядить. Выключил, запустил VMWare – и, о чудо, она прекрасно завелась. Каким образом съемный диск (карточка телефона) повлиял на VMWare – не ясно. =/

Bug #1

Первый баг обнаружился раньше, VMWare наотрез отказывается работать с физическим диском, если в системе есть software raid из динамических дисков (dymanic disks). Баг вроде даже как известный, но ВМВаревцы не чешут яйца, чтобы исправить, видимо мало кто жалуется и она забили болт.

Скрытие кода, метод 5

Следующий код был выдран из тела страницы взломанного сайта, этот javascript вставлял небольшой фрейм (сразу покажу причесанный вид, изначально все было в одну строку и без пробелов, пугающе 🙂 ):

var s = '';
  try { new asd[0]
}
catch (q) {
  if (q) r = 1;
  c = String;
}
if (r && document.createTextNode) t = 2;
e = eval;
m = [4.5*t,18/t,52.5*t,204/t,16*t,80/t,...,4.5*t,18/t,62.5*t]; // здесь очень длинная строка
mm = c['fro'+'mCharCode'];
for (i = 0; i != m.length; i++) s += mm( e( "m" + "[" + "i" + ']' ) );
try {
  document.appendChild( null )
}
catch (q) {
  e( s );
}

На первый взгляд все крайне запутано и сложно, java-скрипты я пишу/читаю редко, поэтому сразу слегка даже растерялся. В причесанном коде выделил понятные места и довел все до понимания.

mm = c['fro'+'mCharCode'];

c – обозначает строку (String), т.е. переменной mm будет присвоена строка fromCharCode и mm будет выполнять роль этой функции.

mm( e( "m" + "[" + "i" + ']') );
// равносильно
String.fromCharCode( eval( "m[i]" ) );

это значит, что все арифметические выражения в массиве m будут подсчитаны, затем коды переведены в символы функцией fromCharCode и посимвольно в цикле внесены в строку s.

Результирующий код для расшифровки:

Читать далее

Скрытие кода, метод 4

Взято из демо-версии DLE:

<?php $_F=__FILE__;$_X='STRING=';$_D=strrev('edoced_46esab');eval($_D('STRING2=='));?>

В коде бросаются в глаза две длиннющие строки в base64, раскодировать “в лоб” можно только вторую, там содержится кусок кода для дешифрации первой строки (STRING=). Причесанный вид файла:

$_F = __FILE__;
$_X = 'STRING=';
$_D = strrev( 'edoced_46esab' );
eval( $_D( 'STRING2==' ) );

edoced_46esab – это всего лишь перевертыш base64_decode. Вторая строка (STRING2==) после раскодировки и причесывания:

$_X = base64_decode( $_X );
$_X = strtr( $_X, 'STR1', 'STR2' );
$_R = str_replace( '__FILE__', "'".$_F."'", $_X );
eval( $_R );
$_R = 0;
$_X = 0;

Опять eval, от которого нужно избавиться. Собственно, интерес представляют только 2 и 3 строки. Дальше, общая раскодировка выглядит так:

$_F = __FILE__;
$_X = 'STRING=';
$_X = base64_decode( $_X );
$_Y = 'STRING2==';
$_Y = base64_decode( $_Y );
$_P = array(); // массив строк, которые будут вырезаны
$_P[0] = '$_X=base64_decode($_X);';
$_P[1] = 'eval($_R);$_R=0;$_X=0;';
$_Y = str_replace($_P, '', $_Y);
eval($_Y);
echo $_X;

Скрытие кода, метод 3

Не совсем PHP, но тоже может быть интересно. Для вставки в страницы вредительского кода, в частности блоков iframe, используют javascript и данные, закодированные в unicode:

<script type="text/javascript">document.write('\u003c\u0069\u0066\u0072\u0061\u006d\u0065')</script>

Раскодировать можно с помощью PHP:

$str = "\u003c\u0069\u0066\u0072\u0061\u006d\u0065";
$str = preg_replace( "/\\\\u([0-9a-f]{3,4})/i", "&#x\\1;", $str );
$str = html_entity_decode( $str, null, 'UTF-8' );

echo $str . "\n";

Чтобы посмотреть, что же находится в строке, не прибегая к PHP или каким-то инструментам, просто замените document.write на alert.

Когда-то давно я раскодировывал куски javascript-кода помещая его в теги <textarea>, пока в одном коде мне не попался </textarea> в начале зашифрованного кода. Вполне себе рабочие грабельки 🙂