原付免許をとった

 アルバイトでも始めようかと思ったのがきっかけだった。

バイトをはじめるにあたって良い機会だから、銀行口座を開設しようと思ってゆうちょ銀行の口座を作ろうとしたら、本人確認書類というものが必要らしく困った。

免許もパスポートも持ってないし、保険証もどこにあるのか把握していないとあってどうしたものかと思いGoogle先生を頼ったのだけれど、免許やパスポート、印鑑登録証明書などを新たに取得しようとすると、そのために身分証明書が必要だという。

住基カードは簡単に作れそうだと思ったら、マイナンバー制度による個人番号カードの交付開始に伴い、交付を終了するとのこと。

どうしたものかと思い、ゆうちょ銀行の本人確認書類一覧のページをながめていたら、母子健康手帳(母および子に限る)とあって、おそらくこれであれば家を探せばどこかにあるだろう踏んで家をあさってみたところ見つかったのでその日のうちに近所の郵便局へ行って無事口座開設できた。

ゆうちょ銀行に口座開設する際に必要だったものは次の3点。

これで当初の目的は果たせたのだけれど、身分証明書がなければ何かと不便であると分かったので、この際作ってしまおうと思い比較的容易に取得できそうな原付の免許でもとろうかと考え調べてみると、どうやら住民票の写しと学生証が必要なようだった。

学生証に関しては問題ないとして、住民票の写しはどうやって入手すればいいのか調べたところ、私の住んでる自治体の場合は学生証と預金通帳の2点があれば市役所等で取得可能だとのこと。

住民票の写しを手に入れる際に必要だったものは次の3点。

  • 学生証

  • 預金通帳

  • 手数料(300円)

住民票の写しを手に入れて、後日運転免許試験場に赴き原付免許の試験を受けてだるい講習を経て免許を取得した。

原付の免許を取得するのに必要だったものは次の通り。

  • 住民票の写し
  • 学生証
  • 手数料(合計7,750円)
  • 写真(縦3cm×横2.4cm)
  • 両眼で0.5以上の視力
  • 16歳以上の年齢
  • 学科試験を合格できるだけの知識

学科試験対策はスマホのアプリを主に利用した。下記のアプリがクオリティ高くてよかった。

無料1210問!原付免許問題集! - Google Play の Android アプリ

余談だけど視力検査で2回再検査になって辛かった。なんとか1.0までには回復させたい。

SECCON 2015 オンライン予選 write-up

はじめに

 SECCON 2015 オンライン予選にぼっちチームhoge444として出てた。

競技開催期間は2015年12月05日(土) 15:00:00(JST)から24時間。

実質2問しか解けなかった。

Title Genre Points
Start SECCON CTF Exercises 50
SECCON WARS 2015 Stegano 100
Connect the server Web/Network 100
Last Challenge (Thank you for playing) Exercises 50

Start SECCON CTF

問題文

ex1
Cipher:PXFR}QIVTMSZCNDKUWAGJB{LHYEO
Plain: ABCDEFGHIJKLMNOPQRSTUVWXYZ{}

ex2
Cipher:EV}ZZD{DWZRA}FFDNFGQO
Plain: {HELLOWORLDSECCONCTF}

quiz
Cipher:A}FFDNEVPFSGV}KZPN}GO
Plain: ?????????????????????

解法

置換表がex1で与えられているのでPythonのstring.maketransを使って変換テーブルを作る。

#!/usr/bin/env python2
# -*- conding: utf-8 -*-

import string

cihper = 'A}FFDNEVPFSGV}KZPN}GO'
table = string.maketrans('PXFR}QIVTMSZCNDKUWAGJB{LHYEO', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ{}')

print cihper.translate(table)

trコマンドでも解ける。

$ echo "A}FFDNEVPFSGV}KZPN}GO" | tr PXFR}QIVTMSZCNDKUWAGJB{LHYEO ABCDEFGHIJKLMNOPQRSTUVWXYZ{}
SECCON{HACKTHEPLANET}

FLAG:

SECCON{HACKTHEPLANET}

Connect the server

問題文

login.pwn.seccon.jp:10000

解法

 まずncコマンドで接続を試みる。

f:id:kira000:20151206054213p:plain

WireSharkで通信を監視して適当にFollow TCP StreamするとFLAGっぽいものが見える。

f:id:kira000:20151206054234p:plain

FLAG:

SECCON{Sometimes_what_you_see_is_NOT_what_you_get}

SECCON WARS 2015

問題文

https://youtu.be/8SFsln4VyEk

解法

[追記]

 よくよく考えたらgifをそのままPythonで処理すればよかった。

  • Youtubeからmp4の動画をダウンロードしFree Video to GIF Converterで動画の00:25から01:05を切り取ってhoge.gifに変換(このときフレームレートは2 fpsで幅は600pxぐらいにするとよい)

あとは以下のようなスクリプトQRコードを作成すればいい。

#!/usr/bin/env python
#-*- coding: utf-8 -*-

from PIL import Image

gif = Image.open('hoge.gif')

width, height = gif.size
png = Image.new('RGB', gif.size, 'black')

while True:
    gif.load()
    for pos in ((x, y) for x in range(width) for y in range(height)):
        if gif.getpixel(pos) < 0x80:
            png.putpixel(pos, (0xff, 0xff, 0xff))

    try:
        gif.seek(gif.tell() + 1)
    except:
        break

png.save('flag.png', 'PNG')
  • gifのフレームレートを10 fpsにしたとき生成される画像

f:id:kira000:20151223012840p:plain

[ここまで追記]

 ひどい解き方をした。手順は次の通り。

  • youtubeから、問題の動画をダウンロード

  • Free Video to GIF Converterで動画の00:25から01:05を切り取ってhoge.gifに変換(フレームレートは1fpsにした)

  • convertコマンドで分離

$ convert +adjoin hoge.gif fuga.gif
  • Gimpで一枚一枚白黒の画像に加工(全部で42枚)。(画像>モード>グレースケールを選択し、色>しきい値からしきい値を127に設定)

f:id:kira000:20151206054353p:plain

(最初まっ黒な画像を作って読み込んだgifに白いところがあったら白を描画してる)

wars_solver.py · GitHub

※このコードは汚いだけでなくて実行時間もかなりかかるので色々とひどい。

f:id:kira000:20151206054433p:plain

  • 最後にQRコードを読み取るとFLAGが分かる。

FLAG:

SECCON{TH3F0RC3AVVAK3N53P7}

Last Challenge (Thank you for playing)

問題文

ex1
Cipher:PXFR}QIVTMSZCNDKUWAGJB{LHYEO
Plain: ABCDEFGHIJKLMNOPQRSTUVWXYZ{}

ex2
Cipher:EV}ZZD{DWZRA}FFDNFGQO
Plain: {HELLOWORLDSECCONCTF}

