Шахтинская Linux User Group. Поддержка пользователей Linux и Unix. Обмен дистрибутивами.

Модераторы: ShurShun, Vitas

Ответить
Аватара пользователя
TOSHIK
Не в сети
Администратор
Администратор
Сообщения: 6596
Зарегистрирован: Пт авг 08, 2003 13:49
Откуда: Ростов-на-Дону
Контактная информация:

Война на передовой в условиях шаред хостинга

Сообщение TOSHIK »

"Война на передовой в условиях шаред хостинга на базе WHM/Cpanel/RHE"

Вступление


Сегодня в условиях развития информационных технологий на рынке е-комерции особое внимание уделяеться таким видам е-бизнеса как "shared hosting". Этот сегмент рынка продолжает стремительно рости и из-за своей распространенности и прибыльности попадает в поле зрения злоумышленников различного уровня.

Обеспечение безопасности "shared hosting" имеет свои особенности. Я постараюсь обрисовать особенности защиты при проникновении через apache/mod_php.

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

И так, рассмотрим стандартные методы проникновения в систему.

Приблизительный план атакующего:
  1. поиск на сервере доменов, содержащих php скрипт с уязвимостью;
  2. использование скрипта для выполнения локальных команд (с уровнем nobody);
  3. заливка, запуск backdoor;
  4. вход через backdoor;
  5. повышение привилегий.
Противодействие пунктам 1 и 5 не рассматриваются, так как предполагается, что дырявый скрипт уже найден, а также, что предполагаемые статьей мероприятия нацелены на действия, предотвращающие 5-ый пункт.

Учитывая, что среднестатистический сервер на базе WHM (исходя из default установки которую мало кто меняет) использует php как модуль apache (safe_mode = Off ), запускаемые через уязвимый скрипт команды имеют уровень привилегий apache (пользователь nobody).

Пример списка процессов:

Код: Выделить всё

[root@redhat root]# ps -eo %p%u%a --forest
......
23091	root		/usr/local/apache/bin/httpd -DSSL
23092	nobody		\_ /usr/local/apache/bin/httpd -DSSL
23093	nobody			\_ uname -a 
......
После определения возможности запускать програмы, атакующий попытаеться залить backdoor's, exploit's, bot's .... etc с целью получить полноценный shell, повысить уровень привелегий.

Исходя из вышеопределенного - выводим следующий план противодействия:
  1. Установка noexec nosuid на директории свалок
    - ограничение директорий свалок (/tmp,/var/tmp) от запуска backdoor, bot и другой закачанной нечисти;
  2. Контроль выполняемых процессов
    - ограничение количества команд, выполняемых от пользователя nobody;
  3. Настройка firewall.
  4. Настройка cPanel(WHM)+apache+php.ini.
Данные меры вполне способны нарушить план атакующего, и отпугнуть многих scriptkidies.

Перейдем к непосредственному расмотрению пунктов нашего плана.

1. Установка noexec nosuid на директории свалок (/tmp, /var/tmp).

К сожалению, в предустановленном варианте /tmp раздел не всегда идет отдельным разделом, что открывает атакующему дополнительные возможности. Мы прикроем это следующим образом:

- директории-свалки сделаем отдельными файлами и будем присоединять их через mount -o loop,noexec,nosuid;

- будем проверять все директории-свалки и что-то делать с файлами с опастными правами (x, s). Этот пункт противодействия важен, так-как noexec ограничение на раздел возможно обойти;

Разобьем первый пункт на подпункты:

1.1 Определение директорий для контроля

1.2 Создание файл-разделов.

1.3 Проверка работы noexec,nosuid.

1.4 Обход ограничения noexec

1.5 Скрипт для дополнительной защиты.

1.1 Определение директорий для контроля

Определяем, для каких директорий будут создаваться файл-разделы. Обычно это /tmp, /var/tmp .

Для поиска директорий имеющих права запись/выполнение/чтение для всех + sticky bit (1**7) . можно использовать следующую команду:

Код: Выделить всё

[root@redhat root]# find / -perm -1007 -type d -print
Тоже но без sticky bit:

Код: Выделить всё

[root@redhat root]# find / -perm -007 -type d -print
Пример вывода:

Код: Выделить всё

