| RSS



Меню

Bookmark and Share


Статистика
Ваш IP: 3.145.108.87
Вы используете: v





Сейчас на сайте:

Тех поддержка ->

Облако тэгов
ОС видио Tor Обратная сторона антенна 4.6 PHP Эксплоит Windows Server 2008 qip Virtual chroot kernel proc sysctl tune FreeBSD bridge Boot Disk Bluetooth GEO game directx Emulator Python Shell DDoS червь Conficker вирус троян Лаборатория Касперского пиратство apple iPhone ИТ-отрасль Щеголев Microsoft экономический кризис Twitter социальная сеть анонимность Лицензия Open Source ASP.NET MVC уязвимость MySQL база данных файлообмен закон франция пират Skype мобильный Deutsche Telekom Хакер киберпреступник Trend Micro кибератака Германия робот утечка данных персональные данные ноутбук интернет Китай цензура ядро Linux Торвальдс Windows Vista Acer Linux патент браузер Firefox Internet Explorer Opera Net Applications Safari Intel Linux Foundation Moblin Oracle патч банкомат кардер HSM IBM X-Force Cofee сша кибервойна Эстония Dell ИТ-специалист хакерские атаки Pirate Bay контроль кибербезопасность язык программирования The Pirate Bay Пиратская партия утечка информации приговор Mozilla Chrome безопасность Госдума СМИ Windows 8 Баллмер взлом Пентагон ботнет Украина Facebook Cisco cloud Windows XP нетбук торрент музыка биометрический nokia ФБР IP-адрес CIPAV Comcast sms RSA java Google CAPTCHA Symantec спам конфиденциальная информация инсайдер Perimetrix антивирус тест Anti-Malware Windows 7 операционная система Windows провайдер авторское право RapidShare UNIX свиной грипп шантаж дети EFF BluWiki копирайт экстремизм Panda Security cloud computing McAfee Cybercrime Response Unit Bottle Domains HTTPS ICANN студент шпионское ПО Норвегия школьник New York Times XSS YouTube Warner Music кибершпионаж КНДР Ubuntu свободное ПО AMD ATI касперский Россия РФ сервер хостинг фальшивый антивирус Comodo CA Wi-Fi D-Link суд пароль блог фишинг Одноклассники медведев контрафакт мошенник штраф Sony GPS по Gumblar JAVASCRIPT хакеры вредоносное ПО Yahoo ФАС компьютер Софт MPAA кибероружие PandaLabs Red Hat Минкомсвязи сбой ASUSTeK Computer мошенничество Доктор Веб ВКонтакте Cyber-Arc исходный код PCI DSS МВД фильтр порнография BREIN свобода слова Казахстан GEMA Autodesk сисадмин Gmail кредитная карта кибермошенник LiveJournal шифрование криптография Deep Purple банк нанотехнологии Wikipedia zero-day ColdFusion выборы кража данных DNS BIND Android BASIC атака Black Hat Mac OS X Click Forensics Clampi домен фсб Прокуратура Уголовное дело icq Barrelfish киберпреступность Sophos AT&T ошибка Electa Gamma Knife OpenBSD DARPA военные Сайт Visual Studio 2010 .NET Framework 4 Chrome OS электронная почта турция конференция спамер FTC полиция российская ОС Koobface Великобритания БЕЛОРУССИЯ грузия BSA Bittorrent облачные вычисления Azure Европа Dr.Web Билл Гейтс спецслужбы Cryzip Живой Журнал Royal Bank of Scotland смартфон Canonical Pwn2Own F-Secure Symbian Hotmail фильм

Главная » Статьи » Общие Статьи

Filter::Decrypt: расшифровка вслепую

В Perl предусмотрен механизм фильтров через которые пропускаюся исходные файлы перед тем, как они будут обработаны  интерпретатором. Одним из таких фильтров является Decrypt, который расшифровывает предварительно зашифрованный файл. Таким образом в Perl можно реализовать скрытие исходных текстов. По-умолчанию применяется обычный XOR, однако разработчик имеет возможность подключить любой алгоритм. Сам модуль, включая алгоритм шифрования, как правило, статически линкуется с интерпретатором, что немного усложняет расшифровку. В статье будет показано как можно получить исходный текст из зашифрованного файла независимо от того, чем изначально этот файл зашифрован. Об алгоритме шифрования нам не нужно знать ничего, это может быть самый стойкий криптографический алгоритм с бесконечной длиной ключа. Вот пример такого файла (часть строк вырезана):

