SECCON Beginners CTF 2018 write up

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>`をしている。
それぞれを見てみると、コマンドライン引数で与えた文字列の最初の１６文字、次の１６文字をループで処理して、flagかどうかを判定している。

メモリの0x601048番の値をキーとして、１文字ずつキーを更新しながらコマンドライン引数で与えた文字と一文字ずつ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.txt` と `message_2_of_3.png`が出てくる。
テキストの中身は`Y3RmNGJ7eTB1X3QwdWNoZWQ=`であり、最後の`=`がbase64にしか見えないので、
復号。
pngは開こうとするとファイルが壊れて居ると言われるので、バイナリを見てみると、先頭の８バイトが`XXXXXXXX`
となっている。
これをバイナリエディタでpngの正しいマジックナンバー`89 50 4e 47 0d 0a 1a 0a`に書き換えて開けるようにすると、画像中に文字が書かれている。

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

```
foremost disk.img
```

# 感想

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