/tmp
/tmp/.font-unix
/var/tmp
/var/spool/samba 
Так как обычно на Shared hosting не поддерживается работа samba (которая входит в установку по умолчанию), рекомендуется удалить пакет samba*. Вывести все пакеты, имеющие отношение к samba, может следующая команда:

Код: Выделить всё

[root@redhat root]# rpm -qa|grep samba
Пример вывода:

Код: Выделить всё

samba-3.0.9-1.3E.2
samba-common-3.0.9-1.3E.2
samba-client-3.0.9-1.3E.2
redhat-config-samba-1.0.16-2
samba-swat-3.0.9-1.3E.2
Удаляем пакеты:

Код: Выделить всё

[root@redhat root]# rpm -e samba samba-common samba-client redhat-config-samba samba-swat
Если не желаете удалять пакеты, тогда уберите права с директории /var/spool/samba:

Код: Выделить всё

[root@redhat root]# chmod 0000 /var/spool/samba
Если Вы таки используете samba, тогда с этой директорией поступайте так же, как дальше по статье работаем с /tmp.

1.2 Создание файл-разделов.

Мы определили директории, для которых необходимо создать раздел-файлы. Это /tmp, /var/tmp.

Создаем директорию, где будут лежать файлы-разделы:

Код: Выделить всё

mkdir /filesystems
Создаем файл-разделы:

Код: Выделить всё

[root@redhat root]# dd if=/dev/zero of=/filesystems/tmp_fs seek=100 count=1 bs=1M
[root@redhat root]# dd if=/dev/zero of=/filesystems/var_tmp_fs seek=100 count=1 bs=1M

Я решил выделить под /tmp и /var/tmp по 100 M. Вы можете выделить больше - по Вашим потребностям.

Следующим шагом создаем в файлах ФС:

Код: Выделить всё

[root@redhat root]# mkfs.ext3 /filesystems/tmp_fs
[root@redhat root]# mkfs.ext3 /filesystems/var_tmp_fs
Добавляем в /etc/fstab строки автоматического присоединения файл-разделов при старте сервера:

Код: Выделить всё

/filesystems/tmp_fs /tmp ext3 defaults, noexec, nosuid, loop 1 1
/filesystems/var_tmp_fs /var/tmp ext3 defaults, noexec, nosuid, loop 1 1       
Присоединяем и проверяем присоединились ли новые файл-разделы (не забыв удалить данные из папок /tmp /var/tmp или, если там есть нужные данные, - временно перенести в другое место, а потом положить в новые файл-разделы):

Код: Выделить всё

[root@redhat root]# mount /tmp
[root@redhat root]# mount /var/tmp
[root@redhat root]# df 
Пример вывода:

Код: Выделить всё

Filesystem            Size  Used Avail Use% Mounted on
/dev/hda1              2.0G  988M  926M  52% /
/filesystems/tmp_fs    98M  4.1M   89M   5% /tmp
/filesystems/var_tmp_fs
                      98M  4.1M   89M   5% /var/tmp
1.3 Проверка работы noexec,nosuid.

Пробуем запустить suid файл из под nobody. Вот код С программы:

Код: Выделить всё

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main (int argc, const char * argv[],char * envp[])
        {
           uid_t uid;
           uid = getuid();
           printf("My id is %d\n",uid);
           if(0 != setuid(0)) printf("\nError suid to root\n");
           uid = getuid();
           printf("After suid My id is %d\n",uid);
        } 


Собираем:

Код: Выделить всё

[root@redhat root]# gcc suid.c -o suid
Ставим SUID на suid:

Код: Выделить всё

[root@redhat root]# chmod 4775 suid
Копируем для проверки в /:

Код: Выделить всё

[root@redhat root]# cp suid /
проверяем:

Код: Выделить всё

[root@redhat root]# sudo -u nobody /suid
My id is 99
After suid My id is 0


Копируем в защищенные директории /tmp /var/tmp:

Код: Выделить всё

[root@redhat root]# cp suid /tmp/
[root@redhat root]# cp suid /var/tmp/
Проверяем:

Код: Выделить всё

[root@redhat root]# sudo -u nobody /tmp/suid 
sudo: unable to exec /tmp/suid: Permission denied
[root@redhat root]# sudo -u nobody /var/tmp/suid 
sudo: unable to exec /var/tmp/suid: Permission denied


