WeCTF 2020 Writeup

この大会は2020/6/14 2:00(JST)~2020/6/15 2:00(JST)に開催されました。
今回もチームで参戦。結果は441点で257チーム中106位でした。
自分で解けた問題をWriteupとして書いておきます。

Note App

アカウントを作成してログインすると、Note作成画面になる。適当に文字を追加して、Create Noteをすると、Noteが作成される。
f:id:satou-y:20200621221157p:plain
Note ID: 19のリンクをクリックして見てみると、入力した内容が表示され、URLは以下に移る。

http://na1.w-jp.cf/note/19

なぜかIDは19から始まっている。IDを1にしたURLでアクセスしてみる。

http://na1.w-jp.cf/note/1

Note ID: 1のページにフラグが書いてあった。
f:id:satou-y:20200621221246p:plain

we{7b9f9649-9226-4027-92cc-53d192efa414@H0w-1-Cee-CLasSmaTe8-sc0Res}

RE

添付のphpを整形する。

<?php
goto N0szu;

veU3P: 
goto pQRcr;
goto IumIK;

h6FIk: 
echo "\x67\x6f\157\144\40\x6a\x6f\142\x21";
goto UUbDK; 

EGqNR: 

npj3x: 
goto zu5hE; 

s2urN: 
echo iK43N(); 
goto wOcDP; 

l9KrJ: 
echo "\x6e\x6f\164\40\164\x68\145\40\x66\154\x61\147\x21"; 
goto veU3P; 

yL5pP: 
function z3UeR($ImMRk) { 
    goto TajPo; 

    p5dMS: 
    return $FAAyo === $ImMRk; 
    goto cmY0H; 

    RIhuW: 
    $JrhK3 = "\150\x74\x74\x70\163\72\57\57\x63\x6c\x62\151\156\x2e\143\157\155\x2f{$Z58VF}"; 
    goto AB_gB; 

    TajPo: 
    $Z58VF = "\x49\123\x4b\x34\x31"; 
    goto RIhuW; 

    AB_gB: 
    $FAAyo = str_replace("\12", '', file_get_contents($JrhK3)); 
    goto p5dMS; 

    cmY0H: 
} 
goto tsmPP; 

rCgwE: 
if (!($argc !== 2 || $argv[1] === "\55\55\x68\x65\154\160")) { 
    goto npj3x; 
} 
goto s2urN; 

HqIXQ: 
if (z3Uer($WYrTt[0]) && pkxLr($WYrTt[1])) { 
    goto bNu31; 
} 
goto l9KrJ; 

wOcDP: 
die; 
goto EGqNR; 

zu5hE: 
$WYrTt = explode("\x40", $argv[1]); 
goto yL5pP; 

