Установка Kali Linux
Скачать 2.4 Mb.
|
ffffffffffff static Теперь вы можете видеть, что у бедной Клэр (Clare) (трудно быть женой хакера, хакерство — это не легко и т. д.) есть свой отравленный ARP кэш, где у шлюза такой же MAC-адрес, как и у атакующего компьютера. В записи выше, вы можете четко видеть шлюз, который я атакую с адреса 172.16.1.64. Когда захват пакетов завершен, вы должны заметить файл arper.pcap в той же директории, что и ваш скрипт. Обработка PCAP Wireshark и другие инструменты, как Network Miner отлично подходят для интерактивного изучения пакетного захвата файлов. Однако иногда будут складываться такие ситуации, когда вам захочется изучить PCAP вдоль и поперек при помощи Python и Scapy. К таким ситуациям могут относиться: генерация тестов для фаззинга на основе перехваченного сетевого трафика или даже что-то совсем простое, как повторное проигрывание уже перехваченного трафика. Мы же хотим подойти к этому совершенно иначе и попытаться вырезать изображения из HTTP трафика. Имея н руках файлы с изображениями, мы воспользуемся компьютерным инструментом OpenCV [9] и попытаемся распознать изображения с лицами людей. Таким образом, мы сможем сократить количество изображений и оставить только те, что нас интересуют. Для генерации PCAP файлов, мы можем использовать прошлый скрипт ARP отравления или вы можете расширить возможности сниффера. Начнем с написания кода для проведения PCAP анализа. Откройте pic_carver.py и введите следующий код: import re import zlib import cv2 from scapy.all import * pictures_directory = "/home/justin/pic_carver/pictures" faces_directory = "/home/justin/pic_carver/faces" pcap_file = "bhp.pcap" def http_assembler(pcap_file): carved_images = 0 faces_detected = 0 a = rdpcap(pcap_file) ➊ sessions = a.sessions() ➋ for session in sessions: http_payload = "" for packet in sessions[session]: try: if packet[TCP].dport == 80 or packet[TCP].sport == 80: # reassemble the stream ➌ http_payload += str(packet[TCP].payload) except: pass headers = get_http_headers(http_payload) ➍ if headers is None: continue image,image_type = extract_image(headers,http_payload) ➎ if image is not None and image_type is not None: # store the image ➏ file_name = "%spic_carver_%d.%s" % (pcap_file,carved_images,image_type) fd = open("%s/%s" % (pictures_directory,file_name),"wb") fd.write(image) fd.close() carved_images += 1 # now attempt face detection try: result = face_detect("%s/%s" % (pictures_directory,file_name),file_name) if result is True: faces_detected += 1 except: pass return carved_images, faces_detected carved_images, faces_detected = http_assembler(pcap_file) print "Extracted: %d images" % carved_images print "Detected: %d faces" % faces_detected Это основной каркас логики всего нашего скрипта, и мы будем добавлять поддерживающие функции. Для начала, откроем PCAP файл для обработки . Мы воспользуемся отличной ➊ возможностью Scapy автоматически разделять каждую TCP сессию в словарь. Мы ➋ указываем, что нам нужен только HTTP трафик, а затем соединяем полезную нагрузку всего HTTP трафика в один буфер. По сути, это то де самое, что и функция в Wireshark ➌ «следовать TCP потоку» (Follow TCP Stream). Когда HTTP данные повторно собраны, мы передаем их функции парсинга HTTP-заголовка , что позволит нам изучить заголовки HTTP ➍ по отдельности. Убедившись, что мы получаем обратно изображение в ответ на HTTP запрос, мы извлекаем сырое изображение и возвращаем тип изображения и бинарное тело самого ➎ изображения. Это не гарантированный способ извлечения изображения, но вы сами увидите, что он работает на удивление хорошо. Мы сохраняем извлеченные изображения , а затем ➏ передаем путь файла для детекции лица . ➐ Теперь давайте напишем поддерживающие функции, добавив следующий код выше функции http_assembler def get_http_headers(http_payload): try: # split the headers off if it is HTTP traffic headers_raw = http_payload[:http_payload.index("\r\n\r\n")+2] # break out the headers headers = dict(re.findall(r"(?P<'name>.*?): (?P headers_raw)) except: return None if "ContentType" not in headers: return None return headers def extract_image(headers,http_payload): image = None image_type = None try: if "image" in headers['ContentType']: # grab the image type and image body image_type = headers['ContentType'].split("/")[1] image = http_payload[http_payload.index("\r\n\r\n")+4:] # if we detect compression decompress the image try: if "ContentEncoding" in headers.keys(): if headers['ContentEncoding'] == "gzip": image = zlib.decompress(image, 16+zlib.MAX_WBITS) elif headers['ContentEncoding'] == "deflate": image = zlib.decompress(image) except: pass except: return None,None return image,image_type Эти поддерживающие функции помогают нам поближе рассмотреть HTTP данные, которые мы получили из нашего PCAP файла. Функция get_http_headers захватывает сырой HTTP-трафик и выбирает заголовки при помощи регулярных выражений. Функция extract_image берет HTTP-заголовки и определяет, получили ли мы изображение в ответ на HTTP запрос. Если мы обнаруживаем, что заголовок Content-Type действительно содержит MIME-тип, то мы разбиваем тип изображения; а если изображение было сжато, мы пытаемся вернуть его в изначальный размер, прежде чем вернем тип изображения и буфер сырого изображения. Давайте вставим код детекции лица, чтобы определить, есть ли лицо человека на тех изображениях, что мы получили. В pic_carver.py добавляем следующий код: def face_detect(path,file_name): img = cv2.imread(path) ➊ cascade = cv2.CascadeClassifier("haarcascade_frontalface_alt.xml") ➋ rects = cascade.detectMultiScale(img, 1.3, 4, cv2.cv.CV_HAAR_ SCALE_IMAGE, (20,20)) if len(rects) == 0: return False rects[:, 2:] += rects[:, :2] # highlight the faces in the image for x1,y1,x2,y2 in rects: ➌ cv2.rectangle(img,(x1,y1),(x2,y2),(127,255,0),2) cv2.imwrite("%s/%s-%s" % (faces_directory,pcap_file,file_name),img) ➍ return True Этим кодом с нами любезно поделился Крис Фидао (Chris Fidao, http://www.fideloper.com/facial-detection/ ), я лишь внес небольшие изменения. Используя привязку OpenCV Python, мы можем считать изображение и затем применить ➊ классификатор , который заранее настроен на выявление лиц во фронтальной плоскости. ➋ Есть классификаторы для детекции лица в профиль, для определения рук, фруктов и других самых разных предметов. После запуска процесса детекции, мы получим координаты прямоугольника, которые соответствуют той области, в которой было обнаружено лицо на изображении. Затем в этой области мы рисуем зеленый прямоугольник и считываем ➌ получившееся изображение . Теперь давайте проделаем все это на вашей Kali. ➍ Проверка на деле Если вы не устанавливали библиотеки OpenCV, то запустите следующие команды (и снова, спасибо Крису Фидао) из терминала на свой Kali: #:> apt-get install python-opencv python-numpy python-scipy У вас должны установиться все необходимые для детекции лица файлы. Нам также потребуется тренировочный файл по детекции лиц: wget http://eclecti.cc/files/2008/03/haarcascade_frontalface_alt.xml Теперь создайте пару директорий для ваших исходящих данных, добавьте PCAP и запустите скрипт. Все должно выглядеть примерно так: #:> mkdir pictures #:> mkdir faces #:> python pic_carver.py Extracted: 189 images Detected: 32 faces #:> Возможно, вы увидите ряд сообщений об ошибках. Это вызвано тем, что некоторые изображения могут быть повреждены или не до конца скачены или их формат не поддерживается. (пусть извлечение изображений и их проверка будут вашим домашним заданием). Если вы откроете свои директории, то должны увидеть ряд файлов с лицами и зелеными квадратами вокруг них. Этот метод можно применять для определения типа содержимого, а также для установления возможных подходов через социальную инженерию. Конечно, вы можете выйти за пределы возможностей, описанных в этом примере и использовать этот метод совместно с поисковым роботом и методами парсинга, которые будут описаны позже в этой книге. [8] http://www.secdev.org/projects/scapy/doc/installation.html#windows [9] OpenCV можно найти по этой ссылке: http://www.opencv.org/ Глава 5. Веб-хакинг Анализ веб-приложений — это совершенно необходимо для любого взломщика или пентестера. В большинстве современных сетей, веб-приложения представляют собой самую большую поверхность для атак, поэтому здесь велика вероятность получить доступ. Существует целый ряд отличных инструментов, написанных для Python, в том числе w3af, sqlmap и другие. Если честно, то такие темы, как SQL-инъекция уже изъезжены до дыр, а инструменты для этого уже достаточно продвинуты, поэтому нет смысла изобретать колесо. Вместо этого, мы с вами разберем основы взаимодействия с веб при помощи Python, а затем создадим инструменты для разведки и атак методом «грубой силы». Вы увидите, чем может быть полезен HTML-парсинг для создания брутфоресров, инструментов разведки и анализа сайтов с большим количеством текста. Суть в том, чтоб создать несколько разных инструментов и выработать у вас основные навыки, которые потребуются для создания любого инструмента для оценки веб-приложения. Библиотека сокетов urllib2 Примерно так же, как мы пишем сетевые инструменты при помощи библиотеки сокетов, когда вы создаете инструменты для взаимодействия с веб-службами, вы будете использовать библиотеку urllib2 . Давайте посмотрим, как можно создать очень простой запрос GET для сайте No Starch Press: import urllib2 body = urllib2.urlopen("http://www.nostarch.com") ➊ print body.read() ➋ Это простейший пример, как можно сделать запрос GET для сайта. Не забывайте, что мы просто выбираем сырые страницы с сайта No Starch, и никакой JavaScript или другие языки на стороне клиента не будут выполняться. Мы просто передаем URL функции urlopen и ➊ она возвращает файловый объект, что позволяет нам прочитать то, что вернул удаленный ➋ веб-сервер. Однако в большинстве случаев, вы захотите иметь более точный контроль над тем, как вы делаете эти запросы, в том числе вы захотите иметь возможность определять конкретные заголовки, управлять cookies и создавать POST запросы. Urllib2 прописывает класс Request , который и дает вам такой уровень контроля. Ниже представлен пример, как создавать такой же запрос GET, используя класс Request и определяя HTTP-заголовок User-Agent: import urllib2 url = "http://www.nostarch.com" headers = {} ➊ headers['UserAgent'] = "Googlebot" request = urllib2.Request(url,headers=headers) ➋ response = urllib2.urlopen(request) ➌ print response.read() response.close() Создание объекта Request немного отличается от того, что мы делали в предыдущем примере. Для создания заголовков, вы определяете словарь заголовков , который позволяет ➊ вам устанавливать ключ заголовка и значение, которое вы хотите использовать. В этом случае, мы будем создавать наш Python скрипт, как Googlebot. Затем мы создаем объект Request и передаем url и словарь заголовков , а затем передаем объект ➋ Request функции urlopen . В результате, мы получаем нормальный файловый объект, который ➌ можно использовать для считывания данных с удаленного веб-сайта. Итак, теперь у нас есть базовое средство коммуникации с веб-сервисами и веб-сайтами, поэтому давайте приступим к созданию полезного инструмента для атаки любого веб- приложения или проведения теста на проникновение. Установка веб-приложений с открытым исходным кодом Системы управления контентом и платформы для ведения блогов, такие как Joomla, WordPress и Drupal позволяют быстро и без проблем запустить новый блог или сайт. Они достаточно распространены в среде совместного хостинга или даже в корпоративной сети. Все системы имеют свои недостатки при установке, конфигурации и управлении исправлениями, эти CMS не исключение. Когда, перегруженный работой сисдамин или незадачливый веб-разработчик не следуют всем правилам безопасности и установки, то система может стать легкой добычей для взломщика, который без труда получит к ней доступ. Так как мы можем скачать любое веб-приложение с открытым исходным кодом и определить его файл и структуру директории, то мы можем создать специальный сканер, который будет находить все файлы, доступные на удаленной цели. Это поможет нам извлечь незаконченные файлы, директории, которые требуют защиты файлами .htaccess и другие вещи, которые помогают взломщику зацепиться за веб-сервер. Вы также узнаете, как использовать объекты Python Queue , при помощи которых мы можем создать большой стек для использования в многопоточной среде. Наш сканер будет работать очень быстро. Давайте откроем web_app_mapper.py и введем следующий код: import Queue import threading import os import urllib2 threads = 10 targe = "http://www.blackhatpython.com" ➊ directory = "/Users/justin/Downloads/joomla3.1.1" filters = [".jpg",".gif","png",".css"] os.chdir(directory) web_paths = Queue.Queue() ➋ for r,d,f in os.walk("."): ➌ for files in f: remote_path = "%s/%s" % (r,files) if remote_path.startswith("."): remote_path = remote_path[1:] if os.path.splitext(files)[1] not in filters: web_paths.put(remote_path) def test_remote(): while not web_paths.empty(): ➍ path = web_paths.get() url = "%s%s" % (target, path) request = urllib2.Request(url) try: response = urllib2.urlopen(request) content = response.read() print "[%d] => %s" % (response.code,path) ➎ response.close() except urllib2.HTTPError as error: ➏ #print "Failed %s" % error.code pass for i in range(threads): ➐ print "Spawning thread: %d" % i t = threading.Thread(target=test_remote) t.start() Начинаем с того, что определяем удаленный целевой веб-сайт и локальную директорию, в ➊ которую мы скачали и извлекли веб-приложение. Мы также создаем простой список файловых расширений, в которых мы не заинтересованы. Этот список будет отличаться, в зависимости от целевого приложения. Переменная web_paths — это наш ➋ Queue объект, где мы будем хранить файлы, которые попытаемся разместить на удаленном сервере. Затем мы используем функцию os.walk , чтобы пройтись по всем файлам и ➌ директориям в локальной директории веб-приложения. Когда мы проходим по файлам и директориям, мы создаем полный путь к целевым файлам и проверяем их по нашему фильтру, чтобы убедиться, что мы ищем только нужные нам файлы. Для каждого подходящего файла, мы добавляем наш web_paths Queue Если посмотреть в конец скрипта , видно, что мы создаем ряд потоков (как указано в ➐ начале файла), каждый из которых будет вызван функцией test_remote . Эта функция выполняется в цикле, и процесс будет продолжаться, пока web_paths Queue не опустеет. При каждой итерации цикла, мы захватываем путь из Queue , прописываем его в базовый ➍ путь целевого веб-сайта и затем предпринимаем попытку снова извлечь его. Если нам удается извлечь файл, мы выводим код состояния HTTP и полный путь в извлеченный файл . Если файл не найден или защищен файлом ➎ .htaccess , то это приведет к тому, что urllib2 выдаст ошибку, которую мы решаем , чтобы цикл смог продолжить свое ➏ исполнение. Проверка на деле В целях тестирования, я установил Joomla 3.1.1 на свою виртуальную машину Kali, но вы можете использовать любое веб-приложение с открытым кодом. Когда вы запустите web_app_mapper.py, то у вас должен получиться такой результат: Spawning thread: 0 Spawning thread: 1 Spawning thread: 2 Spawning thread: 3 Spawning thread: 4 Spawning thread: 5 Spawning thread: 6 Spawning thread: 7 Spawning thread: 8 Spawning thread: 9 [200] => /htaccess.txt [200] => /web.config.txt [200] => /LICENSE.txt [200] => /README.txt [200] => /administrator/cache/index.html [200] => /administrator/components/index.html [200] => /administrator/components/com_admin/controller.php [200] => /administrator/components/com_admin/script.php [200] => /administrator/components/com_admin/admin.xml [200] => /administrator/components/com_admin/admin.php [200] => /administrator/components/com_admin/helpers/index.html [200] => /administrator/components/com_admin/controllers/index.html [200] => /administrator/components/com_admin/index.html [200] => /administrator/components/com_admin/helpers/html/index.html [200] => /administrator/components/com_admin/models/index.html [200] => /administrator/components/com_admin/models/profile.php [200] => /administrator/components/com_admin/controllers/profile.php Вы видите, что мы получили корректный результат, в том числе у нас есть несколько .txt и XML файлов. Конечно, вы можете встроить в скрипт дополнительные возможности, чтобы получать только интересующие вас файлы, например, содержащие слово install. Атака директорий и местоположений файлов методом «грубой силы» В предыдущем примере предполагалось, что вы многое знаете о своей цели. Однако в большинстве случаев, когда вы атакуете веб-приложение или большую систему электронной коммерции, вы не знаете, какие файлы есть на сервере. Обычно применяется поисковый робот, такой как в Burp Suite, для сканирования целевого веб-сайта с целью обнаружения как можно большего количества веб-приложений. Очень часто можно столкнуться с файлами конфигурации, удаленными файлами для разработки, скриптами отладки и прочими мерами безопасности, которые могут предоставить чувствительную информацию или раскрыть функциональность, которые разработчик ПО хотел бы скрыть. Единственный способ получить это содержимое — использовать инструмент атаки методом «грубой силы». Мы создадим простой инструмент, который принимает списки слов от приложений для брутфорса, таких как DirBuster [10] или SVNDigger [11] и принимает попытки обнаружить директории и файлы, которые доступны на целевом веб-сервере. Как и ранее, мы создадим пул потоков для агрессивного обнаружения содержимого. Начнем с функциональных возможностей для создания Queue из файла списка слов. Открываем новый файл, называем его content_bruter.py и прописываем следующий код: import urllib2 import threading import Queue import urllib threads = 50 target_url = "http://testphp.vulnweb.com" wordlist_file = "/tmp/all.txt" # from SVNDigger resume = None user_agent = "Mozilla/5.0 (X11; Linux x86_64; rv:19.0) Gecko/20100101 Firefox/19.0" def build_wordlist(wordlist_file): # read in the word list fd = open(wordlist_file,"rb") ➊ raw_words = fd.readlines() fd.close() found_resume = False words = Queue.Queue() for word in raw_words: ➋ word = word.rstrip() if resume is not None: if found_resume: words.put(word) else: if word == resume: found_resume = True print "Resuming wordlist from: %s" % resume else: words.put(word) return words Думаю, что эта вспомогательная функция вполне понята. Мы считываем файл списка слов и затем начинаем выполнять итерацию каждой строки файла . У нас уже есть ➊ ➋ встроенный функционал, который позволяет нам возобновить сессию брутфорсинга, если соединение с сетью будет прервано или целевой сайт зависнет. Этого можно достичь, задав переменную resume в последнем пути. Когда будет завершен парсинг всего файла, мы возвращаем Queue со словами, которые будут использоваться в функции брутфорсинга. Позже в этой главе мы будем использовать эту функцию еще раз. Нам нужна базовая функция, доступная для нашего скрипта брутфорсинга. Первое, что нам нужно — это возможность применять список расширений, когда делается запрос. В некоторых случаях, вы захотите попробовать не только /admin, например, но и admin.php, admin.inc и admin.html. def dir_bruter(word_queue,extensions=None): while not word_queue.empty(): attempt = word_queue.get() attempt_list = [] # check to see if there is a file extension; if not, # it's a directory path we're bruting if "." not in attempt: ➊ attempt_list.append("/%s/" % attempt) else: attempt_list.append("/%s" % attempt) # if we want to bruteforce extensions if extensions: ➋ for extension in extensions: attempt_list.append("/%s%s" % (attempt,extension)) # iterate over our list of attempts for brute in attempt_list: url = "%s%s" % (target_url,urllib.quote(brute)) try: headers = {} headers["UserAgent"] = user_agent ➌ r = urllib2.Request(url,headers=headers) response = urllib2.urlopen® if len(response.read()): ➍ print "[%d] => %s" % (response.code,url) except urllib2.URLError,e: if hasattr(e, 'code') and e.code != 404: print "!!! %d => %s" % (e.code,url) ➎ pass Наша функция dir_bruter принимает объект Queue, который заселен словами для использования во время атаки и опциональный список расширений файлов. Мы начинаем с тестирования, чтобы посмотреть, есть ли в текущем слове файловое расширение , если нет, ➊ то мы относим его к директории, которую хотим проверить на удаленном веб-сервере. Если имеется список файловых расширений , то мы берем текущее слово и применяем его к ➋ каждому файловому расширению, которое мы хотим проверить. Здесь может быть полезно использовать такие расширения, как .orig и .bak . Когда мы создали список попыток брутфорсинга, мы задаем заголовок User-Agent в отношении чего-нибудь безобидного и ➌ тестируем удаленный веб-сервер. Если код состояния ответа 200, то мы выводим URL и ➍ если мы получаем что-то отличное от 404, мы также это выводим , так как это может ➎ указывать на то, что на удаленном веб-сервере есть кое-что интересное, кроме ошибки «файл не найден». Полезно обратить внимание и отреагировать на ваши выводимые данные, так как в зависимости от конфигурации удаленного веб-сервера, вы можете отфильтровывать еще больше кодов HTTP-ошибок, чтобы очистить результаты. Давайте завершим скрипт, задав наш список слов, создав список расширений и запустив потоки атаки методов «грубой силы». word_queue = build_wordlist(wordlist_file) extensions = [".php",".bak",".orig",".inc"] for i in range(threads): t = threading.Thread(target=dir_bruter,args=(word_queue,extensions,)) t.start() В снипе этого кода нет ничего сложного и он должен быть вам знаком. Мы получаем наш список слов для атаки, создаем простой список файловых расширений для тестирования и затем запускаем несколько потоков для совершения брутфорсинга. Проверка на деле Проект OWASP имеет список онлайн и офлайн (виртуальные машины, ISO и т. д.) уязвимых веб-расширений, на которых вы можете протестировать свои инструменты. В этом случае, URL, который содержится в исходном коде, указывает на веб-приложение на Acunetix, в котором намеренно есть ошибки. Самое крутое, что оно показывает, насколько эффективным может быть брутфорсинг веб-приложения. Я рекомендую установить переменную thread_count на значении 5 и запустить скрипт. Вскоре, вы должны увидеть подобные результаты: [200] => http://testphp.vulnweb.com/CVS/ [200] => http://testphp.vulnweb.com/admin/ [200] => http://testphp.vulnweb.com/index.bak [200] => http://testphp.vulnweb.com/search.php [200] => http://testphp.vulnweb.com/login.php [200] => http://testphp.vulnweb.com/images/ [200] => http://testphp.vulnweb.com/index.php [200] => http://testphp.vulnweb.com/logout.php [200] => http://testphp.vulnweb.com/categories.php Вы видите, что мы получили довольно любопытные результаты от удаленного сайта. Я не могу не подчеркнуть еще раз важность брутофрсинга содержимого на всех целевых веб- приложениях. Атака на HTML-формы аутентификации В вашей карьере хакера может наступить период, когда вам понадобится получить доступ к цели или, если вы консультируете, то оценка надежности пароля в существующей веб- системе. Сейчас многие веб-системы устанавливают защиту от атак методом «грубой силы», будь то капча, простое математическое вычисление или регистрационный маркер, который нужно отправить вместе с запросом. Сейчас существуют брут-форсеры, которые могут совершить атаку методом запроса POST к скрипту авторизации, но в большинстве случаев эти брут-форсеры недостаточно гибкие, чтобы справиться с динамическим содержимым или проверками «я не робот». Мы создадим простой брут-форсер для Joomla, популярной системы управления контентом. Современные системы Joomla включают в себя некоторые базовые методы против атак методом «грубой силы», но они пока еще не блокируют учетные записи и не имеют надежной капчи по умолчанию. Для совершения брут-форс атаки на Joomla, нам нужно выполнить два требования: получить регистрационный маркер из формы авторизации, прежде чем делать попытку отправки пароля. Второе требование — необходимо убедиться, что в сессии urllib2 мы принимаем cookies. Для того чтобы парсинга значений формы авторизации, мы будем использовать нативный HTMLParser для Python. Начнем с того, что посмотрим на форму авторизации администратора в Joomla. Ее можно найти по ссылке http:// Для краткости, я включил только релевантные элементы формы. |