Сделаем аналогичную проверку для SheLL, Perl, PHP скриптов.


Пример скриптов:

test.php:

Код: Выделить всё

#!/usr/bin/php -q
<? echo "running\n"; ?>



test.pl:

Код: Выделить всё

#!/usr/bin/perl
print "running\n"



test.sh:

Код: Выделить всё

#!/bin/sh 
echo "running"


Результатты проверок:

PHP:

Код: Выделить всё

	[root@redhat root]# chmod 755 test.php
	[root@redhat root]# ./test.php
	running
	[root@redhat root]# cp test.php /tmp 
	[root@redhat root]# /tmp/test.php
	-bash: /tmp/test.php: /usr/bin/php: bad interpreter: Permission denied

Perl:

Код: Выделить всё

	[root@redhat root]# chmod 755 test.pl
	[root@redhat root]# ./test.pl
	running
	[root@redhat root]# cp test.pl /tmp/
	[root@redhat root]# /tmp/test.pl
	-bash: /tmp/test.pl: /usr/bin/perl: bad interpreter: Permission denied

Shell:

Код: Выделить всё

	root@redhat root]# chmod 755 test.sh
	[root@redhat root]# ./test.sh
	running
	[root@redhat root]# cp test.sh /tmp/
	[root@redhat root]# /tmp/test.sh
	-bash: /tmp/test.sh: /bin/sh: bad interpreter: Permission denied
На первый взгляд все хорошо. Ничего из директорий-свалок запустить нельзя.

1.4 Обход ограничения noexec .

Обход noexec при запуске исполняемого файла:

Код: Выделить всё

	root@redhat root]# sudo -u nobody  /lib/ld-linux.so.2 /tmp/suid
	My id is 99
	error suid to root
	After suid My id is 99   
Как видите, ограничение noexec было обойдено, ограничение на nosuid обойти не удалось (мне не известны способы обхода nosuid на директорию...).

Данный способ обхода был действителен для всех доступных мне ОС Linux RHE (<=2.4.21-27.0.4.EL - последний kernel, доступный для обновление через up2date, в момент написания статьи). В случае использование 2.6.x kernel, собранного с исходников, данный способ уже недействителен.

Код: Выделить всё

root@redhat root]# sudo -u nobody  /lib/ld-linux.so.2 /tmp/suid
/tmp/suid: error while loading shared libraries: 
/tmp/suid: failed to map segment from shared object: Operation not permitted 
Вот пример обхода ограничения на запуск скриптов PHP/Perl/Shell:

PHP:

Код: Выделить всё

[root@redhat root]# /usr/bin/php -q /tmp/test.php
running
Perl:

Код: Выделить всё

[root@redhat root]# /usr/bin/perl /tmp/test.pl
running
Shell:

Код: Выделить всё

[root@redhat root]# /bin/sh /tmp/test.sh
running    


1.5 Скрипт для дополнительной защиты.

Как видим, одно ограничение noexec, nosuid не способно остановить вторжение, но является дополнительным сдерживающим средством. Расширим его скриптом, который будет проходить по директориям-свалкам и изменять/удалять неугодные нам файлы. Я лишь приведу пример написанный на shell. Вы можете реализовать данную методику любым удобным Вам способом.

Вот код:

Код: Выделить всё

#!/bin/sh
DIR4PROTECT="/root/dir4protect"
for dir in `cat $DIR4PROTECT`;do
FILE2DELETE=`find $dir -perm +1111 -print`
for file in `echo $FILE2DELETE`;do
        if [ -f $file ];then
                chmod 0000 $file
                chown root.root $file
        fi
done
done


Проверяем его работу:

Код: Выделить всё

