SECCON Beginners CTF 2018 write up

More than 1 year has passed since last update.

SECCON Beginners CTFに参加してきたので、解けた問題を残しておく。


Crypto


RSA is Power


問題

N = 97139961312384239075080721131188244842051515305572003521287545456189235939577

E = 65537
C = 77361455127455996572404451221401510145575776233122006907198858022042920987316


解法

http://www.factordb.com/ 素因数分解をしてくれるwebサービスがあるので、

そこに投げたら因数分解してくれた。

あとは、復号するのみ。

import gmpy

import codecs

p = 299681192390656691733849646142066664329

q = 324144336644773773047359441106332937713

e = 65537

l = gmpy.lcm(p-1, q-1)

gcd, u, v = gmpy.gcdext(e, l)
if u < 0:
u += l
c = 77361455127455996572404451221401510145575776233122006907198858022042920987316

n = p * q
d = u
m = pow(c, d, n)
print(codecs.decode(('%x'%m),'hex_codec'))


Pwn


[Warmup] condition


問題

あなたは flag にアクセスする権限を持っていますか?

Host: pwn1.chall.beginners.seccon.jp

Port: 16268


解法

サーバーのプログラムが配布されているので、逆アセンブル。

0000000000400771 <main>:

400771: 55 push rbp
400772: 48 89 e5 mov rbp,rsp
400775: 48 83 ec 30 sub rsp,0x30
400779: c7 45 fc 00 00 00 00 mov DWORD PTR [rbp-0x4],0x0
400780: bf d8 08 40 00 mov edi,0x4008d8
400785: b8 00 00 00 00 mov eax,0x0
40078a: e8 71 fe ff ff call 400600 <printf@plt>
40078f: 48 8d 45 d0 lea rax,[rbp-0x30]
400793: 48 89 c7 mov rdi,rax
400796: b8 00 00 00 00 mov eax,0x0
40079b: e8 80 fe ff ff call 400620 <gets@plt>
4007a0: 81 7d fc ef be ad de cmp DWORD PTR [rbp-0x4],0xdeadbeef
4007a7: 75 16 jne 4007bf <main+0x4e>
4007a9: bf f8 08 40 00 mov edi,0x4008f8
4007ae: e8 0d fe ff ff call 4005c0 <puts@plt>
4007b3: bf 1e 09 40 00 mov edi,0x40091e
4007b8: e8 16 00 00 00 call 4007d3 <read_file>
4007bd: eb 0a jmp 4007c9 <main+0x58>
4007bf: bf 27 09 40 00 mov edi,0x400927
4007c4: e8 f7 fd ff ff call 4005c0 <puts@plt>
4007c9: bf 00 00 00 00 mov edi,0x0
4007ce: e8 6d fe ff ff call 400640 <exit@plt>

cmp DWORD PTR [rbp-0x4],0xdeadbeef[rbp-0x4]0xdeadbeefかどうかをチェックして、一致していたらflagを出力している。

入力はgets関数の引数で渡している[rbp-0x30]に格納されるので、その分文字数を調整すれば良い。

リトルエンディアンに気をつけて以下のコマンドでFlagゲット。

echo -e 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\xef\xbe\xad\xde' | nc pwn1.chall.beginners.seccon.jp 16268


Reversing


[Warmup] Simple Auth


問題

認証に使われているパスワードを探せ!


解法

問題ファイルが渡されるので、逆アセンブル。 、、、しなくても、ltraceするとflagが出てくることを後から知った、、。

0000000000400792 <main>:

400792: 55 push rbp
400793: 48 89 e5 mov rbp,rsp
400796: 48 83 ec 30 sub rsp,0x30
40079a: 64 48 8b 04 25 28 00 mov rax,QWORD PTR fs:0x28
4007a1: 00 00
4007a3: 48 89 45 f8 mov QWORD PTR [rbp-0x8],rax
4007a7: 31 c0 xor eax,eax
4007a9: bf b4 08 40 00 mov edi,0x4008b4
4007ae: b8 00 00 00 00 mov eax,0x0
4007b3: e8 98 fd ff ff call 400550 <printf@plt>
4007b8: 48 8d 45 d0 lea rax,[rbp-0x30]
4007bc: 48 89 c6 mov rsi,rax
4007bf: bf c5 08 40 00 mov edi,0x4008c5
4007c4: b8 00 00 00 00 mov eax,0x0
4007c9: e8 a2 fd ff ff call 400570 <__isoc99_scanf@plt>
4007ce: 48 8d 45 d0 lea rax,[rbp-0x30]
4007d2: 48 89 c7 mov rdi,rax
4007d5: e8 ac fe ff ff call 400686 <auth>
4007da: 83 f8 01 cmp eax,0x1
4007dd: 75 22 jne 400801 <main+0x6f>
4007df: bf ca 08 40 00 mov edi,0x4008ca
4007e4: e8 37 fd ff ff call 400520 <puts@plt>
4007e9: 48 8d 45 d0 lea rax,[rbp-0x30]
4007ed: 48 89 c6 mov rsi,rax
4007f0: bf da 08 40 00 mov edi,0x4008da
4007f5: b8 00 00 00 00 mov eax,0x0
4007fa: e8 51 fd ff ff call 400550 <printf@plt>
4007ff: eb 0a jmp 40080b <main+0x79>
400801: bf e6 08 40 00 mov edi,0x4008e6
400806: e8 15 fd ff ff call 400520 <puts@plt>
40080b: b8 00 00 00 00 mov eax,0x0
400810: 48 8b 55 f8 mov rdx,QWORD PTR [rbp-0x8]
400814: 64 48 33 14 25 28 00 xor rdx,QWORD PTR fs:0x28
40081b: 00 00
40081d: 74 05 je 400824 <main+0x92>
40081f: e8 1c fd ff ff call 400540 <__stack_chk_fail@plt>
400824: c9 leave
400825: c3 ret
400826: 66 2e 0f 1f 84 00 00 nop WORD PTR cs:[rax+rax*1+0x0]
40082d: 00 00 00

call 400686 <auth> が怪しいので見てみる。

0000000000400686 <auth>:

400686: 55 push rbp
400687: 48 89 e5 mov rbp,rsp
40068a: 48 83 ec 50 sub rsp,0x50
40068e: 48 89 7d b8 mov QWORD PTR [rbp-0x48],rdi
400692: 64 48 8b 04 25 28 00 mov rax,QWORD PTR fs:0x28
400699: 00 00
40069b: 48 89 45 f8 mov QWORD PTR [rbp-0x8],rax
40069f: 31 c0 xor eax,eax
4006a1: c7 45 c0 01 00 00 00 mov DWORD PTR [rbp-0x40],0x1
4006a8: c6 45 d0 63 mov BYTE PTR [rbp-0x30],0x63
4006ac: c6 45 d1 74 mov BYTE PTR [rbp-0x2f],0x74
4006b0: c6 45 d2 66 mov BYTE PTR [rbp-0x2e],0x66
4006b4: c6 45 d3 34 mov BYTE PTR [rbp-0x2d],0x34
4006b8: c6 45 d4 62 mov BYTE PTR [rbp-0x2c],0x62
4006bc: c6 45 d5 7b mov BYTE PTR [rbp-0x2b],0x7b
4006c0: c6 45 d6 72 mov BYTE PTR [rbp-0x2a],0x72
4006c4: c6 45 d7 65 mov BYTE PTR [rbp-0x29],0x65
4006c8: c6 45 d8 76 mov BYTE PTR [rbp-0x28],0x76
4006cc: c6 45 d9 33 mov BYTE PTR [rbp-0x27],0x33
4006d0: c6 45 da 72 mov BYTE PTR [rbp-0x26],0x72
4006d4: c6 45 db 73 mov BYTE PTR [rbp-0x25],0x73
4006d8: c6 45 dc 69 mov BYTE PTR [rbp-0x24],0x69
4006dc: c6 45 dd 6e mov BYTE PTR [rbp-0x23],0x6e
4006e0: c6 45 de 67 mov BYTE PTR [rbp-0x22],0x67
4006e4: c6 45 df 5f mov BYTE PTR [rbp-0x21],0x5f
4006e8: c6 45 e0 70 mov BYTE PTR [rbp-0x20],0x70
4006ec: c6 45 e1 34 mov BYTE PTR [rbp-0x1f],0x34
4006f0: c6 45 e2 73 mov BYTE PTR [rbp-0x1e],0x73
4006f4: c6 45 e3 73 mov BYTE PTR [rbp-0x1d],0x73
4006f8: c6 45 e4 77 mov BYTE PTR [rbp-0x1c],0x77
4006fc: c6 45 e5 30 mov BYTE PTR [rbp-0x1b],0x30
400700: c6 45 e6 72 mov BYTE PTR [rbp-0x1a],0x72
400704: c6 45 e7 64 mov BYTE PTR [rbp-0x19],0x64
400708: c6 45 e8 7d mov BYTE PTR [rbp-0x18],0x7d
40070c: 48 8b 45 b8 mov rax,QWORD PTR [rbp-0x48]
400710: 48 89 c7 mov rdi,rax
400713: e8 18 fe ff ff call 400530 <strlen@plt>
400718: 89 45 c8 mov DWORD PTR [rbp-0x38],eax
40071b: 48 8d 45 d0 lea rax,[rbp-0x30]
40071f: 48 89 c7 mov rdi,rax
400722: e8 09 fe ff ff call 400530 <strlen@plt>
400727: 89 45 cc mov DWORD PTR [rbp-0x34],eax
40072a: 8b 45 c8 mov eax,DWORD PTR [rbp-0x38]
40072d: 3b 45 cc cmp eax,DWORD PTR [rbp-0x34]
400730: 75 40 jne 400772 <auth+0xec>
400732: c7 45 c4 00 00 00 00 mov DWORD PTR [rbp-0x3c],0x0
400739: eb 2d jmp 400768 <auth+0xe2>
40073b: 8b 45 c4 mov eax,DWORD PTR [rbp-0x3c]
40073e: 48 63 d0 movsxd rdx,eax
400741: 48 8b 45 b8 mov rax,QWORD PTR [rbp-0x48]
400745: 48 01 d0 add rax,rdx
400748: 0f b6 10 movzx edx,BYTE PTR [rax]
40074b: 8b 45 c4 mov eax,DWORD PTR [rbp-0x3c]
40074e: 48 98 cdqe
400750: 0f b6 44 05 d0 movzx eax,BYTE PTR [rbp+rax*1-0x30]
400755: 38 c2 cmp dl,al
400757: 75 06 jne 40075f <auth+0xd9>
400759: 83 45 c4 01 add DWORD PTR [rbp-0x3c],0x1
40075d: eb 09 jmp 400768 <auth+0xe2>
40075f: c7 45 c0 00 00 00 00 mov DWORD PTR [rbp-0x40],0x0
400766: eb 11 jmp 400779 <auth+0xf3>
400768: 8b 45 c4 mov eax,DWORD PTR [rbp-0x3c]
40076b: 3b 45 c8 cmp eax,DWORD PTR [rbp-0x38]
40076e: 7c cb jl 40073b <auth+0xb5>
400770: eb 07 jmp 400779 <auth+0xf3>
400772: c7 45 c0 00 00 00 00 mov DWORD PTR [rbp-0x40],0x0
400779: 8b 45 c0 mov eax,DWORD PTR [rbp-0x40]
40077c: 48 8b 4d f8 mov rcx,QWORD PTR [rbp-0x8]
400780: 64 48 33 0c 25 28 00 xor rcx,QWORD PTR fs:0x28
400787: 00 00
400789: 74 05 je 400790 <auth+0x10a>
40078b: e8 b0 fd ff ff call 400540 <__stack_chk_fail@plt>
400790: c9 leave
400791: c3 ret