tsmPP: 
function PKxlr($ImMRk) { 
    goto Ovh2D; 

    Ovh2D: 
    foreach (str_split($ImMRk) as $NXbA9 => $LW9s3) { 
        goto wixWZ; 

        wixWZ: 
        $LW9s3 = md5($LW9s3); 
        goto ZDD1u; 

        ZDD1u: 
        if (!(["\x38\x30\60\x36\x31\70\71\x34\x33\60\x32\x35\63\61\65\x66\70\x36\71\x65\x34\145\x31\146\60\x39\64\x37\x31\x30\61\62", "\x37\142\x37\x37\64\145\x66\146\145\x34\141\63\64\x39\143\66\144\144\70\62\x61\x64\x34\x66\x34\146\62\61\x64\x33\x34\x63", "\70\144\71\143\63\60\x37\143\x62\67\146\63\143\64\x61\63\x32\x38\x32\62\x61\65\61\x39\x32\62\144\x31\x63\145\x61\141", "\142\61\x34\x61\67\x62\70\x30\65\x39\144\71\143\x30\65\65\x39\x35\64\x63\71\x32\x36\x37\x34\143\145\x36\x30\60\63\62", "\x39\x32\x65\142\x35\x66\146\x65\145\x36\x61\145\62\x66\x65\x63\63\x61\x64\x37\x31\143\x37\67\67\x35\x33\x31\65\67\70\x66", "\67\142\67\67\64\145\x66\x66\145\64\x61\63\64\x39\x63\66\144\x64\70\62\x61\144\64\146\64\146\x32\x31\x64\63\x34\x63", "\x38\146\x31\64\x65\x34\65\146\x63\x65\x65\x61\x31\x36\67\141\65\x61\63\66\144\x65\144\144\x34\x62\145\x61\62\65\64\63", "\142\x31\x34\141\67\142\x38\60\65\x39\x64\x39\x63\x30\65\x35\x39\65\x34\143\71\x32\x36\67\64\x63\x65\x36\60\60\63\62", "\x37\x62\x38\x62\71\x36\65\141\x64\64\x62\x63\141\60\x65\x34\61\x61\142\65\x31\144\145\x37\142\x33\x31\x33\x36\x33\141\x31", "\143\146\x63\x64\x32\x30\x38\64\x39\x35\144\x35\x36\x35\x65\x66\66\66\145\x37\x64\x66\x66\x39\146\71\70\67\x36\64\144\x61", "\142\61\x34\x61\67\142\x38\60\x35\71\144\71\x63\60\x35\65\71\65\x34\x63\x39\62\66\x37\x34\x63\145\x36\x30\60\63\62", "\71\x32\x65\142\x35\146\146\x65\145\x36\141\145\62\146\x65\x63\63\141\x64\x37\x31\143\67\67\x37\65\x33\x31\x35\67\x38\x66", "\x65\x31\x65\61\x64\63\x64\x34\x30\65\x37\x33\x31\x32\67\145\x39\x65\145\60\64\70\60\x63\x61\146\x31\62\70\63\x64\66", "\67\x62\x37\67\64\145\146\x66\145\x34\x61\63\64\71\143\66\x64\x64\70\x32\141\x64\x34\x66\64\x66\x32\x31\144\x33\64\143", "\x62\71\145\x63\145\x31\70\x63\71\x35\x30\x61\x66\x62\146\x61\x36\142\60\146\144\x62\146\x61\64\146\x66\x37\x33\x31\x64\63", "\x38\60\x30\66\61\x38\71\64\63\x30\x32\x35\x33\61\65\x66\70\66\x39\x65\x34\145\61\146\60\71\64\x37\x31\x30\61\x32", "\70\x34\x63\64\60\64\x37\x33\64\61\64\143\x61\x66\62\145\x64\64\x61\67\x62\x31\62\70\x33\145\64\70\x62\x62\146\x34", "\71\x33\67\61\144\67\141\x32\x65\63\141\x65\70\66\141\60\x30\x61\x61\x62\64\67\x37\x31\x65\63\x39\x64\x32\x35\x35\144", "\64\x62\x34\x33\142\x30\x61\x65\x65\63\65\66\x32\64\143\144\x39\65\x62\71\x31\x30\61\70\x39\142\x33\144\143\62\x33\x31", "\60\x64\x36\61\146\x38\63\67\60\143\x61\x64\61\144\x34\x31\x32\x66\70\x30\142\x38\x34\144\x31\x34\x33\145\61\x32\x35\x37", "\x65\61\x36\x37\x31\67\71\67\x63\65\62\x65\61\65\146\x37\x36\x33\x33\x38\60\x62\64\65\145\x38\64\x31\x65\143\x33\x32", "\x65\61\x36\67\x31\x37\71\x37\x63\x35\x32\145\61\x35\x66\x37\66\x33\63\x38\60\x62\64\65\x65\70\x34\61\145\x63\63\62", "\145\x31\66\67\61\67\71\67\143\65\62\145\61\x35\146\67\x36\63\x33\70\60\x62\x34\x35\145\70\64\61\145\x63\x33\x32", "\x65\x31\66\x37\61\x37\x39\x37\x63\x35\x32\x65\x31\x35\146\67\66\x33\63\70\60\142\64\65\x65\x38\x34\x31\145\143\x33\62", "\x65\61\66\67\x31\x37\x39\67\x63\65\62\x65\61\x35\146\x37\x36\x33\63\70\x30\x62\64\65\x65\70\64\61\145\143\63\x32", "\142\61\x34\x61\67\142\70\60\65\71\144\71\x63\x30\65\65\x39\x35\64\143\x39\x32\66\x37\x34\143\145\66\60\x30\63\62", "\x32\144\x62\71\x35\x65\70\x65\61\x61\x39\62\66\x37\142\x37\141\x31\x31\70\x38\65\65\66\x62\x32\x30\61\63\142\63\63", "\143\146\143\144\x32\60\x38\x34\x39\65\144\x35\66\x35\x65\146\66\66\x65\67\144\146\146\71\146\x39\x38\67\66\64\144\x61", "\x63\x34\143\141\x34\62\x33\x38\141\60\142\71\62\63\70\x32\60\144\x63\143\65\60\71\141\x36\146\67\x35\x38\x34\71\x62", "\x39\60\63\x33\x65\60\145\x33\x30\65\x66\62\x34\x37\143\x30\143\63\143\x38\x30\144\x30\x63\x37\x38\x34\x38\x63\x38\142\63"][$NXbA9] !== $LW9s3)) { 
            goto cjeNi; 
        } 
        goto Wq20G; 

        esj_P: 

        W8_V0: 
        goto su1qt; 

        Wq20G: 
        return false; 
        goto y40lA; 

        y40lA: 

        cjeNi: 
        goto esj_P; 

        su1qt: 
    } 
    goto ZbMyy; 

    Nu8WA: 
    return true; 
    goto brx16; 

    ZbMyy: 

    fqhOn: 
    goto Nu8WA; 

    brx16: 
} 
goto HqIXQ; 

