← Retour aux projets
🐍 Python Capture The Flag
Cybersecurity Hacking Réseau Encoding Regex Cryptographie CTF
Capture The Flag avec plusieurs challenges à résoudre et envoyer vers un serveur distant. Projet validant à l'ESGI pour la matière scripting python.
Code Source
'''
# @ Author: Enzo Juillard
# @ Description: Python exam (CTF) file
'''
import socket
import datetime as date
import re
import base64
import base58
import webcolors
ip = ""
#port =
# Functions
def caesar_decode(text, key):
result = ''
for char in text:
if char.isalpha():
if char.isupper():
# DEBUG : inversion du sens
result += chr((ord(char) - ord('A') + key) % 26 + ord('A'))
else:
result += chr((ord(char) - ord('a') + key) % 26 + ord('a'))
else:
result += char
return result
def send_answer(client_socket, answer):
client_socket.send(answer.encode("utf-8"))
response = client_socket.recv(1024)
return response.decode()
def ascii_to_char(ascii_codes_string):
return ''.join(chr(int(code) + 64) for code in ascii_codes_string.split())
# Connect to server
clientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
clientSocket.connect((ip,port))
# Receive first response
firstResponse = clientSocket.recv(1024)
print(firstResponse.decode())
# 1er FLAG - Send name, class
txt = "enzo/juillard/3SI3"
response = send_answer(clientSocket, txt)
print(response)
# 2ème FLAG - Send today's date
todayDate = date.datetime.now().strftime("%d/%m")
dateResponse = send_answer(clientSocket, todayDate)
print(dateResponse)
# 3ème FLAG - Send the result of calculation
regexCalculation = r"(d+)s*([+-*/])s*(d+)"
calculationQuestion = dateResponse
findNumbers = re.search(regexCalculation, calculationQuestion)
num1 = int(findNumbers.group(1))
operator = findNumbers.group(2)
num2 = int(findNumbers.group(3))
match operator:
case "*":
result = num1 * num2
case "-":
result = num1 - num2
case "+":
result = num1 + num2
calculationResponse = send_answer(clientSocket, str(result))
print(calculationResponse)
# 4ème FLAG - Message Decode
regexDecode = r"message:s*(.+)$"
decodeResponse = calculationResponse
code = re.search(regexDecode, decodeResponse)
codeString = code.group(1)
print(codeString)
decodedString = None
# Check base64
base64_pattern = r"^[A-Za-z0-9+/]*={0,2}$"
if re.match(base64_pattern, codeString) and len(codeString) % 4 == 0:
try:
decodedBytes = base64.b64decode(codeString)
decodedString = decodedBytes.decode("utf-8")
print(f"Decoded from base64: {decodedString}")
except Exception as e:
print(f"Base64 failed: {e}")
decodedString = None
# Check base32
if decodedString is None:
base32_pattern = r"^[A-Z2-7=]*$"
if re.match(base32_pattern, codeString):
try:
decodedBytes = base64.b32decode(codeString)
decodedString = decodedBytes.decode("utf-8")
print(f"Decoded from base32: {decodedString}")
except Exception as e:
print(f"Base32 failed: {e}")
decodedString = None
# Check base58
if decodedString is None:
base58_pattern = r"^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]*$"
if re.match(base58_pattern, codeString):
try:
decodedBytes = base58.b58decode(codeString)
decodedString = decodedBytes.decode("utf-8")
print(f"Decoded from base58: {decodedString}")
except Exception as e:
print(f"Base58 failed: {e}")
decodedString = None
# Check base85
if decodedString is None:
base85_pattern = r"^[!-u]+$"
if re.match(base85_pattern, codeString):
# Try first base85
try:
decodedBytes = base64.b85decode(codeString)
decodedString = decodedBytes.decode("utf-8")
print(f"Decoded from base85: {decodedString}")
except Exception:
# Try second base85
try:
decodedBytes = base64.a85decode(codeString)
decodedString = decodedBytes.decode("utf-8")
print(f"Decoded from base85: {decodedString}")
except Exception as e:
print(f"Base85 failed: {e}")
decodedString = None
if decodedString is not None:
finalResponse = send_answer(clientSocket, decodedString)
print(finalResponse)
# 5ème FLAG - Message Majuscle Decode
regexMajDecode = r"majuscule:s*(.+)$"
decodeMajResponse = finalResponse
majCode = re.search(regexMajDecode, decodeMajResponse)
majCodeString = majCode.group(1)
print(majCodeString)
majDecoded = (bytes.fromhex(majCodeString).decode("utf-8").upper())
word = ''
word += majDecoded[0]
for i in range(len(majDecoded)):
if majDecoded[i] == " " and i+1 < len(majDecoded):
word += majDecoded[i+1].upper()
print(f"Decoded: {word}")
majDecodeResponse = send_answer(clientSocket, word)
print(majDecodeResponse)
# 6ème FLAG - Message majuscle Decode 2
regexCaesarDecode = r"majuscule:s*(.+)$"
decodeCaesarResponse = majDecodeResponse
hexCaesarCode = re.search(regexCaesarDecode, decodeCaesarResponse)
hexCaesarCodeString = hexCaesarCode.group(1)
print(hexCaesarCodeString)
# Convertion HEXA vers ASCII
asciiCodesString = bytes.fromhex(hexCaesarCodeString).decode("utf-8")
print(f"HEXA decode: {asciiCodesString}")
# Convertion ASCII vers char
asciiCharacters = ascii_to_char(asciiCodesString)
print(f"ASCII decode: {asciiCharacters}")
# Caesar decode
caesarPlaintext = caesar_decode(asciiCharacters, 5).upper()
print(f"Ceasar decoded: {caesarPlaintext}")
caesarDecodeResponse = send_answer(clientSocket, caesarPlaintext)
print(caesarDecodeResponse)
# 7ème FLAG - RGB
regexRGB = r"RGBs*[:=]?s*(?(d+),s*(d+),s*(d+))?"
rgbResponse = caesarDecodeResponse
rgbCode = re.search(regexRGB, rgbResponse)
rgbRed = int(rgbCode.group(1))
rgbGreen = int(rgbCode.group(2))
rgbBlue = int(rgbCode.group(3))
print(rgbRed, rgbGreen, rgbBlue)
rgbColor = webcolors.rgb_to_name((rgbRed, rgbGreen, rgbBlue)).upper()
print(f"RGB Name: {rgbColor}")
rgbResponse = send_answer(clientSocket, rgbColor)
print(rgbResponse)
# 8ème FLAG - Previous question answer (Build function that detect numero of question and return the answer)
regexPreviousQuestion = r"questions+(d+)"
previousQuestionResponse = rgbResponse
previousNumber = re.search(regexPreviousQuestion, previousQuestionResponse)
questionNumber = int(previousNumber.group(1))
print(f"Question number: {questionNumber}")
tabAnswers = [txt, todayDate, str(result), decodedString, word, caesarPlaintext, rgbColor]
previousAnswer = tabAnswers[questionNumber - 1]
previousQuestionAnswer = send_answer(clientSocket, previousAnswer)
print(previousQuestionAnswer)
# 9ème FLAG - Last letter of the Xth word
regexNumberWord = r"dernière lettre du (d+)ème mot"
regexWordsList = r"liste:s*(.+)$"
lastLetterResponse = previousQuestionAnswer
numberWordMatch = re.search(regexNumberWord, lastLetterResponse)
wordsListMatch = re.search(regexWordsList, lastLetterResponse)
wordIndex = int(numberWordMatch.group(1)) - 1
wordsList = wordsListMatch.group(1).split()
lastLetter = wordsList[wordIndex][-1]
lastLetterResponse = send_answer(clientSocket, lastLetter)
print(lastLetterResponse)
# 10ème FLAG - All previous answers with underscore
tabAnswers.append(previousAnswer)
tabAnswers.append(lastLetter)
underscoreAnswers = '_'.join(tabAnswers)
print(tabAnswers)
print(underscoreAnswers)
underscoreResponse = send_answer(clientSocket, underscoreAnswers)
print(underscoreResponse)
# Close the connection
clientSocket.close()