1. 程式人生 > 實用技巧 >Jarvis OJ-superexpress

Jarvis OJ-superexpress

下載附件後,得到了一個py指令碼與一個的文字,如下:

problem.py:

import sys
import re
"""
key = '****CENSORED***************'
flag = 'TWCTF{*******CENSORED********}'

if len(key) % 2 == 1:
    print("Key Length Error")
    sys.exit(1)

n = len(key) / 2
encrypted = ''
for c in flag:
    c = ord(c)
    for a, b in zip(key[0:n], key[n:2
*n]):#每個字元都會經過這裡 c = (ord(a) * c + ord(b)) % 251#每個字元都仿射加密n次 encrypted += '%02x' % c#轉換為16進位制 print(encrypted)

encryted:

805eed80cbbccb94c36413275780ec94a857dfec8da8ca94a8c313a8ccf9

演算法大致如下:

①將key分成等份的兩組,並用zip打包成為一個元組

②將flag中的每一個元素c*key[0:n]+key[n:2n]

③將得到的數值轉化為十六進位制,形成字串

一開始以為要把key通過暴力方式破解出來,但發現幾乎不可能!看了下writeup(>^<)!說演算法實質是仿射加密,仔細分析發現確實是這樣。雖然flag的每個元素讀會經過很多次處理,但每個元素每次都進行了相同的處理,每次處理都是在群251下的仿射加密!因此,可以直接看為進行了一次仿射加密,寫出解密演算法即可得出flag.

from libnum import invmod
import re
enflag='805eed80cbbccb94c36413275780ec94a857dfec8da8ca94a8c313a8ccf9'
enflag=re.findall('.{2}',enflag)
table=[]
for i in enflag:
    x=int('0x'+i,16)
    table.append(x)
lenflag=len(enflag)
print(lenflag,'\n',enflag)
print(table)
a=0
b=0
for i in range(252):
    for j in
range(252): c1=(ord('T')*i + j)%251 c2=(ord('W')*i + j)%251 c3=(ord('C')*i + j)%251 if c1==table[0] and c2==table[1] and c3==table[2]: a=i b=j print("a:",a,"\tb:",b) inva=invmod(a,251) flag=[] for n in table: x=((n-b)*inva)%251 flag.append(chr(x)) print(''.join(flag))

運算結果: