题目给了一个密文以及一段加密代码
密文:
805eed80cbbccb94c36413275780ec94a857dfec8da8ca94a8c313a8ccf9
加密代码
import sys
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
encrypted += '%02x' % c
print(encrypted)
按照加密代码所示:
对于给定flag里面的任意一个字符:
for c in flag:
for i in range(0, n):
c = (a[i] * c + b[i]) % 251
那么将其展开其实就是:
c
n
=
(
a
n
(
a
n
−
1
(
.
.
.
(
a
1
c
1
+
b
1
)
.
.
.
)
+
b
n
−
1
)
+
b
n
)
%
251
c_{n} = (a_{n}(a_{n-1}(...(a_1c_1 + b_1)...)+b_{n-1})+b_{n})\%251
cn=(an(an−1(...(a1c1+b1)...)+bn−1)+bn)%251
而我们需要的仅仅是
c
1
c_1
c1到
c
n
c_n
cn的转化,所以该式最终可以转化为:
c
n
=
(
a
c
1
+
b
)
%
251
c_n = (ac_1+b)\%251
cn=(ac1+b)%251
那么我们只要求出a和b就可以进行解码了
给定的flag中有一些确定的字符:“TWCTF{”
那么我们可以根据这些字符以及对应的编码后的数字来求a,b
{
128
=
(
a
∗
84
+
b
)
%
251
94
=
(
a
∗
87
+
b
)
%
251
237
=
(
a
∗
67
+
b
)
%
251
203
=
(
a
∗
70
+
b
)
%
251
188
=
(
a
∗
123
+
b
)
%
251
\left\{ \begin{aligned} 128 = (a*84 + b) \% 251\\ 94 = (a*87 + b)\%251\\ 237=(a*67+b)\%251\\ 203=(a*70+b)\%251\\ 188=(a*123+b)\%251 \end{aligned} \right.
⎩⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎧128=(a∗84+b)%25194=(a∗87+b)%251237=(a∗67+b)%251203=(a∗70+b)%251188=(a∗123+b)%251
拿几个式子相减就可以去掉b:
{
3
a
=
k
1
∗
251
−
34
20
a
=
5
2
∗
251
−
143
\left\{ \begin{aligned} 3a=k_1*251-34\\ 20a=5_2*251-143 \end{aligned} \right.
{3a=k1∗251−3420a=52∗251−143
根据这两个式子可以解出来
a
=
156
a=156
a=156
进而尝试求出
b
=
76
b=76
b=76
如此,便可以进行解码了
对flag中的每一个字符,在ascii可见字符中进行尝试,知道编码后结果与给定结果相同为止
# 将给定的十六进制数,变为字节码放入hexarray中
def convert_hexarray(s):
hexarray = []
while s:
hexarray.append(s & 0xff)
s >>= 8
hexarray.reverse()
return hexarray
def solve(hexarray, a, b):
flag = ""
for data in hexarray:
# 枚举ascii码所有可见字符,并用 (a * c + b) % 251 编码,判断是否与给定编码相等
for c in range(0x20, 0x7f):
if (a * c + b) % 251 == data:
flag += chr(c)
break
return flag
if __name__ == "__main__":
output_hex = 0x805eed80cbbccb94c36413275780ec94a857dfec8da8ca94a8c313a8ccf9
a = 156
b = 76
print(solve(convert_hexarray(output_hex), a, b))
flag: TWCTF{Faster_Than_Shinkansen!}