0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[AlpacaHack] typhoon-pythoon writeup

0
Posted at

ひとこと

べんりなつーるがよのなかにはあるものですな すばらしい

問題

情報

ジャンル: Rev
難易度: Medium 4.5
問題リンク: https://alpacahack.com/daily/challenges/typhoon-pythoon

問題文

台風がプログラムを遠くへ飛ばしてしまいました。 どうやらフラグは台風の目の中にあるようです。

このファイルは Python 3.10 でコンパイルされています。import や実行には Python 3.10 を使用してください。

初心者向けヒント
  • .pycファイルにはコンパイル済みのPythonバイトコードが含まれます
  • モジュールとしてimportし、 dirやdis.dis()で調べてみましょう。

唐突ですが初心者向けヒントを無視します

実は世の中にはpycdcというコンパイル済みPythonはデコンパイルしてくれる素晴らしいソフトがあります。これを用いてデコードすることにすると

# Source Generated with Decompyle++
# File: server.pyc (Python 3.10)

from pathlib import Path
EYE_DATA = bytes([
    207,
    197,
    236,
    194,
    221,
    208,
    195,
    183,
    175,
    190,
    183,
    178,
    145,
    162,
    132,
    159,
    119,
    90,
    105,
    94,
    127,
    126,
    83,
    73,
    105,
    37,
    44,
    46,
    57,
    45,
    25,
    11,
    6,
    26,
    255,
    237,
    247])

def is_inside_the_typhoon_eye():
    '''Check whether the observation server is in the only calm place.'''
    current_place = Path(__file__).resolve().parent.name
    required_place = bytes([
        101,
        121,
        101]).decode()
    return current_place == required_place


def reverse_the_wind(observations = None):
    '''Return observations to their state before the wind moved them.'''
    location = Path(__file__).resolve().parent.name.encode()
    restored = []
    for position, value in enumerate(observations):
        place = location[position % len(location)]
        wind = position * 7 + 41 + place & 255
        restored.append(chr(value ^ wind))
    return ''.join(restored)


def main():
    if not is_inside_the_typhoon_eye():
        print('Hint: Move this file into the eye of the typhoon.')
        return None
    answer = None('What was inside the eye? > ')
    if answer == reverse_the_wind(EYE_DATA):
        print('The typhoon is gone. Correct!')
        return None
    None('The wind is still too strong...')

if __name__ == '__main__':
    main()
    return None

こういうコードが出てきます。printfがNoneになってたりと色々おかしいですが結構いろいろ見れます。

第一段階

if not is_inside_the_typhoon_eye():
    print('Hint: Move this file into the eye of the typhoon.')
    return None
def is_inside_the_typhoon_eye():
    '''Check whether the observation server is in the only calm place.'''
    current_place = Path(__file__).resolve().parent.name
    required_place = bytes([
        101,
        121,
        101]).decode()
    return current_place == required_place

とのことです。どうやら実行ファイルの親ディレクトリが

bytes([
    101,
    121,
    101]).decode()

にいればいい、と...。これは解読するとeyeになるのでこのディレクトリに入れてあげます。

第二段階

if answer == reverse_the_wind(EYE_DATA):
    print('The typhoon is gone. Correct!')
    return None
def reverse_the_wind(observations = None):
    '''Return observations to their state before the wind moved them.'''
    location = Path(__file__).resolve().parent.name.encode()
    restored = []
    for position, value in enumerate(observations):
        place = location[position % len(location)]
        wind = position * 7 + 41 + place & 255
        restored.append(chr(value ^ wind))
    return ''.join(restored)

locationは第一段階で判明した通りb'eye'であり、復号化された文字の$i$文字目を$A_i$とし、observations=EYE_DATAをB_iとすると

  • $\text{place} = \text{location}_{i\bmod |\text{location}|} = \text{"eye"} _{i\bmod3}$
  • $\text{wind} = 7i+41+(\text{place} \& 255) = 7i+41+(\text{"eye"} _{i\bmod3} \& 255)$

より
$$A_i=B_i\oplus (7i+41+(\text{"eye"} _{i\bmod3} \& 255))$$
よって

>>> EYE_DATA = bytes([ ... ])
>>> for i, value in enumerate(EYE_DATA):
...     place = location[i % len(location)]
...     wind = (i * 7 + 41 + place) & 255
...     restored.append(chr(value ^ wind))

こんな風に入れてあげれば勝手にflagが出てきます

出てきたフラグ

Flag: Alpaca{dis_is_the_eye_of_the_typhoon}

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?