use Filter::decrypt;

>>>>>>
Fingerprint: C1B9-A752-E2DF-C5AA-9C09-531D-7507-BE40-374D-36D4
n1KxoeHEBwZFQHiWGOiMVHeLb9E1m9BVF1QH2w/UsaPM2cmg2Z7gPi7kKy30eMmu
X6iGP0jRSb/kx/lvZvUMt7pj2azLUbTm5hUHlwxwoVBRj2NnqbTA69mLikfrwuxq
ma8TdqOu5oewwJBIexm05yfsmb1+Lrva60NBkCBWda5Aetr005baT6gHJSXTgGox
...
KYNVtmXuvUYhH/9tL9ZR6QkYmc0kn2r1Gc034mRQOHP+6xXw8nvetRshlC9AMc9J
Bauu6o0CEyJCafDaUe3Ojbk=

Что это за алгоритм – неважно, хотя видно, что сверху он накрыт base64. Итак, берем интерпретатор и копируем его в домашниюю директорию. В моем случае это mod_perl, что заметно облегчит расшифровку, поскольку динамический объект можно открыть через dlopen или линковаться с ним. От интерпретатора нам нужна функция filter_decrypt, которая производит расшифровку. Эта callback-функция регистрируется вместе с фильтром при инициализации perl и затем вызывается для каждой строки файла:

$ nm ./libperl.so | grep filter_decrypt
00050100 t filter_decrypt

Можно "добывать" эту функцию через dlopen, а можно просто слинковать программу вместе с этой библиотекой. Но есть проблема. Чтобы dlopen (или программа) могла увидеть функцию, она должна находиться в dynamic-секции открываемой библиотеки. А в нашем случае функция даже не является глобальной. Если бы достаточно было глобализовать функцию, то можно было бы воспользоваться objcopy --globalize-symbol=filter_decrypt и на этом успокоиться. А вот для того, чтобы засунуть символ в dynamic-секцию у objcopy аргументов нет. Поступить можно так: взять любой ненужный символ в dynamic-секции и подменить его адрес на адрес функции filter_decrypt.

Что касается адреса функции, то его мы можем получить с помощью указанной выше команды nm. Но что делать, если из библиотеки удалены символы (т.е. она стрипнута)? Определить адрес filter_decrypt в общем случае становится достаточно трудно. Для этого дизассемблируем библиотеку в районе вызова функции XS_Filter__decrypt_import:

$ objdump -d ./libperl.so | less
...
0004fd60 <XS_Filter__decrypt_import>
...
4fe57: 8d 93 fc 3e fe ff lea 0xfffe3efc(%ebx),%edx
4fe5d: 57 push %edi
4fe5e: 52 push %edx
4fe5f: 50 push %eax
4fe60: e8 8f ad fb ff call abf4 <Perl_filter_add@plt>
...

В ней вызывается Perl_filter_add для добавления нашего фильтра. Эти функции мы увидим даже в стрипнутой библиотеке. На i386 адрес filter_decrypt передается в стеке. В данном случае через регистр edx. В ebx находится адрес Global Offset Table, найти который можно так:

$ readelf -S ./libperl.so | awk '/\.got\.plt/{print $4}'
0006c204

Поскольку размер edx == 32 бита, то адрес filter_decrypt равен (u32) 0x6c204 + 0xfffe3efc = 0x50100. Теперь, зная адрес filter_decrypt, нужно подставить его вместо адреса любого символа из dynamic-секции. Я выбрал символ XS_Apache_last. Теперь необходимо рассчитать смещение в файле по которому расположен адрес этого символа. Символ расположен в секции .dynsym, узнаем его номер в этой секции и смещение самой секции:

$ readelf -S ./libperl.so | grep '.dynsym'
[ 2] .dynsym DYNSYM 00000dac 000dac 003550 10 A 3 12 4

$ readelf -s ./libperl.so | grep XS_Apache_last
775: 00021710 503 FUNC GLOBAL DEFAULT 10 XS_Apache_last

Смещение секции равно 0xdac, номер XS_Apache_last равен 775. Так же необходимо знать размер структуры символа в секции .dynsym. На твоей архитектуре это значение равно sizeof(Elf32_Sym). На i386 это значение равно 16. Вычисляем смещение:

offset = 0xdac + 775 * 16 + 4 = 0xdac + 0x307 * 0x10 + 0x4 = 0x3e20

