1001001

73。CTFのWrite-upや技術的な備忘録を書きとめたいです。

【Mac/Python】homebrewでインストールしたPythonライブラリがpyenv環境で使えない時の対処法

chipwispererというツールをこのページを参考にインストールしようとしていて,homebrewでscipyを入れる手順があった.scipyのインストールには成功したが,Pythonでモジュールが見つからない.pyenv環境から上手いこと参照されてないのでは?と思ったらそうだったという内容です.

続きを読む

【Cordova】Androidのリリースビルドで通信エラー

Apache Cordovaを使ったハイブリッドアプリ開発にて,Androidのapkのリリースビルドをしたところ,開発用では動いていたアプリが通信エラーを吐くようになった.その原因と対策についてメモ.

  • 環境
  • 症状
  • 調査
  • 原因
  • 対処
    • 推奨する対処
    • 一時的な対処
  • まとめ
  • 参考
続きを読む

Pythonのクラスにおけるインスタンス変数とクラス変数の挙動の覚書

Python(3.6.3)でクラスを書いていた時に「え,これ動くんだ」と感じた挙動についてメモ.

  • self.クラス変数,<instance>.クラス変数 でクラス変数にアクセスできる (特別な理由がなければ非推奨)
  • クラス変数とインスタンス変数を同名にすることが許される
  • 上二つが混ざるとややこしいことになる
  • まとめ
  • りふぁれんす
続きを読む

HITCON CTF 2017 Secret Server Revenge 解いてみた

HITCON CTF 2017で出題された Secret Server Revenge を海外のWriteupを参考に解いてみたので、自分なりの言葉でまとめてみます。

本番中はSecret Serverに着手し、フラグ半分まで得ましたが、方針が間違っており時間内に全て特定できず。。。後日、時間内に解いたチームメイトにチーム内の勉強会で方針を聞いて解くことができたので、その拡張の問題であるSecret Server Revengeを解いてみました。

続きを読む

CSAW CTF 2017 Write-up

CSAW CTF 2017にチームm1z0r3で出ていました.

Misc 100とCrypto 350を解いたのでそのWrite-upになります.

CVV ( Misc 100 pts)

CVVとはCard Verification Valueの略で,クレジットカード番号のこと.

netcatでサーバに接続すると,"I need a new Visa!" , "I need a new American Express!" のようにクレジットカード会社の番号を求められる.なお,newと付いているのは一度の接続で同じ数字を使いまわしてはいけないということを表している.

つまりこの問題は,指定された会社のクレジットカード番号として正しい番号を送り続ける問題である.では,クレジットカードの番号として正しい値がどのような値かというと,以下の二つを満たす値である.

  1. クレジットカード会社ごとのプレフィックスを満たす
  2. Luhnアルゴリズムを満たす

1.クレジットカード会社ごとのプレフィックスというのは決まっていて,Wikipediaにも記載されている.詳細はこちらを参照してほしい.

2.Luhnアルゴリズムというのはクレジットカード番号を決定する際に用いられるアルゴリズムである.1954年にハンス・ペーター・ルーンという当時IBMの研究者だった方が考案したアルゴリズムで,当初は特許化されていたが現在ではISOにより世界標準となっている(ISO/IEC 7812).

このアルゴリズムの説明は割愛するが,こちらもWikipediaに詳細が記載されているので参考にしてほしい.なんとPythonのコードまで記載されていたので拝借した.

スクリプトを書いて何度か試行していると,求められる条件が以下のように変動することがわかる.

  • "I need a new ...": 特定のクレジットカード会社の正当な番号を答える
  • "I need a new card that starts with ...": ある数列で始まる正当な番号を答える
  • "I need a new card that ends with ...": ある数列で終わる正当な番号を答える
  • "I need to know if ... is valid! (0 = No, 1 = Yes)": 与えられた番号が正当かどうか答える(16桁?)

これらによって条件分岐するようなスクリプトを書いた.

The flag is "flag{ch3ck-exp3rian-dat3-b3for3-us3}"

 

baby_crypt ( Crypto 350 )

crypto.chal.csaw.io:1578 にnetcatにアクセスする.usernameを入力するとクッキーを発行してくれるというだけのサーバが動いている.

