# CRYPTOHACK

## Introduction to CryptoHack

{% tabs %}
{% tab title="Finding Flags" %}
*Each challenge is designed to help introduce you to a new piece of cryptography. Solving a challenge will require you to find a "flag".*\
\
*These flags will usually be in the format `crypto{y0ur_f1rst_fl4g}`. The flag format helps you verify that you found the correct solution.*\
\
*Try submitting this flag into the form below to solve your first challenge.*

*Answer - `crypto{y0ur_f1rst_fl4g}`*
{% endtab %}

{% tab title="Great Snakes" %}
{% code title="Exploit.py" %}

```python
#!/usr/bin/env python3

import sys
# import this

if sys.version_info.major == 2:
    print("You are running Python 2, which is no longer supported. Please update to Python 3.")

ords = [81, 64, 75, 66, 70, 93, 73, 72, 1, 92, 109, 2, 84, 109, 66, 75, 70, 90, 2, 92, 79]

print("Here is your flag:")
print("".join(chr(o ^ 0x32) for o in ords))

```

{% endcode %}

### **Code Explanation**

```python
#!/usr/bin/env python3
```

**Shebang Line**: *This tells the system to use Python 3 to run this script.*

### Import Statements

```python
import sys
```

**Imports the `sys` module**: *Used to check the version of Python running the script.*

```python
# import this
```

**Commented out**: *The line `import this` would display "The Zen of Python," a list of aphorisms that capture the philosophy of Python, but it's commented out, so it does nothing.*

### Python Version Check

```python
if sys.version_info.major == 2:
    print("You are running Python 2, which is no longer supported. Please update to Python 3.")
```

*This checks if the script is being run with Python 2. If so, it prints a message advising the user to switch to Python 3. Python 2 is outdated and no longer maintained.*

### Encrypted Data

```python
ords = [81, 64, 75, 66, 70, 93, 73, 72, 1, 92, 109, 2, 84, 109, 66, 75, 70, 90, 2, 92, 79]
```

*`ords` is a list of integers that represent encrypted data.*

### Decryption Process

```python
print("Here is your flag:")
print("".join(chr(o ^ 0x32) for o in ords))
```

* **Decryption Logic**:
  * **`chr(o ^ 0x32)`**: *For each integer `o` in the `ords` list, a bitwise XOR operation is performed with `0x32` (which is 50 in decimal). The result is then converted to a character using `chr()`.*
  * **`o ^ 0x32`**: *The XOR operation is used to decrypt each integer. XOR is a common operation used in simple encryption and decryption.*
* **Result**:
  * **`"".join(...)`**: *Joins all the decrypted characters into a single string, which is printed as the flag.*

### How XOR Works

* *XOR (exclusive OR) is a bitwise operation that returns `1` if the bits are different and `0` if they are the same. It is often used in encryption because applying the same operation twice with the same key will return the original value. In this case, `0x32` is the key used for both encryption and decryption.*

### Output

* *The script decrypts the integers in `ords` and prints the hidden flag.*

*Answer -* `crypto{z3n_0f_pyth0n}`
{% endtab %}

{% tab title="ASCII" %}
*ASCII is a 7-bit encoding standard which allows the representation of text using the integers 0-127.*

*Using the below integer array, convert the numbers to their corresponding ASCII characters to obtain a flag.*

```python
[99, 114, 121, 112, 116, 111, 123, 65, 83, 67, 73, 73, 95, 112, 114, 49, 110, 116, 52, 98, 108, 51, 125]
```

&#x20;In Python, the `chr()` function can be used to convert an ASCII ordinal number to a character (the `ord()` function does the opposite).

## Solution

{% code title="Exploit.py" %}

```python
# This script converts an array of ASCII ordinal numbers into a string using Python's chr() function

# Define the array of ASCII ordinal numbers
ascii_numbers = [99, 114, 121, 112, 116, 111, 123, 65, 83, 67, 73, 73, 95, 112, 114, 49, 110, 116, 52, 98, 108, 51, 125]

# Convert each number to its corresponding character using chr() and join them into a single string
flag = ''.join(chr(number) for number in ascii_numbers)

# Print the resulting flag
print("The flag is:", flag)
```

{% endcode %}

### **Explanation**

*The code converts a list of ASCII ordinal numbers into a string:*

1. *It uses `chr()` to transform each number into a character.*
2. *It joins all characters into a single string.*
3. *Finally, it prints the string as the flag.*

**Result**: *A readable flag from the given numbers.*

*Answer -* `crypto{ASCII_pr1nt4bl3}`
{% endtab %}

{% tab title="Hex" %}
*When we encrypt something the resulting ciphertext commonly has bytes which are not printable ASCII characters. If we want to share our encrypted data, it's common to encode it into something more user-friendly and portable across different systems.*

*Hexadecimal can be used in such a way to represent ASCII strings. First each letter is converted to an ordinal number according to the ASCII table (as in the previous challenge). Then the decimal numbers are converted to base-16 numbers, otherwise known as hexadecimal. The numbers can be combined together, into one long hex string.*

*Included below is a flag encoded as a hex string. Decode this back into bytes to get the flag.*

```python
63727970746f7b596f755f77696c6c5f62655f776f726b696e675f776974685f6865785f737472696e67735f615f6c6f747d
```

*In Python, the `bytes.fromhex()` function can be used to convert hex to bytes. The `.hex()` instance method can be called on byte strings to get the hex representation.*

