Skip to content

Instantly share code, notes, and snippets.

@cetaSYN
Last active December 12, 2020 00:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cetaSYN/c7c6050ff141a02062598095254fbf22 to your computer and use it in GitHub Desktop.
Save cetaSYN/c7c6050ff141a02062598095254fbf22 to your computer and use it in GitHub Desktop.
Solve for 5CTF Disorderly2
#!/usr/bin/env python3
# Wrapper for binary setsolve performing set de-duplication and decryption bruting
import argparse
import re
import subprocess
import itertools
from disorderly2 import decrypt
FLAG_PTRN = re.compile(r"flag{[a-zA-Z0-9$!@_-]+}")
with open("encoded.txt") as f:
encmsg = f.read().strip()
def alphagen(sets, delims):
for i in list(itertools.permutations(sets, 7)): # Generate all possible sets
yield "".join(
# Combine tuples and append delimiters
list(itertools.chain(*[i[0], i[1], i[2], i[3], i[4], i[5], i[6], delims]))
)
def main():
parser = argparse.ArgumentParser()
parser.add_argument("delimiters")
args = parser.parse_args()
if len(args.delimiters) != 5:
raise Exception("Must specify all 5 delimiter characters as a single string")
# Get and handle set solving from binary
sets = (
subprocess.check_output(["./setsolve", args.delimiters, "encoded.txt"])
.decode()
.split("\n")
)
sets = [s for s in list(set(sets)) if s != ""] # De-duplicate and remove empty
for alphabet in alphagen(sets, args.delimiters): # Iterate over all possible alphabets
decmsg = decrypt(encmsg, alphabet)
if re.search(FLAG_PTRN, decmsg):
print("FOUND: {}\nABET: {}".format(decmsg, alphabet))
break
if __name__ == "__main__":
main()
#!/usr/bin/python
# Provided by 5CTF Round 4
from random import choice, shuffle
from re import split as resplit
def encrypt(message, rnd=False, alphabet="abcdefghijklmnopqrstuvwxyz"):
if len(alphabet) != 26:
return ("error", "alphabet must be 26 letters")
if rnd:
alphabet = [alphabet[x] for x in range(len(alphabet))]
shuffle(alphabet)
alphabet = "".join(alphabet)
bits = {
64: alphabet[0:3],
32: alphabet[3:6],
16: alphabet[6:9],
8: alphabet[9:12],
4: alphabet[12:15],
2: alphabet[15:18],
1: alphabet[18:21],
}
endbit = alphabet[21:26]
output = ""
for letter in range(len(message)):
letter = message[letter]
crypt_letter = ""
for bit in bits.keys():
if ord(letter) & bit:
crypt_letter += choice(bits[bit])
crypt_letter = list(crypt_letter)
shuffle(crypt_letter)
crypt_letter = "".join(crypt_letter) + choice(endbit)
output += crypt_letter
return (alphabet, output)
def decrypt(message, alphabet="abcdefghijklmnopqrstuvwxyz"):
if len(alphabet) != 26:
return ("error", "alphabet must be 26 letters")
bits = {
64: alphabet[0:3],
32: alphabet[3:6],
16: alphabet[6:9],
8: alphabet[9:12],
4: alphabet[12:15],
2: alphabet[15:18],
1: alphabet[18:21],
}
endbit = alphabet[21:26]
letters = resplit("[" + endbit + "]", message)
output = ""
for letter in letters:
byte_value = 0
for part in range(len(letter)):
for k, v in bits.items():
if letter[part] in v:
byte_value += k
break
if byte_value:
output += chr(byte_value)
return output
ctlvoxqzgiaumcpuokwxuzbgmdxqaixdxgwufeojwqarvwckomvzgiaywhqtjcdplmdmowgajhpcwerfqgdxabpdvjzjvfqewreapqdjcdvlrowtcyzjczgljdicmzoarwcepmzmpambodcrduscerncphdojcdvkmwapxpcswyeuazjpdiareczonjdjslzmzjvszarioaugwxawtqkxigczmpzfydrwhfjtoawrwxkhozaxbwgusfjtdifjlctuwrfsgdytzaxvpbzjdmzrasuyozcvngxiagdvrvwapsyawkvjcqwxedgamtokazydgifxzcoxkwtcmdconxnpwvfoyatwuijqflzvywoyzrzxansmhtzsmbtofzjzmuzamcwsmczkhsjdanoyhcozjzfomazbpyadbtrnlaodrzyiawvygoadkrdqualyftezywjdotevcrehawmciqwxlwapjswbampfihzjozcghjwxqgczhnjgoadlrzlgcrzmswfrwychwjzestcmfwigvxuaozywciyzxiqagvdxfpvzxwxazquglyqndvgcxuzkfydgfmdflvqxdrkzsfuyqzuciprwridaokjipdquajqlcgzydxndcrqzarvplwcxgcwomwycpdiojofiugdyuzfejsgfzjwycpzmwqcrldapjazsjdjkpadxsfidugmzmvloadpxnuogwcrhldfrqczuijwmugdaskxqadbjtwalrifdxphwbrzywygauobmgeczycwnjawgorlwhcxvpqldamowanmqeavdjzcogjdmnawsxwgckxdmqtcvlzjcwpuqnyqzgfkxgnzargczjwxcwvygqczxdmbfdtoxotiwvarewvcrdpsajdxgcdywasnragzvxzpcujcsdbyhdfsmopedfmbzparpaedjpiwvydxdrocjgzcvbrzclqbxowkgaujszaxblfwqxbgzjdmqznaejtihswcxdcstexdalvjdywghcmtbwfjzqcjczqgujzxbszaycezuqrwmtzauyfizgyqdfrswatvyocvbezypkzcjnzcysazgjilfguoyzfuktqrhanzpqrehadmatndjgwcjqickthjsfziyldohayophcblrdvatmqfdnrhztnfmfowxcbwtjgdbcxlbqwcynaqlvgrawobmbwavgjqnkcphyangzqumvkzaxtfzrtfsdykdchxfbgkvsjewpamfzbjecwhrgnhoazrkotwfyhcwtsjcnzjqlghbaxzsfpjdncvprlczgyeavzywihqgfxlczrdnceqjtikwcsm
/**
* cetasyn - 10 Dec 20
*
* Finds characters that do not appear in groups together and prints the sets
* Does not de-duplicate, sort, find delimiters, or bruting decryption
* Run using c_solve.py wrapper for dedup and brute
*/
// $ gcc -Wall -pedantic -o setsolve setsolve.c
// $ ./setsolve jmrxy encoded.txt
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#define FILE_BUF_SZ 2048
#define ABET_LEN 26
#define DELIM_LEN 5
#define ALPHA_START 97
/**
* Print usage message to stderr
*/
void print_usage(char* path)
{
fprintf(stderr, "Usage: %s <delimiters{5}> <path>\nExample: %s vwxyz ./message.txt\n",
path,
path);
}
/**
* Alters a letter buffer to set a specified character to space
*/
void lbuf_spc_char(char* letter_buf, char c)
{
char* c_loc = strchr(letter_buf, c);
if (c_loc) {
*c_loc = ' ';
}
}
/**
* Returns non-space character count until \0
*/
unsigned int nonspc_strcnt(char* str) {
unsigned int count = 0;
while(*str) {
if(*str != ' ') {
count++;
}
str++;
}
return count;
}
/**
* Prints a string while removing all spaces
*/
void nonspc_print(char* str) {
while(*str) {
if(*str != ' ') {
putc(*str, stdout);
}
str++;
}
}
int main(int argc, char* argv[])
{
if (argc != 3) { // Verify correct number of args
print_usage(argv[0]);
return -1;
}
if (strlen(argv[1]) != DELIM_LEN) { // Verify correct delimiter string length
fprintf(stderr, "%i delimiters characters required\n", DELIM_LEN);
print_usage(argv[0]);
return -1;
}
FILE* f = fopen(argv[2], "r"); // File pointer
if (!f) { // Verify successful file open
int err = errno;
fprintf(stderr, "Failed to open: %s - %s\n", argv[2], strerror(err));
return -1;
}
char bits_delim[6] = { 0 }; // Delimiter bits
strncpy(bits_delim, argv[1], DELIM_LEN);
char contentbuf[FILE_BUF_SZ]; // Encoded text file content buffer
fscanf(f, "%s\n", contentbuf); // Read file contents
// Create and fill alphabet letter solve buffers
char letters_buf[ABET_LEN][ABET_LEN + 1];
for (int a = 0; a < ABET_LEN; a++) {
strcpy(letters_buf[a], "abcdefghijklmnopqrstuvwxyz\0");
}
// Pre-remove delimiters
for (int a = 0; a < ABET_LEN; a++) {
for (int dc = 0; dc < DELIM_LEN; dc++) {
lbuf_spc_char(letters_buf[a], bits_delim[dc]);
}
}
char* token; // Pointer to representation of encoded character
char* psub = contentbuf; // Pointer to delimiter position in content buffer
// Iterate over delimiters
for (;; psub = NULL) {
token = strtok(psub, bits_delim);
if (token == NULL) {
break;
}
// Iterate over characters in token - index of letter_buf
int tok_len = strlen(token);
for (int i_lb = 0; i_lb < tok_len; i_lb++) {
// Iterate again, remove all other characters from representative array
for (int i_c = 0; i_c < tok_len; i_c++) {
if (i_lb == i_c) {
continue; // Don't remove self
}
lbuf_spc_char(
letters_buf[(*(token + i_lb) - ALPHA_START)], // Index of letter buf by iter position offset
*(token + i_c)); // Letter by iter position offset
}
}
}
// Print sets of 3
for (int a = 0; a < ABET_LEN; a++) {
if (nonspc_strcnt(letters_buf[a]) == 3) {
nonspc_print(letters_buf[a]);
printf("\n");
}
}
fclose(f);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment