你会算md5吗
分析
将flag逐字md5加密,得到output
单字符md5,可以理解为单字节加密,没有行列转换混淆的话,一般都可以直接爆破,得到每个原字符
(如果答案不对一般就是字符集的问题,整数32-126就是可见字符范围)
exp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import hashlib output = ['9d5ed678fe57bcca610140957afab571' , '0cc175b9c0f1b6a831c399e269772661' , '03c7c0ace395d80182db07ae2c30f034' , 'e1671797c52e15f763380b45e841ec32' , '0d61f8370cad1d412f80b84d143e1257' , 'b9ece18c950afbfa6b0fdbfa4ff731d3' , '800618943025315f869e4e1f09471012' , 'f95b70fdc3088560732a5ac135644506' , '0cc175b9c0f1b6a831c399e269772661' , 'a87ff679a2f3e71d9181a67b7542122c' , '92eb5ffee6ae2fec3ad71c777531578f' , '8fa14cdd754f91cc6554c9e71929cce7' , 'a87ff679a2f3e71d9181a67b7542122c' , 'eccbc87e4b5ce2fe28308fd9f2a7baf3' , '0cc175b9c0f1b6a831c399e269772661' , 'e4da3b7fbbce2345d7772b0674a318d5' , '336d5ebc5436534e61d16e63ddfca327' , 'eccbc87e4b5ce2fe28308fd9f2a7baf3' , '8fa14cdd754f91cc6554c9e71929cce7' , '8fa14cdd754f91cc6554c9e71929cce7' , '45c48cce2e2d7fbdea1afc51c7c6ad26' , '336d5ebc5436534e61d16e63ddfca327' , 'a87ff679a2f3e71d9181a67b7542122c' , '8f14e45fceea167a5a36dedd4bea2543' , '1679091c5a880faf6fb5e6087eb1b2dc' , 'a87ff679a2f3e71d9181a67b7542122c' , '336d5ebc5436534e61d16e63ddfca327' , '92eb5ffee6ae2fec3ad71c777531578f' , '8277e0910d750195b448797616e091ad' , '0cc175b9c0f1b6a831c399e269772661' , 'c81e728d9d4c2f636f067f89cc14862c' , '336d5ebc5436534e61d16e63ddfca327' , '0cc175b9c0f1b6a831c399e269772661' , '8fa14cdd754f91cc6554c9e71929cce7' , 'c9f0f895fb98ab9159f51fd0297e236d' , 'e1671797c52e15f763380b45e841ec32' , 'e1671797c52e15f763380b45e841ec32' , 'a87ff679a2f3e71d9181a67b7542122c' , '8277e0910d750195b448797616e091ad' , '92eb5ffee6ae2fec3ad71c777531578f' , '45c48cce2e2d7fbdea1afc51c7c6ad26' , '0cc175b9c0f1b6a831c399e269772661' , 'c9f0f895fb98ab9159f51fd0297e236d' , '0cc175b9c0f1b6a831c399e269772661' , 'cbb184dd8e05c9709e5dcaedaa0495cf' ] flag = []for i in output: for j in range (32 , 127 ): my_md5 = hashlib.md5() my_md5.update(chr (j).encode()) if my_md5.hexdigest() == i: flag.append(chr (j)) break print (f"flag: {'' .join(flag)} " )
十七倍
源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 #include <stdio.h> int main () { unsigned char flag[] = "BaseCTF{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}" ; int i; for (i = 0 ; i < 40 ; i++) { flag[i] = flag[i] * 17 ; } if (flag[0 ] != 98 ) { printf ("CPU Error???\n" ); return 1 ; } unsigned char cipher[] = { 98 , 113 , 163 , 181 , 115 , 148 , 166 , 43 , 9 , 95 , 165 , 146 , 79 , 115 , 146 , 233 , 112 , 180 , 48 , 79 , 65 , 181 , 113 , 146 , 46 , 249 , 78 , 183 , 79 , 133 , 180 , 113 , 146 , 148 , 163 , 79 , 78 , 48 , 231 , 77 }; for (i = 0 ; i < 40 ; i++) { if (flag[i] != cipher[i]) { printf ("flag[%d] is wrong, expect %d, got %d.\n" , i, cipher[i], flag[i]); return 1 ; } } return 0 ; }
分析
flag每个字符转换成ASCII码后,unsigned char 决定了对应的二进制只保留低8位, 2^8, 相当于模256
c i p h e r [ i ] = f l a g [ i ] ∗ 17 m o d 256 cipher[i] = flag[i] * 17 \mod 256
c i p h e r [ i ] = f l a g [ i ] ∗ 1 7 m o d 2 5 6
模运算中,有公式
a ⋅ b m o d c = ( ( a m o d c ) ∗ ( b m o d c ) ) m o d c a \cdot b \mod c = ((a \mod c) * (b \mod c)) \mod c
a ⋅ b m o d c = ( ( a m o d c ) ∗ ( b m o d c ) ) m o d c
方便起见, 令 y = cipher[i] , x = flag[i]
那么
x ∗ 17 m o d 256 = ( ( x m o d 256 ) ∗ ( 17 m o d 256 ) ) m o d 256 x * 17 \mod 256 = ((x \mod 256) * (17 \mod 256)) \mod 256
x ∗ 1 7 m o d 2 5 6 = ( ( x m o d 2 5 6 ) ∗ ( 1 7 m o d 2 5 6 ) ) m o d 2 5 6
要得到x, 就要使后面的 17 m o d 256 = 1 17 \mod 256 = 1 1 7 m o d 2 5 6 = 1
设17 ∗ a ≡ 1 m o d 256 17 * a \equiv 1 \mod 256 1 7 ∗ a ≡ 1 m o d 2 5 6
a 就是 17 的逆元
a = inverse(17, 256)
得到a=241
等式两边同时乘241
y ∗ 241 = ( x ∗ 17 ∗ 241 ) m o d 256 = ( ( x m o d 256 ) ∗ ( 17 ∗ 241 m o d 256 ) ) m o d 256 = x m o d 256 y * 241 = (x * 17 * 241) \mod 256 = ((x \mod 256) * (17*241 \mod 256)) \mod 256 = x \mod 256
y ∗ 2 4 1 = ( x ∗ 1 7 ∗ 2 4 1 ) m o d 2 5 6 = ( ( x m o d 2 5 6 ) ∗ ( 1 7 ∗ 2 4 1 m o d 2 5 6 ) ) m o d 2 5 6 = x m o d 2 5 6
可以得到 x 就是 y * 241 模256 的结果
x ≡ y ∗ 241 m o d 256 x \equiv y*241 \mod 256
x ≡ y ∗ 2 4 1 m o d 2 5 6
遍历cipher,还原flag
exp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 from Crypto.Util.number import * cipher = [ 98 , 113 , 163 , 181 , 115 , 148 , 166 , 43 , 9 , 95 , 165 , 146 , 79 , 115 , 146 , 233 , 112 , 180 , 48 , 79 , 65 , 181 , 113 , 146 , 46 , 249 , 78 , 183 , 79 , 133 , 180 , 113 , 146 , 148 , 163 , 79 , 78 , 48 , 231 , 77 ] ascii_flag = [] for i in cipher: x = i*241 %256 ascii_flag.append(x) print ('' .join(chr (x) for x in ascii_flag), end = '' )
mid_math