2025第九届御网杯半决赛Crypto–wp
本文最后更新于38 天前,其中的信息可能已经过时,如有错误请发送邮件到1416359402@qq.com

YWB_Crypto_02

题目描述:

CTF赛题的解一般以flag为开头,已知字符串“a3FmbHs4Mjlfb244N184OHVwfQ==”,请给出对应的flag值。

一眼base64直接随波逐流解码就行

kqfl{829_on87_88up}

凯撒密码解密:

flag{829_ji87_88pk}

YWB_Crypto_01

题目描述:

小明在做中间人攻击时,截取了这样一段信息传输内容“4WC2ZZVNUPSYLLHGVWR6LBNM42W2HZMPRPSZNBHFQWWONLND4WC2ZZVNUPTLBEPEXC56LBNM42W2HZVTSXTLFO7GWOK6NMV35CXZVZF7UHTLBEPEXC56LBNM42W2HZMSRTULBEHFQWWONLND42K2ZZFYTLTLHFPGWK56LEUM5CYJBZVTSXTLFO7FV6GOLPF24W43HZ5NRHSY7C7FS2CONFNM4S4JVZMFVTTK3I7FR6F6LFUE46ELDZM3XXSYLLHGVWR6NFNM4S4JVZVTSXTLFO7FSKGORMEQ42ZZLZVSXPS27DHFXS5OLONT46WYTZMPRPSZNBHGSWWOJOE24WJIZ2FQSDTLBEPEXC56LEUM5CYJBZUWQ7TJRDXFSKGORMEQ4WJIZ2FQSDTLHFPGWK56RL424S72DZMSRTULBEA=” 请帮你他解开谜底吧。        

base32解码:

公正公正公正友善公正公正民主公正法治法治诚信民主公正和谐公正敬业法治和谐法治富强平等友善敬业公正友善爱国公正敬业法治和谐法治富强平等友善敬业和谐民主和谐文明和谐和谐法治诚信和谐

社会主义核心价值观解码:

flag{cisp_nisp_123}

Find_flag

题目原题:

题目源码

index.html:

<html>
    <head>
        <title>Find_flag</title>
        <style type="text/css">
            body {
                padding-left: 30%;
            }

            #flag {
                font-family: Garamond, serif;
                font-size: 36px;
            }

            #flagtitle {
                font-family: Garamond, serif;
                font-size: 24px;
            }

            .rightflag {
                color: green;
            }

            .wrongflag {
                color: red;
            }
        </style>
        <script src="script-min.js"></script>
        <script type="text/javascript">
            var ic = false;
            var fg = "";

            function getFlag() {
                var token = document.getElementById("secToken").value;
                ic = checkToken(token);
                fg = bm(token);
                showFlag()
            }

            function showFlag() {
                var t = document.getElementById("flagTitle");
                var f = document.getElementById("flag");
                t.innerText = !!ic ? "You got the flag below!!" : "Wrong!";
                t.className = !!ic ? "rightflag" : "wrongflag";
                f.innerText = fg;
            }
        </script>
    </head>
    <body>
        <h1>Find_flag</h1>
        <p>Type in some token to get the flag.</p>
        <p>Tips:Find_flag</p>
        <div>
            <p>
                <span>Token:</span>
                <span><input type="text" id="secToken"/></span>
            </p>
            <p>
                <input type="button" value="Get flag!" onclick="getFlag()" />
            </p>
        </div>
        <div>
            <p id="flagTitle"></p>
            <p id="flag"></p>
        </div>
    </body>
</html>

script-min.js:

function hm(s) {
    return rh(rstr(str2rstr_utf8(s)));
}
function bm(s) {
    return rb(rstr(str2rstr_utf8(s)));
}
function rstr(s) {
    return binl2rstr(binl(rstr2binl(s), s.length * 8));
}
function checkToken(s) {
    return s === "FAKE-TOKEN";
}
function rh(ip) {
    try {
        hc
    } catch (e) {
        hc = 0;
    }
    var ht = hc ? "0123456789ABCDEF" : "0123456789abcdef";
    var op = "";
    var x;
    for (var i = 0; i < ip.length; i++) {
        x = ip.charCodeAt(i);
        op += ht.charAt((x >>> 4) & 0x0F) + ht.charAt(x & 0x0F);
    }
    return op;
}
function rb(ip) {
    try {
        bp
    } catch (e) {
        bp = '';
    }
    var b = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    var op = "";
    var len = ip.length;
    for (var i = 0; i < len; i += 3) {
        var t = (ip.charCodeAt(i) << 16) | (i + 1 < len ? ip.charCodeAt(i + 1) << 8 : 0) | (i + 2 < len ? ip.charCodeAt(i + 2) : 0);
        for (var j = 0; j < 4; j++) {
            if (i * 8 + j * 6 > ip.length * 8)
                op += bp;
            else
                op += b.charAt((t >>> 6 * (3 - j)) & 0x3F);
        }
    }
    return op;
}
function ck(s) {
    try {
        ic
    } catch (e) {
        return;
    }
    var a = [105, 104, 102, 120, 117, 108, 48, 75, 81,70,87,73];
    if (s.length == a.length) {
        for (i = 0; i < s.length; i++) {
            if (a[i] - s.charCodeAt(i) != 3)
                return ic = false;
        }
        return ic = true;
    }
    return ic = false;
}
function str2rstr_utf8(input) {
    var output = "";
    var i = -1;
    var x, y;
    while (++i < input.length) {
        x = input.charCodeAt(i);
        y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
        if (0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF) {
            x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
            i++;
        }
        if (x <= 0x7F)
            output += String.fromCharCode(x);
        else if (x <= 0x7FF)
            output += String.fromCharCode(0xC0 | ((x >>> 6) & 0x1F), 0x80 | (x & 0x3F));
        else if (x <= 0xFFFF)
            output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F), 0x80 | ((x >>> 6) & 0x3F), 0x80 | (x & 0x3F));
        else if (x <= 0x1FFFFF)
            output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07), 0x80 | ((x >>> 12) & 0x3F), 0x80 | ((x >>> 6) & 0x3F), 0x80 | (x & 0x3F));
    }
    return output;
}
function rstr2binl(input) {
    var output = Array(input.length >> 2);
    for (var i = 0; i < output.length; i++)
        output[i] = 0;
    for (var i = 0; i < input.length * 8; i += 8)
        output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (i % 32);
    return output;
}
function binl2rstr(i) {
    var o = "";
    for (var j = 0; j < i.length * 32; j += 8)
        o += String.fromCharCode((i[j >> 5] >>> (j % 32)) & 0xFF);
    return o;
}
function binl(x, len) {
    s = binl2rstr(x);
    x[len >> 5] |= 0x80 << ((len) % 32);
    x[(((len + 64) >>> 9) << 4) + 14] = len;
    var a = 1732584193;
    var b = -271733879;
    var c = -1732584194;
    var d = 271733878;
    for (var i = 0; i < x.length; i += 16) {
        var olda = a;
        var oldb = b;
        var oldc = c;
        var oldd = d;
        a = ff(a, b, c, d, x[i + 0], 7, -680876936);
        d = ff(d, a, b, c, x[i + 1], 12, -389564586);
        c = ff(c, d, a, b, x[i + 2], 17, 606105819);
        b = ff(b, c, d, a, x[i + 3], 22, -1044525330);
        a = ff(a, b, c, d, x[i + 4], 7, -176418897);
        d = ff(d, a, b, c, x[i + 5], 12, 1200080426);
        c = ff(c, d, a, b, x[i + 6], 17, -1473231341);
        b = ff(b, c, d, a, x[i + 7], 22, -45705983);
        a = ff(a, b, c, d, x[i + 8], 7, 1770035416);
        d = ff(d, a, b, c, x[i + 9], 12, -1958414417);
        c = ff(c, d, a, b, x[i + 10], 17, -42063);
        b = ff(b, c, d, a, x[i + 11], 22, -1990404162);
        a = ff(a, b, c, d, x[i + 12], 7, 1804603682);
        d = ff(d, a, b, c, x[i + 13], 12, -40341101);
        c = ff(c, d, a, b, x[i + 14], 17, -1502002290);
        b = ff(b, c, d, a, x[i + 15], 22, 1236535329);
        ck(s);
        a = gg(a, b, c, d, x[i + 1], 5, -165796510);
        d = gg(d, a, b, c, x[i + 6], 9, -1069501632);
        c = gg(c, d, a, b, x[i + 11], 14, 643717713);
        b = gg(b, c, d, a, x[i + 0], 20, -373897302);
        a = gg(a, b, c, d, x[i + 5], 5, -701558691);
        d = gg(d, a, b, c, x[i + 10], 9, 38016083);
        c = gg(c, d, a, b, x[i + 15], 14, -660478335);
        b = gg(b, c, d, a, x[i + 4], 20, -405537848);
        a = gg(a, b, c, d, x[i + 9], 5, 568446438);
        d = gg(d, a, b, c, x[i + 14], 9, -1019803690);
        c = gg(c, d, a, b, x[i + 3], 14, -187363961);
        b = gg(b, c, d, a, x[i + 8], 20, 1163531501);
        a = gg(a, b, c, d, x[i + 13], 5, -1444681467);
        d = gg(d, a, b, c, x[i + 2], 9, -51403784);
        c = gg(c, d, a, b, x[i + 7], 14, 1735328473);
        b = gg(b, c, d, a, x[i + 12], 20, -1926607734);
        a = hh(a, b, c, d, x[i + 5], 4, -378558);
        d = hh(d, a, b, c, x[i + 8], 11, -2022574463);
        c = hh(c, d, a, b, x[i + 11], 16, 1839030562);
        b = hh(b, c, d, a, x[i + 14], 23, -35309556);
        a = hh(a, b, c, d, x[i + 1], 4, -1530992060);
        d = hh(d, a, b, c, x[i + 4], 11, 1272893353);
        c = hh(c, d, a, b, x[i + 7], 16, -155497632);
        b = hh(b, c, d, a, x[i + 10], 23, -1094730640);
        a = hh(a, b, c, d, x[i + 13], 4, 681279174);
        d = hh(d, a, b, c, x[i + 0], 11, -358537222);
        c = hh(c, d, a, b, x[i + 3], 16, -722521979);
        b = hh(b, c, d, a, x[i + 6], 23, 76029189);
        a = hh(a, b, c, d, x[i + 9], 4, -640364487);
        d = hh(d, a, b, c, x[i + 12], 11, -421815835);
        c = hh(c, d, a, b, x[i + 15], 16, 530742520);
        b = hh(b, c, d, a, x[i + 2], 23, -995338651);
        a = ii(a, b, c, d, x[i + 0], 6, -198630844);
        d = ii(d, a, b, c, x[i + 7], 10, 1126891415);
        c = ii(c, d, a, b, x[i + 14], 15, -1416354905);
        b = ii(b, c, d, a, x[i + 5], 21, -57434055);
        a = ii(a, b, c, d, x[i + 12], 6, 1700485571);
        d = ii(d, a, b, c, x[i + 3], 10, -1894986606);
        c = ii(c, d, a, b, x[i + 10], 15, -1051523);
        b = ii(b, c, d, a, x[i + 1], 21, -2054922799);
        a = ii(a, b, c, d, x[i + 8], 6, 1873313359);
        d = ii(d, a, b, c, x[i + 15], 10, -30611744);
        c = ii(c, d, a, b, x[i + 6], 15, -1560198380);
        b = ii(b, c, d, a, x[i + 13], 21, 1309151649);
        a = ii(a, b, c, d, x[i + 4], 6, -145523070);
        d = ii(d, a, b, c, x[i + 11], 10, -1120210379);
        c = ii(c, d, a, b, x[i + 2], 15, 718787259);
        b = ii(b, c, d, a, x[i + 9], 21, -343485551);
        a = sa(a, olda);
        b = sa(b, oldb);
        c = sa(c, oldc);
        d = sa(d, oldd);
    }
    return Array(a, b, c, d);
}
function cmn(q, a, b, x, s, t) {
    return sa(br(sa(sa(a, q), sa(x, t)), s), b);
}
function ff(a, b, c, d, x, s, t) {
    return cmn((b & c) | ((~b) & d), a, b, x, s, t);
}
function gg(a, b, c, d, x, s, t) {
    return cmn((b & d) | (c & (~d)), a, b, x, s, t);
}
function hh(a, b, c, d, x, s, t) {
    return cmn(b ^ c ^ d, a, b, x, s, t);
}
function ii(a, b, c, d, x, s, t) {
    return cmn(c ^ (b | (~d)), a, b, x, s, t);
}
function sa(x, y) {
    var lsw = (x & 0xFFFF) + (y & 0xFFFF);
    var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
    return (msw << 16) | (lsw & 0xFFFF);
}
function br(n, c) {
    return (n << c) | (n >>> (32 - c));
}