[root@redhat root]# ./tmpprotect.sh 
	[root@redhat root]# ls -la /tmp
	total 45
	drwxr-xr-x    3 root     root         1024 Apr 29 18:32 .
	drwxr-xr-x   20 root     root         4096 Apr 28 23:45 ..
	----------    1 root     root            0 Apr 29 18:32 1
	drwx------    2 root     root        12288 Apr 27 21:31 	lost+found
	----------    1 root     root        11841 Apr 29 00:36 s2
	----------    1 root     root           34 Apr 29 00:10 shell.sh
	----------    1 root     root        11841 Apr 29 00:00 suid
	----------    1 root     root           40 Apr 29 16:30 test.php
	----------    1 root     root           38 Apr 29 16:35 test.pl
	----------    1 root     root           26 Apr 29 16:40 test.sh
	[root@redhat root]# ls -la /var/tmp
	total 29
	drwxr-xr-x    3 root     root         1024 Apr 29 00:00 .
	drwxr-xr-x   19 root     root         4096 Mar  4 23:29 ..
	drwx------    2 root     root        12288 Apr 27 21:32 	lost+found
	----------    1 root     root        11841 Apr 29 00:00 suid


Проверяем возможно ли запустить скрипты:

Код: Выделить всё

	[root@redhat root]# sudo -u nobody /usr/bin/php -q /tmp/test.php
	[root@redhat root]# sudo -u nobody  /usr/bin/perl /tmp/test.pl
	Can't open perl script "/tmp/test.pl": Permission denied 
	[root@redhat root]# sudo -u nobody /bin/sh /tmp/test.sh
	/tmp/test.sh: /tmp/test.sh: Permission denied


Написанный скрипт помогает блокировать файлы, которые могут быть backdoor, exploits, trojanhorse в директориях свалках. Его можно расширить автоматическим отправлением письма администратору, любыми другими пришедшими вам на ум идеями. Самый простой способ - это установить данный скрипт для автозапуска в crontab на запуск раз в минуту.

Пример содержимого файла крон службы:

Код: Выделить всё

	* * * * * /root/tmpprotect.sh
2. Контроль выполняемых процессов.

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

Вот пример скрипта, который, основываясь на файле-списке разрешенных процессов, убивает остальные.

/root/nobody.sh

Код: Выделить всё

#!/bin/sh
USER="nobody"
RULEFILE="/root/nobody"
if [ -f "$RULEFILE" ]; then
         KPID=`ps -eo "%p%u%c"|grep $USER|grep -vi $$|grep -vif $RULEFILE |awk '{print$1}'`
         for j in `echo "$KPID"`; do
 		kill -9 $j >> /dev/null 2>&1
         done
fi
файл список разрешенных програм:

/root/nobody

Код: Выделить всё

httpd
suexec
*Для корректной работы WHM/Cpanel в /root/nobody необходимо внести список выполняемых файлов из директорий /scripts/ /usr/local/cpanel/bin/.

Проверим работу скрипта. Открыв второй шелл, запустим там команду "sudo -u nobody sleep 500", а в первом – на выполнение наш скрипт.

Код: Выделить всё

[root@redhat root]# sudo -u nobody sleep 500
Killed                
---
[root@redhat root]# chmod 750 nobody.sh
[root@redhat root]# ./nobody.sh
Процесс, не входящий в список разрешенных, был убит нашим скриптом.

Теперь попробуем другой скрипт:

httpd:

Код: Выделить всё

#!/bin/sh
while [ "1" ];do
sleep 1
done 
Сохраним его в директории /tmp, сделаем запускаемым и запустим:

Код: Выделить всё

[root@redhat tmp]# sudo -u nobody ./httpd
sudo: unable to exec ./httpd: Permission denied
[root@redhat tmp]# sudo -u nobody /bin/sh ./httpd
Killed


Наш скрипт его убивает, и все потому, что он видится как процесс sh. Для примера того, что скрипт может быть не убиваем, скопируем его в / и запустим оттуда. ( в реальной жизни это будет директория какого-то пользователя, который открыл директорию на заливку (777) )

Код: Выделить всё

[root@redhat /]# sudo -u nobody ./httpd
./httpd: line 4:  4101 Killed                  sleep 1
./httpd: line 4:  4111 Killed                  sleep 1 


Позапускав наш скрипт nobody.sh видим, что главный скрипт не умирает, а вот потомки снимаються с выполнения. Это из-за того, что главный скрипт подпадает под разрешенные процессы.

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

3. Настройка Firewall.

Учитывая нюансы WHM/Cpanel, перечислим порты, которые должны быть открыты на вход:

