新出密码题,记录一下。
源码:
# Python3
from secret import flag
import random
import base64pool = 'qwertyuiopasdfghjklzxcvbnm1234567890QWERTYUIOPASDFGHJKLZXCVBNM'
r = random.randint(2, 250)
assert flag.startswith('hsctf{')def generate(length):return ''.join(random.choices(pool, k=length))def f(x):random.seed(x)return random.getrandbits(8)def encrypt(plaintext, key):plaintext = list(map(ord, plaintext))for _ in range(20):key = f(key)assert key != 0for i in range(len(plaintext)):key = f(key)tmp = (key * r) % 251assert tmp != 0 and key != 0plaintext[i] = plaintext[i] ^ tmpplaintext = bytes(plaintext)return base64.b64encode(plaintext)m = generate(random.randint(200, 300)) + flag + generate(random.randint(200, 300))
c = encrypt(m, random.getrandbits(128))
print(c)
# b'8OcTbAfL6/kOMQnC9v8SNmmSzvQMeGTT8vANM1T+7vIce2fo0fc2RnScrNxTSmeSyuMjMF//w8BWaXX91dsGcnvmreg0NQTw96ceVVXj3sQ3Znn51OU1S0bOyaMtNHTj36AcWFqewN4zRUXD6agGbAPE+tQtd3XG0doAa1Ll9fhcQ1zk0McTM1bv8PIQOAnn3vQ3UgLD3PsONXLs4KkXMnjTyMEQOFn/0uYVUwOY1PsleEHCyNopRVDr+Kc0e2PH9v0XNXfprfIPU3nw7KYTNX/G7twLSkHoyaUlQHXi3v02UHmdy/4iNgme3Pc8bgPp+tYWV1+YzPkXYkXM4ulUc27DrM4SNUPT2fQlckj1qP4Fal+YoPYJMlyZ8qhXfF3Y0tUDdUXl3vg0dFTi++VVOFfH/dgMS1ru9N8WU0HF9cUCTgPe+qVdSn/u7Mkda0GTw/QDcWPZ9KYGN2jSzfk0OVrMzt0yRHD64KMrUgPF2sFWcmP56KZSTAD61PUGeXrd49MgU1bL8OsVNWj91vIsalXwqf0qaWbwzv0lWETA4eElS3L99cYmU1nv9dRQTWbDyclScQTN6NIhV2j//+ZWbH7Z68kwM3Dy4dcUc1PQy8kRTl/4zcU9WGWfoakOMXuf69MXZQTEz+kJT1Dar8UN'
大概分析一下题目逻辑,首先明文 m 是 flag 前后各加200多个字符padding生成的字符串。
加密得到密文的函数 encrypt 逻辑包括:
key = f(key) 取随机字节,上一次的返回值作为下一次的随机数种子key = f(key) 取一个随机字节,然后计算 tmp = (key * r) % 251 其中 2,最后将当前明文字符与 tmp 进行一次异或加密 随机数题目还是要先解决种子未知的问题,好在这个题目 key,r 都只有8位,直接爆破,寻找 hsctf{ 正确加密后的密文,然后就是个简单的异或解密了。
最终exp:
# Python3
#from secret import flag
import random
import base64cc=b'8OcTbAfL6/kOMQnC9v8SNmmSzvQMeGTT8vANM1T+7vIce2fo0fc2RnScrNxTSmeSyuMjMF//w8BWaXX91dsGcnvmreg0NQTw96ceVVXj3sQ3Znn51OU1S0bOyaMtNHTj36AcWFqewN4zRUXD6agGbAPE+tQtd3XG0doAa1Ll9fhcQ1zk0McTM1bv8PIQOAnn3vQ3UgLD3PsONXLs4KkXMnjTyMEQOFn/0uYVUwOY1PsleEHCyNopRVDr+Kc0e2PH9v0XNXfprfIPU3nw7KYTNX/G7twLSkHoyaUlQHXi3v02UHmdy/4iNgme3Pc8bgPp+tYWV1+YzPkXYkXM4ulUc27DrM4SNUPT2fQlckj1qP4Fal+YoPYJMlyZ8qhXfF3Y0tUDdUXl3vg0dFTi++VVOFfH/dgMS1ru9N8WU0HF9cUCTgPe+qVdSn/u7Mkda0GTw/QDcWPZ9KYGN2jSzfk0OVrMzt0yRHD64KMrUgPF2sFWcmP56KZSTAD61PUGeXrd49MgU1bL8OsVNWj91vIsalXwqf0qaWbwzv0lWETA4eElS3L99cYmU1nv9dRQTWbDyclScQTN6NIhV2j//+ZWbH7Z68kwM3Dy4dcUc1PQy8kRTl/4zcU9WGWfoakOMXuf69MXZQTEz+kJT1Dar8UN'
cc=base64.b64decode(cc)
flag = 'hsctf{'
pool = 'qwertyuiopasdfghjklzxcvbnm1234567890QWERTYUIOPASDFGHJKLZXCVBNM'
#r = random.randint(2, 250)
assert flag.startswith('hsctf{')def generate(length):return ''.join(random.choices(pool, k=length))def f(x):random.seed(x)return random.getrandbits(8)def encrypt(plaintext, key):plaintext = list(map(ord, plaintext))for i in range(len(plaintext)):key = f(key)tmp = (key * r) % 251#assert tmp != 0 and key != 0plaintext[i] = plaintext[i] ^ tmpplaintext = bytes(plaintext)return plaintextdef decrypt(ciphertext, key):ciphertext=list(ciphertext)for i in range(len(ciphertext)):key = f(key)tmp = (key * r) % 251#assert tmp != 0 and key != 0ciphertext[i] = ciphertext[i] ^ tmpciphertext = bytes(ciphertext)return ciphertextfor r in range(2,251):for key in range(1,256):m = flagc = encrypt(m, key)if(c in cc):print(r)print(key)print(c)print(cc.index(c))r=187
key=34
pos=247
mm=decrypt(cc[247:],key)
print(mm)