IumIK: 

bNu31: 
goto h6FIk; 

N0szu: 
function Ik43N() { 
    return "\125\163\x61\147\x65\72\x20\12" . "\x20\x20\40\x70\150\x70\40\170\56\160\150\160\40\74\x66\x6c\141\147\x3e\40\x20\x20\x20\40\103\150\x65\143\x6b\40\164\x68\145\40\146\x6c\141\x67\12" . "\40\40\x20\160\x68\160\40\x78\x2e\160\150\x70\x20\55\55\150\x65\154\x70\40\40\x20\x20\x20\120\162\x69\156\x74\x20\x74\150\151\163\40\155\145\163\163\x61\x67\145\12"; 
} 
goto rCgwE; 

UUbDK: 

pQRcr:

さらに書き換える。

<?php
goto N0szu;

veU3P: 
goto pQRcr;
goto IumIK;

h6FIk: 
echo "good job!";
goto UUbDK; 

EGqNR: 

npj3x: 
goto zu5hE; 

s2urN: 
echo iK43N(); 
goto wOcDP; 

l9KrJ: 
echo "not the flag!"; 
goto veU3P; 

yL5pP: 
function z3UeR($ImMRk) { 
    goto TajPo; 

    p5dMS: 
    return $FAAyo === $ImMRk; 
    goto cmY0H; 

    RIhuW: 
    $JrhK3 = "https://clbin.com/{$Z58VF}"; 
    goto AB_gB; 

    TajPo: 
    $Z58VF = "ISK41"; 
    goto RIhuW; 

    AB_gB: 
    $FAAyo = str_replace("\12", '', file_get_contents($JrhK3)); 
    goto p5dMS; 

    cmY0H: 
} 
goto tsmPP; 

rCgwE: 
if (!($argc !== 2 || $argv[1] === "--help")) { 
    goto npj3x; 
} 
goto s2urN; 

HqIXQ: 
if (z3Uer($WYrTt[0]) && pkxLr($WYrTt[1])) { 
    goto bNu31; 
} 
goto l9KrJ; 

wOcDP: 
die; 
goto EGqNR; 

zu5hE: 
$WYrTt = explode("@", $argv[1]); 
goto yL5pP; 

tsmPP: 
function PKxlr($ImMRk) { 
    goto Ovh2D; 

    Ovh2D: 
    foreach (str_split($ImMRk) as $NXbA9 => $LW9s3) { 
        goto wixWZ; 

        wixWZ: 
        $LW9s3 = md5($LW9s3); 
        goto ZDD1u; 

        ZDD1u: 
        if (!(["800618943025315f869e4e1f09471012", "7b774effe4a349c6dd82ad4f4f21d34c", "8d9c307cb7f3c4a32822a51922d1ceaa", "b14a7b8059d9c055954c92674ce60032", "92eb5ffee6ae2fec3ad71c777531578f", "7b774effe4a349c6dd82ad4f4f21d34c", "8f14e45fceea167a5a36dedd4bea2543", "b14a7b8059d9c055954c92674ce60032", "7b8b965ad4bca0e41ab51de7b31363a1", "cfcd208495d565ef66e7dff9f98764da", "b14a7b8059d9c055954c92674ce60032", "92eb5ffee6ae2fec3ad71c777531578f", "e1e1d3d40573127e9ee0480caf1283d6", "7b774effe4a349c6dd82ad4f4f21d34c", "b9ece18c950afbfa6b0fdbfa4ff731d3", "800618943025315f869e4e1f09471012", "84c40473414caf2ed4a7b1283e48bbf4", "9371d7a2e3ae86a00aab4771e39d255d", "4b43b0aee35624cd95b910189b3dc231", "0d61f8370cad1d412f80b84d143e1257", "e1671797c52e15f763380b45e841ec32", "e1671797c52e15f763380b45e841ec32", "e1671797c52e15f763380b45e841ec32", "e1671797c52e15f763380b45e841ec32", "e1671797c52e15f763380b45e841ec32", "b14a7b8059d9c055954c92674ce60032", "2db95e8e1a9267b7a1188556b2013b33", "cfcd208495d565ef66e7dff9f98764da", "c4ca4238a0b923820dcc509a6f75849b", "9033e0e305f247c0c3c80d0c7848c8b3"][$NXbA9] !== $LW9s3)) { 
            goto cjeNi; 
        } 
        goto Wq20G; 

        esj_P: 

        W8_V0: 
        goto su1qt; 

        Wq20G: 
        return false; 
        goto y40lA; 

        y40lA: 

        cjeNi: 
        goto esj_P; 

        su1qt: 
    } 
    goto ZbMyy; 

    Nu8WA: 
    return true; 
    goto brx16; 

    ZbMyy: 

    fqhOn: 
    goto Nu8WA; 

    brx16: 
} 
goto HqIXQ; 

