TsukuCTF 2023 Writeup

TsukuCTFに0nePaddingで参加してきました。

順位は13位でした。

image

ToC

[rev] title_screen

問題文

image

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

image

二通りの解法があるので記載します。

静的解析

以下サイト等を参考にNESの命令を調べているとI/Oポート$2006への書き込み(二回)でアクセス先VRAMアドレスを決定しI/Oポート$2007で書き込む、という命令になるらしいです。$20062000が書き込まれていますが、これはネームテーブル0に対応しておりネームテーブルへの書き込みでどのブロック位置にどのキャラクタが埋め込まれるかが決定されるようです。

NES研究室
ファミコン用ROMを作成するための情報サイト
NES研究室 favicon http://hp.vector.co.jp/authors/VA042397/nes/index.html

ので$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がないと怒られます。

image

渡されたBMPファイルからchrファイルを生成するため、以下のツールを使用しました。

GitHub - suzukiplan/bmp2chr: Make NES pattern table from 8bit bitmap (CLI)
Make NES pattern table from 8bit bitmap (CLI). Contribute to suzukiplan/bmp2chr development by creating an account on GitHub.
GitHub - suzukiplan/bmp2chr: Make NES pattern table from 8bit bitmap (CLI) favicon https://github.com/suzukiplan/bmp2chr
GitHub - suzukiplan/bmp2chr: Make NES pattern table from 8bit bitmap (CLI)

このツールは128x128のBMPしか変換できないようなので、PythonでBMPをサイズ変換します。

image

from PIL import Image
i = Image.open("./character.bmp")
i = i.crop((0,0,128,128))
i = i.quantize(8)
i.save("resized.bmp")

image

この状態で変換ツールを実行するとBMPからCHRへの変換が成功します。

image

CHRが生成できたのでアセンブリをビルドしてみるとビルドに成功したのがわかります。

image

Webで公開されているエミュレータを使用するとタイトル画面?が表示されフラグが表示されます。

JSNES: A JavaScript NES emulator
JSNES: A JavaScript NES emulator favicon https://jsnes.org/

image

[Web] basic

問題文

image

pcapファイルが渡されます。

問題名から問題文で触れられているパスワードはBASIC認証のことでしょう。

WiresharkでフィルターをかけることでBASIC認証情報が見つかります。

http.request and http contains "Authorization: Basic"

image

[OSINT] 3636

問題文

image

以下の画像が渡されます。

image

チームの方が既に電話番号とドメインの一部からとうみょう子ども園で有ることを特定していました。

その周辺の施設をストリートビューで散歩していたら見つかりました。

image

TsukuCTF23{37.502_139.929}

[OSINT] fiction

問題文

image

image

ゲーム上の画像?が渡されます。チームの方がValorantというゲームのSunsetというマップであるということは調べてくれていたので、調べると当ゲームはマップごとに座標が割り当てられているらしく、検索すると下記のようなサイトがヒットし、記載されている座標を提出することでフラグとなりました。

Sunset
A disaster at a local kingdom facility threatens to engulf the whole neighborhood. Stop at your favorite food truck then fight across the city in this traditional three lane map.Official description Sunset is the tenth map to be released in VALORANT. Sunset is one of VALORANT's more traditional maps with two sites and three lanes. Its one additional feature is a mechanical door found between B Market and Mid Courtyard. Players can use a switch on the Market side of the door to close or open it.
Sunset favicon https://valorant.fandom.com/wiki/Sunset
Sunset

[OSINT] river

問題文

image

以下の画像の座標を当てる問題です。

image

ニューギンの看板が目に付きます。

ニューギンの本部は名古屋の割と中心にあったと思いますが、名古屋の町並みっぽくなかったのでニューギン販売の営業所を当たることにしました。

会社のHPから支店を虱潰しに見ていくと鹿児島営業所付近であることがわかりました。

newgin ニューギン
ニューギンは総合アミューズメント企業としてお客様とファンの皆様に,これからも「あそびにマジメ」をご提案し続けます。
newgin ニューギン favicon https://www.newgin.co.jp/company/overview/?tab=3
newgin ニューギン

image

[OSINT] sunset

問題文

image

運営のshioさんという方が以下の写真を撮った日時を答える問題です。

夕日が海側に見えるので多分西側かなとわかります。向こう側に陸地も少し見えます。

image

shioさんがなにかのイベント参加後に撮った、ということなのでイベントを特定します。

shioさんのxの2023年分の投稿をざっと漁った感じ、CTFに出題するほどの思い出がありそうなのは講師を努めていたセキュリティ・ミニキャンプ2023新潟かなぁと、勘で推測しました。

このイベントは2023/9/10に開催されており、開催地は新潟コンピュータ専門学校で海が近いです。

image

海側をストリートビューで散歩していると画像の風景に似た箇所を発見しました。

寄居浜というところですね。少し高い位置から写真が取られていたのは日和山展望台から撮影したのでしょうか。

image

場所がわかったので次は撮影日時ですが、写真では夕暮れである(日没に近い)ことがわかります。

2023/9/10の日没時間を調べると18:01であることがわかりました。

image

まだ完全に日が沈んでいないことから18:01より前の時間を何回か入力することでフラグとして受け付けられました。