Post

HackTheBox Secure Singning Writeup

Explore the basics of cybersecurity in the Secure Singning Challenge on Hack The Box. This easy-level Challenge introduces encryption reversal and file handling concepts in a clear and accessible way, perfect for beginners.

https://app.hackthebox.com/challenges/509

Description

Can you crack our Ultra Secure Signing Oracle?

Source

server.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
from hashlib import sha256
from secret import FLAG

WELCOME_MSG = """
Welcome to my Super Secure Signing service which uses unbreakable hash function.
We combine your Cipher with our secure key to make sure that it is more secure than it should be.
"""

def menu():
    print("1 - Sign Your Message")
    print("2 - Verify Your Message")
    print("3 - Exit")

def xor(a, b):
    return bytes([i ^ j for i, j in zip(a, b)])

def H(m):
    return sha256(m).digest()

def main():
    print(WELCOME_MSG)
    while True:
        try:
            menu()
            choice = int(input("> "))
        except:
            print("Try again.")
            continue
        if choice == 1:
            message = input("Enter your message: ").encode()
            hsh = H(xor(message, FLAG))
            print(f"Hash: {hsh.hex()}")
        elif choice == 2:
            message = input("Enter your message: ").encode()
            hsh = input("Enter your hash: ")
            if H(xor(message, FLAG)).hex() == hsh:
                print("[+] Signature Validated!\n")
            else:
                print(f"[!] Invalid Signature!\n")
        else:
            print("Good Bye")
            exit(0)

if __name__ == "__main__":
    main()

secret.py

1
FLAG = b"HTB{T3ST}"

Overview

The goal of this process is to extract a secret FLAG from a signing service that hashes messages combined with the FLAG. By understanding how the XOR operation works, we can cleverly deduce the FLAG without needing direct access to it.

Key Concepts

  1. Self-Canceling: \(A \oplus A = 0\)
    • XORing a value with itself results in zero.
  2. Reversible: \(A \oplus B \oplus B = A\)
    • You can recover the original value by XORing it with the same value again.
  3. Hashing Function: The signing function produces a hash of the format H(xor(message, FLAG)). This means the hash depends on both the input message and the secret FLAG.

Attack Strategy

  1. Submit Two Distinct Messages:
    • Choose two different messages (e.g., m1 and m2) and submit them to the signing service to get their hashes:
      • HASH1 = H(xor(m1, FLAG))
      • HASH2 = H(xor(m2, FLAG))
  2. Extract FLAG Using XOR:
    • XOR the two hashes: [ FLAG = HASH1 \(\oplus\) HASH2]
    • This operation isolates the FLAG by canceling out the contributions from the messages.

Exploitation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#!/usr/bin/env python
import sys
import string
from hashlib import sha256
from pwn import *

exe = 'server.py'
context.log_level = 'info'
charset = string.ascii_letters + string.digits + string.punctuation

def get_process():
    if len(sys.argv) != 2:
        print(f'Usage: python {sys.argv[0]} <ip:port>')
        sys.exit(1)
    host, port = sys.argv[1].split(':')
    return remote(host, int(port))

def xor(a, b):
    return bytes(i ^ j for i, j in zip(a, b))

def H(m):
    return sha256(m).digest()

def main():
    io = get_process()
    p = log.progress('Flag')
    last_flag = last_hash = new_hash = zero_xor_hash = ""
    while zero_xor_hash == new_hash:
        flag_length = len(last_flag) + 1
        zero_xor_flag = "." * flag_length
        zero_xor_hash = H(xor(zero_xor_flag.encode(), zero_xor_flag.encode())).hex()
        for c in charset:
            new_flag = last_flag + c
            io.recvuntil(b"> ")
            io.sendline(b"1")
            io.recvuntil(b": ")
            io.sendline(new_flag.encode())
            io.recvuntil(b": ")
            new_hash = io.recvline().strip().decode()
            if zero_xor_hash == new_hash:
                last_flag = new_flag
                last_hash = new_hash
                p.status(f"{new_flag} {new_hash}")
                break
            elif last_hash == new_hash:
                p.success(f"{last_flag}")
                io.close()
                return
    io.close()

if __name__ == '__main__':
    main()

Summary

The Secure Signing Challenge on Hack The Box is an entry-level cryptography task that exposes vulnerabilities in cryptographic signing via a Python server using SHA-256 and XOR operations. Participants exploit XOR’s reversible nature by manipulating message hashes to deduce a hidden FLAG. This challenge allows beginners to explore cryptographic weaknesses practically, underscoring the need for robust encryption and secure hashing practices in cybersecurity.

This post is licensed under CC BY 4.0 by the author.