misc-零寬字元隱寫自寫指令碼

Fxe0_0發表於2024-06-02

PS: 從零寬字元隱寫的javascript程式碼提取出來的解密方式, 由於零寬字元隱寫的題目存在需要先判定存在哪些零寬字元, 勾選對應隱寫字元後再進行解密. 而據我調研, 各解密網站都不具備自動識別判斷解密的功能, 所以自寫了一個

# encoding=utf-8

import re
import math
from typing import Set, Union, Any


def get_use_chars(encode_str: str):
    special_chars = ['\u200a', '\u200b', '\u200c', '\u200d', '\u200e', '\u200f', '\u202a', '\u202b', '\u202c',
                     '\u202d', '\u2062', '\u2063', '\ufeff']
    pattern = "[" + "".join(re.escape(char) for char in special_chars) + "]"
    found_chars = set(re.findall(pattern, encode_str))
    return sorted(list(found_chars))


class UnicodeSteganographer:
    def __init__(self):
        self.chars = []
        self.radix = 0
        self.codelength_text = 0

    def set_use_chars(self, new_chars: str):
        if len(new_chars) >= 2:
            self.chars = list(new_chars)
            self.radix = len(self.chars)
            self.codelength_text = math.ceil(math.log(65536, self.radix))

    def decode_text(self, text: str) -> dict:
        splitted = self.split_zerowidth_characters(text)
        return {
            'originalText': splitted['originalText'],
            # splitted['hiddenText'],
            'hiddenText': self.decode_from_zero_width_characters_text(splitted['hiddenText'])
        }

    def split_zerowidth_characters(self, str1: str) -> dict:
        split_result = {
            'originalText': re.sub('[' + ''.join(re.escape(char) for char in self.chars) + ']', '', str1),
            'hiddenText': re.sub('[^' + ''.join(re.escape(char) for char in self.chars) + ']', '', str1)
        }
        return split_result

    def decode_from_zero_width_characters_text(self, zero_width_str: str) -> str:
        # 初始化
        r = zero_width_str
        decode_result = []

        # 字元替換
        for i in range(len(self.chars)):  # 修改這裡為遍歷chars的長度
            r = re.sub(self.chars[i], str(i), r)

        # 解碼文字字元
        for i in range(0, len(r), self.codelength_text):
            char_code = int(r[i:i + self.codelength_text], self.radix)
            decode_result.append(chr(char_code))

        # 合併結果為字串並返回
        return ''.join(decode_result)


if __name__ == '__main__':
    # 只需要把零寬隱寫的文字貼上過來
    zerotext = """
    ​​​​‍‬‬flag​​​​‍‬‍‍ ​​​​‍‬‍is ​​​​​‬‬​​​​‍‍​not​​​​‍‬‬ ​​​​‍‬here!​​​​‍‍​​​​​‬​​​​​​‍‍‍​​​​‍‬‬​​​​​‍‬‬‍​​​​‍‍​​​​​‍‬‍‍
    """

    # 自動化計算方式
    stegano = UnicodeSteganographer()
    stegano.set_use_chars("".join(get_use_chars(zerotext)))
    result = stegano.decode_text(zerotext)
    print("try1:" + result['hiddenText'])

    print("---------------------------------------------------------------------------")

    # 預設計算方式
    stegano2 = UnicodeSteganographer()
    stegano2.set_use_chars('\u200c\u200d\u202c\ufeff')
    result2 = stegano2.decode_text(zerotext)
    print("try2:" + result2['hiddenText'])
	

原js解密指令碼參考

https://330k.github.io/misc_tools/unicode_steganography.js

相關文章