原付免許をとった
アルバイトでも始めようかと思ったのがきっかけだった。
バイトをはじめるにあたって良い機会だから、銀行口座を開設しようと思ってゆうちょ銀行の口座を作ろうとしたら、本人確認書類というものが必要らしく困った。
免許もパスポートも持ってないし、保険証もどこにあるのか把握していないとあってどうしたものかと思いGoogle先生を頼ったのだけれど、免許やパスポート、印鑑登録証明書などを新たに取得しようとすると、そのために身分証明書が必要だという。
住基カードは簡単に作れそうだと思ったら、マイナンバー制度による個人番号カードの交付開始に伴い、交付を終了するとのこと。
どうしたものかと思い、ゆうちょ銀行の本人確認書類一覧のページをながめていたら、母子健康手帳(母および子に限る)とあって、おそらくこれであれば家を探せばどこかにあるだろう踏んで家をあさってみたところ見つかったのでその日のうちに近所の郵便局へ行って無事口座開設できた。
ゆうちょ銀行に口座開設する際に必要だったものは次の3点。
印鑑
現金(1円以上)
これで当初の目的は果たせたのだけれど、身分証明書がなければ何かと不便であると分かったので、この際作ってしまおうと思い比較的容易に取得できそうな原付の免許でもとろうかと考え調べてみると、どうやら住民票の写しと学生証が必要なようだった。
学生証に関しては問題ないとして、住民票の写しはどうやって入手すればいいのか調べたところ、私の住んでる自治体の場合は学生証と預金通帳の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コマンドで接続を試みる。
WireSharkで通信を監視して適当にFollow TCP StreamするとFLAGっぽいものが見える。
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ぐらいにするとよい)
#!/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')
[ここまで追記]
ひどい解き方をした。手順は次の通り。
youtubeから、問題の動画をダウンロード
Free Video to GIF Converterで動画の00:25から01:05を切り取ってhoge.gifに変換(フレームレートは1fpsにした)
convertコマンドで分離
$ convert +adjoin hoge.gif fuga.gif
(最初まっ黒な画像を作って読み込んだgifに白いところがあったら白を描画してる)
※このコードは汚いだけでなくて実行時間もかなりかかるので色々とひどい。
- flag.png
- 最後に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