ПЕРЕЛІК ДИСЦИПЛІН:
  • Адміністративне право
  • Арбітражний процес
  • Архітектура
  • Астрологія
  • Астрономія
  • Банківська справа
  • Безпека життєдіяльності
  • Біографії
  • Біологія
  • Біологія і хімія
  • Ботаніка та сільське гос-во
  • Бухгалтерський облік і аудит
  • Валютні відносини
  • Ветеринарія
  • Військова кафедра
  • Географія
  • Геодезія
  • Геологія
  • Етика
  • Держава і право
  • Цивільне право і процес
  • Діловодство
  • Гроші та кредит
  • Природничі науки
  • Журналістика
  • Екологія
  • Видавнича справа та поліграфія
  • Інвестиції
  • Іноземна мова
  • Інформатика
  • Інформатика, програмування
  • Юрист по наследству
  • Історичні особистості
  • Історія
  • Історія техніки
  • Кибернетика
  • Комунікації і зв'язок
  • Комп'ютерні науки
  • Косметологія
  • Короткий зміст творів
  • Криміналістика
  • Кримінологія
  • Криптология
  • Кулінарія
  • Культура і мистецтво
  • Культурологія
  • Російська література
  • Література і російська мова
  • Логіка
  • Логістика
  • Маркетинг
  • Математика
  • Медицина, здоров'я
  • Медичні науки
  • Міжнародне публічне право
  • Міжнародне приватне право
  • Міжнародні відносини
  • Менеджмент
  • Металургія
  • Москвоведение
  • Мовознавство
  • Музика
  • Муніципальне право
  • Податки, оподаткування
  •  
    Бесплатные рефераты
     

     

     

     

     

     

         
     
    Нове - добре забуте старе
         

     

    Інформатика, програмування

    Нове - добре забуте старе

    Кріс Касперски

    Вразливість java-додатків

    Виробники java-машин досить оперативно реагують на повідомлення про вразливості, випускаючи численні латки, неспішно встановлюються користувачами на комп'ютери. В результаті чого шанси на успішну атаку з часом неухильно зменшуються і в якийсь момент дірка стає неактуальною.

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

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

    Припустимо, для реалізації атаки необхідно задіяти властивості А, В і С. Припустимо також, що подібна комбінація властивостей практично не використовується в звичайних програмах. Тоді виробник додає фільтр, який блокує їх виконання. Але якщо уявити властивість В у вигляді прямих (або побічних) ефектів властивостей D і Е, то фільтр, очевидно, пропустить таку комбінацію. Звідси випливає важливий висновок: навіть якщо виробник рапортує про успішну ліквідації дірки і користувачі вже встановили латки, це ще не означає, що діри дійсно немає. Виправляється адже причина, а не наслідок. Хакери просто знаходять іншого шлях для досягнення того ж самого слідства, «воскрешаючи» дірки, про які всі забули. Вразливості, зав'язані на специфікацію Java-машини і набір виконуваних нею команд, взагалі неможливо залатати без втрати сумісності з уже існуючими Java-додатками. У деяких випадках допомагає встановлення нового Java-компілятора з наступною перезібравши вихідних текстів проекту, яких, до речі кажучи, у більшості користувачів просто немає. Але навіть якби вони й були, цю роботу повинен виконувати програміст, оскільки варто заздалегідь бути готовим до того, що в тексти доведеться вносити зміни, інакше програма може відмовитися збиратися або поведе себе непередбачуваним чином.

    Обхід системи типів

    Жорстка типізація мови Java запобігає безліч ненавмисним помилок програмування, пов'язаних з присвоєнням одного типу іншому. Захист реалізована науровне віртуальної машини, а не в самій мові програмування (як, наприклад, це зроблено в Сі + +). Спроба здійснити вихід з функції, підсунувши інструкції return масив або символьну рядок замість адреси повернення (типовий сценарій хакерської атаки на переповнюють буфери), призведе до аварійного завершення Java-додатки. На цьому ж тримається контроль кордонів масивів, доступ до приватних полів класів та багато іншого. Якщо перехитрити типізацію, можна зламати всю систему безпеки Java і робити практично все що завгодно: переповнювати буфери, викликати приватні методи захищених класів і т. д. Природно, це вже будуть умисні «помилки», побудовані на слабкості механізмів контролю типів. А хакерська атака і є не що інше, як навмисний відхід від специфікації.

    Далеко не всі знають, що на рівні віртуальної машини Java-платформи захищені набагато слабше, ніж це випливає з популярних посібників для чайників. У специфікації на JVM присутня велика кількість задокументованих інструкцій для низькорівневого перетворення типів: i2b, i2c, i2d, i2f, i2l, i2s, I2i, I2f, I2d, f2i, f 21, f 2d, d2i, d2l, d2f і навіть пара команд для роботи з класами: checkcst, instanceof. Їх опис викладено на http://mrl.nyu.edu/ ~ meyer/jvmref/ref-Java.html. Більш того, у пакеті інструментарію для розробників Java-програм міститься офіційна код, що показує, як «правильно» перетворити один тип до будь-якого іншого. Так що в деякому розумінні це не злом, а документована особливість Java.

    Як використовується ця особливість на практиці? Припустимо, ми маємо два класи: trusted (що виконується в привілейованому інтервалі, а значить, що володіє всіма ресурсами віртуальної машини) і untrusted (поміщений в «пісочницю»). Припустимо також, що клас trusted має ряд приватних методів, призначених строго для внутрішнього використання та прихованих від «зовнішнього світу» системою типізації. На папері ця схема виглядає бездоганною, але насправді її легко обійти шляхом створення підробленого класу (назвемо його spoofed), повністю ідентичного даним, але тільки з public-атрибутами замість private. Явне перетворення екземплярів класу trusted і spoofed дозволить звертатися до захищених методам, викликаючи їх не тільки з інших класів, але навіть з untrusted-коду. Такий беззаконня відбувається тому, що в JVM відсутній runtime-перевірка атрибутів полів класу при зверненні до них методами getfield/putfield. А якщо б вони і були (сжірая додаткові процесорні такти), зловмиснику нічого б не варто було хакнуть атрибути шляхом прямої модифікації структури класу двома чудовими інструкціями JVM - getLong і putLong, спеціально призначеними для низькорівневого взаємодії з пам'яттю віртуальної Java-машини. Однак у цьому випадку атакуючому доведеться враховувати версію JVM, оскільки «фізична» структура класів не залишається постійною, а схильна суттєвих змін. Тепер перейдемо до відео буфера. Як вже було сказано вище, Java контролює вихід за межі масивів на рівні JVM і тому випадково переповнити буфер неможливо. Однак це легко зробити навмисне-достатньо скористатися перетворенням типів, штучно розсунувши кордону масиву. Під час запису в буфер JVM відслідковує лише вихід індексу за його межі, але (з міркувань продуктивності) не перевіряє, чи належить записуємося пам'ять кому-то еще. Враховуючи, що примірники класів (вони ж об'єкти) розташовуються в пам'яті більш-менш послідовно, можна вільно перезаписувати атрибути, покажчики та інші дані інших класів (в тому числі і довірених).

    Природно, для реалізації даної атаки необхідно написати злоблива Java-додаток і закинути його на цільовий комп'ютер. Атакувати вже встановлені додатки не вийде, оскільки хакер не в змозі здійснювати віддалене перетворення типів. Але й тут деякі зачіпки є. Деякі програмісти при перенесенні Сі-програм на Java відчувають потребу в роботі з покажчиками на блок «Нерозбірливих» даних заздалегідь невідомої довжини. Java таких фокус не дозволяє, доводиться викручуватися шляхом явних перетворень. Фактично це означає, що програміст свідомо відмовляється від жорсткої типізації і говорить Java-машини, що не треба перевіряти типи, межі масивів і т. п.

    Таким чином, не можна апріорі стверджувати, що Java-додатки вільні від помилок переповнення буферів. Зустрічаються вони, звичайно, набагато рідше, ніж у Сі-програмах, але все-таки зустрічаються ...

    Обхід верифікатори

    Верифікатор відноситься до одного з найбільш розрекламованих компонентів JVM. Весь Java-код (у тому числі і додається динамічно) в обов'язковому порядку проходить через складну систему численних фільтрів, стурбованих суворими перевірками на предмет коректності виконуваного коду. Зокрема, якщо тупо спробувати закинути на вершину стека масив командою aloadj, а потім піти у повернення з функції з ireturn, Верифікатор негайно стрепенеться і цей номер не пройде. Як і будь-яка інша досить складна програма, Верифікатор недосконалий і схильний до помилок. Першу помилку виявив співробітник Маргбурского університету Карстер Зорі (Karsten Sohr) в далекому 1999-му, він звернув увагу на те, що Верифікатор починає «буксувати» у випадку, якщо остання перевіряється інструкція знаходиться всередині обробника виключень. Що дозволяє, зокрема, здійснювати «нелегальне» перетворення одного класу до будь-якого іншому.

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

    Інший цікавий момент-атака на відмову в обслуговуванні. Зазвичай для перевірки методу, що складається з N інструкцій віртуальної машини, верифікатори потрібно зробити N ітерацій, в результаті чого складність лінійно зростає з розміром класу. Якщо ж кожна інструкція методу взаємодіє з усіма іншими (наприклад, через стек або якось ще), то верифікатори вже потрібне N в квадраті ітерацій і складність відповідно зростає. Підсунувши верифікатори метод, що складається з десятків (або навіть сотень) тисяч інструкцій, що взаємодіють один з одним, можна ввести його в глибоку задуму, вихід з якої конструктивно не передбачений, і користувачеві доведеться аварійно завершувати роботу Java-програми разом з Java-машиною на додачу. Ліки від цієї «хвороби» немає. І хоча Sun робить деякі кроки в цьому напрямку, переглядаючи набір команд JVM і викидаючи з нього все «непотрібне», складність аналізу байт-коду залишається такою ж. Особливо ця проблема актуальна для серверів, вбудованих пристроїв, стільникових телефонів-там, де зняття завислий Java-машини неможливо або поєднане з втратою часу/даних.

    Помилки в JIТ-компіляторах

    Сучасні процесори досить швидкі, але Java-машини настільки неповороткі, що здатні виконувати тільки найпростіші програми, не критичні до часу виконання, наприклад перевіряти коректність заповнення Web-форм перед їх відправкою на сервер. Спроби створити на Java щось дійсно серйозне наштовхуються на невиправдано низьку продуктивність JVM, для подолання якої придумали JIТ-компілятори (Just-In-Time), які транслюють байт-код безпосередньо в «наївний» (native) код цільового процесора, в результаті чого Java-програми за швидкістю виконання не сильно поступаються своїм аналогам на Сі, а в деяких випадках навіть перевершують їх.

    скомпільованій машинний код виконується з мінімумом перевірок і Верифікатор з динамічного вироджується в статичний. Зокрема, якщо відбудеться переповнення буферу, то хакер без зусиль зможе впровадити туди shell-код і передати йому управління, захопивши всі привілеї віртуальної машини, досить часто виконується з правами адміністратора. Відсутність динамічного аналізу і скрупульозних перевірок виконавчі (їх наявність сильно сповільнило б продуктивність) дозволяє зловмисникові порівняно чесними шляхами вириватися за межі віртуальної машини, викликаючи довільні API-функції операційної системи або навіть модифікуючи саму віртуальну машину на свій розсуд. До того ж JIТ-компілятори за деяких обставин суворо помиляються, генеруючи неправильний код. Розглянемо приклад некоректної роботи Symantec JIТ-компілятора, який використовується, зокрема, в браузері Netscape версій 4.0-4.79 під Windows/x86. Байт-код закидає на вершину стека нульову константу (команда aconst_null), після чого викликає локальну підпрограму командою jsr 11, де відразу виштовхує подвійне слово з вершини стека в віртуальний регістр R1 і повертається з неї назад, переходячи за адресою, що міститься у віртуальному регістрі R1 (а в ньому якраз і лежить адреса повернення з локальної підпрограми). Так що з точки зору верифікатори все виглядає гранично коректно і в нього ніяких претензій немає. Що ж до JIТ-компілятора, то перед входом у функції він зберігає регістр ЕАХ в стеку (умовно відповідний віртуального регістру R1), далі обнуляє його (команда XOR ЕАХ.ЕАХ), але не кладе в стек, а прямо так в регістрі і залишає. Потім викликає локальну підпрограму (інструкція CALL I1), закидаючи на стек адреса повернення (тобто адресу першого наступного за нею команди - інструкції POP ЕСХ). У самій же підпрограмі компілятор стягує з вершини стека подвійне слово, розміщуючи його в регістр ЕАХ (команда POP ЕАХ), що абсолютно правильно. Потім, відпрацьовуючи RET 1, замість того, щоб відразу стрибнути на JMP ЕАХ, за цілком незрозумілих причин ще разлезет в стек і копіює в ЕАХ подвійне слово, перебуває на її вершині (інструкція «MOV ЕАХ, [ESP]»), в результаті чого реальний перехід здійснюється з фізичного вказівником, що знаходиться в регістрі ЕАХ. Зазвичай там збирається сміття і програма (разом з Java-машиною) просто валиться. При бажанні можна впливати на ЕАХ, засунув в нього вказівник на shell-код або щось подібне. Для цього перед викликом функції jump () досить виконати послідовність команд віртуальної машини: iloadj/ireturn. Зараз ця дірка вже закрита.

    Підвищення власних привілеїв

    Несанкціоноване підвищення привілеїв актуально головним чином для Java-додатків, що надходять з ненадійних джерел (наприклад, з Мережі) і які виконуються в «пісочниці» (sandbox), прорив за межі якої призводить до плачевних наслідків. Зловмисник отримує можливість виконувати будь-який код, відкривати порти, звертатися до локальних файлів і т. д.

    В останніх версіях JVM «пісочницю» розтягли на будматеріали, які пішли на створення нової системи безпеки, що забезпечує розмежування доступу не на рівні Java-додатків (як це було раніше), а на рівні окремих класів. Довірені (trusted) класи можуть робити все що завгодно (якщо тільки не зазначено інше). Інші задовольняються зверненням до публічних методам довірених класів. Якщо атакуючий зможе дістатися до приватних (або захищених) методів довіреної класу, його мета буде досягнута.

    В верифікатори Java-машини, вбудованої в MS IE версій 4.0,5.0 і 6.0, був присутній підступний дефект, що дозволяє створювати повністю початкові екземпляри класів, навіть при виникненні виключення в методі super (). Метод super () схожий на покажчик this, підтримуваний Java / Сі + +, проте на відміну від this, що вказує на екземпляр цього класу, super () викликає конструктор суперкласу (або базового класу, якщо в термінах Сі + +), до якого належить даний екземпляр похідного класу. Дізнатися докладніше про методи this () і super () можна за посиланням www.laas. org/docs/javap/c5/s5.html. Гарна ідея - взяти довірений клас і створити примірник похідного класу (sub-класу) і проініціалізувати його викликом super (). Тоді зловмисник зможе вирватися за межі «пісочниці». Єдина проблема, з якою зіткнеться атакуючий,-Java-компілятор відмовиться транслювати такий код. Але якщо

    Історична довідка

    Java виникла в результаті внутрішнього проекту Stealth Project (пізніше перейменованого в Green Project), початого в 1990 р. компанією Sun. Його метою було створення мови програмування для своєї ж операційної системи Green Operating System, яка використовується для управління вбудованими пристроями і побутової електронікою. Ідея створення мови належить Патріку Наутону, втомленому програмувати мікроконтролери на Сі/Сі + +, долаючи несумісність різних компіляторів укупі з їх прихильністю до конкретного залозу. Для «Відв'язування» від нього, він вирішив зробити ефективну системно-незалежну віртуальну машину. Пізніше до нього приєдналися Джеймс Гослінг (що придумав ім'я Oak, але він виявився вже зарезервованої торговою маркою) і Майк Шерідан. Вони завершили створення мови в 1992 р. і продемонстрували успішну роботу Green OS на PDA-комп'ютері типу Star?.

    Що таке enterprise-додатки?

    За сформованою традицією enterprise-додатками (від англійського «enterprise» -підприємство) называются програми, орієнтовані на промислове застосування у великих організаціях. Відповідно enterprise-сервери-це сервери, обслуговуючі підприємства і, що включають в себе: web-сервери, сервери друку, бази даних та інші життєво важливі для функціонування корпоративної мережі служби. До ключових характеристик enterprise-додатків відносять їх відмовостійкість, можливість швидкого відновлення після «падіння» і, звичайно, безпека (докладніше - на http://en.wiki pedia. orq/wiki/Enterprise server і http://wiki. debian.org/EnterpriseServer).

    Зміни JVM

    Структура байт-коду та набір інструкцій JVM не залишаються постійними, а змінюються від версії до версії, що істотно ускладнює як створення незалежних трансляторів від сторонніх виробників, так і реалізацію атак на байт-код. Хакеру доводиться або фокусуватися на суворо визначених версіях (яких може взагалі не виявитися в жертви), або враховувати особливості кожної окремо взятої реалізації JVM, що вельми непросто. До того ж команди віртуальної машини повільно, але неухильно рухаються до вилучення потенційно небезпечних інструкцій. У Зокрема, з лексикону Java SE 6 зникли команди JSR і JSR.W, що представляють собою віддалений аналог Бейсік-команди GOSUB, що передає управління на процедуру. Sun з цього приводу пише: «Верифікатор забороняє виконання інструкцій JSR і RET. Ці інструкції використовуються для виклику підпрограм при генерації try/f inally-блоків. Замість цього компілятор буде вбудовувати код програм безпосередньо за місцем виклику ». вручну запрограмувати шкідливу програму на Java-асемблері (у якості якого можна взяти безкоштовний транслятор Жасмин-jasmin.sf.net), Верифікатор байт-коду візьме її як рідну, оскільки Java-машина, реалізована в IE, виконує лінійний аналіз коду, а з цієї точки зору код цілком нормальний.

    Схожі помилки містяться і в інших віртуальних машинах. Зокрема, в Netscape версій 4.0-4.79 взагалі можна обійтися без викликів this () і super (), замінивши їх розгалуження (jsr/astore/ret).

    Дірки в runtime-бібліотеки і системних класах

    В Наприкінці квітня 2007 р. в Apple QuickTime Player'e всіх версій, аж до 7.1.5, виявилась дірка, що дозволяє Java-додаткам виконувати довільний код на віддаленій системі. Достатньо зайти на Web-сторінку зловмисника ... З огляду на величезну поширеність Apple QuickTime Player'a і Microsoft Internet Explorer'a, відбулося своєрідне перехресне «запилення», в результаті чого постраждали відразу обидві системи: вся лінійка Windows NT (включаючи Vista) і Mac OS.

    Але сама Java-машина тут не при чому. Помилка сидить у зовнішньому (по відношенню до неї компоненті), і тому вразливість поширюється не тільки на IE, але і FireFox.

    Exploit, пробиває практично будь-яку Java-машину, при наявності встановленого Apple QuickTime Player'a з версією 7.1.5 або більш ранньої// ініціалізує Quick-Time QTSession.openO;

    // отримує обробник, який вказує на що завгодно

    byte b [] = new byte [l Л тут може бути будь-яке число V];

    QTHandle h = new QTHandle (b);

    // перетворює обробник в покажчик на об'єкт

    // величезне негативне значення обходить перевірку діапазону QTPointerRef p = h.toQTPointer (-2000000000/* зміщення * /, 10/* розмір */);

    II перезаписує об'єкт p.copyFromArray (0 Л зсув V, b Л джерело V, О, 1/* довжина V ),'

    Цей приклад наочно доводить, що говорити про безпеку Java у відриві від надійності всіх інших компонентів операційної системи та її оточення - наївно. Java повинна або бути «річчю в собі» і не допускати ніяких зовнішніх викликів (так вели себе деякі діалекти Бейсіка на 8-розрядних комп'ютерах, з лек-Сікон яких були виключені оператори CALL, PEEK і Роке), або відкрито визнати, що на хиткому фундаменті фортеці не збудуєш і довіряти Java-додатків навіть з урахуванням всієї багаторівневої системи безпеки на 100% не можна. Втім, відмова від зовнішніх викликів нічого не вирішує, оскільки системні бібліотеки, що поставляються разом з Java-машиною, нічим не краще за інших компонентів і можуть містити різні дефекти проектування. Хочете приклад? На початку 2007 р. в Sun JRE 5.0 Update 9 (включаючи і більш ранні версії) була виявлена помилка, пов'язана з обробником заголовків GIF-файлів і містить уразливість, яка приводила до можливості передачі управління на shell-код, розташований безпосередньо в самому GIF-файлі. Технічні подробиці можна знайти нa www.securityfocus. com/archive/1/457159. а код exploit'a є нa www.securitvfocus.сom/archive/1/457638. Для нас же важливий сам факт небездоганною реалізації Java-машини. Виходить, що в той час як теоретики від програмування старанно виводять заплутані діаграми, що ілюструють «Просунутий» модель безпеки Java з багаторівневою системою захисту, хакери дізассембліруют бібліотечні файли на предмет пошуку реальних вразливостей.

    Військова мудрість говорить-чим більше розставлено ліній оборони, тим вища ймовірність прориву супротивника, бо надійна лінія оборони справляється зі своїм завданням і один. Можна скільки завгодно зміцнювати замок кріпаками валами та ровами, але це не захистить його від пікіруючого бомбардувальника. З «повітря» (тобто зсередини системних бібліотек) Java не захищена. Помилки там були і будуть. Досить поглянути на розмір дистрибутива (півсотні мегабайтів в упакованому вигляді) і спробувати уявити собі, скільки людино-годин потрібно для його тестування і чи реально зібрати таку кількість висококваліфікованих фахівців під одним дахом. Але ж крім стандартних бібліотек загального призначення є ще й нестандартні (наприклад, JGL, яка використовується для обробки тривимірних об'єктів і широко застосовується в задачах моделювання).

    Висновок

    Інтерес хакерів до Java-технологій неухильно зростає. Відпрацьовуються дослідні методики, створюються інструменти для аналізу байт-коду та різні іспитові стенди для верифікатори і т. п. Словом, ведуться інтенсивні наступальні роботи і в осяжному майбутньому, очевидно, слід очікувати вибухового зростання атак на Java-машини, захищеність яких на практиці виявляється значно нижче, ніж в теорії.

    Як цьому протистояти? Універсальних рецептів немає. Однак експлуатація Java-додатків нічим не відрізняється від інших, написаних на Сі/Сі + +, DELPHI, PHP. Запорука здоров'я - у своєчасній установки латочок і правильному виборі партнерів, реалізація JVM від Sun за багатьма параметрами краще, ніж у IBM, але в силу своєї величезної поширеності у Sun-машини набагато більше шансів бути атаковані.

    Список літератури

    IT спец № 07 ЛИПЕНЬ 2007

         
     
         
    Реферат Банк
     
    Рефераты
     
    Бесплатные рефераты
     

     

     

     

     

     

     

     
     
     
      Все права защищены. Reff.net.ua - українські реферати ! DMCA.com Protection Status