IumIK: 

bNu31: 
goto h6FIk; 

N0szu: 
function Ik43N() { 
    return "Usage: \n" . "   php x.php <flag>     Check the flag\n" . "   php x.php --help     Print this message\n"; 
} 
goto rCgwE; 

UUbDK: 

pQRcr:

処理の概要は以下の通り。

・引数が2個でないか、--helpが指定されている場合は、Usageを表示
・$WYrTt: 入力文字列を@で区切った文字列の配列
・z3UeR(@の前の文字列)
 ・$JrhK3 = "https://clbin.com/ISK41";
 ・このファイルの内容を取得、改行を削除
  $FAAyo = "b021b020-4d11-4857-8138-edb2ff753637";★
・pkxLr(@の後ろの文字列)
 ・1文字ずつのmd5の値がコード中の値と一致していることが必要。

@の前は"b021b020-4d11-4857-8138-edb2ff753637"である必要がある。@の後ろはブルートフォースで条件を満たすものを探せる。

from hashlib import md5

hashes = ['800618943025315f869e4e1f09471012', 
    '7b774effe4a349c6dd82ad4f4f21d34c', '8d9c307cb7f3c4a32822a51922d1ceaa', 
    'b14a7b8059d9c055954c92674ce60032', '92eb5ffee6ae2fec3ad71c777531578f', 
    '7b774effe4a349c6dd82ad4f4f21d34c', '8f14e45fceea167a5a36dedd4bea2543', 
    'b14a7b8059d9c055954c92674ce60032', '7b8b965ad4bca0e41ab51de7b31363a1', 
    'cfcd208495d565ef66e7dff9f98764da', 'b14a7b8059d9c055954c92674ce60032', 
    '92eb5ffee6ae2fec3ad71c777531578f', 'e1e1d3d40573127e9ee0480caf1283d6', 
    '7b774effe4a349c6dd82ad4f4f21d34c', 'b9ece18c950afbfa6b0fdbfa4ff731d3', 
    '800618943025315f869e4e1f09471012', '84c40473414caf2ed4a7b1283e48bbf4', 
    '9371d7a2e3ae86a00aab4771e39d255d', '4b43b0aee35624cd95b910189b3dc231', 
    '0d61f8370cad1d412f80b84d143e1257', 'e1671797c52e15f763380b45e841ec32', 
    'e1671797c52e15f763380b45e841ec32', 'e1671797c52e15f763380b45e841ec32', 
    'e1671797c52e15f763380b45e841ec32', 'e1671797c52e15f763380b45e841ec32', 
    'b14a7b8059d9c055954c92674ce60032', '2db95e8e1a9267b7a1188556b2013b33', 
    'cfcd208495d565ef66e7dff9f98764da', 'c4ca4238a0b923820dcc509a6f75849b', 
    '9033e0e305f247c0c3c80d0c7848c8b3']

flag1 = 'b021b020-4d11-4857-8138-edb2ff753637'
flag2 = ''
for h in hashes:
    for code in range(32, 127):
        if md5(chr(code)).hexdigest() == h:
            flag2 += chr(code)
            break

flag = 'we{%s@%s}' % (flag1, flag2)
print flag
we{b021b020-4d11-4857-8138-edb2ff753637@FuN_bu7_n0_bRuTF()rCeeeee_l01!}