Главная / Блог / Tmux для CTF: настраиваем рабочую среду без потери прогресса

14 мин.00

Tmux для CTF: настраиваем рабочую среду без потери прогресса

Tmux для CTF: настраиваем рабочую среду без потери прогресса

Tmux для CTF: настраиваем рабочую среду без потери прогресса

HackTheBox-машина средней сложности. Foothold через SMB получен, nmap сканирует оставшиеся 64 тысячи портов, gobuster перебирает директории на веб-сервере, netcat слушает порт 4444 на входящий reverse shell. Четыре SSH-окна открыты параллельно. Wi-Fi мигнул на две секунды — четыре сессии мертвы. 40-минутный скан в пустоту, listener убит, даже вывод gobuster не скопирован. Полтора часа прогресса обнулены.

Ровно после такого случая tmux стал первой командой, которую я набираю при подключении к атакующему VPS. Без исключений.

Зачем CTF-игроку мультиплексор терминала

Типичная CTF-сессия — одновременная работа в четырёх-шести терминалах. В одном крутится сканер портов, во втором — перечисление директорий, третий слушает входящий шелл, в четвёртом пишутся заметки или запускается эксплойт. Без мультиплексора каждый процесс привязан к отдельному SSH-соединению. Обрыв связи — потеря всего.

Мультиплексор терминала решает три проблемы, критичные именно для CTF.

Персистентность. Tmux работает как серверный процесс на удалённой машине. SSH-соединение может падать хоть десять раз подряд — процессы внутри tmux продолжают жить. Переподключился, набрал tmux attach — nmap досканировал, listener поймал шелл, gobuster нашёл /admin. Ничего не пропало. Из документации NCSA: «tmux sessions remain active on the login node, you can simply log back in, attach to your existing session, and resume your work exactly where you left off».

Организация рабочего пространства. Вместо переключения между окнами PuTTY или вкладками терминала — одно окно, разбитое на панели (panes). Слева запущен эксплойт, справа — вывод listener, внизу — шелл на целевой машине. Всё видно одновременно, без Alt+Tab. Tmux организует информацию в трёхуровневую иерархию: сессия (session) → окна (windows, аналог вкладок браузера) → панели (panes, разделение одного окна на части).

Воспроизводимость. Скрипт запуска tmux-сессии с нужной раскладкой — и через три секунды после SSH-подключения к VPS готова полноценная рабочая среда для CTF. Не нужно каждый раз руками создавать окна и расставлять инструменты. На CTF-соревнованиях с ограниченным временем это особенно ощутимо: каждая минута на пересоздание среды после обрыва — минута, которая могла уйти на решение таска.

Tmux vs screen: какой мультиплексор терминала выбрать для CTF

Оба инструмента решают задачу сохранения сессии терминала. Для CTF-задач разница существенная.

Критерий tmux screen
Разделение на панели Нативно, горизонтально и вертикально Есть, но после сплита нужно вручную создать шелл
Скриптование раскладок Полноценное API: send-keys, split-window Ограниченное
Поддержка мыши set -g mouse on — клик, прокрутка, ресайз Через настройку, менее стабильно
Настройка статусной строки Гибкая, из коробки Требует отдельной конфигурации
Синхронизация ввода в панели synchronize-panes on Нет нативной поддержки
Предустановлен в Kali Linux Да Да
Копирование между панелями Встроенный буфер с vi/emacs-режимом Есть, менее интуитивно
Доступность на старых серверах Может отсутствовать Почти всегда предустановлен

Tmux — основной инструмент. Он гибче, лучше скриптуется и удобнее для многопанельной работы. Screen стоит знать как запасной вариант: пригодится, когда tmux не установлен, а прав на установку пакетов нет. Такое бывает на shared-хостингах и на целевых машинах, куда попал через полученный шелл.

Kali Linux, Parrot OS и большинство атакующих дистрибутивов поставляются с tmux из коробки. На Ubuntu/Debian установка — sudo apt install tmux, на CentOS/Fedora — sudo dnf install tmux. Проверка версии: tmux -V. Всё описанное в статье работает на tmux 3.x.

