N0PSctf 2024
N0PSCTF 2024
CRYPTOGRAPHY WRITEUP
Author:
Pham Quoc Trung
Used Language:
Python3
Problem Solving:
Crypto Rookie
Description:
Hey Rookie, decode this and I'll give you a cookie!
STSABEAOE OEIEALGSETRHNCOI MMFITTAK
The flag's format is N0PS{DECODEDMESSAGE}.
Solution:
Đưa vào một trang Cipher Identifier, ta sẽ ra được đây là Rail-fence Cipher.
Đưa vào tool để decode và mình ra được flag.

Flag: N0PS{SOMETIMESAFLAGISBETTERTHANACOOKIE}
Broken OTP
Description:
i heard OTP it the most secure encryption algorithm ever
sc nopsctf-broken-otp.chals.io
Attachments:
main.py
Dockerfile
Recon:
Sau khi thử decode e bằng tay, mình ra được hàm eval(). Có vẻ đây là một chương trình bị obfuscate. Các bạn có thể deobfuscate bằng cách chạy từng dòng code để xem output (nhớ sử dụng python 3.12 vì kết quả sẽ khác nhau với mỗi phiên bản python, đây là lí do ta có Dockerfile)
Tuy nhiên, mình sẽ sử dụng GPT để deobfuscate hộ mình:

Bỏ qua vấn đề về chính tả các thứ thì GPT làm mọi thứ khá tốt. Ở đây mình thấy được chương trình dạng như sau
Ở đây ta chỉ nhìn vào logic của chương trình (vì đây là code gen minh họa nên chắc sẽ không chạy được). Có thể thấy đây chỉ đơn giản là chương trình mã hóa bằng cách gen ra một keystream bytes random.randint(0, 255) và xor với message tùy ý (option 1) hoặc secret (option 2). Xem chừng có vẻ khá là secure cho tới khi mình thấy dòng này:
Seed của hàm random sẽ được set bằng cách lấy time hiện tại của hệ thống tính theo giây + secret ở dạng số nguyên. Do secret là không đổi và time là tính theo giây, nếu mình có thể kết nối tới 2 lần trong cùng 1 giây, cả 2 lần đó đều sẽ có cùng 1 seed.
Khi đó, mình sẽ dùng option số 1 với 1 message dài và lấy ra keystream đó bằng cách xor plaintext với ciphertext thu được. Vì cùng 1 seed nên keystream này sẽ có đoạn từ [0:len(secret)] trùng với keystream tạo ra ở option 2. Cuối cùng, ta chỉ cần xor ciphertext của secret với đoạn keystream này là sẽ ra được flag.
Thật ra có thể gửi
\x00thay vìA, khi đó ciphertext trả về sẽ chính là key luôn.
Flag: N0PS{0tP_k3Y_r3u53}
Side Channel
Description:
Your goal is to extract the key used for the encryption of the captured data.
All blocks have been encrypted in Electronic Codebook (ECB) mode.
All data blocks are in hexadecimal, byte 0 first, byte 15 last. First column: 128 bits input block, second column: 128 bits encrypted block, third column: encryption time.
The key length is 128 bits.
The format of the flag is N0PS{key} where key is the 32 digits hexadecimal representation of the secret key you found, byte 0 first, byte 15 last, with everything in capital letters.
If the correct key was 0102030405060708090A0B0C0D0E0F the following command would output the first ciphertext bloc in ta.dat: printf "$(sed -n 's/ .*//;s/\(..\)/\\x\1/gp;q' ta.dat)" | openssl enc -aes-128-ecb -nosalt -nopad -K 0102030405060708090A0B0C0D0E0F | od -v -A none -tx1
Hint 1: https://en.wikipedia.org/wiki/Timing_attack
Hint 2: http://www.ee.unb.ca/cgi-bin/tervo/calc2.pl?num=42&den=16&f=m&p=36&d=1&y=1&m=1
Attachments:
Solution:
<Not Yet>
Last updated