問題文に

The cookie is input + flag AES ECB encrypted with the sha256 of the flag as the key.

とあったみたいなのだが,私は完全に見落としていて入力検証から始めた.(途中で追記されたものと信じたい)

ひたすら入力検証をしていると以下のことが分かった.

  1. クッキーの長さは入力の長さに依存
  2. 長さは16文字おきに変化し,その差は32文字
  3. "a"*16個と,"a"*32個の時のクッキーを比較すると前のブロックに依存していないことが分かる
  4. 同じ長さの複数の入力を比較したとき,後ろ32文字が同じ

1.から,クッキーは入力を共通鍵暗号などで暗号化されて作られているのではないかということはわかる(自明という説もある).2.から,1ブロック16文字のブロック暗号ではないかと推測できる.3.によりモードはECBであることが分かる.4.により,パディング以外に後ろに何かくっついていることが分かる.

もう少し詳しく説明すると,3.は以下のような検証をした.

Enter your username (no whitespace): aaaaaaaaaaaaaaaa # "a"*16
Your Cookie is: 469ac6eba774ac471777f35c88d9dd6a / f9cc1330ae5830732a18d1a23211ffbce3725519adb9e6f10d658d87c80825ed
Enter your username (no whitespace): aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa # "a"*32
Your Cookie is: 469ac6eba774ac471777f35c88d9dd6a / 469ac6eba774ac471777f35c88d9dd6a / f9cc1330ae5830732a18d1a23211ffbce3725519adb9e6f10d658d87c80825ed

もしもCBCモードのようにIVが使われていたり前の暗号化結果が依存するならこのような結果にはならない."a"16個のクッキーの1ブロック目と"a"32個のクッキーの2ブロック目はまず同じにならない(きちんと検証するなら"b"16個+"a"16個などが分かりやすい).

そして,もしもブロック暗号だとすると,基本的にはパディングが施されるので,ブロックごとに分けられた入力の最後はブロック長にパディングされる.しかし,上の結果を見てみると,入力とは関係ない末尾の部分がパディングだけにしては長すぎる.従ってこの問題は,入力の末尾にflagをくっつけた後にパディングをしてAES ECBモードで暗号化してるのではないかという推測をした.

もしそうであれば,flagが"flag{...}"であるとき,以下の二つの入力のクッキーの1ブロック目は同じになるはずである.

  • "aaaaaaaaaaaaaaaf" ("a"*15個+"f") -> "aaaaaaaaaaaaaaaf / flag{.....}padpadpad...."
  • "aaaaaaaaaaaaaaa"   ("a"*15個)        -> "aaaaaaaaaaaaaaaf / lag{.....}padpad...."

よって,仮に上のfの部分が未知でも,アルファベットを総当たりすることで1文字特定可能である.あとは以下のようにずらしていけば1文字ずつ特定することが可能である.

  • "aaaaaaaaaaaaaaf?" ("a"*14個+"f"+"?") -> "aaaaaaaaaaaaaaf? / flag{......}padpad..."
  • "aaaaaaaaaaaaaa"    ("a"*14個)                 -> "aaaaaaaaaaaaaafl / ag{......}padpad..."

?の部分を総当たりすればlで当たるはずである.

実際に推測できる"flag{"の部分を試すと同じになるので,この方針でスクリプトを書いた.なお,フラグが1ブロック長より長い可能性があるのでスクリプトでは"a"*32から始めた.

The flag is "flag{Crypt0_is_s0_h@rd_t0_d0...}"

まとめ

時間中に解いた二つの問題(CVV, baby_crypt)のWrite-upでした.Almost Xorが解けなかったので精進が必要です.

hashcatをCPU OnlyのUbuntu16.06環境にインストール

オープンソースの高速パスワードリカバリーツールであるhashcatをCPU OnlyのUbuntu16.04環境にインストールする手順になります.

環境

hashcatはGPUを利用することでより高速に処理が可能ですが,私のサーバにはCPUしか積んでいないのでCPU環境で使えるようにしました.CPU(やIntel GPU)でhashcatを使う場合には,OpenCLという並列コンピューティングのためのクロスプラットフォームをインストールする必要もあります.下記のインストール手順で順に説明します。

