TsukuCTFに0nePaddingで参加してきました。
順位は13位でした。
問題文
NESのアセンブリソース一式とキャラクターのBMPファイルが渡されます。
main.asm
.setcpu "6502"
.autoimport on
PPU_ADDR1 = $0001
PPU_ADDR2 = $0002
PPU_STATUS = $2002
.segment "HEADER"
.byte $4E, $45, $53, $1A
.byte $02
.byte $01
.byte $01
.byte $00
.byte $00, $00, $00, $00
.byte $00, $00, $00, $00
.segment "STARTUP"
.proc Reset
sei
ldx #$ff
txs
clc
cld
lda #$00
sta $2000
sta $2001
sta $2005
sta $2006
lda $4015
and #%11111110
sta $4015
lda PPU_STATUS
lda #$00
sta $2000
sta $2001
lda #$00
ldx #$00
clear_memory:
sta $0000, X
sta $0100, X
sta $0200, X
sta $0300, X
sta $0400, X
sta $0500, X
sta $0600, X
sta $0700, X
inx
cpx #$00
bne clear_memory
lda #$20
sta $2006
lda #$00
sta $2006
lda #$00
ldx #$00
ldy #$04
clear_vram_loop:
sta $2007
inx
bne clear_vram_loop
dey
bne clear_vram_loop
lda #$3F
sta $2006
lda #$00
sta $2006
ldx #$00
ldy #$10
setpal:
lda palettes, x
sta $2007
inx
dey
bne setpal
lda #$20
sta $2006
lda #$00
sta $2006
ldy #0
jsr set_row
jmp mapping1
mapping1:
ldy #11
ldx #$00
lda #$8c
mapping1_y_loop:
jsr set_row
ldx #05
jsr set_col
ldx #$14
mapping1_x_loop:
sta $2007
dex
bne mapping1_x_loop
iny
cpy #16
bne mapping1_y_loop
mapping2:
ldy #13
jsr set_row
ldx #08
jsr set_col
ldx #00
ldy #14
mapping2_x_loop:
lda data, x
sta $2007
inx
dey
bne mapping2_x_loop
screenend:
lda #$00
sta $2005
sta $2005
lda #$08
sta $2000
lda #$1e
sta $2001
loop:
jmp loop
set_row:
pha
tya
lsr a
lsr a
lsr a
clc
adc #$20
sta PPU_ADDR1
tya
asl a
asl a
asl a
asl a
asl a
sta PPU_ADDR2
lda PPU_ADDR1
sta $2006
lda PPU_ADDR2
sta $2006
pla
rts
set_col:
pha
txa
adc PPU_ADDR2
sta PPU_ADDR2
lda PPU_ADDR1
sta $2006
lda PPU_ADDR2
sta $2006
pla
rts
.endproc
palettes:
.byte $01, $18, $39, $30
.byte $0f, $06, $16, $26
.byte $0f, $08, $18, $28
.byte $0f, $0a, $1a, $2a
data:
.byte $22, $a4, $39, $26, $39
.byte $a4, $55, $79, $bb, $4c
.byte $39, $c7, $a4, $d1, $8c
.segment "VECINFO"
.word $0000
.word Reset
.word $0000
.segment "CHARS"
.incbin "character.chr"
character.bmp
二通りの解法があるので記載します。
以下サイト等を参考にNESの命令を調べているとI/Oポート$2006
への書き込み(二回)でアクセス先VRAMアドレスを決定しI/Oポート$2007
で書き込む、という命令になるらしいです。$2006
に2000
が書き込まれていますが、これはネームテーブル0に対応しておりネームテーブルへの書き込みでどのブロック位置にどのキャラクタが埋め込まれるかが決定されるようです。
ので$2007
への書き込みに注目します。すると下記の部分で、事前に定義されたdata[x]
を$2007
に書き込むループ処理があります。
mapping2_x_loop:
lda data, x
sta $2007
inx
dey
bne mapping2_x_loop
data
の定義は以下。
data:
.byte $22, $a4, $39, $26, $39
.byte $a4, $55, $79, $bb, $4c
.byte $39, $c7, $a4, $d1, $8c
data[x]
がcharacter.bmp
に対するキャラクタ画像のインデックスになっているようで
character.bmp
の左上を0とし順に見ていくと文字列が復元できました。
cl65
コマンドで素直にビルドしようとするとcharacter.cfg
がないと怒られます。
渡されたBMPファイルからchrファイルを生成するため、以下のツールを使用しました。
このツールは128x128のBMPしか変換できないようなので、PythonでBMPをサイズ変換します。
from PIL import Image
i = Image.open("./character.bmp")
i = i.crop((0,0,128,128))
i = i.quantize(8)
i.save("resized.bmp")
この状態で変換ツールを実行するとBMPからCHRへの変換が成功します。
CHRが生成できたのでアセンブリをビルドしてみるとビルドに成功したのがわかります。
Webで公開されているエミュレータを使用するとタイトル画面?が表示されフラグが表示されます。
問題文
pcapファイルが渡されます。
問題名から問題文で触れられているパスワードはBASIC認証のことでしょう。
WiresharkでフィルターをかけることでBASIC認証情報が見つかります。
http.request and http contains "Authorization: Basic"
問題文
以下の画像が渡されます。
チームの方が既に電話番号とドメインの一部からとうみょう子ども園
で有ることを特定していました。
その周辺の施設をストリートビューで散歩していたら見つかりました。
TsukuCTF23{37.502_139.929}
問題文
ゲーム上の画像?が渡されます。チームの方がValorant
というゲームのSunset
というマップであるということは調べてくれていたので、調べると当ゲームはマップごとに座標が割り当てられているらしく、検索すると下記のようなサイトがヒットし、記載されている座標を提出することでフラグとなりました。
問題文
以下の画像の座標を当てる問題です。
ニューギンの看板が目に付きます。
ニューギンの本部は名古屋の割と中心にあったと思いますが、名古屋の町並みっぽくなかったのでニューギン販売の営業所を当たることにしました。
会社のHPから支店を虱潰しに見ていくと鹿児島営業所付近であることがわかりました。
問題文
運営のshioさんという方が以下の写真を撮った日時を答える問題です。
夕日が海側に見えるので多分西側かなとわかります。向こう側に陸地も少し見えます。
shioさんがなにかのイベント参加後に撮った、ということなのでイベントを特定します。
shioさんのxの2023年分の投稿をざっと漁った感じ、CTFに出題するほどの思い出がありそうなのは講師を努めていたセキュリティ・ミニキャンプ2023新潟かなぁと、勘で推測しました。
このイベントは2023/9/10に開催されており、開催地は新潟コンピュータ専門学校で海が近いです。
海側をストリートビューで散歩していると画像の風景に似た箇所を発見しました。
寄居浜というところですね。少し高い位置から写真が取られていたのは日和山展望台から撮影したのでしょうか。
場所がわかったので次は撮影日時ですが、写真では夕暮れである(日没に近い)ことがわかります。
2023/9/10の日没時間を調べると18:01であることがわかりました。
まだ完全に日が沈んでいないことから18:01より前の時間を何回か入力することでフラグとして受け付けられました。