Pwn2Win CTF 2017 Writeup

この大会は2017/10/21 0:37(JST)~2017/10/23 0:37(JST)に開催されました。
今回もチームで参戦。結果は1600点で207チーム中21位でした。
自分で解けた問題をWriteupとして書いておきます。

Differential Privacy (Crypto)

$ nc 200.136.213.143 9999
Hello, chose an option:
[1] Info
[2] Query the flag (in ASCII)
[3] Quit
1
You can query the flag, but the characters are private (indistinguishable).
Differential privacy mechanism: Laplace
Sensitivity: ||125 - 45|| = 80
Epsilon: 6.5

Hello, chose an option:
[1] Info
[2] Query the flag (in ASCII)
[3] Quit
2
[60, 93, 88, 40, 79, 77, 147, 80, 136, 86, 109, 82, 111, 118, 108, 116, 76, 98, 102, 74, 117, 108, 95, 100, 127, 108, 99, 115, 78, 118, 81, 123, 123, 89, 115, 114, 132]
Hello, chose an option:
[1] Info
[2] Query the flag (in ASCII)
[3] Quit
Timeout! Bye...

とりあえず数回どんな数値が返ってくるか見てみる。

[103, 132, 67, 35, 61, 120, 100, 60, 104, 94, 81, 91, 148, 115, 120, 109, 96, 105, 113, 133, 125, 100, 129, 107, 92, 103, 107, 118, 109, 119, 76, 115, 91, 105, 120, 98, 114]
[60, 83, 77, 48, 84, 117, 123, 71, 101, 100, 105, 84, 111, 107, 117, 103, 86, 99, 105, 114, 99, 101, 118, 107, 110, 116, 126, 113, 85, 73, 98, 119, 93, 111, 113, 104, 115]
[72, 81, 71, 9, 59, 74, 130, 80, 96, 109, 119, 139, 101, 122, 133, 109, 106, 124, 95, 103, 49, 76, 96, 58, 122, 110, 71, 110, 94, 100, 104, 159, 113, 123, 124, 108, 138]
[68, 110, 68, 51, 55, 87, 129, 69, 100, 109, 131, 99, 56, 144, 119, 113, 89, 105, 102, 115, 117, 103, 101, 118, 141, 98, 83, 109, 76, 70, 95, 101, 118, 103, 121, 55, 124]
[69, 106, 82, 68, 95, 68, 125, 60, 89, 82, 105, 92, 88, 116, 122, 114, 90, 131, 95, 102, 96, 94, 109, 104, 103, 112, 92, 116, 101, 127, 94, 108, 116, 126, 113, 88, 214]
[78, 82, 42, 25, 30, 94, 138, 72, 108, 84, 108, 80, 104, 113, 134, 166, 102, 93, 94, 94, 116, 93, 108, 106, 157, 76, 83, 98, 104, 76, 112, 118, 123, 111, 116, 100, 131]
[67, 77, 69, 41, 70, 76, 135, 53, 94, 90, 91, 81, 103, 121, 110, 112, 75, 129, 112, 82, 106, 101, 141, 104, 106, 75, 93, 91, 119, 128, 110, 114, 143, 89, 143, 93, 138]

フラグがCTF-BRから始まることを考えると、ASCIIコードで近い数値のような感じがする。できるだけ多くの回数の平均のコード値を取り文字にしてみる。以下のコードを使い、何回か試し、フラグを推定する。

import socket

COLLECT_TIMES = 256

codes = []
for i in range(COLLECT_TIMES):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(('200.136.213.143', 9999))
    data = s.recv(256)
    print data
    print '2'
    s.sendall('2\n')
    data = s.recv(256)
    print data
    codes.append(map(int, data[1:-2].split(', ')))

avg_str = ''
for i in range(len(codes[0])):
    sum = 0
    for j in range(COLLECT_TIMES):
        sum += codes[j][i]
    avg = sum / COLLECT_TIMES
    print avg
    avg_str += chr(avg)

print avg_str

3回試した結果は以下の通り。

BRF+AR}H`bn_iutr_filtfpgmg\ujd_nnjse}
CVE-@SzJ]bl^kust]finserimf_sgf^npire{
BSD,BQyH_`l^hurt^djluesgkh_the_mohte|

この結果から意味を持つように文字を前後させる。

CTF-BR{I_am_just_filtering_the_noise}

Sum (Hello World Platform) (PPC-M)

実行するだけ。

$ python solve_sum.py
received: 4 1 1 5 7 6 1 5 8 7 8 8 3 0
sent: 64
received: 4 1 4 4 9 6 5 3 0
sent: 36
received: 8 1 7 1 6 8 4 3 3 3 0
sent: 44
received: 1 8 8 3 7 8 1 2 4 4 6 0
sent: 52
received: 1 1 1 9 1 9 7 4 4 4 7 3 1 2 7 9 0
sent: 70
received: 5 6 9 9 5 6 3 8 8 0
sent: 59
received: 2 2 3 1 8 2 1 9 9 7 4 9 2 8 1 8 8 4 0
sent: 88
received: 1 4 7 5 3 8 4 9 0
sent: 41
received: 1 7 8 3 5 6 4 8 5 5 8 4 9 2 5 0
sent: 80
received: 9 2 9 2 8 3 0
sent: 33
received: 1 3 4 9 9 5 5 8 6 7 0
sent: 57
received: 9 1 4 7 4 5 3 5 6 6 3 8 0
sent: 61
received: 5 7 8 5 2 2 9 0
sent: 38
received: 9 3 9 4 6 7 9 5 4 6 9 4 8 6 2 0
sent: 91
received: 3 8 1 1 3 7 2 7 4 9 5 1 4 3 9 5 4 9 0
sent: 85
received: 4 1 8 7 1 2 7 3 5 6 8 3 4 6 9 9 7 0
sent: 90
received: 9 1 2 3 3 4 2 1 9 5 4 4 8 2 2 5 0
sent: 64
received: 2 1 6 7 2 4 7 2 0
sent: 31
received: 5 7 7 1 5 9 1 4 6 6 8 0
sent: 59
received: 3 1 5 9 3 3 4 1 5 1 7 0
sent: 42
received: CTF-BR{Congrats!_you_know_how_to_sum!}
CTF-BR{Congrats!_you_know_how_to_sum!}