インストール手順

  1. hashcatのインストール (バイナリ or ビルド)
  2. OpenCLのインストール

1. hashcatのインストール(バイナリ or ビルド)

hashcatのインストール方法は2パターンあります.すでにコンパイル済みのバイナリファイルをインストールするか,ソースからビルドするかの2択です.せっかくですのでどちらの方法についても記載します.

方法1: バイナリファイルをダウンロードする

Ubuntuで扱う場合はこれが一番簡単だと思います.こちらのサイトの上部にある最新版のバイナリをインストールします.(古いバージョンは最下部にあります)

ファイルは7zで圧縮されています.7zコマンドがあれば下記のようにして解凍できます.7zコマンドが使えない場合はお手数ですが7zのインストール方法を調べて入れてください.

$ wget https://hashcat.net/files/hashcat-3.6.0.7z
$ 7z x hashcat-3.6.0.7z
$ file hashcat-3.5.0/hashcat64.bin
hashcat-3.5.0/hashcat64.bin: ELF 64-bit LSB executable,
...省略...

解凍したフォルダ内のhashcat64.binを使うことができます.

方法2: ソースからビルドする

ソースからビルドする場合は,こちらのGithubのBuild.mdを参考にしました.以下のようにすればインストールできます.

$ git clone https://github.com/hashcat/hashcat.git
$ cd hashcat
$ git submodule update --init
$ make
$ sudo make install
$ hashcat --version

最後のコマンドでhashcatのバージョンが表示されていれば成功です.

さて,hashcatをインストールできたところで早速ベンチマークを試してみたいところですが,このままでは実行できません.OpenCLをインストールしていないためです.試しに以下のコマンドでOpenCL infoを表示してみると,そもそも以下のようなメッセージが表示され,環境ができていないことが確認できます.

$ hashcat -I
...
ATTENTION! Can't find OpenCL ICD loader library
...

細かい出力は忘れてしまいましたが,こんな感じのメッセージが表示されます.(ベンチマークを実行するオプションであるhashcat -bなどでも同様のメッセージが表示され,失敗に終わると思います)

2. OpenCLのインストール

こちらのサイトOpenCL™ Runtime for Intel® Core™ and Intel® Xeon® ProcessorsにあるOpenCL™ Runtime 16.1.1 for Intel® Core™ and Intel® Xeon® Processors for Ubuntu* (64-bit)をダウンロードします.

こちらはtgz圧縮してるので,以下のように解凍します.

$ wget http://registrationcenter-download.intel.com/akdlm/irc_nas/9019/opencl_runtime_16.1.1_x64_ubuntu_6.4.0.25.tgz
$ tar zxvf opencl_runtime_16.1.1_x64_ubuntu_6.4.0.25.tgz
$ cd opencl_runtime_16.1.1_x64_ubuntu_6.4.0.25
$ sudo ./install.sh

解凍したフォルダ内にあるinstall.shを実行します.実行後は対話的にインストールを進めていきます.基本的にはdefaultrecommendを選択していけば良いです.

これでOpenCLのインストールが完了し,hashcatが使えるようになったはずです.以下のコマンドを叩いてみます.

$ hashcat -I
hashcat (v3.6.0-117-g99f58f9) starting...

OpenCL Info:

Platform ID #1
  Vendor  : Intel(R) Corporation
  Name    : Intel(R) OpenCL
  Version : OpenCL 1.2 LINUX

  Device ID #1
    Type           : CPU
    Vendor ID      : 8
    Vendor         : Intel(R) Corporation
    Name           : Intel(R) Xeon(R) CPU           E5520  @ 2.27GHz
    Version        : OpenCL 1.2 (Build 25)
    Processor(s)   : 1
    Clock          : 2270
    Memory         : 1491/5967 MB allocatable
    OpenCL Version : OpenCL C 1.2
    Driver Version : 1.2.0.25

このような出力になっていればインストール成功です.

参考

本件には関係ないですが,NVIDIA GPU環境でインストール可能なバージョン以外のNVIDIAドライバを入れてしまいUbuntuにログインできなくなった時の対処は以下