TCP 21,22,25,53,80,110,443,2082,2083,2086,2087,2089,2095,2096
UDP 53
ICMP 0,30,8

на выход:

TCP 25,53,2089
( 2089 необходим для работы WHM для авторизации)
UDP 53
ICMP 0,30,8

Напишем скрипт, который будет загружать в iptables правила для файрволинга при старте системы. Ограничивая исходящие соединения, мы тем самым уменьшаем количество возможных backconnect.

/etc/firewall.sh:

Код: Выделить всё

#/bin/sh
/sbin/iptables -A INPUT -p tcp -s 0/0 -d 10.10.10.10 --dport 21 -j ACCEPT
/sbin/iptables -A INPUT -p tcp -s 0/0 -d 10.10.10.10 --dport 22 -j ACCEPT
/sbin/iptables -A INPUT -p tcp -s 0/0 -d 10.10.10.10 --dport 25 -j ACCEPT
/sbin/iptables -A INPUT -p tcp -s 0/0 -d 10.10.10.10 --dport 53 -j ACCEPT
/sbin/iptables -A INPUT -p tcp -s 0/0 -d 10.10.10.10 --dport 80 -j ACCEPT
/sbin/iptables -A INPUT -p tcp -s 0/0 -d 10.10.10.10 --dport 110 -j ACCEPT
/sbin/iptables -A INPUT -p tcp -s 0/0 -d 10.10.10.10 --dport 443 -j ACCEPT
/sbin/iptables -A INPUT -p tcp -s 0/0 -d 10.10.10.10 --dport 2082 -j ACCEPT
/sbin/iptables -A INPUT -p tcp -s 0/0 -d 10.10.10.10 --dport 2083 -j ACCEPT
/sbin/iptables -A INPUT -p tcp -s 0/0 -d 10.10.10.10 --dport 2086 -j ACCEPT
/sbin/iptables -A INPUT -p tcp -s 0/0 -d 10.10.10.10 --dport 2087 -j ACCEPT
/sbin/iptables -A INPUT -p tcp -s 0/0 -d 10.10.10.10 --dport 2089 -j ACCEPT
/sbin/iptables -A INPUT -p tcp -s 0/0 -d 10.10.10.10 --dport 2095 -j ACCEPT
/sbin/iptables -A INPUT -p tcp -s 0/0 -d 10.10.10.10 --dport 2096 -j ACCEPT
/sbin/iptables -A INPUT -p udp -s 0/0 -d 10.10.10.10 --dport 53 -j ACCEPT
/sbin/iptables -A INPUT -p icmp -s 0/0 -d 10.10.10.10 --icmp-type 0 -j ACCEPT
/sbin/iptables -A INPUT -p icmp -s 0/0 -d 10.10.10.10 --icmp-type 8 -j ACCEPT
/sbin/iptables -A INPUT -p icmp -s 0/0 -d 10.10.10.10 --icmp-type 30 -j ACCEPT
/sbin/iptables -A INPUT -p all -s 0/0 -d 10.10.10.10 -j DROP

/sbin/iptables -A OUTPUT -p tcp -d 0/0 -s 10.10.10.10 --dport 25 -j ACCEPT
/sbin/iptables -A OUTPUT -p tcp -d 0/0 -s 10.10.10.10 --dport 53 -j ACCEPT
/sbin/iptables -A OUTPUT -p tcp -d 0/0 -s 10.10.10.10 --dport 2089 -j ACCEPT
/sbin/iptables -A OUTPUT -p udp -d 0/0 -s 10.10.10.10 --dport 53 -j ACCEPT
/sbin/iptables -A OUTPUT -p icmp -d 0/0 -s 10.10.10.10 --icmp-type 0 -j ACCEPT
/sbin/iptables -A OUTPUT -p icmp -d 0/0 -s 10.10.10.10 --icmp-type 8 -j ACCEPT
/sbin/iptables -A OUTPUT -p icmp -d 0/0 -s 10.10.10.10 --icmp-type 30 -j ACCEPT
/sbin/iptables -A OUTPUT -p all -d 0/0 -s 10.10.10.10 -j DROP
В данном скрипте 10.10.10.10 - это IP адрес Вашего сервера. Если сервер имеет более одного IP то необходимо добавить эти-же строки но с другим IP .

