xorcat

Tool for testing xor keys on encrypted data
git clone git@sinitax.com:sinitax/xorcat
Log | Files | Refs | LICENSE | sfeed.txt

commit 3d2f9ccc6ebe61fea284a043513668dd77d324fb
Author: Louis Burda <quent.burda@gmail.com>
Date:   Mon,  5 Sep 2022 14:16:48 +0200

Allow key masking for bruteforce

Diffstat:
A.gitignore | 1+
AMakefile | 8++++++++
Axorcat.c | 109+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 118 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -0,0 +1 @@ +xorcat diff --git a/Makefile b/Makefile @@ -0,0 +1,8 @@ +all: xorcat + +clean: + rm -f xorcat + +xorcat: xorcat.c + +.PHONY: all clean diff --git a/xorcat.c b/xorcat.c @@ -0,0 +1,109 @@ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <stdint.h> +#include <unistd.h> +#include <err.h> + +static const char usage[] = "USAGE: xorcat KEYMASK"; + +void +die(const char *fmtstr) +{ + fprintf(stderr, "%s\n", fmtstr); + exit(1); +} + +void +xorcat(uint8_t *indata, size_t insize, uint8_t *key, size_t keylen) +{ + uint8_t writebuf[4098]; + size_t i, nout, pos; + + pos = 0; + while (pos < insize) { + for (i = 0; i < sizeof(writebuf) && i < insize - pos; i++) + writebuf[i] = indata[pos + i] ^ key[(pos + i) % keylen]; + nout = write(STDOUT_FILENO, writebuf, i); + if (nout != i) err(1, "write"); + pos += i; + } +} + +uint8_t * +collect(size_t *size) +{ + uint8_t readbuf[4098]; + uint8_t *data; + size_t nread, cap; + + cap = 4098; + data = malloc(cap); + if (!data) err(1, "malloc"); + + *size = 0; + while (1) { + nread = read(STDIN_FILENO, readbuf, sizeof(readbuf)); + if (nread <= 0) break; + if (cap < *size + nread) { + cap *= 2; + data = realloc(data, cap); + } + memcpy(data + *size, readbuf, nread); + *size += nread; + } + + return data; +} + +int +main(int argc, const char **argv) +{ + uint8_t *mask, *key; + size_t keylen; + uint8_t *indata; + size_t insize; + unsigned maskb; + ssize_t i; + + if (argc != 2) die(usage); + + if (strlen(argv[1]) % 2) die(usage); + + keylen = strlen(argv[1]) / 2; + mask = calloc(keylen, 1); + key = calloc(keylen, 1); + if (!mask || !key) err(1, "malloc"); + + for (i = 0; i < keylen; i++) { + if (!strncmp(argv[1] + 2 * i, "??", 2)) { + mask[i] = 1; + } else { + if (!sscanf(argv[1] + 2 * i, "%02X", &maskb)) + die("Bad mask"); + mask[i] = (uint8_t) maskb; + } + } + + indata = collect(&insize); + while (1) { + printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>> "); + for (i = 0; i < keylen; i++) + printf("%02X", key[i]); + printf("\n"); + fflush(stdout); + + xorcat(indata, insize, key, keylen); + + for (i = keylen - 1; i >= 0; i--) { + if (mask[i]) { + key[i] += 1; + if (key[i]) break; + } + } + if (i < 0) break; + } + + free(key); + free(mask); +}