この大会は2022/3/4 23:30(JST)~2022/3/5 23:30(JST)に開催されました。
今回もチームで参戦。結果は301点で372チーム中116位でした。
自分で解けた問題をWriteupとして書いておきます。
Sanity Check (Welcome)
Discordに入り、#announcementsチャネルのメッセージを見ると、フラグが書いてあった。
GLUG{W3lc0m3_7o_F00b4r!!}
Baby Rev (Rev)
Ghidraでデコンパイルする。
undefined8 main(int param_1,long param_2) { char *__s; undefined8 uVar1; size_t sVar2; bool bVar3; bool bVar4; bool bVar5; bool bVar6; bool bVar7; bool bVar8; bool bVar9; bool bVar10; bool bVar11; bool bVar12; bool bVar13; bool bVar14; bool bVar15; bool bVar16; bool bVar17; bool bVar18; bool bVar19; bool bVar20; bool bVar21; bool bVar22; bool bVar23; bool bVar24; bool bVar25; bool bVar26; bool bVar27; bool bVar28; bool bVar29; bool bVar30; bool bVar31; bool bVar32; bool bVar33; bool bVar34; bool bVar35; bool bVar36; bool bVar37; bool bVar38; bool bVar39; bool bVar40; bool bVar41; bool bVar42; bool bVar43; bool bVar44; bool bVar45; bool bVar46; bool bVar47; bool bVar48; bool bVar49; bool bVar50; bool bVar51; bool bVar52; bool bVar53; bool bVar54; bool bVar55; bool bVar56; bool bVar57; bool bVar58; bool bVar59; bool bVar60; bool bVar61; bool bVar62; bool bVar63; bool bVar64; bool bVar65; bool bVar66; bool bVar67; bool bVar68; bool bVar69; bool bVar70; bool bVar71; bool bVar72; bool bVar73; bool bVar74; bool bVar75; bool bVar76; bool bVar77; bool bVar78; bool bVar79; bool bVar80; bool bVar81; bool bVar82; bool bVar83; bool bVar84; bool bVar85; if (param_1 == 2) { __s = *(char **)(param_2 + 8); sVar2 = strlen(__s); if ((int)sVar2 == 0x2a) { bVar3 = (int)__s[8] + (int)__s[0xd] + (int)__s[7] == 0x10d; bVar4 = (int)*__s + ((int)*__s - (int)__s[1]) + (int)__s[0xe] == 0xa5; bVar5 = (int)__s[0x26] + (int)__s[0x15] * (int)__s[0x10] + (int)__s[0x22] == 0x250a; bVar6 = (int)__s[0x17] + (int)__s[0x29] + (int)__s[6] * (int)__s[8] == 0x157c; bVar7 = -(int)__s[0x15] - (int)__s[0x29] == -0xdf; bVar8 = (int)__s[0x13] + (int)__s[0x12] * (int)__s[4] * (int)__s[0xb] == 0x9c2de; bVar9 = (int)__s[0x22] * (int)__s[0x21] + (int)__s[0x17] == 0x1903; bVar10 = (int)__s[0xe] * (int)__s[0x12] - (int)__s[0x21] == 0x13d0; bVar11 = (((int)__s[0x18] - (int)__s[0x27]) - (int)__s[0x1e]) - (int)__s[0x16] == -0x6e; bVar12 = (int)__s[1] + (((int)__s[0x1e] + (int)__s[10]) - (int)__s[0x13]) == 0x6e; bVar13 = ((int)__s[0xf] - (int)__s[0x14]) - (int)__s[0x29] == -0xa9; bVar14 = (int)__s[0x23] * (int)__s[0xf] - (int)__s[8] * (int)__s[0x29] == -0x27f7; bVar15 = ((int)__s[0xb] * (int)__s[0x1f] + (int)__s[0x24]) - (int)__s[0x20] == 0x20ec; bVar16 = (int)__s[0x28] + (int)__s[0x19] + (int)__s[0x1d] == 0x121; bVar17 = (int)__s[0x18] + ((int)__s[7] - (int)__s[0xc]) == 100; bVar18 = (int)__s[0x1e] * (int)__s[0x15] - (int)__s[6] == 0x242e; bVar19 = (int)__s[3] * (int)__s[0x21] * (int)__s[0x26] == 0x753f4; bVar20 = ((int)__s[0x14] - (int)*__s * (int)__s[0x1f]) - (int)__s[2] == -0x1742; bVar21 = (int)__s[0x15] * (int)__s[0xc] + (int)__s[0x1b] == 0x13e7; bVar22 = ((int)__s[6] + (int)__s[8] * (int)__s[0xb]) - (int)__s[8] == 0x2aba; bVar23 = (int)__s[0x18] * (int)__s[7] + ((int)__s[0x22] - (int)__s[5]) == 0x1396; bVar24 = ((int)__s[0x28] - (int)__s[0x12]) - (int)__s[2] == -0x53; bVar25 = (int)__s[0x18] * (int)__s[9] + ((int)__s[0xb] - (int)__s[0x1f]) == 0x2782; bVar26 = ((int)__s[0x1c] + (int)__s[0x1e]) - (int)__s[0x10] * (int)__s[3] == -0x198f; bVar27 = (int)__s[0x19] * (int)__s[0x12] - (int)__s[0xb] == 0x16c4; bVar28 = (int)__s[0xb] * (int)__s[9] * (int)__s[8] == 0x109de8; bVar29 = (int)__s[0x19] * (int)__s[3] - (int)__s[6] * (int)__s[0x1d] == 0x8ee; bVar30 = (int)__s[0x24] - (int)__s[0x21] * (int)__s[7] == -0xe3a; bVar31 = (int)__s[0x14] + ((int)__s[0x20] - (int)__s[1]) == 0x49; bVar32 = (int)__s[4] * (int)__s[5] + (int)__s[0x27] == 0x2073; bVar33 = (int)__s[8] * (int)__s[0x27] * (int)*__s == 0x7dd84; bVar34 = (int)__s[0x1f] + ((int)__s[0xc] - (int)__s[0xd]) == 0x19; bVar35 = (int)__s[0x29] + (int)__s[0x29] + (int)__s[10] + (int)__s[0x12] == 0x15f; bVar36 = (int)__s[0x16] + (int)__s[1] * (int)__s[0xe] + (int)__s[7] == 0x1dc8; bVar37 = (int)__s[0xe] + (int)__s[0x12] * (int)__s[0x18] + (int)__s[0x1b] == 0x157c; bVar38 = (int)__s[0x12] + ((int)__s[0x14] - (int)__s[6] * (int)__s[0x29]) == -0x16dd; bVar39 = ((int)__s[0x21] - (int)__s[2]) - (int)__s[0x1f] * (int)__s[0x19] == -0x2571; bVar40 = (int)__s[0x25] * (int)__s[0xb] * (int)__s[0x12] == 0x56540; bVar41 = ((int)__s[7] + (int)__s[8] + (int)__s[0x11]) - (int)__s[0x27] == 0xc0; bVar42 = ((int)__s[0xb] - (int)__s[0x23]) - (int)__s[0x1f] * (int)__s[9] == -0x205d; bVar43 = (int)__s[0x27] + ((int)__s[0x17] - (int)__s[0x1d]) == 0x28; bVar44 = (int)__s[0x14] * (int)__s[0x19] * (int)__s[10] + (int)__s[0x1c] == 0x81959; bVar45 = (int)__s[3] * (int)__s[0x1d] * (int)__s[0x20] == 0x7142a; bVar46 = (int)__s[0x1e] + ((int)__s[0x20] - (int)__s[0x16]) == 0x62; bVar47 = (((int)*__s - (int)__s[0xd]) + (int)__s[0x28]) - (int)__s[0x26] == -0x4a; bVar48 = ((int)__s[0x15] + (int)__s[0x11]) - (int)__s[0x26] == 0x6c; bVar49 = (int)*__s - (int)__s[0x17] * (int)__s[0x29] == -0x2e1c; bVar50 = (int)__s[0x1b] * (int)__s[0x1d] * (int)__s[2] == 0xf390d; bVar51 = (int)__s[0x19] - (int)__s[0x23] * (int)__s[0x13] == -0x1d34; bVar52 = (int)__s[0x10] - (int)__s[7] * (int)__s[0x13] == -0x14af; bVar53 = (int)__s[0x16] + (int)__s[0x21] + (int)__s[0x1a] * (int)__s[0xc] == 0xaa8; bVar54 = (int)__s[0x20] + (int)__s[0x18] + (int)__s[0x29] == 0x119; bVar55 = (int)__s[0xe] * (int)__s[0x1f] * (int)__s[0x17] == 0xc0e04; bVar56 = ((int)__s[0x23] - (int)__s[6] * (int)__s[0x23]) - (int)__s[0xe] == -0xd0e; bVar57 = ((int)__s[0x1f] + (int)__s[0x28]) - (int)__s[0x19] * (int)__s[0x11] == -0x2b8c; bVar58 = (int)__s[0x13] * (int)__s[0xd] + (int)__s[0x12] * (int)__s[0x24] == 0x3fec; bVar59 = (int)__s[0x12] * (int)__s[2] + ((int)__s[0x28] - (int)__s[5]) == 0x1137; bVar60 = (int)__s[3] + ((int)__s[0x15] - (int)__s[0x19]) == 0x37; bVar61 = ((int)__s[0xd] + (int)__s[0xe] + (int)__s[0xe]) - (int)__s[2] == 0xdf; bVar62 = (int)__s[0x23] * (int)__s[0x24] - (int)__s[0x1d] * (int)__s[5] == -0x991; bVar63 = (int)__s[1] + ((int)__s[0x29] - (int)__s[0x27]) == 0x87; bVar64 = (int)*__s + ((int)__s[0x23] - (int)__s[0x23] * (int)*__s) == -0x1297; bVar65 = ((int)__s[8] - (int)__s[0x15] * (int)__s[10]) - (int)__s[0x1f] == -0x12a8; bVar66 = (int)__s[0x1c] + ((int)__s[0x1d] - (int)__s[0x18]) == 0x7e; bVar67 = ((int)__s[10] * (int)*__s - (int)__s[0x20]) - (int)__s[8] == 0xcf3; bVar68 = (int)__s[0x29] + (int)__s[0x20] * (int)__s[0x1c] == 0x170f; bVar69 = (int)__s[0x20] + ((int)__s[0x25] - (int)__s[0x18]) == 0x14; bVar70 = (int)__s[0x1f] + ((int)__s[10] * (int)__s[0x14] - (int)__s[0xf]) == 0x1250; bVar71 = ((int)__s[0x24] - (int)__s[9]) - (int)__s[0x12] * (int)__s[0x12] == -0xaa1; bVar72 = (int)__s[0x1e] * (int)__s[0x10] + (int)__s[7] * (int)__s[9] == 0x3634; bVar73 = ((int)__s[0x18] + (int)__s[0x22] + (int)__s[0x12]) - (int)__s[7] == 0xbc; bVar74 = (int)__s[0x14] + (int)__s[0x1b] * (int)__s[0x10] == 0x245e; bVar75 = (((int)__s[0x16] - (int)__s[0x1e]) - (int)__s[0x25]) - (int)__s[9] == -0xd3; bVar76 = (int)__s[0x1b] * (int)__s[0x29] * (int)__s[4] - (int)__s[0x26] == 0x16c156; bVar77 = (int)__s[0xd] + ((int)__s[0x23] - (int)__s[8] * (int)__s[0x1d]) == -0x334b; bVar78 = (((int)__s[0x17] - (int)__s[7]) - (int)__s[0x18]) - (int)__s[0x16] == -0x6b; bVar79 = (int)__s[5] * (int)__s[4] * (int)__s[0x25] == 0x88d04; bVar80 = (int)__s[0x20] * (int)__s[0x11] - (int)__s[0xf] == 0x14af; bVar81 = ((int)__s[0x20] + (int)__s[0x12] * (int)__s[0x17]) - (int)__s[5] == 0x133f; bVar82 = (int)__s[0x27] + (int)__s[3] + (int)__s[0x27] * (int)__s[8] == 0x1ce5; bVar83 = (int)__s[0x24] + ((int)__s[0x19] * (int)__s[7] - (int)__s[3]) == 0x15dd; bVar84 = ((int)__s[9] - (int)__s[0x18]) - (int)__s[0x21] == -0x4f; bVar85 = (int)__s[0x24] * (int)__s[0xe] + (int)__s[0x1e] == 0x2015; if (bVar85 && (bVar84 && (bVar83 && (bVar82 && (bVar81 && (bVar80 && (bVar79 && (bVar78 && (bVar77 && (bVar76 && (bVar75 && (bVar74 && (bVar73 && (bVar72 && (bVar71 && (bVar70 && (bVar69 && (bVar68 && (bVar67 && (bVar66 && (bVar65 && (bVar64 && (bVar63 && (bVar62 && (bVar61 && (bVar60 && (bVar59 && (bVar58 && (bVar57 && (bVar56 && (bVar55 && (bVar54 && (bVar53 && (bVar52 && (bVar51 && (bVar50 && (bVar49 && (bVar48 && (bVar47 && (bVar46 && (bVar45 && (bVar44 && (bVar43 && (bVar42 && (bVar41 && (bVar40 && (bVar39 && (bVar38 && (bVar37 && (bVar36 && (bVar35 && (bVar34 && (bVar33 && (bVar32 && (bVar31 && (bVar30 && (bVar29 && (bVar28 && (bVar27 && (bVar26 && (__s[0x29] == '}' && (bVar25 && (bVar24 && (bVar23 && (bVar22 && (bVar21 && (bVar20 && (bVar19 && (bVar18 && (bVar17 && (bVar16 && (bVar15 && (bVar14 && (bVar13 && (bVar12 && (bVar11 && (bVar10 && (bVar9 && (bVar8 && (bVar7 && (bVar6 && (bVar5 && (bVar4 && bVar3))))))))))))))) )))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { puts(":) CORRECT!"); uVar1 = 0; } else if (bVar85 && (bVar84 && (bVar83 && (bVar82 && (bVar81 && (bVar80 && (bVar79 && (bVar78 && (bVar77 && (bVar76 && (bVar75 && (bVar74 && (bVar73 && (bVar72 && (bVar71 && (bVar70 && (bVar69 && (bVar68 && (bVar67 && (bVar66 && (bVar65 && (bVar64 && (bVar63 && (bVar62 && (bVar61 && (bVar60 && (bVar59 && (bVar58 && (bVar57 && (bVar56 && (bVar55 && (bVar54 && (bVar53 && (bVar52 && (bVar51 && (bVar50 && (bVar49 && (bVar48 && (bVar47 && (bVar46 && (bVar45 && (bVar44 && (bVar43 && (bVar42 && (bVar41 && (bVar40 && (bVar39 && (bVar38 && (bVar37 && (bVar36 && (bVar35 && (bVar34 && (bVar33 && (bVar32 && (bVar31 && (bVar30 && (bVar29 && (bVar28 && (bVar27 && (bVar26 && (__s[0x29] == '}' && (bVar25 && (bVar24 && (bVar23 && (bVar22 && (bVar21 && (bVar20 && (bVar19 && (bVar18 && (bVar17 && (bVar16 && (bVar15 && (bVar14 && (bVar13 && (bVar12 && (bVar11 && (bVar10 && (bVar9 && (bVar8 && (bVar7 && (bVar6 && (bVar5 && (bVar4 && bVar3)))))))))) ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) { uVar1 = 0; } else { puts(";( INCORRECT"); uVar1 = 0; } } else { puts(";( INCORRECT"); uVar1 = 0xffffffff; } } else { puts("Usage: ./binary <key>"); uVar1 = 0xffffffff; } return uVar1; }
":) CORRECT!"になる条件を使って、z3で解く。
from z3 import * x = [BitVec('x%d' % i, 8) for i in range(42)] s = Solver() s.add(x[8] + x[0xd] + x[7] == 0x10d) s.add(x[0] + (x[0] - x[1]) + x[0xe] == 0xa5) s.add(x[0x26] + x[0x15] * x[0x10] + x[0x22] == 0x250a) s.add(x[0x17] + x[0x29] + x[6] * x[8] == 0x157c) s.add(-x[0x15] - x[0x29] == -0xdf) s.add(x[0x13] + x[0x12] * x[4] * x[0xb] == 0x9c2de) s.add(x[0x22] * x[0x21] + x[0x17] == 0x1903) s.add(x[0xe] * x[0x12] - x[0x21] == 0x13d0) s.add(((x[0x18] - x[0x27]) - x[0x1e]) - x[0x16] == -0x6e) s.add(x[1] + ((x[0x1e] + x[10]) - x[0x13]) == 0x6e) s.add((x[0xf] - x[0x14]) - x[0x29] == -0xa9) s.add(x[0x23] * x[0xf] - x[8] * x[0x29] == -0x27f7) s.add((x[0xb] * x[0x1f] + x[0x24]) - x[0x20] == 0x20ec) s.add(x[0x28] + x[0x19] + x[0x1d] == 0x121) s.add(x[0x18] + (x[7] - x[0xc]) == 100) s.add(x[0x1e] * x[0x15] - x[6] == 0x242e) s.add(x[3] * x[0x21] * x[0x26] == 0x753f4) s.add((x[0x14] - x[0] * x[0x1f]) - x[2] == -0x1742) s.add(x[0x15] * x[0xc] + x[0x1b] == 0x13e7) s.add((x[6] + x[8] * x[0xb]) - x[8] == 0x2aba) s.add(x[0x18] * x[7] + (x[0x22] - x[5]) == 0x1396) s.add((x[0x28] - x[0x12]) - x[2] == -0x53) s.add(x[0x18] * x[9] + (x[0xb] - x[0x1f]) == 0x2782) s.add((x[0x1c] + x[0x1e]) - x[0x10] * x[3] == -0x198f) s.add(x[0x19] * x[0x12] - x[0xb] == 0x16c4) s.add(x[0xb] * x[9] * x[8] == 0x109de8) s.add(x[0x19] * x[3] - x[6] * x[0x1d] == 0x8ee) s.add(x[0x24] - x[0x21] * x[7] == -0xe3a) s.add(x[0x14] + (x[0x20] - x[1]) == 0x49) s.add(x[4] * x[5] + x[0x27] == 0x2073) s.add(x[8] * x[0x27] * x[0] == 0x7dd84) s.add(x[0x1f] + (x[0xc] - x[0xd]) == 0x19) s.add(x[0x29] + x[0x29] + x[10] + x[0x12] == 0x15f) s.add(x[0x16] + x[1] * x[0xe] + x[7] == 0x1dc8) s.add(x[0xe] + x[0x12] * x[0x18] + x[0x1b] == 0x157c) s.add(x[0x12] + (x[0x14] - x[6] * x[0x29]) == -0x16dd) s.add((x[0x21] - x[2]) - x[0x1f] * x[0x19] == -0x2571) s.add(x[0x25] * x[0xb] * x[0x12] == 0x56540) s.add((x[7] + x[8] + x[0x11]) - x[0x27] == 0xc0) s.add((x[0xb] - x[0x23]) - x[0x1f] * x[9] == -0x205d) s.add(x[0x27] + (x[0x17] - x[0x1d]) == 0x28) s.add(x[0x14] * x[0x19] * x[10] + x[0x1c] == 0x81959) s.add(x[3] * x[0x1d] * x[0x20] == 0x7142a) s.add(x[0x1e] + (x[0x20] - x[0x16]) == 0x62) s.add(((x[0] - x[0xd]) + x[0x28]) - x[0x26] == -0x4a) s.add((x[0x15] + x[0x11]) - x[0x26] == 0x6c) s.add(x[0] - x[0x17] * x[0x29] == -0x2e1c) s.add(x[0x1b] * x[0x1d] * x[2] == 0xf390d) s.add(x[0x19] - x[0x23] * x[0x13] == -0x1d34) s.add(x[0x10] - x[7] * x[0x13] == -0x14af) s.add(x[0x16] + x[0x21] + x[0x1a] * x[0xc] == 0xaa8) s.add(x[0x20] + x[0x18] + x[0x29] == 0x119) s.add(x[0xe] * x[0x1f] * x[0x17] == 0xc0e04) s.add((x[0x23] - x[6] * x[0x23]) - x[0xe] == -0xd0e) s.add((x[0x1f] + x[0x28]) - x[0x19] * x[0x11] == -0x2b8c) s.add(x[0x13] * x[0xd] + x[0x12] * x[0x24] == 0x3fec) s.add(x[0x12] * x[2] + (x[0x28] - x[5]) == 0x1137) s.add(x[3] + (x[0x15] - x[0x19]) == 0x37) s.add((x[0xd] + x[0xe] + x[0xe]) - x[2] == 0xdf) s.add(x[0x23] * x[0x24] - x[0x1d] * x[5] == -0x991) s.add(x[1] + (x[0x29] - x[0x27]) == 0x87) s.add(x[0] + (x[0x23] - x[0x23] * x[0]) == -0x1297) s.add((x[8] - x[0x15] * x[10]) - x[0x1f] == -0x12a8) s.add(x[0x1c] + (x[0x1d] - x[0x18]) == 0x7e) s.add((x[10] * x[0] - x[0x20]) - x[8] == 0xcf3) s.add(x[0x29] + x[0x20] * x[0x1c] == 0x170f) s.add(x[0x20] + (x[0x25] - x[0x18]) == 0x14) s.add(x[0x1f] + (x[10] * x[0x14] - x[0xf]) == 0x1250) s.add((x[0x24] - x[9]) - x[0x12] * x[0x12] == -0xaa1) s.add(x[0x1e] * x[0x10] + x[7] * x[9] == 0x3634) s.add((x[0x18] + x[0x22] + x[0x12]) - x[7] == 0xbc) s.add(x[0x14] + x[0x1b] * x[0x10] == 0x245e) s.add(((x[0x16] - x[0x1e]) - x[0x25]) - x[9] == -0xd3) s.add(x[0x1b] * x[0x29] * x[4] - x[0x26] == 0x16c156) s.add(x[0xd] + (x[0x23] - x[8] * x[0x1d]) == -0x334b) s.add(((x[0x17] - x[7]) - x[0x18]) - x[0x16] == -0x6b) s.add(x[5] * x[4] * x[0x25] == 0x88d04) s.add(x[0x20] * x[0x11] - x[0xf] == 0x14af) s.add((x[0x20] + x[0x12] * x[0x17]) - x[5] == 0x133f) s.add(x[0x27] + x[3] + x[0x27] * x[8] == 0x1ce5) s.add(x[0x24] + (x[0x19] * x[7] - x[3]) == 0x15dd) s.add((x[9] - x[0x18]) - x[0x21] == -0x4f) s.add(x[0x24] * x[0xe] + x[0x1e] == 0x2015) s.add(x[0x29] == ord('}')) r = s.check() assert r == sat m = s.model() flag = '' for i in range(42): flag += chr(m[x[i]].as_long()) print flag
GLUG{C01nc1d3nc3_c4n_b3_fr3aky_T6LSERDYB6}
bijective (Rev)
pycをデコンパイルする。
$ uncompyle6 chall.pyc # uncompyle6 version 3.8.0 # Python bytecode 3.8.0 (3413) # Decompiled from: Python 3.6.9 (default, Dec 8 2021, 21:08:43) # [GCC 8.4.0] # Embedded file name: /home/error/Desktop/Question/chall.py # Compiled at: 2022-03-04 21:59:24 # Size of source mod 2**32: 357 bytes from secret import flag s = 'aabacadaeafagaha' characters = 'abcdefghijklmnopqrstuvwxyz1234567890{}_' def encode(ch): i = characters.index(ch) return s[i // 3:i // 3 + i % 3 + 2] enc = '' for ch in flag: enc += encode(ch) else: print(enc) # okay decompiling chall.pyc
1文字ずつ暗号化しているので、ブルートフォースで復号する。ただし複数候補があるので、全リストを出し、手動で復号していく。
#!/usr/bin/env python3 s = 'aabacadaeafagaha' characters = 'abcdefghijklmnopqrstuvwxyz1234567890{}_' def encode(ch): i = characters.index(ch) return s[i // 3:i // 3 + i % 3 + 2] with open('output.txt', 'r') as f: enc = f.read() for ch in characters: print(ch, '->', encode(ch))
実行結果は以下の通り。
a -> aa b -> aab c -> aaba d -> ab e -> aba f -> abac g -> ba h -> bac i -> baca j -> ac k -> aca l -> acad m -> ca n -> cad o -> cada p -> ad q -> ada r -> adae s -> da t -> dae u -> daea v -> ae w -> aea x -> aeaf y -> ea z -> eaf 1 -> eafa 2 -> af 3 -> afa 4 -> afag 5 -> fa 6 -> fag 7 -> faga 8 -> ag 9 -> aga 0 -> agah { -> ga } -> gah _ -> gaha
以上を元に復号する。
baacaddaeabagacaafagcadeagahadaeagahgahaagahcadabagah g l u g { m 4 n y _ t 0 _ 0 n e }
glug{m4ny_t0_0ne}
Daredevil's server (Crypto)
$ nc chall.nitdgplug.org 30093 WELCOME TO DAREDEVIL'S SIGNING SERVER... AVAILABLE OPTIONS ! [E]ncryption function [P]ublic key [S]ign msg (hex)! [V]erify signature (hex)! [Q]uit > E TOKEN = b'd4r3d3v!l' def chall(): s = Sign() while True: choice = input("> ").rstrip() if choice == 'P': print("\nN : {}".format(hex(s.n))) print("\ne : {}".format(hex(s.e))) elif choice == 'S': try: msg = bytes.fromhex(input('msg to sign : ')) if TOKEN in msg: print('[!] NOT ALLOWED') else: m = bytes_to_long(msg) print("\nsignature : {}".format(hex(s.sign(m)))) #pow(msg,d,n) print('\n') except: print('\n[!] ERROR (invalid input)') elif choice == 'V': try: msg = bytes.fromhex(input("msg : ")) m = bytes_to_long(msg) signature = int(input("signature : "),16) if m < 0 or m > s.n: print('[!] ERROR') if s.verify(m, signature): #pow(sign, e, n) == msg if long_to_bytes(m) == TOKEN: print(SECRET) else: print('\n[+] Valid signature') else: print('\n[!]Invalid signature') except: print('\n[!] ERROR(invalid input)') elif choice == 'Q': print('OK BYE :)') exit(0) else: print('\n[*] SEE OPTIONS') > P N : 0xb56c516e9ba02ad85161943475f451736d7c6669ea368631f965ed02d1a55051b06226104489296a65317b7e6b3fe0988f5f83d128d0932731dc37fd362360614165a01ceebdab72094135928429bb0f79265ae74a7528b06fe7f912f68bc8d27966fcbdc427fd672ec2d6386490a570010de71510cd0d552c9ab47d20bc1d4f e : 0x10001 > S msg to sign : 1234 signature : 0xac3af3667f9ddb5638012dc80cc2c230efd402729f204960cf6bdb45a5d0e1152d714914355e7f53a66ac823925d57d654d6c03140f71382b645a26ea3a87357bb668449f6b72b1c19d88380323462f8127790c14f80d7ad492daa54f7f0a5dd432c8faed85bbc0d74e411d3c4f10485ba4b83ad01bc37a6a7ed23724622d5d > V msg : 1234 signature : 0xac3af3667f9ddb5638012dc80cc2c230efd402729f204960cf6bdb45a5d0e1152d714914355e7f53a66ac823925d57d654d6c03140f71382b645a26ea3a87357bb668449f6b72b1c19d88380323462f8127790c14f80d7ad492daa54f7f0a5dd432c8faed85bbc0d74e411d3c4f10485ba4b83ad01bc37a6a7ed23724622d5d [+] Valid signature >
以下が指定できれば、フラグが表示される。
msg: "d4r3d3v!l"の16進数 signature: d4r3d3v!lを数値化したものの復号データ(pow(bytes_to_long("d4r3d3v!l"), d, N))
bytes_to_long("d4r3d3v!l")は偶数なので、2*Aと表せる。
pow(bytes_to_long("d4r3d3v!l"), d, N) = (pow(2, d, N) * pow(A, d, N)) % N
以上のことを使って、条件を満たす情報を指定し、フラグを取得する。
import socket from Crypto.Util.number import * def recvuntil(s, tail): data = b'' while True: if tail in data: return data.decode() data += s.recv(1) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('chall.nitdgplug.org', 30093)) data = recvuntil(s, b'\n> ') print(data + 'E') s.sendall(b'E\n') data = recvuntil(s, b'\n> ') print(data + 'P') s.sendall(b'P\n') data = recvuntil(s, b'\n> ') print(data + 'S') s.sendall(b'S\n') N = int(data.split('\n')[1].split(' ')[-1], 16) e = int(data.split('\n')[3].split(' ')[-1], 16) TOKEN = b'd4r3d3v!l' c = bytes_to_long(TOKEN) assert c % 2 == 0 c1 = long_to_bytes(2).hex() c2 = long_to_bytes(c // 2).hex() data = recvuntil(s, b': ') print(data + c1) s.sendall(c1.encode() + b'\n') data = recvuntil(s, b'\n').rstrip() print(data) data = recvuntil(s, b'\n').rstrip() print(data) sig1 = int(data.split(' ')[-1], 16) data = recvuntil(s, b'\n> ') print(data + 'S') s.sendall(b'S\n') data = recvuntil(s, b': ') print(data + c2) s.sendall(c2.encode() + b'\n') data = recvuntil(s, b'\n').rstrip() print(data) data = recvuntil(s, b'\n').rstrip() print(data) sig2 = int(data.split(' ')[-1], 16) sig = (sig1 * sig2) % N data = recvuntil(s, b'\n> ') print(data + 'V') s.sendall(b'V\n') data = recvuntil(s, b': ') print(data + TOKEN.hex()) s.sendall(TOKEN.hex().encode() + b'\n') data = recvuntil(s, b': ') print(data + hex(sig)) s.sendall(hex(sig).encode() + b'\n') data = recvuntil(s, b'\n').rstrip() print(data) data = recvuntil(s, b'\n').rstrip() print(data)
実行結果は以下の通り。
WELCOME TO DAREDEVIL'S SIGNING SERVER... AVAILABLE OPTIONS ! [E]ncryption function [P]ublic key [S]ign msg (hex)! [V]erify signature (hex)! [Q]uit > E TOKEN = b'd4r3d3v!l' def chall(): s = Sign() while True: choice = input("> ").rstrip() if choice == 'P': print("\nN : {}".format(hex(s.n))) print("\ne : {}".format(hex(s.e))) elif choice == 'S': try: msg = bytes.fromhex(input('msg to sign : ')) if TOKEN in msg: print('[!] NOT ALLOWED') else: m = bytes_to_long(msg) print("\nsignature : {}".format(hex(s.sign(m)))) #pow(msg,d,n) print('\n') except: print('\n[!] ERROR (invalid input)') elif choice == 'V': try: msg = bytes.fromhex(input("msg : ")) m = bytes_to_long(msg) signature = int(input("signature : "),16) if m < 0 or m > s.n: print('[!] ERROR') if s.verify(m, signature): #pow(sign, e, n) == msg if long_to_bytes(m) == TOKEN: print(SECRET) else: print('\n[+] Valid signature') else: print('\n[!]Invalid signature') except: print('\n[!] ERROR(invalid input)') elif choice == 'Q': print('OK BYE :)') exit(0) else: print('\n[*] SEE OPTIONS') > P N : 0x86dfe4de8bd59d225a26a72eae28e79e8b43f7db623ed0095f22171ce5ba1fd4817e42d8f1cf1cd39e6f96d56ff6db276aff83fa6f5d8299b64b3d51bba61775a98d0c371c7b919ca6528492cfa10bbfb3ed1a173f562ecc6736bae32d8da5345aa68290d0a120985471d184301a38f64cd11a6c102f2cd0d81a57781cfb76e3 e : 0x10001 > S msg to sign : 02 signature : 0x79e13f957788cc876473d71d6804c330bf38046b216ed1b9468134be341feee03a3881b64292d2877f83ae9e85b4dfeb0f16efbdd32ee365d531ebf3069d5d352b6ded7269b57a7c2bcef8cbc7a932c56f4d9d522262d214b22351a2c9e92a1bd79e7770b61bd4debc35905dbabc648a60a115fa18d5409f73bbaad8591bdecd > S msg to sign : 321a3919b219bb10b6 signature : 0x12e7f43bdabb9f82c9401dd76c101d32504cb487988ebbee742f6c4e3880c284263a57158fdd927e9fa114b6270d9d5c41abc1ee19a214ace503ee43d791d1ea889e6ba86e39978508857c82b8f10b8559033ba8a774185d1afee632d74bb025e6544f00493d4152b6d5c3a7cea3cf28352fe2bd59cd6c4c0ecda731968e550b > V msg : 64347233643376216c signature : 0x23a7526933625deb7ef10f119a23ea077dfb91a1e7af5e52eda2fd678a755fbbae93b1cbab6adaa3b0524aa1104b4fc597426daed70b387ffe0999b82881ef59b98dc30b1803b6867f425befb5030f2648e497b8fbd71c5197003195b946624f1214f4b719132706ef0cefaedd2e2e90946faa131c8e4f1fcdd372a2dffa89a4 GLUG{fl4g_15_53rv3d_xD_E9644V2GG0}
GLUG{fl4g_15_53rv3d_xD_E9644V2GG0}