Последняя цифра 4 – это смещение по которому находится адрес в самой symbol entry. К слову, по смещению 0 находится имя символа (точнее индекс имени в строковой таблице). Итак, открываем файл библиотеки в hex редакторе, находим смещение 0x3e20 и вставляем туда адрес символа filter_decrypt, не забывая о порядке следования байтов. Для этой цели я использовал vim + xxd.

Было:

...
0003e10: b082 0100 3802 0000 1200 0a00 341f 0000 ....8.......4...
0003e20: 1017 0200 f701 0000 1200 0a00 972d 0000 .............-..
0003e30: 8047 0400 ca04 0000 1200 0a00 dc37 0000 .G...........7..
...

Стало:

...
0003e10: b082 0100 3802 0000 1200 0a00 341f 0000 ....8.......4...
0003e20: 0001 0500 f701 0000 1200 0a00 972d 0000 .............-..
0003e30: 8047 0400 ca04 0000 1200 0a00 dc37 0000 .G...........7..
...

Библиотека готова. Можно приступать к написанию программы раскодирования.

#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "perlapi.h"
#include <stdio.h>
#include <dlfcn.h>

// Определяем символы заглушки, чтобы не ругался dlopen
int core_module;
void top_module(void) {}
void ap_table_merge(void) {}
void ap_null_cleanup(void) {}
void ap_table_add(void) {}
void ap_server_argv0(void) {}

#define ERR(msg) err(msg,__LINE__)
void err(char *msg,int line) {
        fprintf(stderr,"Error: %s [%d]\n",msg,line);
        exit(1);
}
#define BS 480000

int main(int argc,char *argv[]) {
        void *h;
I32 (*f)(pTHX_ int,SV *, int);
SV *sv,*my_sv;
PerlInterpreter *my_perl;
       int idx=0,rv,pdsv=0;
        char *lib,*fname;

       if (argc != 3) ERR("Usage: ./prog <lib> <fname>");
lib = argv[1];
fname = argv[2];

// Открываем нашу модифицированную библиотеку
h = dlopen(lib,RTLD_LAZY);
if (!h) ERR("open lib");

// На самом деле получаем filter_decrypt
f = dlsym(h,"XS_Apache_last");
if (!f) ERR("Symbol enrty");

// Инициализируем внутренние структуры и переменные Perl'а
my_perl = perl_alloc();
if (!my_perl) ERR("perl struct alloc");
perl_construct(my_perl);
PL_rsfp = PerlIO_open(fname,PERL_SCRIPT_MODE);
if (!PL_rsfp) ERR("perlIO");
PL_rsfp_filters = newAV();
sv = newSV(BS);

// Добавляем наш фильтр
Perl_filter_add(((PerlInterpreter *)pthread_getspecific((*Perl_Gthr_key_ptr(((void *)0))))), f,Nullsv);

// Инициализируем буферы для входного и выходного файла
IoLINES_LEFT(sv) = TRUE ;
my_sv = FILTER_DATA(idx);
IoTOP_GV(my_sv) = (GV*) newSV(BS) ;
IoLINES_LEFT(my_sv) = TRUE;

// В цикле для каждой строки зашифрованного файла вызываем функцию фильтра
while(1) {
pdsv = ((XPV*) (sv)->sv_any)->xpv_cur;
                rv = ((I32 (*)(pTHX_ int,SV *, int))IoANY(my_sv))(my_perl,idx,sv,48);
                if (pdsv && (pdsv == ((XPV*) (sv)->sv_any)->xpv_cur)) break;
        }

// Выводим результат:
printf("%s\n",((XPVIO *)sv->sv_any)->xpv_pv);
return;
}

Собираем и запускаем программу:

$ PL_DIR=/usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE
$ gcc -rdynamic -ldl go.c -lperl -L$PL_DIR -I$PL_DIR -o go
$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PL_DIR
$ ./go ./libperl.so File_to_decrypt.pm

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

Категория: Общие Статьи | Добавил: aka_kludge (17.12.2008)
Просмотров: 1952 | Рейтинг: 0.0/0
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
    Главная      
...
На службе : дней

00:36
Обновить


Пользователи
aka_kludge
qwerty
LeadyTOR
aka_Atlantis
AdHErENt
mAss
Sissutr
hiss
DrBio
tHick

Поиск


Copyright tHR - TeAM 2024 г. admin: aka_kludge (ICQ:334449009) Moderator's: LeadyTOR, ... Яндекс.Метрика