用结果中的 iv 和 key 的替换掉 encrypt 函数中的随机数。加密的过程很简单。首先是将 flag 分割成了 8 字符一段的 parts 列表,然后对每一个 part 执行 reduce(xor, [part, iv if index == 0 else results[-1], key])——实际上对应的 result 就是 part、上一个结果或 iv 和 key 的异或。
import operatorimport randomimport refrom functools import reduce# from secret import flagdef pad(s): padding_length = (8 - len(s)) % 8 return s + chr(padding_length) * padding_lengthdef xor(a, b): assert len(a) == len(b) return bytes(map(operator.xor, a, b))def encrypt(s): iv = b'\xba=y\xa3\xc6)\xcf\xf7' # bytes(random.randint(0, 255) for _ in range(8)) key = b'}6E\xeb(\x91\x08\xa0' # bytes(random.randint(0, 255) for _ in range(8)) parts = list(map(str.encode, map(pad, re.findall(r'.{1,8}', s)))) print(parts) results = [] for index, part in enumerate(parts): print(index, part) results.append(reduce(xor, [part, iv if index == 0 else results[-1], key])) return iv, key, results# xor(part, result[-1], key)# xor(part, y) = result, y = xor(result, y)iv, key, parts = encrypt( "BUAACTF{abcdefgh}")print(f"iv = {iv}")print(f"key = {key}")print(f"parts = {parts}")
由异或的性质,,据此编码根据结果倒序还原,便可解出原 parts。
parts = [b'\x85^}\t\xad\xec\x81,', b'\xba\x04W\xa1\xee"\xea\xc5', b'\xb7ZW\x18\x99\x82\xd6:', b'\x99\x03}\x9c\xde|\xb1\xc5', b'\xa1Tk.\x8b\xee\xbaf']decrypted = ""for i, value in reversed(list(enumerate(parts))): value = xor(value, key) prev = parts[i-1] if i > 0 else iv value = xor(value, prev) print(value) decrypted = value.decode() + decryptedprint("Flag:", decrypted)
A magical variable is available in every template if you want to print the current context: __tera_context.
随意构造一个错误的语句,从返回的报错中可以发现使用了 Tera::one_off one off template。
fetch("{% println!(__tera_context) %}")Error while rendering: Error { kind: Msg("Failed to parse '__tera_one_off'"), source: Some(Error { kind: Msg(" --> 18:35 |18 | <div class="result">您的身高为 {% println!(__tera_context) %} cm</div> | ^--- | = unexpected tag; expected end of input or some content"), source: None })
与字符串相关的有 filter,但是并没有实际可以使用的,也没有函数可分割字符串。查阅文档发现 for 循环可以逐字符,不过比较坑的是 Playground 的版本可能旧了,这个功能无法使用。
{% for letter in "hahahaha" %} {% if loop.index % 2 == 0%} <span style="color:red">{{ letter }}</span> {% else %} <span style="color:blue">{{ letter }}</span> {% endif %}{% endfor %}
评论