WeChall - WC Hashing Game

WC Hashing Game (Cracking) by gizmore 破解两组 hash:WC3(定盐 MD5)和 WC4(加盐 SHA1)。答案格式:word1,word2,word3,word4

Challenge

两组 hash 列表,各 17 条:

  • WC3(WeChall v3 算法):固定盐 MD5
  • WC4(WeChall v4 算法):每条 hash 独立加盐 SHA1
  • 答案 = 两组各自最长的两个明文,逗号分隔

题面示例:wordfrom1,wordfrom1,wordfrom2,wordfrom2

Solution

算法

1
2
3
4
5
6
7
8
9
10
import hashlib, string, random

# WC3: md5(md5(plaintext) + "zomgsalt")
digest = hashlib.md5(
hashlib.md5(word.encode()).hexdigest().encode() + b"zomgsalt"
).hexdigest()

# WC4: sha1("zomgsalt4" + password + salt + "zomgsalt4") + salt
t = hashlib.sha1(b"zomgsalt4" + password.encode() + salt.encode() + b"zomgsalt4")
digest = t.hexdigest() + salt # salt 追加到 hash 末尾

攻击路线

  1. 从 WeChall 页面获取两组 hash 列表(需登录)
  2. 用 rockyou 或类似英文词典做字典攻击
  3. 对每个 word 计算 WC3 hash 匹配;对 WC4 每条 hash 提取尾部 4 字节 salt,计算后匹配
  4. 排序取最长各两个
  5. 提交格式:longest_wc3,second_wc3,longest_wc4,second_wc4

完整脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import hashlib, string

# 从页面提取 hash 列表
wc3_hashes = [...] # 17 条 hex hash
wc4_raw = [...] # 17 条 hash+salt(44 hex chars = 40 hash + 8 salt)

# 字典攻击
for word in dictionary:
# WC3
h = hashlib.md5(hashlib.md5(word.encode()).hexdigest().encode() + b"zomgsalt").hexdigest()
if h in wc3_hashes:
found_wc3.append((len(word), word))

# WC4 — 每条 hash 的 salt 不同
for entry in wc4_raw:
target_hash = entry[:-8] # 前 40 hex = SHA1
salt = entry[-8:] # 后 8 hex = 4 bytes salt
t = hashlib.sha1(b"zomgsalt4" + word.encode() + bytes.fromhex(salt) + b"zomgsalt4").hexdigest()
if t == target_hash:
found_wc4.append((len(word), word))

found_wc3.sort(reverse=True)
found_wc4.sort(reverse=True)
answer = f"{found_wc3[0][1]},{found_wc3[1][1]},{found_wc4[0][1]},{found_wc4[1][1]}"

Key Points:

  • WC3 salt 固定zomgsalt,追加在第一次 MD5 hex 之后
  • WC4 每条 hash 尾 8 hex 是 salt:4 字节随机字母数字,需要按条提取
  • 所有明文是小写英文词典词
  • hash 列表在 页面:需从 /en/challenge/wechall/hashing_game/index.php 的 HTML 中提取
coincidence,subversion,triangulation,orthography