と、文字列をメモリにせっせと書き込んでいるのでgdbで見てみると、stackにflagが表示される。

[----------------------------------registers-----------------------------------]

RAX: 0x7fffffffea70 --> 0x696e ('ni')
RBX: 0x0
RCX: 0xa ('\n')
RDX: 0x7ffff7dd3790 --> 0x0
RSI: 0x1
RDI: 0x7fffffffea70 --> 0x696e ('ni')
RBP: 0x7fffffffea60 --> 0x7fffffffeaa0 --> 0x400830 (<__libc_csu_init>: push r15)
RSP: 0x7fffffffea10 --> 0x7ffff7dd3780 --> 0x0
RIP: 0x400710 (<auth+138>: mov rdi,rax)
R8 : 0x0
R9 : 0x7ffff7fe9700 (0x00007ffff7fe9700)
R10: 0x4008c5 --> 0x7475410073303325 ('%30s')
R11: 0x246
R12: 0x400590 (<_start>: xor ebp,ebp)
R13: 0x7fffffffeb80 --> 0x1
R14: 0x0
R15: 0x0
EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x400704 <auth+126>: mov BYTE PTR [rbp-0x19],0x64
0x400708 <auth+130>: mov BYTE PTR [rbp-0x18],0x7d
0x40070c <auth+134>: mov rax,QWORD PTR [rbp-0x48]
=> 0x400710 <auth+138>: mov rdi,rax
0x400713 <auth+141>: call 0x400530 <strlen@plt>
0x400718 <auth+146>: mov DWORD PTR [rbp-0x38],eax
0x40071b <auth+149>: lea rax,[rbp-0x30]
0x40071f <auth+153>: mov rdi,rax
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffea10 --> 0x7ffff7dd3780 --> 0x0
0008| 0x7fffffffea18 --> 0x7fffffffea70 --> 0x696e ('ni')
0016| 0x7fffffffea20 --> 0x1
0024| 0x7fffffffea28 --> 0x602000 --> 0x0
0032| 0x7fffffffea30 ("ctf4b{rev3rsing_p4ssw0rd}")
0040| 0x7fffffffea38 ("v3rsing_p4ssw0rd}")
0048| 0x7fffffffea40 ("p4ssw0rd}")
0056| 0x7fffffffea48 --> 0xff0000007d
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
0x0000000000400710 in auth ()


