
題目給了一個 micorchip.cpp 與 python.h
但 microchip.cpp 卻是一個長得很 python 的 cpp 檔

當下就對 code 做大概的清理,轉換成 python 能跑的格式
import string
def track(name, id) -> str :
if len(name) % 4 == 0 :
padded = name + "4444"
elif len(name) % 4 == 1 :
padded = name + "333"
elif len(name) % 4 == 2 :
padded = name + "22"
elif len(name) % 4 == 3 :
padded = name + "1"
keys = list()
temp = id
for i in range(4) :
keys.append(temp % 96)
temp = int(temp / 96)
result = ""
for i in range(0, len(padded), 4) :
nums = list()
for j in range(4) :
num = ord(padded[i + j]) - 32
num = (num + keys[j]) % 96
nums.append(num + 32)
result += chr(nums[3])
result += chr(nums[2])
result += chr(nums[1])
result += chr(nums[0])
return result
def main() -> int :
name = open("flag.txt", "r").read().strip()
id = int(input("key = "))
print("result is:", track(name, id))
return 0
main()Code language: PHP (php)
所以程式大概就是傳進 flag 跟 key,並轉換成加密的文字
題目也有提供加密後的 flag : =Js&;*A`odZHi’>D=Js&#i-DYf>Uy’yuyfyu<)Gu
但問題是 flag 也不知道,key 也不知道,要解出來也不簡單
或者是….其實已經有flag的一部分了?

加密的函式 track 的第一段中,可以看到是在將 plaintext padding 到長度為 4 的倍數
第二段則是將 key 轉換成 96 進位的 4 digit keys
第三段也能看到 i 是 4的倍數在跳的
所以能發現 plaintext 是 4 個 4 個一組在做加密的
而 Flag 的形式是 AIS3{___________}
最前面的 4 個字剛好是已知的 AIS3
又 track 最後是反向的將 4 個字填入 result
所以在這邊能知道 encrypted 的前 4 個字 “=Js&” 為 “AIS3” + key 轉換而成
因此先將 encrypted 反向回來 “&sJ=”,且會分別對應到 A I S 3 這四個字
加密的公式是 (ord(plain) – 32) + keys[i] %96 = ord(encrypted) – 32
能寫成 python script
plain = "AIS3"
encrypted = "&sJ="
keys = []
for i in range(4):
ch = ord(text[i]) - 32
num = ord(cipher[i]) - 32
key = num - ch
if key < 0:
key += 96
keys.append(key)
key = 0
for i in reversed(keys):
key *= 96
key += i
print(key)Code language: HTML, XML (xml)
如果 num < ch 的話代表過程中有被 %96 去掉
所以要加回來
其中的 keys 在原加密函式中是左邊最小右邊最大
如 key = 124 , keys = [28,1,0,0]
所以倒過來算 key 的時候要由右往左算
透過這個 script 能得到 key = 9653253
有 key 了,就能很輕鬆的 decrypt
寫個 python script 跑一下
text = "AIS3"
keys = []
# cipher = ";&sJ"
true_flag = "=Js&;*A`odZHi'>D=Js&#i-DYf>Uy'yuyfyu<)Gu"
keys = list()
key = 9653253
for i in range(4) :
keys.append(key % 96)
key = int(key / 96)
for i in range(0, len(true_flag), 4) :
seg = true_flag[i:i+4]
seg = seg[::-1]
for j in range(4):
num = ord(seg[j]) - 32
num -= keys[j]
if num < 0:
num += 96
print(chr(num + 32),end="")Code language: PHP (php)