Настройка tmux: базовые команды и горячие клавиши

Базовый цикл работы: создаёшь именованную сессию tmux new -s htb, работаешь внутри, отсоединяешься через Ctrl+b d (detach), позже возвращаешься через tmux attach -t htb. Сессия всё это время жива — процессы работают, вывод сохраняется в буфере.

Хоткеи, которые реально нужны для CTF (все начинаются с префикса Ctrl+b):

  • c — создать новое окно (вкладку внутри сессии)
  • , — переименовать текущее окно (назвать «recon», «exploit», «privesc»)
  • n / p — перейти к следующему / предыдущему окну
  • 0–9 — перейти к окну по номеру
  • w — интерактивный список всех окон с предпросмотром содержимого
  • " — разделить текущую панель горизонтально (верх и низ)
  • % — разделить панель вертикально (лево и право)
  • стрелки — переключение фокуса между панелями
  • z — развернуть текущую панель на весь экран и обратно (zoom/unzoom)
  • [ — режим прокрутки и поиска по буферу (выход — q)
  • x — закрыть текущую панель (с подтверждением)
  • d — detach, отсоединиться от сессии

Отдельно про Ctrl+b z — штука, которую недооценивают. Когда вывод nmap занимает 300 строк, а панель — четверть экрана, разворачиваешь её на полный экран, спокойно изучаешь результат, нажимаешь Ctrl+b z снова — возвращаешься к раскладке. Не нужно перетаскивать границы панелей.

Список живых сессий: tmux ls. Вывод покажет имя сессии, количество окон и время создания. Полезно, когда утром забыл — создавал ли сессию для текущей машины. Завершить сессию целиком, не заходя внутрь: tmux kill-session -t htb. Уничтожить все сессии разом: tmux kill-server.

Конфигурация tmux.conf под CTF-задачи

Файл ~/.tmux.conf превращает tmux из терпимого в незаменимый. Вот конфиг, который стоит на моих атакующих VPS:

# мышь — потому что иногда проще кликнуть, чем считать панели
set -g mouse on
# 50к строк буфера — nmap -sV -sC на 65535 портов не потеряется
set -g history-limit 50000
# нумерация с 1, потому что 0 на клавиатуре далеко
set -g base-index 1
setw -g pane-base-index 1
set -g renumber-windows on
# убираем лаг Escape для vim
set -s escape-time 0
# | и - вместо " и % — логичнее
bind | split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"
# перезагрузка конфига без перезапуска
bind r source-file ~/.tmux.conf \; display "Reloaded"
# vi-режим для поиска по буферу
setw -g mode-keys vi

Разбор в контексте CTF-работы.

history-limit 50000 — размер буфера прокрутки. По умолчанию tmux хранит 2000 строк. Вывод nmap -sV -sC на весь диапазон портов легко перешагивает эту границу. С 50000 строк ни одна строчка не теряется — можно прокрутить назад и найти нужный баннер сервиса. Значения 10000–50000 — стандартная практика для рабочих машин.

base-index 1 и pane-base-index 1 — нумерация окон и панелей с единицы вместо нуля. По умолчанию первое окно имеет номер 0, и для переключения приходится тянуться к Ctrl+b 0. С единицей — Ctrl+b 1 для первого окна. Мелочь, но за четырёхчасовой CTF эти мелочи складываются.

escape-time 0 — убирает задержку после нажатия Escape. Без этой настройки vim внутри tmux реагирует с заметным лагом при переключении режимов. Когда правишь эксплойт в vim и тут же запускаешь его — лаг раздражает ощутимо.

bind | split-window -h -c "#{pane_current_path}" — биндинг Ctrl+b | для вертикального сплита. Флаг -c "#{pane_current_path}" тут критичен: без него каждая новая панель открывается в домашней директории, и приходится заново делать cd /tmp/ctf/exploit/. С флагом новая панель стартует в той же директории, где работаешь. Аналогично bind - для горизонтального разделения.

mode-keys vi — навигация в режиме прокрутки через vi-клавиши: hjkl для движения, / для поиска по тексту. Найти порт 8443 в выводе nmap: Ctrl+b [/8443Enter. Секунда вместо ручной прокрутки стрелками.

Применить конфиг без перезапуска: Ctrl+b r (через биндинг из конфига выше) или Ctrl+b : → ввести source-file ~/.tmux.conf.

Рабочая среда для CTF: раскладки панелей в tmux

Раскладка для разведки и сканирования

На этапе reconnaissance нужны три-четыре панели одновременно. Верхняя левая — основное сканирование (nmap или rustscan). Верхняя правая — перечисление директорий (gobuster, feroxbuster, dirsearch). Нижняя левая — рабочий терминал для ручных команд и быстрых проверок (curl, whatweb, ручные HTTP-запросы). Нижняя правая — заметки в vim или nano, куда записываешь найденные порты, учётные данные, потенциальные векторы.

Создаётся за десять секунд. Запускаешь tmux new -s recon. Делаешь Ctrl+b | — две вертикальные панели. Переходишь в левую, Ctrl+b - — левая половина разделяется горизонтально. Стрелкой вправо, снова Ctrl+b - — правая половина тоже разделяется. Четыре панели готовы. Переименовываешь окно: Ctrl+b , → вводишь «recon».

По MITRE ATT&CK этот этап — System Information Discovery (T1082) и File and Directory Discovery (T1083): перечисление портов, сервисов, доступных каталогов и файлов на целевой машине. Каждая панель tmux закрывает свой вектор разведки, и весь контекст виден одновременно.

Когда начинается эксплуатация — создаёшь новое окно Ctrl+b c, называешь «exploit». Переключение между фазами атаки: Ctrl+b 1 (recon) и Ctrl+b 2 (exploit). Данные разведки остаются в первом окне, можно вернуться и пересмотреть вывод в любой момент.

Раскладка для эксплуатации и перехвата шеллов

На этапе эксплуатации раскладка меняется. Одна панель постоянно занята listener: rlwrap nc -lvnp 4444 или pwncat-cs :4444. Соседняя панель — для запуска эксплойта или отправки payload. Нижняя большая панель — для работы в полученном шелле после успешной эксплуатации.

Почему listener и эксплойт в соседних панелях — видишь одновременно и отправку payload, и момент прихода обратного соединения. Не нужно переключаться между окнами, чтобы понять — сработал эксплойт или нет. Когда шелл приходит, переключаешься в панель listener стрелкой (Ctrl+b стрелка-вниз) и начинаешь работу на целевой машине.

Для командных CTF есть крутая штука — синхронизация панелей: Ctrl+b :set-window-option synchronize-panes on. После этого каждый введённый символ дублируется во все панели текущего окна. Получены шеллы на трёх машинах и нужно выполнить whoami на всех? Набираешь один раз — результат появляется в трёх панелях одновременно. Выключить: та же команда с off.

Сохранение сессии терминала: detach, attach и восстановление после обрыва

Центральная ценность мультиплексора — возможность отсоединиться от сессии, не убивая процессы. Ctrl+b d — detach. Ты вернулся в обычный шелл SSH, но сессия tmux жива. Nmap сканирует, listener слушает, панели сохранены.

Просмотреть живые сессии: tmux ls. Подключиться к конкретной: tmux attach -t htb или сокращённо tmux a -t htb. Если сессия одна — достаточно tmux a.

Практический сценарий для работы в терминале без потери прогресса: утром создал tmux new -s htb-machine, отработал два часа, сделал detach, ушёл. Вечером подключился к VPS с другого устройства — ноутбук, планшет, даже телефон через Termux. Команда tmux a -t htb-machine — рабочее место восстановлено в точности. Вывод nmap прокручивается вверх, шелл ждёт ввода, vim с заметками на месте. Из документации RunPod: «TMUX runs your commands in persistent terminal sessions that continue even if you disconnect».

Если SSH оборвался без явного detach — tmux-сессия всё равно жива. Вот тут ключевое отличие от работы без мультиплексора: без tmux обрыв SSH отправляет SIGHUP всем дочерним процессам — они завершаются. С tmux процессы живут в серверном процессе tmux, который не зависит от SSH-соединения.

При переподключении tmux ls покажет существующую сессию. Если старый SSH-клиент не успел отправить сигнал отключения и сессия помечена как «attached» — используй tmux attach -dt htb. Флаг -d принудительно отсоединяет предыдущий клиент и подключает текущий. Для screen аналог: screen -DR ctf.

Полезная команда для начала каждой работы: tmux attach || tmux new -s ctf. Сначала пытается подключиться к существующей сессии, и только если сессий нет — создаёт новую. Так не плодятся дубли, когда забываешь, запускал ли tmux утром.

Автоматизация рабочего процесса CTF скриптами

Создавать раскладку руками при каждом подключении — рутина. Скрипт разворачивает готовую рабочую среду за секунды.

#!/bin/bash
TARGET=${1:-"10.10.10.1"}
SESSION="ctf-$TARGET"
# если сессия уже есть — просто цепляемся к ней
tmux has-session -t $SESSION 2>/dev/null && tmux a -t $SESSION && exit
tmux new-session -d -s $SESSION -n recon
tmux send-keys -t $SESSION:recon "echo Target: $TARGET" Enter
tmux split-window -h -t $SESSION:recon
tmux new-window -t $SESSION -n exploit
tmux split-window -v -t $SESSION:exploit
# listener сразу в боевой готовности
tmux send-keys -t $SESSION:exploit.1 "rlwrap nc -lvnp 4444" Enter
tmux select-window -t $SESSION:recon
tmux attach -t $SESSION

Использование: chmod +x ctf-start.sh && ./ctf-start.sh 10.10.10.45. За секунду создаются два окна: «recon» с двумя панелями для сканирования и «exploit» с панелью для эксплойта и уже запущенным listener на порту 4444.

tmux has-session проверяет, существует ли сессия с таким именем. Если да — скрипт просто подключается к ней, не создавая дубликат. Имя сессии включает IP цели (ctf-10.10.10.45), поэтому для каждой машины — отдельная среда. Через tmux ls видно, с какими целями работаешь параллельно.

Для разных платформ можно создать варианты: скрипт для HackTheBox — с проверкой VPN через ip a | grep tun0 перед запуском, скрипт для TryHackMe — с автозапуском openvpn. Принцип один: скрипт разворачивает tmux-сессию с нужной раскладкой под конкретный тип задач.

Дополнительные окна легко добавляются. Окно «privesc» для повышения привилегий: tmux new-window -t $SESSION -n privesc. Или окно «notes» с запущенным vim: tmux new-window -t $SESSION -n notestmux send-keys -t $SESSION:notes "vim /tmp/ctf/notes.md" Enter.

Screen linux терминал: запасной вариант для CTF

GNU Screen появился в 1987 году и предустановлен почти на любом Linux-сервере. Для CTF screen актуален в одном конкретном сценарии: ты получил шелл на целевой машине, хочешь организовать работу прямо на ней, а tmux не установлен. Screen с высокой вероятностью окажется на месте.

Базовые команды screen с префиксом Ctrl+a (в отличие от Ctrl+b у tmux):

  • Создать сессию: screen -S ctf
  • Отсоединиться: Ctrl+a d
  • Список сессий: screen -ls
  • Подключиться: screen -r ctf
  • Принудительное подключение: screen -DR ctf
  • Новое окно: Ctrl+a c
  • Следующее / предыдущее окно: Ctrl+a n / Ctrl+a p
  • Список окон: Ctrl+a "
  • Разделение горизонтально: Ctrl+a S
  • Разделение вертикально: Ctrl+a |
  • Переключение между регионами: Ctrl+a Tab
  • Прокрутка (copy mode): Ctrl+a
  • Завершить сессию извне: screen -X -S ctf quit

На практике screen раздражает одной вещью: после разделения окна новый регион пустой. Нужно переключиться туда (Ctrl+a Tab) и создать в нём шелл (Ctrl+a c). В tmux новая панель сразу получает рабочий терминал. При быстрой работе на CTF эта дополнительная операция ощутимо тормозит.

Минимальный конфиг ~/.screenrc для нормальной работы: defscrollback 10000 (буфер прокрутки), startup_message off (убрать приветствие), term screen-256color (корректные цвета). Трёх строк хватит за глаза.

Рабочий подход: на атакующей VPS — tmux с полноценным конфигом. На целевой машине после получения шелла — screen, если доступен. Не тратить время на выбор — использовать то, что есть под рукой.

Приёмы продуктивности в терминале для CTF-игроков

Несколько техник, которые ускоряют работу в tmux и редко попадают в стандартные шпаргалки.

Именование окон под фазы атаки. Ctrl+b , → ввести «recon», «privesc», «loot». При пяти открытых окнах Ctrl+b w покажет список с понятными именами вместо пяти одинаковых «bash». За четырёхчасовой CTF набегают минуты — каждое переключение на секунды быстрее.

Поиск по буферу прокрутки. Ctrl+b [/ → строка поиска → Enter. Нашёл упоминание порта 8443 в 500 строках вывода nmap за секунду. n — к следующему совпадению, N — к предыдущему. Без поиска пришлось бы листать стрелками — удовольствие сомнительное.

Сохранение вывода панели в файл. Ctrl+b : → ввести capture-pane -S - → затем Ctrl+b :save-buffer /tmp/scan.txt. Содержимое панели — в текстовый файл. Незаменимо для writeups и отчётов.

Отправка команды в панель извне. tmux send-keys -t ctf:exploit.1 "id" Enter отправляет id в конкретную панель без переключения в неё. Можно встроить в скрипты автоматизации: один скрипт рассылает нужные команды по панелям.

Zoom для вывода. Уже упомянутый Ctrl+b z, но стоит подчеркнуть: он сохраняет позицию прокрутки. Развернул панель, прокрутил вверх, нашёл нужное, свернул — позиция осталась. Панель не сбрасывается.

Безопасность: история команд. Все команды в tmux-сессии попадают в [Shell History (T1552.003, Credential Access). На shared VPS пароли и API-токены, набранные напрямую в терминале, сохраняются в ~/.bash_history. Для учебных CTF это некритично, но привычку стоит формировать сразу: переменные окружения (export TOKEN=...) или файлы вместо открытого ввода. На реальных проектах это уже вопрос безопасности клиента.


Tmux для CTF — навык, который окупается с первого применения. Порог входа — один вечер, отдача — постоянная. На каждом CTF, на каждом VPS, при каждом подключении по SSH. Именно такие навыки linux для CTF отделяют «знаю, что такое терминал» от «продуктивно работаю в терминале».

Если ты тратишь на CTF больше часа в неделю и до сих пор работаешь без мультиплексора — ты регулярно теряешь время на вещах, которые решаются одной командой. Потеря reverse shell при обрыве SSH — это повторный запуск эксплойта, иногда повторный скан, иногда полная перезагрузка машины на платформе. Пятнадцать-двадцать минут в пустоту. Умножаем на количество сессий в месяц — получаем часы, выброшенные на пересоздание того, что должно было сохраниться само.

Tmux — не «продвинутый инструмент для опытных». Это базовая гигиена, вроде именования файлов или ведения заметок. Выучить его — вопрос одного вечера. А вот построить системное понимание инфобеза — задача масштабнее, и тут одних статей мало. На IB Basics на codeby.school как раз дают структуру: от терминала и сетей до первых задач, без академического тона и без входных требований.

🚀 Хочешь закрепить на практике? Реши задачи по теме на HackerLab — категория «pentest-machines».

Поделиться

0 комментариев

Пожалуйста, войдите, чтобы оставить комментарий.

Загрузка комментариев...