这道题考察对混淆代码的静态分析能力、密码学直觉(识别减3的简单加密)以及授权绕过思路

方法一对应的解密脚本:

def get_valid_tokens():
    # 从ck函数中提取的编码数组
    encoded = [105, 104, 102, 120, 117, 108, 48, 75, 81, 70, 87, 73]

    # 根据ck函数逻辑解码
    decoded = ''.join([chr(x - 3) for x in encoded])

    # 从checkToken函数获取的硬编码token
    hardcoded_token = "FAKE-TOKEN"

    return {
        "decoded_from_ck": decoded,
        "hardcoded_token": hardcoded_token
    }

def validate_token(token):
    # 模拟原JS中的两个验证函数
    ck_valid = False
    if len(token) == 12:  # 编码数组长度是12
        a = [105, 104, 102, 120, 117, 108, 48, 75, 81, 70, 87, 73]
        valid = True
        for i in range(len(token)):
            if a[i] - ord(token[i]) != 3:
                valid = False
                break
        ck_valid = valid

    check_token_valid = (token == "FAKE-TOKEN")

    return {
        "ck_valid": ck_valid,
        "checkToken_valid": check_token_valid
    }

# 获取所有可能的有效token
tokens = get_valid_tokens()
print("Possible valid tokens:")
print(f"1. From ck function: {tokens['decoded_from_ck']}")
print(f"2. Hardcoded in checkToken: {tokens['hardcoded_token']}")

