

역시 새벽 시간이라서 운 좋게 퍼블에 성공했다.
난이도는 어렵지 않다.
같은 출제자님의 기존 이상한 랜섬웨어의 Revenge 버전이라, 업그레이드 됐을 것이라고 생각한다.
정확하게는 기존 문제를 풀어보질 않아서 잘 모르겠다…
분석 시작하겠다.
import hashlib
import random
import os
k = b"DH{??????????????????????????????????????????????????????????????}"
def a(data, uk):
seed = int.from_bytes(hashlib.md5(uk).digest(), 'big')
random.seed(seed)
indices = list(range(len(data)))
random.shuffle(indices)
return bytes([data[i] for i in indices])
def ra(data, uk):
seed = int.from_bytes(hashlib.md5(uk).digest(), 'big')
random.seed(seed)
indices = list(range(len(data)))
random.shuffle(indices)
result = [0] * len(data)
for orig, shuf in enumerate(indices):
result[shuf] = data[orig]
return bytes(result)
def b(data, k):
k_stream = hashlib.sha256(k).digest()
return bytes([b ^ k_stream[i % len(k_stream)] for i, b in enumerate(data)])
def c(data, k):
uk = b"cry_me_a_river"
pw = str(0x????).encode() # 0x000 ~ 0xffff
salt = b"ransomrevenge"
dk = hashlib.pbkdf2_hmac('sha256', pw, salt, 1000, dklen=32)
s1 = int.from_bytes(hashlib.md5(pw).digest()[:4], 'big')
s2 = int.from_bytes(hashlib.md5(dk).digest()[:4], 'big')
ad = a(data, uk)
random.seed(s1)
indices = list(range(len(ad)))
random.shuffle(indices)
shuffled1 = bytes([ad[i] for i in indices])
xored = b(shuffled1, dk)
random.seed(s2)
indices = list(range(len(xored)))
random.shuffle(indices)
final = bytes([xored[i] for i in indices])
return final
if not os.path.exists('flag.txt'):
with open('flagg.txt', 'rb') as f:
plain = f.read().strip()
lol = c(plain, k)
with open('flag.txt', 'wb') as f:
f.write(lol)
flagg.txt 파일이 존재하면 open을 사용하지만, 해당 파일은 첨부파일에 존재하지 않는다.
flag.txt 파일을 확인해보면, 암호화된 형식의 내용이 보인다.
아마도 바이너리 형태인 것 같다. open() 명령어로 ‘rb’로 읽는 이유가 이 파일이 바이너리 형식이라 그런 것 같다.
조금 헤맸던 이유는 문제의 힌트 때문이였다.
발표 자료의 첫 글자가 W로 시작한다고 적혀 있는데, 그걸 flag의 첫 글자라고 생각했다..
DH{W..} 형태의 flag값이라고 생각해서 그것만 검색하다가 값을 제대로 못찾았다.
문제 힌트에서 주어진 첫 글자 W 는 모든 평문의 첫 글자였다.
어쩐지 flag.txt 파일의 길이가 길더라..