quiz
Cipher:A}FFDNEA}}HDJN}LGH}PWO
Plain: ??????????????????????

解法

 最初の問題と同じ。

$ echo "A}FFDNEA}}HDJN}LGH}PWO" | tr PXFR}QIVTMSZCNDKUWAGJB{LHYEO ABCDEFGHIJKLMNOPQRSTUVWXYZ{}
SECCON{SEEYOUNEXTYEAR}

FLAG:

SECCON{SEEYOUNEXTYEAR}

おわりに

 問題は全然解けなかったけど、時間はたくさん溶けた。とても辛かった。

x86アセンブリ言語に関するメモ

x86系マイクロプロセッサの持つ主なレジスタ

レジスタ 呼び名 主な機能
EAX アキュムレータ 算術演算の結果を格納
EBX ベースレジスタ メモリアドレスを格納
ECX カウントレジスタ ループ回数をカウント
EDX データレジスタ データを格納
ESI ソースインデックス データ転送元のメモリアドレスを格納
EDI ディスティネーションインデックス データ転送先のメモリアドレスを格納
EBP ベースポインタ データの格納領域のメモリアドレスを格納
ESP スタックポインタ スタック領域のメモリアドレスを格納

主な命令

命令 使用例 意味    詳細
MOV MOV EAX,ECX EAX = ECX ECXの値をEAXに格納
MOVZX MOVZX_EAX,ECX EAX = ECX MOVのサイズが違うレジスタにコピーするとき用いる版
ADD ADD EAX,ECX EAX += ECX EAXにECXを加算
SUB SUB EAX,ECX EAX -= ECX EAXからECXを減算
MUL MUL EAX,ECX EAX *= ECX EAXにECXを乗算
DIV DIV EAX,ECX EAX =EAX / ECX EAXをECXで割って,商をEAXに,余りをEDXに格納
EDX = EAX % ECX
INC INC EAX EAX++ EAXに1を加算
DEC DEC EAX EAX-- EAXに1を減算
XOR XOR EAX,ECX EAX = EAX ^ ECX EAXとECXの各ビットごとに排他的論理和を取り,結果をEAXに格納
LEA LEA EAX,[ECX+4] EAX = ECX + 4 ECX+4(アドレス値)をEAXに格納
CMP CMP EAX,ECX if(EAX==ECX)_ZF=1 EAXとECXの値を比較してフラグに反映
else ZF = 0 EAXとECXが等しければZF=1,EAXとECXが等しくなければ、ZF=0
TEST TEST EAX,EAX if(EAX==0) ZF = 1 EAXの値を0と比較してフラグに反映
else ZF = 0 EAXが0と等しければZF=1,EAXが0でなければZF=0
JE(JZ) JE 041001000 if(ZF == 1) ZFが1なら041001000にジャンプ
GOTO 041001000
JNE(JNZ) JNE 041001000 if(ZF == 0) ZFが0なら041001000にジャンプ
GOTO 041001000
JMP JMP 041001000 GOTO 041001000 無条件で041001000にジャンプ
CALL CALL lstrcmpW lstrcmpW() lstrcmpw関数の呼び出し
PUSH PUSH 00000001 スタックへ00000001を格納
POP POP EAX スタックからEAXへ値を取得
NOP NOP 何もしない
SAR SAR EAX EAXを右にシフトする,すなわち2で割る
RET RET 処理を呼び出し元に戻す

豆知識

  • XOR EAX,EAX は MOV EAX,0 と同様の働きをする。

  • dword ptr は、指定されたメモリアドレスから4バイトのデータを読み出すことを示す。

例えば、

MOV DWORD PTR SS:[EBP-8],1

の場合ベースポインタのアドレス-8から4バイトまでのデータに整数値1を格納している。

Pythonで16進文字列をintに変換

16進文字列からint

  • 基数を指定してintにパースすればいい。
>>> s = 'abcdef'
>>> print int(s, 16)
11259375
  • ちなみにインタラクティブシェルなら0xからはじめた16進文字列を入力すれば10進数にしたものを返してくれる。
>>> 0xdeadbeef
3735928559

intから16進文字列

  • hex()を使う
>>> a = 111223
>>> print hex(a)
0x1b277
  • 先頭に0xがつくのがいやならformatメソッドを使うとよい
>>> a = 111223
>>> print format(a, 'x')
1b277
  • こうなふうに先頭2文字を削除するという手もある
>>> a = 111223
>>> print hex(a)[2:]
1b277
  • フォーマット指定子(%記法)を使ってもいい
>>> a = 111223
>>> print '%x' % a
1b277