## Solution

{% code title="Exploit.py" %}

```python
# Script to decode a hex string to ASCII

# Given hex string
hex_string = "63727970746f7b596f755f77696c6c5f62655f776f726b696e675f776974685f6865785f737472696e67735f615f6c6f747d"

# Convert hex string to bytes
decoded_bytes = bytes.fromhex(hex_string)

# Convert bytes to ASCII string
decoded_string = decoded_bytes.decode('ascii')

# Print the result
print("Decoded String:", decoded_string)
```

{% endcode %}

### **Explanation**

*This script decodes a given hexadecimal string into an ASCII text. Here's a short explanation of what each part does:*

1. **hex\_string**: *The given hexadecimal string represents encoded text.*
2. **bytes.fromhex(hex\_string)**: *Converts the hex string into a sequence of bytes.*
3. **decode('ascii')**: *Translates the byte sequence into an ASCII string.*
4. **print**: *Outputs the decoded ASCII string.*

*Answer -* `crypto{You_will_be_working_with_hex_strings_a_lot}`
{% endtab %}

{% tab title="Base64" %}
*Another common encoding scheme is Base64, which allows us to represent binary data as an ASCII string using an alphabet of 64 characters. One character of a Base64 string encodes 6 binary digits (bits), and so 4 characters of Base64 encode three 8-bit bytes.*\
\
*Base64 is most commonly used online, so binary data such as images can be easily included into HTML or CSS files.*\
\
*Take the below hex string, decode it into bytes and then encode it into Base64.*

```python
72bca9b68fc16ac7beeb8f849dca1d8a783e8acf9679bf9269f7bf
```

*In Python, after importing the base64 module with `import base64`, you can use the `base64.b64encode()` function. Remember to decode the hex first as the challenge description states.*

## Solution

{% code title="Exploit.py" %}

```python
import base64

# Given hex string
hex_string = "72bca9b68fc16ac7beeb8f849dca1d8a783e8acf9679bf9269f7bf"

# Step 1: Decode the hex string to bytes
decoded_bytes = bytes.fromhex(hex_string)

# Step 2: Encode the bytes into Base64
base64_encoded = base64.b64encode(decoded_bytes)

# Step 3: Convert the Base64 bytes to a string
base64_string = base64_encoded.decode('ascii')

# Print the result
print("Base64 Encoded String:", base64_string)
```

{% endcode %}

### Explanation

*This script takes a hexadecimal string, decodes it to bytes, and then re-encodes it in Base64 format. Here’s a concise explanation:*

1. **hex\_string**: *A given string in hexadecimal format, where each pair of characters represents a byte.*
2. **bytes.fromhex(hex\_string)**: *Converts the hexadecimal string into a sequence of raw bytes.*
3. **base64.b64encode(decoded\_bytes)**: *Encodes the byte sequence into Base64, a commonly used encoding for binary data.*
4. **.decode('ascii')**: *Converts the Base64-encoded byte sequence into a readable ASCII string.*
5. **print**: *Outputs the final Base64-encoded string.*

**In short:** *The script converts a hex-encoded string to a Base64-encoded string and prints it.*

*Answer -* `crypto/Base+64+Encoding+is+Web+Safe/`
{% endtab %}

{% tab title="Bytes and Big Integers" %}
*Cryptosystems like RSA works on numbers, but messages are made up of characters. How should we convert our messages into numbers so that mathematical operations can be applied?*

*The most common way is to take the ordinal bytes of the message, convert them into hexadecimal, and concatenate. This can be interpreted as a base-16/hexadecimal number, and also represented in base-10/decimal.*

*To illustrate:*

```python
message: HELLO
ascii bytes: [72, 69, 76, 76, 79]
hex bytes: [0x48, 0x45, 0x4c, 0x4c, 0x4f]
base-16: 0x48454c4c4f
base-10: 310400273487
```

*Python's PyCryptodome library implements this with the methods `bytes_to_long()` and `long_to_bytes()`. You will first have to install PyCryptodome and import it with `from Crypto.Util.number import *`.*

**Convert the following integer back into a message:**

```python
11515195063862318899931685488813747395775516287289682636499965282714637259206269
```

## Solution

{% code title="Exploit.py" %}

```python
from Crypto.Util.number import long_to_bytes

# Given large integer
large_integer = 11515195063862318899931685488813747395775516287289682636499965282714637259206269

# Convert the integer to bytes and then decode to ASCII
message = long_to_bytes(large_integer).decode('ascii')

# Print the result
print("Decoded Message:", message)
```

{% endcode %}

### Explanation

*This script converts a large integer into a readable ASCII message using the `long_to_bytes` function from the `Crypto.Util.number` module. Here’s a breakdown of what the code does:*

1. **large\_integer**: *A very large integer that represents encoded data.*
2. **long\_to\_bytes(large\_integer)**: *Converts the large integer into a sequence of bytes. This is a common step in cryptography when dealing with large numbers that encode text.*
3. **.decode('ascii')**: *Translates the byte sequence into a readable ASCII string.*
4. **print**: *Outputs the decoded ASCII message.*

#### In Short:

*The script decodes a large integer into an ASCII message. It does this by first converting the integer to bytes and then decoding those bytes into text.*

*Answer -* `crypto{3nc0d1n6_4ll_7h3_w4y_d0wn}`
{% endtab %}
{% endtabs %}
