generated from stratosphereips/awesome-code-template
-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
implement new challenge Leet Messenger
- Loading branch information
1 parent
f028721
commit 5613f69
Showing
9 changed files
with
266 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
FROM python:3-slim | ||
|
||
RUN apt update && apt install -y gcc | ||
|
||
RUN mkdir /opt/app | ||
WORKDIR /opt/app | ||
|
||
COPY main.c send.py /opt/app/ | ||
|
||
RUN gcc main.c -o binary && gzip binary | ||
|
||
CMD ["python3", "send.py"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
# Leet Messenger | ||
|
||
This challenge has 2 phases. | ||
|
||
In the first one, students are told someone is trying to speak with them. They should start capturing packets. They should | ||
notice there is a lot of TCP SYN packets coming to a port 1337 (leet). But there is no listener. After starting a TCP listener on | ||
port 1337, they will get a payload. | ||
|
||
The payload has a custom protocol format. The format is | ||
|
||
``` | ||
MAGIC_NUMBER (4 bytes) | VERSION (1 byte) | LEN_OF_MSG (8 bytes) | BASE_64_MSG_DATA | LEN_OF_DATA (8 bytes) | DATA | ||
``` | ||
|
||
The base64 encoded message contains a first flag and also hint to keep digging. | ||
|
||
The data section contains raw bytes which is a gz compressed ELF 64 bits executable file. Students should extract the | ||
data, gunzip the file and reverse engineer the binary. By reversing the binary, students should find a correct input to the | ||
binary which passes the implemented check. If they succeed, the binary prints that this is a correct input and that the input is | ||
also a 2nd flag. | ||
|
||
Voilá. | ||
|
||
## How to solve | ||
<details> | ||
<summary>Click to reveal how to solve steps</summary> | ||
|
||
TODO: write proper how to solve | ||
|
||
1. start ncat listener and pipe the received data to a file | ||
```bash | ||
root@hackerlab:~# nc -lnvp 1337 > received.data | ||
Ncat: Version 7.93 ( https://nmap.org/ncat ) | ||
Ncat: Listening on :::1337 | ||
Ncat: Listening on 0.0.0.0:1337 | ||
Ncat: Connection from 172.20.0.67. | ||
Ncat: Connection from 172.20.0.67:49948. | ||
``` | ||
|
||
2. decode the base64 encoded message to find 1st flag | ||
```bash | ||
root@hackerlab:~# strings received.data | head -n1 | base64 -d | ||
Oh finally you hear me!!! This is your flag BSY{a!sk&fjlhý76S5F9OUILFNRQKJLRHIUFKHAS}. Now, you might be interested in the rest of the messagebase64: invalid input``` | ||
``` | ||
|
||
3. install binwalk, use it to extract the gzip and find the binary. Then use your favorite disassembler (gdb, ida, ghidra, ...) to find the implementation of the check and figure out a correct input (the 2nd flag) | ||
```bash | ||
root@hackerlab:~# binwalk -e received.data --run-as=root | ||
DECIMAL HEXADECIMAL DESCRIPTION | ||
-------------------------------------------------------------------------------- | ||
213 0xD5 gzip compressed data, has original file name: "binary", from Unix, last modified: 2024-11-20 22:56:19 | ||
root@hackerlab:~# ls | ||
_received.data.extracted received received.data | ||
root@hackerlab:~# gzip _received.data.extracted/binary^C | ||
root@hackerlab:~# file _received.data.extracted/binary | ||
_received.data.extracted/binary: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=7442f69752d03fa6c11be89b5427782a6879efd9, for GNU/Linux 3.2.0, not stripped | ||
root@hackerlab:~# chmod +x ./_received.data.extracted/binary | ||
root@hackerlab:~# ./_received.data.extracted/binary | ||
Usage: ./_received.data.extracted/binary flag | ||
root@hackerlab:~# ./_received.data.extracted/binary is_this_the_flag? | ||
Incorrect flag. Try harder! | ||
root@hackerlab:~# ./_received.data.extracted/binary iam-reverse-king | ||
You found it! You can submit the flag, good job :) | ||
``` | ||
|
||
</details> | ||
|
||
## Testing | ||
|
||
The script [auto-solve.sh](./auto-solve.sh) automatically verifies that the challenge can be solved. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
#!/bin/bash | ||
|
||
# try to get the payload with all required data | ||
nc -lnvp 1337 > received.data 2> /dev/null | ||
|
||
# search for the 1st flag | ||
MATCH=`strings received.data | head -n1 | base64 -d 2> /dev/null | \ | ||
grep -o "BSY{a!sk&fjlhý76S5F9OUILFNRQKJLRHIUFKHAS}"` | ||
if [[ "$MATCH" == "" ]] | ||
then | ||
echo "Error - did not find a 1st base64 encoded flag in the received data" | ||
exit 1 | ||
fi | ||
|
||
# submit the 1st flag | ||
RES=`curl -s 'http://172.20.0.3/api/challenges/submit' \ | ||
-X POST \ | ||
-H 'Content-Type: application/json' \ | ||
--data-binary '{"challenge_id": "leet_messenger_id", "task_id": "task1", "flag" : "BSY{a!sk&fjlhý76S5F9OUILFNRQKJLRHIUFKHAS}"}'` | ||
|
||
if [[ $RES != *"Congratulations"* ]]; then | ||
echo "Failed to submit the 1st flag - $RES" | ||
exit 2 | ||
fi | ||
|
||
|
||
# if the machine is x86, run the binary with a correct input (2nd flag) to see if it outputs expected output. | ||
# (first we have to extract the binary tho) | ||
if [ "$(uname -m)" == "x86_64" ] || [ "$(uname -m)" == "i686" ]; then | ||
binwalk -e received.data --run-as=root > /dev/null | ||
chmod +x ./_received.data.extracted/binary | ||
MATCH=`./_received.data.extracted/binary iam-reverse-king | grep -o "You found it! You can submit the flag, good job :)"` | ||
if [[ "$MATCH" == "" ]] | ||
then | ||
echo "Error - inputting correct input to the binary did not print expected output" | ||
exit 3 | ||
fi | ||
|
||
RES=`curl -s 'http://172.20.0.3/api/challenges/submit' \ | ||
-X POST \ | ||
-H 'Content-Type: application/json' \ | ||
--data-binary '{"challenge_id": "leet_messenger_id", "task_id": "task2", "flag" : "iam-reverse-king"}'` | ||
if [[ $RES != *"Congratulations"* ]]; then | ||
echo "Failed to submit the 2st flag - $RES" | ||
exit 4 | ||
fi | ||
|
||
else | ||
echo "Skipping check of 2nd flag because this is probably not x86 machine. so I cannot run the ELF x86 binary" | ||
fi | ||
|
||
|
||
echo "OK - tests passed" | ||
exit 0 | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
version: '3.3' | ||
|
||
services: | ||
challenge-leet-messenger: | ||
container_name: scl-leet-messenger | ||
stop_grace_period: 0s | ||
build: . | ||
networks: | ||
playground-net: | ||
ipv4_address: 172.20.0.67 | ||
healthcheck: | ||
test: ["CMD", "python", "-c", "'import requests; response = requests.get(\"http://localhost/\"); assert response.status_code == 200'"] | ||
interval: 30s | ||
timeout: 10s | ||
retries: 3 | ||
start_period: 10s | ||
|
||
networks: | ||
playground-net: | ||
external: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#include <stdio.h> | ||
#include <string.h> | ||
|
||
const char bsy[] = "!cyberlab_rocks!"; | ||
const char just_an_array[16] = { 0x4d, 0x7, 0x19, 0x54, 0x1c, 0x1c, 0x1f, 0x9, 0x15, 0x31, 0x1c, 0x47, 0xd, 0x7, 0x22, 0x4b }; | ||
|
||
int check_flag(char *flag){ | ||
int str_len = strlen(flag); | ||
for (int i=0; i<str_len; i++){ | ||
char temp = (just_an_array[i] - 5) ^ bsy[i]; | ||
if (temp != flag[i]){ | ||
return 0; | ||
} | ||
} | ||
return 1; | ||
} | ||
|
||
int main(int argc, char **argv){ | ||
if (argc != 2){ | ||
printf("Usage: %s flag\n", argv[0]); | ||
} else { | ||
char *flag = argv[1]; | ||
if (strlen(flag) != 16){ | ||
printf("Incorrect flag. Try harder!\n"); | ||
} else { | ||
int result = check_flag(flag); | ||
if (result == 1){ | ||
printf("You found it! You can submit the flag, good job :)\n"); | ||
} else { | ||
printf("Nope, that's not it!\n"); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
{ | ||
"name": "Leet Messenger", | ||
"id": "leet_messenger_id", | ||
"difficulty": "hard", | ||
"description": "", | ||
"tasks": [ | ||
{ | ||
"id": "task1", | ||
"name": "A message", | ||
"description": "A leet coder is trying to tell you something, can you find it and make a sense of it?", | ||
"flag": "BSY{a!sk&fjlhý76S5F9OUILFNRQKJLRHIUFKHAS}" | ||
}, | ||
{ | ||
"id": "task2", | ||
"name": "Reverse it", | ||
"description": "After you find the 1st message, there might be a 2nd hidden message.", | ||
"flag": "iam-reverse-king" | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import struct | ||
import socket | ||
import base64 | ||
|
||
from time import sleep | ||
|
||
|
||
def craft_payload(message: str, data: bytes) -> bytes: | ||
magic_number = 0x1A2B3C4D | ||
version = 0x01 | ||
|
||
msg_encoded = base64.b64encode(message.encode()) | ||
|
||
payload = struct.pack('!I B', magic_number, version) # represents header | ||
payload += struct.pack("Q", len(msg_encoded)) | ||
payload += msg_encoded | ||
payload += struct.pack("Q", len(data)) | ||
payload += data | ||
return payload | ||
|
||
|
||
def send(payload: bytes): | ||
dst_ip = "172.20.0.2" | ||
dst_port = 1337 | ||
|
||
with socket.create_connection((dst_ip, dst_port)) as sock: | ||
sock.sendall(payload) | ||
|
||
|
||
def main(): | ||
first_flag = "BSY{a!sk&fjlhý76S5F9OUILFNRQKJLRHIUFKHAS}" | ||
msg = f"Oh finally you hear me!!! This is your flag {first_flag}. Now, you might be interested in the rest of the message" | ||
binary_file = "binary.gz" | ||
|
||
with open(binary_file, "rb") as f: | ||
file_data = f.read() | ||
|
||
payload = craft_payload(msg, file_data) | ||
while True: | ||
try: | ||
send(payload) | ||
except ConnectionRefusedError: | ||
pass | ||
except Exception as e: | ||
print(f"Unexpected exception while sending packets: {e}") | ||
|
||
sleep(5) | ||
|
||
if __name__ == "__main__": | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters