exfiltrated entropy

Original Writeup on seall.dev
We are given a server.py
, client.py
, params.py
and a PCAP.
We are given some initial parameters:
a = 0xa1d41ebef9c575ac113fcfd5ac8dbda9
b = 0x8dcf3cf766e0b6c30e753416a70e2367
m = 0x100000000000000000000000000000000
Itβs an LCG encryption system:
class LCG:
def __init__(self):
self.state = SEED
self.a = a
self.b = b
self.m = m
def _next(self):
self.state = (self.a * self.state + self.b) % self.m
return self.state
def generate_key(self, l):
return bytes([self._next() & 0xff for _ in range(l)])
def generate_packet_uuid(self):
return hex(self._next())
def encrypt(self, msg):
key = self.generate_key(len(msg))
return xor(msg, key)
def decrypt(self, msg):
return self.encrypt(msg)
The issue is with every _next
it sets the state
again, so we can predict it with information with the PCAP and decrypt the message.
The blue is the server, so the id
we are seeing is the first self._next()
for the string as its sent before the output is encrypted, and we can calculate all future ones for the encrypted string from that, meaning we can decrypt outputs.
The state encryption is made with 3 known params (a, b, and m) and the state from the previous execution.
We can start by making a state calculation function:
def calculate_next_state(S_n,a,b,m):
return (a * S_n + b) % m
The function for key generation is using a new state with a & 0xff
for each character in the length of the message, so the key covers the full message. The message is then XORβed with this key.
def decode_and_xor(encoded_message, key):
decoded_message = base64.b64decode(encoded_message)
state = int(key,16)
key_bytes = []
for i in range(len(decoded_message)):
state = calculate_next_state(state, a, b, m)
val = state & 0xff
key_bytes.append(val)
key_bytes = bytes(key_bytes)
return xor(decoded_message, key_bytes)
The message
is first base64 decoded, then we convert the hexadecimal state
to an integer. For each character in the message
the state
is calculated and then the key is created in key_bytes
. The key is then used with the xor
function from the pwn
library.
Now that the script works, we can use the id
from the 2nd server message and the response from the clientβs 2nd message to decode the output:
import base64
from itertools import product
from pwn import xor
from params import *
def calculate_next_state(S_n,a,b,m):
return (a * S_n + b) % m
def decode_and_xor(encoded_message, key):
decoded_message = base64.b64decode(encoded_message)
state = int(key,16)
key_bytes = []
for i in range(len(decoded_message)):
state = calculate_next_state(state, a, b, m)
val = state & 0xff
key_bytes.append(val)
key_bytes = bytes(key_bytes)
return xor(decoded_message, key_bytes)
key = 'eba14c429a64b2251717da016e096091'
encoded_message = 'Ve7i4H2jQpnQaq2QVgLqprnTCzzM8xLx3TzrV/17HYPvkpZOkcLiOWhXSybh+QMNAie+CTVC7lZ928epBo/yMoQ1KfAlfwBckLny2pSb86i8RcHlz/aG9kEjfNy8ek/VKciP0V+Duq1xT9c5cH/Cl5mzM0I1z3bP4B/CMJMf/2eJKzdt+jucTAz7OwONh3twYB/a/R0nzzBG5iKUZe/SE2wSA8lDHCbh8dOP5DIj2cLR+XiIrooI'
result = decode_and_xor(encoded_message, key)
print(f'Key: {key} -> Decoded XOR Result: \n{result.decode(errors='ignore')}')
$ python3 solve.py
Key: eba14c429a64b2251717da016e096091 -> Decoded XOR Result:
uid=1000(user) gid=1000(user) groups=1000(user),20(dialout),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),106(netdev),110(lpadmin),114(bluetooth),116(scanner)
Yay!
Now decoding the huge output we get the flag.
$ python3 solve.py
Key: 8829affbed23334d34016095627ba065 -> Decoded XOR Result:
0βββββ000βββββ0βββββββββββ0βββββββββββ000000βββ0000000000βββββ00000βββ00ββββ00ββββ000000000000000000000000000000000βββββ00000000000000000000000000000000000000000000000000000000βββ00000000000000000000000000000000000βββββ0000000000
βββββ000βββββ0βββββββββββββββββββββββββ0000βββ0000000000βββββ00000βββ00βββββ0βββββ00000000000000000000000000000000βββββ00000000000000000000000000000000000000000000000000000000βββ00000000000000000000000000000000000βββββ00000000000
0ββββ0000ββββ0β000ββββ00β00ββββ0000ββββ000ββ00000βββββ00βββββββ000ββββ00ββββ00ββββ000000000000ββββββββ0000ββββββ00βββββββ00000000000000ββββββ000ββββββ00ββββββββ000βββββ0βββββ0ββββ00ββββββββ0000ββββββ000ββββββ000βββββββ00000000000
0ββββββββββββ00000ββββ00000βββββββββββ00βββ00000βββββ00βββββββ000βββββ00ββββ00ββββ00000000000ββββββββββ00βββββββββββββββ00000000000000ββββββββ0ββββββββββββββββββ0βββββ0βββββ0βββββ0ββββββββββ00ββββββββ0ββββββββ0ββββββββ00000000000
0ββββββββββββ00000ββββ00000βββββββββββββββββ000βββββββ000ββββ00000ββββ00ββββ00ββββ000000000000ββββ0ββββ0ββββ0ββββ00ββββ00000000000000ββββ0βββ0ββββ0ββββ0ββββ0ββββ00ββββ00ββββ00ββββ00ββββ0ββββ0ββββ0βββ0ββββββββ0ββββ0ββββ00000000000
0ββββ0000ββββ00000ββββ00000ββββ0000ββββ00ββββ000βββββββ00ββββ0βββ0ββββ00ββββ00ββββ000000000000ββββ0ββββ0ββββ0ββββ00ββββ0βββ0000000000ββββ00βββββββ0ββββ0ββββ0ββββ00βββββ0βββ000ββββ00ββββ0ββββ0ββββ00ββββββββββ00ββββ0ββββ00000000000
0βββββ000βββββ0000βββββ0000βββββββββββ0000βββββ0ββββββ000βββββββ00βββββ0βββββ0βββββ0βββββββββ0ββββ0βββββββββββββ000βββββββ00βββββββββββββββββ0ββββββββ00ββββ0βββββ00βββββββ0000βββββ0ββββ0βββββββββββββ0ββββββββ0ββββββββββ0βββββββββ
βββββ000βββββ0000βββββ0000βββββββββββ000000βββ0ββββββ00000βββββ00βββββ0βββββ0βββββ0βββββββββ0ββββ0βββββ00ββββββ00000βββββ00βββββββββ00ββββββ000ββββββ00ββββ0βββββ0000βββββ0000βββββ0ββββ0βββββ00ββββββ000ββββββ000ββββββββ0βββββββββ0
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000βββββ00000000000000000000000000βββββ00000000000000βββββ000000000βββββββββ0000βββββββββ000000000000000000000000000000000000000000000000000000000000βββ000βββββ0000000000000000βββββββ00βββ000000000000000000000000000000000
0000000000βββββ00000000000000000000000000βββββ00000000000000βββββ000000000βββββββββββ00βββββββββββ0000000000000000000000000000000000000000000000000000000000βββ000βββββ0000000000000000ββββββββββββββ00000000000000000000000000000000
00ββββββ000ββββββββ000ββββββ00βββββ0ββββ0βββββββ0000000000000ββββ00000000βββ00000βββ00βββ00000βββ0000000000000βββββ000ββββββ000ββββββ00βββββ0ββββ0ββββββββ00ββββ00βββββββ000βββββ0βββββββ000ββββ00ββββ0000000000000000000000000000000
0ββββββββ00βββββββββ0βββββββββββββ0ββββ0βββββββ00000000000000ββββ0000000ββββ000000000ββββ00000000000000000000βββββ000ββββββββ0βββββββββββββ0ββββ0βββββββββββββββ0βββββββ000βββββ0ββββ000βββββββ0000βββββ00000000000000000000000000000
00βββββββ00ββββ0ββββββββ0ββββ0ββββ0ββββ000ββββ000000000000000ββββ0000000ββββ000000000ββββ0000βββββ0000000000βββββββ0ββββββββ0ββββ0βββ00ββββ0ββββ00ββββ0βββ00ββββ000ββββ00000ββββ0ββββ00βββββββ000000βββ000000000000000000000000000000
0ββββββββ00ββββ0ββββββββ0ββββ0ββββ0ββββ000ββββ0βββ00000000000ββββ000000ββββββ00000ββββββββ00βββββ000000000000ββββββββββββββ00ββββ00βββ0ββββ0ββββ00ββββ000000ββββ000ββββ0βββ0ββββ0ββββ00βββ000000000ββ00000000000000000000000000000000
ββββββββββ0ββββββββ0ββββββββ00ββββββββββ00βββββββ00βββββββββ0βββββββββββ0βββββββββββ00βββββββββββ00βββββββββ0ββββββ0ββββββββ0ββββββββ00ββββββββββ0βββββ00000βββββ00βββββββ00βββββββββ000βββ000000βββ000000000000000000000000000000000
0ββββββββ0ββββββββ000ββββββ0000ββββββββ0000βββββ00βββββββββ0βββββββββββ000βββββββββ0000βββββββββ00βββββββββ0ββββββ000ββββββ000ββββββ0000ββββββββ0βββββ00000βββββ0000βββββ0000ββββββββ00βββ000000βββ0000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000βββ0ββββ000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ββββββββ0000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ββββββ00000000000000000000000000000000000000000000000000
Flag: HTB{still_not_convinced_about_LCG_security?}