# 验证这些token
print("nValidation results:")
for name, token in tokens.items():
    results = validate_token(token)
    print(f"nToken: {token}")
    print(f"- ck function valid: {results['ck_valid']}")
    print(f"- checkToken valid: {results['checkToken_valid']}")

代码解释:

分析和验证JavaScript代码中的token验证机制

get_valid_tokens() 函数

  • 从JavaScript的ck()函数中提取硬编码的ASCII值数组
  • 根据ck()函数的验证逻辑解码出可能的有效token
  • 同时获取checkToken()函数中硬编码的token
  1. encoded数组来自JS代码中ck()函数的a数组
  2. 根据ck()函数的检查条件a[i] - s.charCodeAt(i) == 3,可以推导出正确的字符应该是a[i] - 3
  3. 使用列表推导式将每个编码值减3并转换为对应字符
  4. 返回两个可能的有效token:一个是从ck()解码的,一个是checkToken()硬编码的

validate_token() 函数

  • 模拟JavaScript中的两个验证函数ck()checkToken()
  • 检查给定的token是否通过这两个验证
  1. ck_valid初始为False,只有当token满足所有条件时才设为True
  2. 首先检查token长度是否为12(与编码数组长度一致)
  3. 检查每个字符是否满足a[i] - ord(char) == 3的条件
  4. check_token_valid直接比较token是否为”FAKE-TOKEN”
  5. 返回包含两个验证结果的字典

最后:

  • 获取所有可能的有效token
  • 打印这些token
  • 验证每个token在两个验证函数中的有效性
  • 输出验证结果
  1. 调用get_valid_tokens()获取两个token
  2. 打印这两个token
  3. 对每个token调用validate_token()进行验证
  4. 打印每个token的验证结果

对于给定的编码数组[105, 104, 102, 120, 117, 108, 48, 75, 81, 70, 87, 73],解码后的token应该是fecuri-HNCTF(每个数字减3后对应的ASCII字符)

方法二:手动输入

已经知道原理直接手动输入

105, 104, 102, 120, 117, 108, 48, 75, 81,70,87,73 --—>(-3)

102 101 99 117 114 105 45 72 78 67 84 69

转成ASCII码

fecuri-HNCTE
FAKE-TOKEN

然后验证这两个就行

flag{4gl6lDO096EMj1DGCCwOzw}

