密码学实战 - HTB RLotto

397 阅读1分钟

概述

RLotto是来自于HTB(hackthebox.com)的一个容易级密码学挑战,完成该挑战所需要掌握的知识点在于使用Python生成随机数。

题目分析

相关的任务文件包括Python源代码文件server.py以及一个在线的运行环境。

server.py内容节选如下

# Connection handler
def handle(self):
    print("[+] Incoming connection")
    
    seed = int(time.time())
    
    ...
    
    extracted = []
    next_five = []

    # Initialize the (pseudo)random number generator
    random.seed(seed)
    
    # First extraction
    while len(extracted) < 5:
        r = random.randint(1, 90)
        if(r not in extracted):
            extracted.append(r)
            time.sleep(1)

    ...
            
    # Next extraction
    solution = ""
    while len(next_five) < 5:
        r = random.randint(1, 90)
        if(r not in next_five):
            next_five.append(r)
            solution += str(r) + " "
    solution = solution.strip()
    print("\n[+] SOLUTION: " + solution)
    
    question = "\n\033[33m[?]\033[0m Guess the next extraction!!!"
    self.send(question)
    response = self.receive()
    
    # CHECK
    print("[>] Sent:", summary[25:])
    print("[<] Recv:", response)
    
    if str(response) == solution:
        self.send("Good Job!\nHTB{f4k3_fl4g_f0r_t3st1ng}")
    else:
        self.send("Nope! Try again.")

解题过程

以上代码使用Python提供的random.randint方法生成两组各5个随机数,输出第一组5个数字后提示用户输入,如果输入的数字与第二组5个数字相同,则返回flag。

其问题在于使用了系统时间作为随机数生成的seed,

seed = int(time.time())

# Initialize the (pseudo)random number generator
random.seed(seed)

对于Python的random.randint方法而言,使用相同的seed值,会导致相同的随机数序列。 因此我们只要使用相同的方法来生成随机数就可以得到答案。

from pwn import remote
import time
import random

conn = remote('167.99.204.5', 31244, level = 'debug')

seed = int(time.time())
random.seed(seed)

conn.recvuntil('Put here the next 5 numbers:')

for _ in range(5):
  random.randint(1, 90)

solution = ""
for _ in range(5):
  r = random.randint(1, 90)
  solution += str(r) + " "
  
solution = solution.strip()  
conn.sendline(solution)

## 返回flag
conn.recvline()