← Back to Writeups
CUSTOMEasyReversing

Забытый пароль (Forgotten Password)

XESXOR9/2/20262 min read
#reversing#custom#easy#byte_addition_reversal#flag_format_exploitation#known_plaintext_attack#linux

Забытый пароль (Forgotten Password)

Platform: duckerz | Category: Reversing | Type: Challenge | Difficulty: Easy | OS: Linux | Author: XESXOR | Date: 2026-01-09 | Status: Solved Techniques: byte_addition_reversal, flag_format_exploitation, known_plaintext_attack

Summary

Task: Python script with encrypted flag using byte-shift cipher. Solution: Known plaintext attack using flag format to calculate key (ASCII 40), then decrypt by adding key to each byte.

Забытый пароль (Forgotten Password) — duckerz

Description

"Мой друг сисадмин забыл пароль от своей админской учётки.. стоит ли мне ему говорить, что я уже как месяц её взломал?"

A Python script rev.py with an encrypted flag is provided.

Analysis

Source Code

python
from math import *

flag = b'\x1c-\x1b#\x1d*2S(\x0c\n\nO\x08J<7\x1bJ\x0c\x1bC=\x1c7/\t\x0f@7\x1b\x0c\x1d\r\x0cJU'
print('[*] Hello this is simple cipher program. Enter the message: ')
message = str(input())
if message == "Give me flag":
    print("[*] where 'please'?")
elif message == "Give me flag please":
    print("[*] None. GLHF")
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

key = ord(message[len(message)-1])
list_output = []
flag_ouput = []
for i in range(0, len(message)):
    list_output.append(chr(ord(message[i])+key))
for i in range(0, len(flag)):
        flag_ouput.append(chr(flag[i]+key))

str_ouput = ''.join(list_output)
str_flag = ''.join(flag_ouput)

print('[*] This is your cipher text: ', str_ouput.encode())
print('[*] This is flag output: ', str_flag)

Encryption Mechanism

  1. Key: ASCII code of the last character of the input message
  2. Encryption: Each byte of the flag is added to the key
  3. Formula: encrypted[i] = flag[i] + key ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Vulnerability: Known Plaintext Attack

Since the flag format DUCKERZ{...} is known, we can calculate the key:

encrypted[0] = 0x1c = 28
plaintext[0] = 'D' = 68

key = plaintext[0] - encrypted[0] = 68 - 28 = 40

The value 40 corresponds to ASCII character (.

Solution

Decryption Script

python
#!/usr/bin/env python3
"""
Duckerz CTF - Forgotten Password
Known Plaintext Attack on simple byte-shift cipher
"""

flag = b'\x1c-\x1b#\x1d*2S(\x0c\n\nO\x08J<7\x1bJ\x0c\x1bC=\x1c7/\t\x0f@7\x1b\x0c\x1d\r\x0cJU'
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

# Calculate key using known plaintext
# First byte of encrypted flag: 0x1c (28)
# First character of flag format: 'D' (68)
# key = 68 - 28 = 40 (ASCII '(')
key = ord('D') - flag[0]
print(f"[*] Calculated key: {key} (ASCII: '{chr(key)}')")

# Decrypt
decrypted = []
for byte in flag:
    decrypted.append(chr(byte + key))

result = ''.join(decrypted)
print(f"[*] Flag: {result}")

Alternative Method: Using the Program Itself

You can enter a message ending with the character ( (ASCII 40):

bash
$ python3 rev.py
[*] Hello this is simple cipher program. Enter the message: 
test(
[*] This is your cipher text: ...
[*] This is flag output: DUCKERZ{REDACTED}

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Notes

  • The flag name C4E54r hints at Caesar cipher
  • This is a classic example of byte-shift encryption
  • Known Plaintext Attack is effective against any cipher with a fixed key
  • import math in the code is unused (possibly a red herring) ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