ez_classical

}MZS0wu4aiwJsREMZS{qmwp

题目说是古典密码

说实话我当时这个我在当时根本解不出来

当时是先把他反转

pwmq{SZMERsJwia4uw0SZM}

然后直接凯撒解码

然后解不出来,当时也想过位移pwmq–>flag

p-f 位移-10,w-l位移-11,m-a位移-12 q-g位移-10 那么就以【-10,-11,-12】的位移排序

代码:

def decrypt_flag(ciphertext: str) -> str:
    """使用自定义映射表解密CTF flag"""
    # 基于 pwmq -> flag 的映射关系,构建完整映射表
    char_mapping = {
        # 基础映射 (p->f, w->l, m->a, q->g)
        'p': 'f', 'w': 'l', 'm': 'a', 'q': 'g',
        # 扩展小写字母映射
        's': 's', 'j': 'h', 'i': 'r', 'a': 'e', 'u': '_', 'e': 'r',
        # 扩展大写字母映射
        'S': 'C', 'Z': 'T', 'M': 'F', 'E': 'A', 'R': 'G', 'J': 'H', 'W': 'E',
        # 数字和特殊字符映射
        '4': '4', '0': '0', '{': '{', '}': '}'
    }

    # 解密过程
    decrypted = []
    for char in ciphertext:
        # 优先使用映射表转换,未知字符保持不变
        decrypted_char = char_mapping.get(char, char)
        # 处理映射表中未定义的字符(保持原始字符)
        decrypted.append(decrypted_char)

    return ''.join(decrypted)

# 待解密的密文
ciphertext = "pwmq{SZMERsJwia4uw0SZM}"

# 执行解密
flag = decrypt_flag(ciphertext)

# 输出结果
print(f"解密后的flag: {flag}")

flag{CTFAGsHlre4_l0CTF}

这个好像已经很像了但是不对

我服了

然后在尝试看看

先解码

发现凯撒10,11,12 很像fla

我们可以通过循环步进为3拼接字符得到flag

手动:

尝试解密整个字符串 pwmq{SZMERsJwia4uw0SZM}

分组:p w m q { S Z M E R s J w i a 4 u w 0 S Z M }

偏移量循环:10, 11, 12, 10, 11, 12, 10, 11, 12, 10, 11, 12, 10, 11, 12, 10, 11, 12, 10, 11, 12

逐字符解密:

  1. p -10 -> f
  2. w -11 -> l
  3. m -12 -> a
  4. q -10 -> g
  5. { -> {(不变)
  6. S -11 -> H
  7. Z -12 -> T
  8. M -10 -> C
  9. E -11 -> T
  10. R -12 -> F
  11. s -10 -> i
  12. J -11 -> Y
  13. w -12 -> k
  14. i -10 -> y
  15. a -11 -> p
  16. 4 -> 4(不变)
  17. u -12 -> i
  18. w -10 -> m
  19. 0 -> 0(不变)
  20. S -11 -> H
  21. Z -12 -> T
  22. M -10 -> C
  23. } -> }(不变)

拼接结果:flag{HTCTFiykyp4im0HTC}

py3代码解码:

def caesar_decrypt(ciphertext, offsets):
    plaintext = []
    offset_index = 0
    for char in ciphertext:
        if char.isalpha():
            # Determine the offset for the current character
            offset = offsets[offset_index % len(offsets)]
            offset_index += 1
            # Decrypt uppercase and lowercase letters
            if char.isupper():
                decrypted_char = chr(((ord(char) - ord('A') - offset) % 26) + ord('A'))
            else:
                decrypted_char = chr(((ord(char) - ord('a') - offset) % 26) + ord('a'))
        else:
            # Leave non-alphabetic characters unchanged
            decrypted_char = char
        plaintext.append(decrypted_char)
    return ''.join(plaintext)

# Encrypted string
ciphertext = "pwmq{SZMERsJwia4uw0SZM}"

# Define the offsets to cycle through (10, 11, 12)
offsets = [10, 11, 12]

# Decrypt the ciphertext
plaintext = caesar_decrypt(ciphertext, offsets)

print("Decrypted text:", plaintext)

flag{HNCTFiYkyp4im0HNC}

答案就是这个

文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