Решения
http://ppp.cylab.cmu.edu/wordpress/?p=1140 (Plaid Parliament of Pwning) | Назад к списку заданий |
Задание (crypto)
Question 7 - Gitzino
Points: 400
Like all good bitcoin casinos, the gitscoin casino gitzino uses unbreakable Provably Fair technology. File running at gitzino.2014.ghostintheshellcode.com
Подробное описание
Перевод решения команды Plaid Parliament of Pwning.
Заголовок сообщает, что, как и bitcoin-казино, gitscoin-казино под названием Gitzino предоставляет нам не ломаемую доказуемо честную технологию. Для анализа нам доступен исполняемый файл сервера. При подключении к сервису нас встречает меню.
Итак, gitsZino – это аналог видео-покера на игровых автоматах. Его правила такие же, как и в любом другом видео-покере. Игрок делает ставку, после чего ему раздают пять карт в открытую. Он оставляет те карты, которые захочет, а остальные меняет. После обмена у игрока образуется обычная пятикарточная комбинация. Все комбинации видео-покера полностью соответствуют комбинациям классического покера (флэш, каре, стрит и так далее). Из баннера мы узнаем, что для старта у нас есть 1000 gitsCoins (проверка баланса – 2-й пункт меню). Наша задача выиграть миллион. Описание чудо-технологии, используемой в gitsZino при сдаче карт, получим, если отправить пункт меню 1.
Судя по описанию, Gitzino похожа на проблему предсказывания внутреннего состояния генератора псевдослучайных чисел. Зная, как будет вести себя генератор, мы сможем угадывать, какие карты выпадут и делать соответствующие ставки, чтобы выиграть игру. Но нашелся более простой способ. Даже не способ, а ошибка, связанная со слабым контролем входных значений. Изучая код сервера, выясняется, что ставка может быть отрицательной. Есть только единственная проверка на превышение текущего баланса: .text:08048D7E call _strtol # eax = значение ставки (bet) .text:08048D83 mov ebx, [esp+98h] #текущий баланс gitsCoins .text:08048D8A cmp eax, ebx .text:08048D8C mov [esp+0A8h], eax #сохраняем значение ставки .text:08048D93 jle short bet_ok .text:08048D95 mov eax, [esp+7C0h] .text:08048D9C mov dword ptr [esp+4], offset aBetTooBig_ ; "Bet too big.\n" .text:08048DA4 mov [esp], eax .text:08048DA7 call sendMsg И в случае если карты не дали никакую комбинацию, то при отрицательном значении ставки – мы выиграем. .text:080498AC mov eax, [esp+7C0h] .text:080498B3 mov dword ptr [esp+4], offset aNothing___ ; "Nothing...\n" .text:080498BB mov [esp], eax .text:080498BE call sendMsg .text:080498C3 mov eax, [esp+0A8h] # eax = значение ставки .text:080498CA sub [esp+98h], eax # баланс = баланс – ставка Да, конечно, есть вариант, что выпадет флэш, "тройка", "валеты или выше" и т.п., то при отрицательном значении ставки – мы проиграем. Такая ситуация возможна, но как показывает жизнь - редко. Последовательность действий такая: каждый раз задаем максимальную отрицательную ставку (-99999) до тех пор, пока не наберем миллион (а значит, и получим флаг). Кстати, колода карт задается алфавитом (0-9a-zA-P), всего 52 карты. Пример (наш ввод выделен жирным):
Флаг: |