Сделаем скрипт запускаемым:

Код: Выделить всё

chmod 755 /etc/firewall.sh
Добавим в /etc/rc.local строку:

Код: Выделить всё

/etc/firewall.sh
Осталось вручную загрузить правила:

/etc/firewall.sh

Будте осторожны - Вы можете закрыть доступ на сервер для самого себя.

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

4. Настройка cPanel(WHM)+apache+php.ini

Есть две задачи, которые в данном случае приходится решать, идя на компромис между ними:

- максимум возможностей для пользователя,

- максимум безопасности на уровне пользователя.

Увеличивая возможности для пользователя, а, соответственно, и привлекательность хостинга, нам прийдется забыть о safe mode для PHP. Однако, чтоб немного оградить тех же пользователей от взлома их страниц, а свой хостинг от проникновения скрипт-кидди, нам необходимо ограничить опасные функции, которые обычно используются для начального взлома системы.

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

Во-первых, это внедрение PHP кода в сценарии и выполнение произвольных команд. В php.ini прописываем следующее:

- запретим открытие/включение удаленных файлов:

Код: Выделить всё

allow_url_fopen = Off
enable_dl     = Off
- запретим выполнение команд:

Код: Выделить всё

disable_functions = ini_alter, curl_exec, exec, system, passthru, shell_exec, proc_open, proc_close, proc_get_status, proc_nice, proc_terminate, leak, listen, chgrp, chmod, set_time_limit, apache_note, apache_setenv, closelog, debugger_off, debugger_on, define_syslog_variables, openlog, syslog,ftp_exec,phpinfo,dl ; 
запретим вывод php скриптами ошибок:

Код: Выделить всё

display_errors = Off
- выключим передачу информации о php в заголовках HTTP ответов:

Код: Выделить всё

expose_php = Off
Если пользователи не настаивают, то рекомендуем отключить и функции posix, с помощью которых возможен обход некоторых ограничений на выполнение команд.

Уязвимости типа SQL injection ограничим включением параметра

Код: Выделить всё

magic_quotes_gpc = on
В некоторых случаях можно было бы установить mod_security. Полезный модуль, который ограничивает внедрение SQL, java script и др. кода.

Полезно было бы сбить с толку горе-хакеров, изменив заголовок веб-сервера, отправляемый по умолчанию. Для apache это делается следующим образом. В файле src/include/httpd.h редактируем строки типа:

Код: Выделить всё

#define SERVER_BASEPRODUCT “Apache”
#define SERVER_BASEVERSION “1.3.27”
После этого компилируем веб-сервер и устанавливаем его. Впрочем, если вы установили mod_security, это все можно сделать с его помощью, не переустанавливая веб сервер.

И, наконец, зайдем в закладку "Tweak Security" в cPanel/WHM и активируем:

Php open_basedir Tweak
Compilers Tweak

Первый установит в httpd.conf на все VirtualHost open_basedir на домашнюю папку пользователя.

Второй разрешит доступ к GCC только для указанных в списке пользователей.

Эпилог

В данной статье рассмотрены методы борьбы на "передовой"; противодействие атакующему через веб-скрипты (apache/mod_php) на базе распространенной панели для shared hosting WHM/Cpanel (cpanel.net) с ОС Linux RHE. (Учитывая особенности работы данной панели, применяемые меры не идут в разрез с работой WHM/Cpanel), которые дают Вам зацепку, через которую можно выстроить достаточно плотную защиту обход которой будет не всегда соразмерен полученному результату.

P.S. Для всех используемых команд для более детального понимания прошу обращаться к man страницам.

Оригинал статьи здесь: http://www.securitylab.ru/contest/212124.php
Активисты все еще ищутся здесь!

Аватара пользователя
TOSHIK
Не в сети
Администратор
Администратор
Сообщения: 6596
Зарегистрирован: Пт авг 08, 2003 13:49
Откуда: Ростов-на-Дону
Контактная информация:

Сообщение TOSHIK »

Статья очень порадовала. Начало описано правильно и очень в тему. Показана суть проблемы и основные направления для её решения. Основываясь на описаных аспектах можно дальше уже сделать больше.
Активисты все еще ищутся здесь!

Ответить