Skip to content

Commit

Permalink
rev(license-ops): re-commit challenge
Browse files Browse the repository at this point in the history
  • Loading branch information
s3nn authored Apr 30, 2024
1 parent 65e49fe commit ff3aee6
Show file tree
Hide file tree
Showing 8 changed files with 261 additions and 0 deletions.
28 changes: 28 additions & 0 deletions reverse/license-ops/challenge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: "License Ops"
author: "s3nn"
category: reverse

description: |
You are thrust into a clandestine digital realm, where enigmatic forces threaten global stability. As a recruit of an elite cyber task force, your mission is to navigate the shadowy depths of encrypted networks. Unravel the mysteries of covert communications, decrypt encrypted traffic, and decipher the intentions behind cryptic commands. Amidst the chaos, you'll confront the challenge of dissecting obscure digital artifacts, piecing together their secrets to safeguard the digital frontier. Are you prepared to dive into the unknown and emerge as a master of the digital domain?
value: 500
type: dynamic_docker
extra:
initial: 500
minimum: 100
decay: 25
redirect_type: direct
compose_stack: !filecontents docker-compose.yml

flags:
- CCSC{Y0ur_Rev3rsing_Journey_Just_st4rted}

tags:
- reverse
- easy

files:
- "public/license"

state: visible
version: "0.1"
13 changes: 13 additions & 0 deletions reverse/license-ops/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
version: "3.7"

services:
challenge:
image: ghcr.io/cybermouflons/ccsc2024/license-ops:latest
restart: always
ports:
- 1337:1337
build:
context: ./setup
dockerfile: Dockerfile
labels:
ctf.challenge.name: License Ops
Binary file added reverse/license-ops/public/license
Binary file not shown.
15 changes: 15 additions & 0 deletions reverse/license-ops/setup/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@

FROM ubuntu

RUN apt-get update && apt-get upgrade -y
RUN apt-get install -y socat gcc-multilib

# set workdir and transfer binary
WORKDIR /root
COPY license .
COPY flag.txt .

RUN chmod 755 license

EXPOSE 1337
CMD ["socat", "-v","TCP-LISTEN:1337,reuseaddr,fork,su=root", "EXEC:'/root/license'"]
1 change: 1 addition & 0 deletions reverse/license-ops/setup/flag.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CCSC{Y0ur_Rev3rsing_Journey_Just_st4rted}
Binary file added reverse/license-ops/setup/license
Binary file not shown.
95 changes: 95 additions & 0 deletions reverse/license-ops/setup/license.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>

//gcc -o license license.c -g

void get_flag() {
FILE *file = fopen("flag.txt", "r");
if (file != NULL) {
char line[256];
while (fgets(line, sizeof(line), file)) {
printf("%s", line);
}
fclose(file);
} else {
printf("Error: Unable to open flag file.\n");
}
}

bool isValidProductKey(char *productKey) {
// Check the first 3 characters
char *invalidPrefixes[] = {"333", "444", "555", "666", "777", "888", "999"};
for (int i = 0; i < 7; i++) {
if (strncmp(productKey, invalidPrefixes[i], 3) == 0) {
return false;
}
}

// Check the fourth character
if (productKey[3] != '_') {
return false;
}

// Check the last 7 characters
char *lastSevenDigits = productKey + 4; // Skip the first 4 characters
for (int i = 0; i < 7; i++) {
if (lastSevenDigits[i] < '0' || lastSevenDigits[i] > '8') {
return false;
}
}

// Calculate the sum of the last 7 digits
int sum = 0;
for (int i = 0; i < 7; i++) {
sum += (lastSevenDigits[i] - '0');
}

// Check if the sum is divisible by 7
if (sum % 7 != 0) {
return false;
}

// If all checks pass, the product key is valid
return true;
}

bool check_password() {
char password[16] = "OrionProtc0l!!!";
char user_input[32];

printf("Enter password: ");
read(0, user_input, 32);

if (strcmp(user_input, password) == 0) {
return true;
} else {
return false;
}
}

int main() {
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stdin, NULL, _IONBF, 0);

char productKey[12] = {0};
printf("Enter a Windows 95 product key: ");
read(0, productKey, 12);
productKey[12] = '\0';

if (isValidProductKey(productKey)) {
printf("Product key is valid!\n");
if (check_password()) {
printf("Password correct!\n");
get_flag();
} else {
printf("Incorrect password.\n");
}
} else {
printf("Invalid product key.\n");
}

return 0;
}
109 changes: 109 additions & 0 deletions reverse/license-ops/sol/sol.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#!/usr/bin/python

import random
import os
from pwn import *

os.chdir('../setup')

elf = context.binary = ELF("license", checksec=False)
context.terminal = ['kitty', '@', 'launch', '--cwd', 'current', '--location', 'hsplit', '--title', 'DEBUG']
gs = '''
init-pwndbg
c
'''

# wrapper functrns
def sl(x): r.sendline(x)
def sla(x, y): r.sendlineafter(x, y)
def se(x): r.send(x)
def sa(x, y): r.sendafter(x, y)
def ru(x): return r.recvuntil(x)
def rl(): return r.recvline()
def cl(): return r.clean()
def uu64(x): return u64(x.ljust(8, b'\x00'))
def uuu(x): return unhex(x[2:])

def run():
if args.GDB:
return gdb.debug(elf.path, gdbscript=gs)
elif args.R:
HOST = args.R.split(':')[0]
PORT = args.R.split(':')[1]
return remote(HOST, PORT)
else:
return process(elf.path)

def is_valid_license(license_key):
prefix, suffix = license_key.split('_')

invalid_prefixes = ['333', '444', '555', '666', '777', '888', '999']
if prefix in invalid_prefixes:
return False

if sum(int(digit) for digit in suffix) % 7 != 0:
return False

return True

def num_digits(num):
ct = 0
while num > 0:
ct += 1
num //= 10
return ct

def sum_of_digits(num):
sm = 0
while num > 0:
rem = num % 10
sm += rem
num //= 10
return sm

def cd_key_gen():
x1 = random.randint(0, 1000)
while x1 % 111 == 0:
x1 = random.randint(0, 1000)
x1str = ""
if x1 > 100:
x1str = str(x1)
if 10 < x1 < 100:
x1str = "0" + str(x1)
if x1 < 10:
x1str = "00" + str(x1)
x2 = 1
while sum_of_digits(x2) % 7 != 0:
x2 = random.randint(0, 10000000)
while x2 % 10 == 0 or x2 % 10 == 8 or x2 % 10 == 9:
x2 = random.randint(0, 10000000)
length = num_digits(x2)
x2str = ""
for i in range(0, 7 - length):
x2str += "0"
x2str += str(x2)
return x1str + "_" + x2str

# =-=-= Solution =-=-==-
r = run()
## Generate valid license and send
#license = cd_key_gen()
# assert(is_valid_license(license)) == True

# send known good license
license = b'716_8206741'

log.info(f'Valid License found: {license}')

sla(b'Enter a Windows 95 product key: ', license)

# Send null-terminated password to bypass strcmp
# add newline to terminate read()
sla(b'Enter password: ', b'OrionProtc0l!!!\x00\n')

log.success(r.recvall())

# run multiple times for valid license key generator
# 716_8206741
# 396_4332063
# 513_0358586

0 comments on commit ff3aee6

Please sign in to comment.