crackme


問題

バイナリを解析して、入力値を求めてください。


解法

問題ファイルが渡されるので、とりあえず実行すると、

usage: ./crackme <FLAG>と使い方を教えてくれる。

正しいflagを入力すると反応するプログラムのようだ。

逆アセンブル。

経験値浅すぎて、解析にめっちゃ時間かかった、、。

  40093c:   55                      push   rbp

40093d: 48 89 e5 mov rbp,rsp
400940: 48 83 ec 10 sub rsp,0x10
400944: 89 7d fc mov DWORD PTR [rbp-0x4],edi
400947: 48 89 75 f0 mov QWORD PTR [rbp-0x10],rsi
40094b: 83 7d fc 02 cmp DWORD PTR [rbp-0x4],0x2
40094f: 74 19 je 40096a <exit@plt+0x4aa>
400951: bf 68 0a 40 00 mov edi,0x400a68
400956: b8 00 00 00 00 mov eax,0x0
40095b: e8 40 fb ff ff call 4004a0 <printf@plt>
400960: bf 00 00 00 00 mov edi,0x0
400965: e8 56 fb ff ff call 4004c0 <exit@plt>
40096a: 48 8b 45 f0 mov rax,QWORD PTR [rbp-0x10]
40096e: 48 83 c0 08 add rax,0x8
400972: 48 8b 00 mov rax,QWORD PTR [rax]
400975: 48 89 c7 mov rdi,rax
400978: e8 09 fe ff ff call 400786 <exit@plt+0x2c6>
40097d: 48 8b 45 f0 mov rax,QWORD PTR [rbp-0x10]
400981: 48 83 c0 08 add rax,0x8
400985: 48 8b 00 mov rax,QWORD PTR [rax]
400988: 48 83 c0 10 add rax,0x10
40098c: 48 89 c7 mov rdi,rax
40098f: e8 42 fc ff ff call 4005d6 <exit@plt+0x116>
400994: 8b 05 b6 06 20 00 mov eax,DWORD PTR [rip+0x2006b6] # 601050 <exit@plt+0x200b90

call 400786 <exit@plt+0x2c6>call 4005d6 <exit@plt+0x116>をしている。

それぞれを見てみると、コマンドライン引数で与えた文字列の最初の16文字、次の16文字をループで処理して、flagかどうかを判定している。

メモリの0x601048番の値をキーとして、1文字ずつキーを更新しながらコマンドライン引数で与えた文字と一文字ずつxorをとって内部の値と比較している。

内部の値とキーのxorをとっていけばflagが復元可能。


misc


[Warmup] plain mail


解法

pcapファイルが渡される。

WireSharkで覗いてみる。

17番目のパケットで

I will send secret information. First, I will send encrypted file. Second, I wll send you the password.といっている。

その後zipファイルを送信し、59版のパケットにpasswordが書かれている。

WireSharkでファイル->オブジェクトをエクスポート->IMF...とすると.emlファイルでzipファイルも手に入るので、解凍してflagゲット。


Find the messages


問題

ディスクイメージに隠されているメッセージファイルを探せ!


解法

ディスクイメージが渡される。

とりあえずbinwalkしてみると、色々入っているようなので下記コマンドで取り出してみる。

binwalk -e disk.img

すると、 message_1_of_3.txtmessage_2_of_3.pngが出てくる。

テキストの中身はY3RmNGJ7eTB1X3QwdWNoZWQ=であり、最後の=がbase64にしか見えないので、

復号。

pngは開こうとするとファイルが壊れて居ると言われるので、バイナリを見てみると、先頭の8バイトがXXXXXXXX

となっている。

これをバイナリエディタでpngの正しいマジックナンバー89 50 4e 47 0d 0a 1a 0aに書き換えて開けるようにすると、画像中に文字が書かれている。

最後に、ディスクイメージだしととりあえずforemostしとけってやったら、message_3_of_3.pdfが出てきてflagゲット。

foremost disk.img


感想

初めてCTFに参加したがとても楽しめた。

初日はそこそこのペースで解けたが、二日目は結局1問も解けず、ズルズルと順位が落ちて悔しかったので、今後も精進したい。