Z333333
https://hgame.vidar.club/games/8/challenges?challenge=105
先看Strings,
![Z333333-1]()
获知flag格式,且需要使用MD5加密
然后分析pseudocode
有一个reverse函数,看一下
![Z333333-2]()
发现实现了一串数字中每组偶数项和奇数项交换,这是一个预处理
然后看到有check1,check2
![Z333333-3]()
发现这其实是对用户输入argv[1]这串数字的一系列约束,
v5,v4分别表示是否满足约束,
在main中最后的判断中,若v5,v4为true,且满足一个额外条件
的输入即为plain
接下来编写脚本即可~~(这题暴搜脚本写起来太麻烦了,请gpt出手)~~
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 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
| def reverse_pairs(s: str) -> str: lst = list(s) for i in range(0, len(lst)//2 * 2, 2): lst[i], lst[i+1] = lst[i+1], lst[i] return ''.join(lst)
def verify(post: str) -> bool: a = [ord(c) for c in post] if len(a) < 10: return False array_dword = 0x00000AF0 d404024 = 0x98 d404028 = 0x9F4 d40402C = 0x33 d404030 = 0x53 d404034 = 0x6B d404038 = 0x5 d40403C = 0x145
if not (a[2] + a[1] == d404034 and a[2] - a[1] == d404038): return False if (a[5] * a[8]) >> 3 != d40403C: return False if a[0] * a[2] != array_dword: return False if a[5] + a[4] + a[3] != d404024: return False if a[3] * a[5] + a[4] != d404028: return False if a[8] + a[6] - a[7] != d40402C: return False if ((a[9] + a[7]) ^ a[8]) != d404030: return False if a[6] != 50: return False return True
digits = list(range(48, 58))
solutions = []
fixed = {0: None, 1:51, 2:56}
array_dword = 0x00000AF0 a2 = 56 a0 = array_dword // a2 if array_dword % a2 != 0: raise SystemExit("无法整除,假设数字范围可能不止 0-9。") fixed[0] = a0
for a3 in digits: for a5 in digits: a4 = 152 - (a3 + a5) if a4 < 48 or a4 > 57: continue if a3 * a5 + a4 != 2548: continue if (a5 * 2600) % a5 != 0: pass if 2600 % a5 != 0: continue a8 = 2600 // a5 if a8 < 48 or a8 > 57: continue need_diff = 51 - a8 for a6 in digits: a7 = a6 - need_diff if a7 < 48 or a7 > 57: continue for a9 in digits: if ((a9 + a7) ^ a8) == 83: a = [fixed[0], fixed[1], fixed[2], a3, a4, a5, a6, a7, a8, a9] post = ''.join(chr(x) for x in a) if verify(post): solutions.append(post)
for post in solutions: original = reverse_pairs(post) print("post-Reverse 用于校验的字符串:", post) print("程序实际接收的 argv[1]:", original)
|
![Z333333-4]()
ok,这样就只剩最后一步——MD5(32bit)加密,直接调用python库散列函数
1 2 3 4 5 6 7 8 9 10 11
| import hashlib
def md5_encrypt(text: str, length: int = 32) -> str: md5_value = hashlib.md5(text.encode()).hexdigest() if length == 16: return md5_value[8:24] return md5_value
s = "3208441202" print("MD5(32位):", md5_encrypt(s, 32)) print("MD5(16位):", md5_encrypt(s, 16))
|
![Z333333-5]()
写在最后:
这道题一开始上传的是没有argv[1][6]==50约束的版本,存在多解
以至于苯人做了半天没做出来,怀疑人生了
好在笨笨shiori测过之后紧急更换了版本