Пишем simple-кейлогер с передачей дампа по TCP на C#. Часть II

Тема в разделе "Этичный хакинг и тестирование на проникновение", создана пользователем Ishikawa, 28 ноя 2016.

Метки:
  1. Ishikawa

    Ishikawa マエストロ
    Команда форума Grey Team

    Репутация:
    1
    Регистрация:
    15 ноя 2016
    Сообщения:
    124
    Симпатии:
    163
    В первой части было показан вариант серверной части простого кейлогера с передачей дампа по сети используя Socket. Сегодня мы доработаем серверную часть, немного расширив функционал и напишем клиента: переделаем функции для работы с сокетами и добавим несложный удаленный shell, использующий возможности Windows CMD.

    Начнем с серверной части. Для начала вынесем функцию screenshot за пределы Main, оформим её отдельно. В дальнейшем мы будем обращаться к функции через команду Screen:
    Пишем simple-кейлогер с передачей дампа по TCP на C#. Часть II

    Кстати, если кто смотрел исходник, то мог заметить, что помимо нажатий клавиш, при запуске программы в лог записывается некоторая информация о системе и есть сохранение последнего содержимого буфера (text) через функцию GetBuff:
    Пишем simple-кейлогер с передачей дампа по TCP на C#. Часть II
    В дальнейшем можно также вынести функцию в отдельную команду, чтобы получать содержимое буфера по запросу. Очень часто в буфер попадают copy-pastу пароли.

    Далее напишем пару функций-помощников. Для начала нам нужно научить пересылать данные между сервером и клиентом. Для начала напишем функцию, которая будет отправлять данные от сервера к клиенту:
    Пишем simple-кейлогер с передачей дампа по TCP на C#. Часть II

    Функция приминает два параметра: непосредственно данные и сокет, который будем использовать.
    Использовать в дальнейшем будем таким образом:
    Пишем simple-кейлогер с передачей дампа по TCP на C#. Часть II

    Поскольку мы планируем сделать небольшой shell, необходимо каким-то образом заставить сервер запускать процессы на удаленном компьютере, а клиенту - пересылать данные.
    Поможет нам в этом метод Process из пространства using System.Diagnostics.
    Функция, написанная на основе этого метода, принимает два параметра: название команды, ее аргументы и сокет, через который будем работать.

    Пишем simple-кейлогер с передачей дампа по TCP на C#. Часть II

    Обращаем внимание на строку process.StartInfo.RedirectStandartOutput = true; она нам поможет формировать output для клиента. process.Start() запускает нашу команду, переданную через string s, string fl. Для формирования output используем StreamReader, читающий весь вывод до конца методом ReadToEnd(), и то, что получилось, отправляем через SSend(output,client).
    process.WaitForExit() означает, что мы ждем завершения команды.
    ВАЖНО! Например, если вы запустите Блокнот, он откроется на сервере и будет висеть до тех пор, пока кто-нибудь не закроет его. Пока на клиент не поступит сигнал о завершении, другую команду провести не выйдет. Вызов SSend как раз означает, что команда завершилась.

    Теперь о сложном. Необходимо полностью переписать функцию ServerSocket():
    Пишем simple-кейлогер с передачей дампа по TCP на C#. Часть II

    Создаем точку подключения ipep, создаем сокет newsock, делаем bind и дальше слушаем на порту 9050. Все дальнейшие операции проводим в цикле while(true), внутри которого все будем обрабатывать через try-catch, чтобы иметь возможность отлавливать ошибки.
    Далее ждем подключения клиента:
    Пишем simple-кейлогер с передачей дампа по TCP на C#. Часть II
    Готовим переменные под входящие данные, создаем просторный массив байтов.
    Дальше начинается магия. Получать команды от клиента мы будем через client.Receive(bytes) и в переменную data направлять результат:
    Пишем simple-кейлогер с передачей дампа по TCP на C#. Часть II

    Дальше нам предстоит получить команду и ее аргументы. Считаем, что сначала идет команда, пробел, аргументы:
    Пишем simple-кейлогер с передачей дампа по TCP на C#. Часть II

    Отделяем команду от аргументов через data.Split(splitChars,2); - таким образом мы делим весь ввод на 2 части. Пробел - разделитель. На выходе получаем одномерный массив string a[].

    Но что будет, если команда будет передана без аргументов, а в функцию мы NewProcess мы передаем аж три параметра? Ничего хорошего. Программа вылетит с ошибкой, т.к. не сможет найти a[1], поскольку его просто не существует. В сети есть куча примеров, как определить наличие индекса в массиве, от маленьких до больших. Но всегда есть способ проще:
    Пишем simple-кейлогер с передачей дампа по TCP на C#. Часть II
    Просто да? А то. Но ведь в NewProcess по-прежнему передается три параметра, скажете вы. Конечно, но теперь я покажу, как мы будем действовать. Пишем модуль для отправки команд.
    Использовать будем switch(fileName). А fileName = a[0];
    Полностью описывать не станем, всё есть в исходнике. Покажу основные моменты:
    Пишем simple-кейлогер с передачей дампа по TCP на C#. Часть II

    Таким образом вызовем ipconfig. В этом случае будет существовать только a[0].
    Если наберем ipconfig /all - будет и a[0] и a[1] и они будут аргументами для NewProcess.
    А вот если мы наберем cmd без параметров, то на сервер откроется cmd-сессия, но поскольку мы не передали аргументов, мы ничего не увидим, клиент останется в неведении и вполне возможно, мы просто потеряем контроль через Socket.
    Чтобы этого не произошло, делаем так:
    Пишем simple-кейлогер с передачей дампа по TCP на C#. Часть II

    Таким простым образом защитили себя от невнимательности. Обратим внимание на вызов NewProcess: "cmd.exe" передается с ключем "/C" - это позволяет выполнить команду с последующим ее завершением. Без завершения нужен ключ "/K". Можете поэкспериментировать. Это позволяет проводить довольно большой список команд через CMD сервера, но не весь. Например переход в каталог через cd работать не будет. Кстати, работа cmd cmd не проверялась.

    Для разнообразия я добавил еще функцию Delete. В ней также присутствует защита от использования без аргументов. А вот для удаления мы используем не cmd del, а метод FileInfo.Delete(). Но если вы дадите команду серверу cmd del path_to_file/file - это тоже сработает.
    Пишем simple-кейлогер с передачей дампа по TCP на C#. Часть II

    Как вы могли заметить, весь вывод идет через SSend. Функция в две строки оказалась чрезвычайно полезной.
    Если вы наберете всякую белиберду, или вовсе пустую команду - есть case default:
    Пишем simple-кейлогер с передачей дампа по TCP на C#. Часть II

    Все что не нашлось в switch, будет распознано как мусор и выполняться не будет (почти, кое-что будет).Осталось совсем немного, дописать вызов функции отправляющей нам лог-файл и функцию, которая создает и отправляет по запросу скриншот удаленного компьютера.
    За пределами switch пишем следующее:

    Пишем simple-кейлогер с передачей дампа по TCP на C#. Часть II

    Это вызов для функции скриншота. Заметили функцию SocketWorker? О ней чуть ниже.
    Для лог-файла делаем аналогично:
    Пишем simple-кейлогер с передачей дампа по TCP на C#. Часть II

    В интернете есть много примеров передачи файлов через сокеты, что-то кривое, что-то нет.
    Некоторые делают FTP-клиент(многие упираются в ошибку 500 при работе), некоторые пишут сервер.
    Мы пойдем проще: останемся верными сокету. Функция принимает только имя файла, который нужен и текущий сокет:
    Пишем simple-кейлогер с передачей дампа по TCP на C#. Часть II

    Первые 5 строк должны быть понятны: берем входные параметры и переводим их в массивы байтов, с учетом смещений и выравнивания. А вот что за CopyTo?
    Это весьма полезная вещь для работы с массивами. Метод позволяет копировать все элементы текущего одномерного массива в заданный одномерный массив начиная с указанного индекса в массиве назначения. Таким образом все содержимое нужного нам файла будет упаковано в массив byte[] и отправлено нам через... Socket.Send, т.е. тем же самым методом, которым мы отправляем и ответы на команды. Весьма удобно, можно протолкнуть слона в игольное ушко.

    На этом моменте с серверной частью покончено. Базис задан, желающие могут пилить под себя. Это легче, чем кажется.

    Приступим к клиенту. Задача клиента - соединяться с сервером, отправлять команды и получать ответы, а также принимать файлы по запросу.
    Для клиента подключаем необходимые адресные пространства:
    Пишем simple-кейлогер с передачей дампа по TCP на C#. Часть II
    Больше для работы не требуется. В функции Main клиента пишем функционал для подключения к серверу:
    Пишем simple-кейлогер с передачей дампа по TCP на C#. Часть II
    В Main все просто. Главное в нем - функция SendMessageFromSocket(host). Функция принимает в качестве аргумента имя хоста или ip-адрес:
    Пишем simple-кейлогер с передачей дампа по TCP на C#. Часть II
    Первые три строки уже должны быть понятны: преобразовываем имя хоста, устанавливаем конечную точку подключения. Обратите внимание на AddressFamily. Метод InterNetwork означает использовать IP-адрес версии 4. Там же можно указать ATM, AppleTalk,Chaos и пр. Материал тут:
    https://msdn.microsoft.com/ru-ru/library/system.net.sockets.addressfamily(v=vs.110).aspx
    Сам метод AddressFamily возвращает семейство адресов IP-адреса.

    Далее готовим буфер под принимаемые данные и соединяемся с удаленной точкой:
    Пишем simple-кейлогер с передачей дампа по TCP на C#. Часть II

    После того, как соединение установлено, нужно как-то послать команду серверу. Делаем это таким образом:
    Пишем simple-кейлогер с передачей дампа по TCP на C#. Часть II

    3 строка - проверка на пустую строку или Null. Наша команда это string message. Чтобы его отправить, его нужно преобразовать в байты - применим Encoding.
    И дальше снова магия:
    Пишем simple-кейлогер с передачей дампа по TCP на C#. Часть II
    Отправляем команды, поддерживаемые сервером и получаем ответ.
    Теперь оформим блок для приема двух файлов: скриншота и лог-файла с сервера.
    Пишем simple-кейлогер с передачей дампа по TCP на C#. Часть II

    Чуть позже напишем функцию SocketReceive, принимающая в качестве параметров Socket клиента и выходной файл. Желающие могу дописать функцию для сохранения в произвольное имя файла.

    Пишем simple-кейлогер с передачей дампа по TCP на C#. Часть II

    Чтобы клиент не закрывался после каждой введенной команды, используем переход в начало функции. Теоретически можно объявить метку и делать goto.

    Обратите внимание, в серверной части нет функций для закрытия сокета, чтобы мы могли подключаться к серверу постоянно, если на клиенте вдруг произойдет сбой, либо мы прервем его выполнение (клиент можно прервать по CTRL+Z. В этом случае сервер напишет у себя в логе Bye!, а клиент завершиться с выводом строки "Передача завершена. Завершите соединение вручную")

    Осталось малое - написать функцию SocketReceive, для приема файлов.
    Пишем simple-кейлогер с передачей дампа по TCP на C#. Часть II
    На вход подаем сокет и имя файла, создается буфер под принятые данные.
    После подготовки к приему, сообщаем что мы готовы и открываем BinaryWriter для записи потока битов напрямую в файл на клиенте.
    int receivedBytesLen = sender.Receive(clientData) - принимает данные от сервера.
    Файлы сохраняются там же, где лежит клиент.
    Пишем simple-кейлогер с передачей дампа по TCP на C#. Часть II
    После приема сообщаем об этом и закрываем поток BinaryWriter.

    На этом шаге написание клиента завершено. Осталось написать отдельный инструмент для работы с шифрованным логом, расшифровать его, проанализировать, восстановить все нажатия.
    Но об этом - в следующей статье.
     

    Вложения:

    #1 Ishikawa, 28 ноя 2016
    Последнее редактирование: 28 ноя 2016
    valerian38, Runinterface, molexuse и 6 другим нравится это.
  2. Ishikawa

    Ishikawa マエストロ
    Команда форума Grey Team

    Репутация:
    1
    Регистрация:
    15 ноя 2016
    Сообщения:
    124
    Симпатии:
    163
    Немного скриншотов, как это работает:
    Прием файла (команда screen):
    Пишем simple-кейлогер с передачей дампа по TCP на C#. Часть II
    Не смотрите что пишет "невыполнимая команда", так и должно быть, позже поправим).

    Пример команды Help:
    Пишем simple-кейлогер с передачей дампа по TCP на C#. Часть II

    Белиберда:
    Пишем simple-кейлогер с передачей дампа по TCP на C#. Часть II

    Команда без аргументов:
    Пишем simple-кейлогер с передачей дампа по TCP на C#. Часть II

    Пустая команда:
    Пишем simple-кейлогер с передачей дампа по TCP на C#. Часть II

    Пробуем taskkill:
    Пишем simple-кейлогер с передачей дампа по TCP на C#. Часть II

    Ну и конечно, исходники сервера и клиента ищите во вложении к этому сообщению :)
    И не забываем, что неправомерный доступ к информации карается законом.
    УК РФ, Статья 272. Неправомерный доступ к компьютерной информации
     

    Вложения:

    #2 Ishikawa, 28 ноя 2016
    Последнее редактирование: 28 ноя 2016
    _Eliot_, kot-gor и WebWare Team нравится это.
  3. poxys

    poxys Member

    Репутация:
    0
    Регистрация:
    23 окт 2016
    Сообщения:
    10
    Симпатии:
    0
    клиент не соединяется! а консоль сервера не скрыта и плюс бредятина высвечивается!
     

    Вложения:

  4. poxys

    poxys Member

    Репутация:
    0
    Регистрация:
    23 окт 2016
    Сообщения:
    10
    Симпатии:
    0
    А то что Visual Studio предлагает удалить лишние, это надо делать или нет?
     

    Вложения:

  5. WebWare Team

    WebWare Team Администратор
    Команда форума

    Репутация:
    1
    Регистрация:
    30 дек 2015
    Сообщения:
    692
    Симпатии:
    615
  6. Ishikawa

    Ishikawa マエストロ
    Команда форума Grey Team

    Репутация:
    1
    Регистрация:
    15 ноя 2016
    Сообщения:
    124
    Симпатии:
    163
    Консоль сервера сам скроешь, я писал в первой части какой параметр отвечает за стелс. Высвечивается не бредятина - а последнее содержимое буфера, бро.

    Клиент и сервер соединяться - если у обоих будет один порт. В моем случае 9050.
    Ко всему этот порт не должен быть закрыт фаерволом.
    Пиши в личку настройки фаера, проверь комп Nmap на наличие открытого порта 9050 на стороне сервера.

    p.s. и как бы по коду программы:
    // Соединяем сокет с удаленной точкой
    sender.Connect(ipEndPoint);
    Console.Write("Введите сообщение: ");
    т.о. клиент и сервер все же соединяются. Так что нужно дебажить :)
    Отследить можно через сетевой монитор:
    Пишем simple-кейлогер с передачей дампа по TCP на C#. Часть II
    Как видишь, у меня клиент соединяется с сервером, находящийся в вообще другой подсети.
     
    #6 Ishikawa, 29 ноя 2016
    Последнее редактирование: 29 ноя 2016
  7. Ishikawa

    Ishikawa マエストロ
    Команда форума Grey Team

    Репутация:
    1
    Регистрация:
    15 ноя 2016
    Сообщения:
    124
    Симпатии:
    163
    Да, лишнее можешь удалить, оно осталось от других наработок.
     
  8. -master-

    -master- Well-Known Member

    Репутация:
    0
    Регистрация:
    14 янв 2012
    Сообщения:
    617
    Симпатии:
    20
  9. Ishikawa

    Ishikawa マエストロ
    Команда форума Grey Team

    Репутация:
    1
    Регистрация:
    15 ноя 2016
    Сообщения:
    124
    Симпатии:
    163
    Можете переместить в нужный раздел, я не против.
    А как metsvc относится ко взлому, бро?
     
  10. -master-

    -master- Well-Known Member

    Репутация:
    0
    Регистрация:
    14 янв 2012
    Сообщения:
    617
    Симпатии:
    20
    Я же не говорю что эту информацию можно/нужно/попробуй-только-не ипользовать в хакинге/тестах/...
    речь только про то что тут явно куча того что можно просто переметить и красиво оформить в соотв. разделе, а здесь красивый линк туда.
    типа вот мы начинаем обалденно тестировать чего то там, но как прогеры мы можем наваять неслабые штуки зырь тут -> линк
    и погналово дальше ..

    там можно будет вети свое обсуждение/дополнение/ а тут свое, и все в шоколаде

    вот както так, я конечно не спец по хакингу, и ели не прав то с честью выдержу прямое попадание))
     
  11. poxys

    poxys Member

    Репутация:
    0
    Регистрация:
    23 окт 2016
    Сообщения:
    10
    Симпатии:
    0
    Фаер выключен локальными политиками. Все заработало со второго раза, консоль тупит, надо энтер несколько раз нажать, короче итоги: при команде screen загружается скриншот, в папку и если еще раз сделать это, то screen.jpg не заменяется, или не создается новый, cmd лист неудобный, нельзя сделать что бы был полноценный cmd shell? Без команд cmd ifconfig (сделать меню в нем две-три команды, первая при нажатии цифры 1 и энтер подгружает логи с сервера, вторая запускает полноценный shell cmd оболочку в которой можно работать как в обычной командной строке, третья показывает инфу о системе, например выпоняет команду sysinfo и выводит содержимое) как у нормальных ратах. Clipboard один раз делается, а неплохо бы было что бы это записывалось в логи когда этот процесс вызывает пользователь. На сервере не нужно выводить команды которые отправляет управляющий клиент.

    Это просто советы по улучшению.
    Я бы сам это попробовал реализовать, но нет знаний:(
     
  12. poxys

    poxys Member

    Репутация:
    0
    Регистрация:
    23 окт 2016
    Сообщения:
    10
    Симпатии:
    0
    с cmd наверно погорячился это можно сказать полноценный шел, но вот cd ../ переходы не работают,
     
  13. Ishikawa

    Ishikawa マエストロ
    Команда форума Grey Team

    Репутация:
    1
    Регистрация:
    15 ноя 2016
    Сообщения:
    124
    Симпатии:
    163
    Я с тобой согласен бро. В момент написания первой части я не нашел куда лучше положить тему. Первую часть никто перемещать не стал, я решил в этом же разделе накатать вторую. Перемещайте тему на свое усмотрение, главное чтобы инфу нашли :)
     
  14. Ishikawa

    Ishikawa マエストロ
    Команда форума Grey Team

    Репутация:
    1
    Регистрация:
    15 ноя 2016
    Сообщения:
    124
    Симпатии:
    163
    Привет, бро. У меня все с первого раза работает, Enter долбить тоже не приходится. Допускаю, что на медленных соединениях возможно будет задержка при передаче файлов и обмене командами. Скриншот создается новый, если удалить текущий. Если смотрел внимательно - в коде нет функции удаления скриншота или лога. Я в первой части писал (ты по-ходу не читал) что код будет с ограничениями, ибо мы пишем simple-версию. Профессиональные кейлогеры пишут иначе, выносят код в драйвер, используют другие функции.
    Cmd-лист явлен как демонстрация возможностей: основные команды, которые доступны в CMD, можно провернуть. То что не работает переход между директориями cd.. я тоже писал.
    И писали все же кейлогер, а не шелл. Clipboard делается один раз, да. Я писал, что желающие могут вынести код в отдельную функцию и добавить ей команду (ты видимо вообще не читал). На сервере - всё в твоих руках, бро.
    Закомментируй строки Console.WriteLine и будет тебе счастье :)

    p.s. я понимаю, что copy-paste рулит, но понимать основы наверное стоит. Начать прежде всего с внимательного чтения, а не бездумной компиляции. Можно ведь и вирус зашить в код или зашифровать всю инфу на компе. Первым делом нужно проверять, что другие дают.
    Могу рекомендовать/подарить две хорошие книги по C#, чтобы знания всё же были.
     
    #14 Ishikawa, 30 ноя 2016
    Последнее редактирование: 30 ноя 2016
  15. WebWare Team

    WebWare Team Администратор
    Команда форума

    Репутация:
    1
    Регистрация:
    30 дек 2015
    Сообщения:
    692
    Симпатии:
    615
    Тема находится на своем месте. Закрываем тему о перемещении ☺
     
    Ishikawa нравится это.
  16. MAdDog719

    MAdDog719 Well-Known Member
    Grey Team

    Репутация:
    0
    Регистрация:
    16 авг 2016
    Сообщения:
    108
    Симпатии:
    26
    Привет, скажи, пожалуйста, это уже полностью готовый кейлогер, или еще нужно написать дешифратор файлов которые будет принимать сервер?
     
  17. WebWare Team

    WebWare Team Администратор
    Команда форума

    Репутация:
    1
    Регистрация:
    30 дек 2015
    Сообщения:
    692
    Симпатии:
    615
    Восстановим ...

    Пишем simple-кейлогер с передачей дампа по TCP на C#. Часть II
     
    Ishikawa нравится это.
  18. Ishikawa

    Ishikawa マエストロ
    Команда форума Grey Team

    Репутация:
    1
    Регистрация:
    15 ноя 2016
    Сообщения:
    124
    Симпатии:
    163
    Привет, бро. Да, будет еще дешифратор. Он самая сложная часть, т.к.нужно парсить строки, используя всякие Replace и Regex. В дальнейшем можно будет объединить клиент и дешифратор в одну программу.
    На текущий момент принцип такой: сервер работает на жертве постоянно, мы подсоединяемся клиентом с целью быстро вытащить логи или скрин и смыться. А награбленное скормить дешифратору.
    Время от времени я дописываю еще и серверную часть, сегодня написал как поставить прогу в автозапуск.
     
    MAdDog719 нравится это.
  19. MAdDog719

    MAdDog719 Well-Known Member
    Grey Team

    Репутация:
    0
    Регистрация:
    16 авг 2016
    Сообщения:
    108
    Симпатии:
    26
    Понятно, жду тогда дешифратор. И спасибо за твой труд, реально клевый проект.
     
    Ishikawa нравится это.
  20. Ishikawa

    Ishikawa マエストロ
    Команда форума Grey Team

    Репутация:
    1
    Регистрация:
    15 ноя 2016
    Сообщения:
    124
    Симпатии:
    163
    Стараюсь, бро :)
     
Загрузка...

Поделиться этой страницей