@ Pohon BBS

tripex tripcode finding software

Go back: thread mode | tree mode | sub tree

#3. tripex 1.2
Published: 2025-01-07 [Tue] 05:24, by taocana◆PhREAk.tEk
tripex 1.2 release notes
+ -f flag to read a list of expressions from a file
* -s flag now takes an argument for when to begin/end stacking. negative values mean to stop stacking after the absolute value of the index.

apply the patch as follows (make sure to apply the previous patch first:)
patch tripex.c tripex-1.2.patch

then recompile the software as follows:
gcc tripex.c -o tripex -O3 -lcrypt

here's an example of the new features combined for efficient dictionary searches.
because expressions from argv are parsed after files, we have to put our first expression in it's own file :(.
'-s -1' means to stop stacking after the first expression, so it will first check if it is even possible to match with any of the dictionary expressions.

aspell -d en dump master | grep "^[a-z]\{5,5\}$" > len5dict.txt
echo "[a-z]\{5,5\}" > 5a-z.txt
./tripex -n $(nproc) -s -1 -f 5a-z.txt -f len5dict.txt

-----BEGIN FILE tripex-1.2.patch-----
13a14
> #define MAX_EXPRS 262144
18a20,23
> /* if i put this garbage on the stack instead of bss, it will segfault. */
> size_t n_exprs = 0;
> regex_t exprs[MAX_EXPRS];
>
21c26
< fprintf(stderr, "usage: tripex [-Ehilnmsv] expressions\n"
---
> fprintf(stderr, "usage: tripex [-Ef:hil:n:m:s:v] expressions\n"
22a28
> " -f\tread expressions from file (use '-' for stdin)\n"
28c34,46
< " -s\tstack expressions (logical AND)\n");
---
> " -s\tstack (logical AND) expressions before/after expr #n (negative for before)\n");
> }
>
> void appendExpr(regex_t exprs[], size_t *i, char *str, int re_flags)
> {
> /* avoiding malloc like the plague, simple and fast shitware!
> * if you somehow need more than MAX_EXPRS, change it & recompile.
> */
> if (*i >= MAX_EXPRS)
> errx(EXIT_FAILURE, "no %s-kun! it's too many exprs, it wont fit!", getlogin());
> if (regcomp(&exprs[*i], str, re_flags))
> errx(EXIT_FAILURE, "failed to compile regex '%s'", str);
> (*i)++;
34a53
> long stack_after = 0;
40c59
< while ((opt = getopt(argc, argv, "E:hil:m:n:sv")) != -1) {
---
> while ((opt = getopt(argc, argv, "E:f:hil:m:M:n:s:v")) != -1) {
44a64,81
> case 'f':
> FILE *fp = stdin;
> if (strcmp(optarg, "-") != 0)
> fp = fopen(optarg, "r");
> if (!fp)
> err(EXIT_FAILURE, "couldn't open regex file '%s'", optarg);
>
> char *line = NULL;
> size_t len = 0;
> ssize_t nread;
> while ((nread = getline(&line, &len, fp)) != -1) {
> *strchr(line, '\n') = '\0';
> appendExpr(exprs, &n_exprs, line, re_flags);
> }
>
> free(line);
> fclose(fp);
> break;
64a102
> stack_after = atol(optarg);
67c105
< printf("tripex 1.1 by taocana\n");
---
> printf("tripex 1.2 by taocana\n");
73d110
<
81c118,121
< if (argc < 1) {
---
> for (size_t i = 0; i < argc; i++)
> appendExpr(exprs, &n_exprs, argv[i], re_flags);
>
> if (n_exprs < 1) {
86,91d125
< size_t n_exps = argc;
< regex_t *exps = malloc(sizeof(regex_t) * n_exps);
< for (size_t i = 0; i < n_exps; i++)
< if (regcomp(&exps[i], argv[i], re_flags))
< errx(EXIT_FAILURE, "failed to compile regex");
<
97c131
< unsigned char key[key_len + 1]; /* dynamic array, bad form but i'm lazy */
---
> unsigned char key[key_len + 1];
100c134
< for (size_t n = 0; !max_tries || n < max_tries ; n++) {
---
> for (size_t n = 0; !max_tries || n < max_tries; n++) {
111,113c145,151
< for (size_t i = 0; i < n_exps; i++)
< if (regexec(&exps[i], trip, ARRAY_SIZE(pmatch), pmatch, 0))
< if (sflag)
---
> for (size_t i = 0; i < n_exprs; i++) {
> int stacking = (sflag
> && ((stack_after >= 0 && i >= stack_after)
> || (stack_after < 0 && i < -stack_after)));
>
> if (regexec(&exprs[i], trip, ARRAY_SIZE(pmatch), pmatch, 0))
> if (stacking)
117c155
< else if (!sflag || i >= n_exps - 1)
---
> else if (!stacking || i >= n_exprs - 1) {
118a157,159
> break;
> }
> }
123,125c164,165
< for (size_t i = 0; i < n_exps; i++)
< regfree(&exps[i]);
< free(exps);
---
> for (size_t i = 0; i < n_exprs; i++)
> regfree(&exprs[i]);
134a175
> /* unsigned for array lookups by character */
152c193
< if (!code)
---
> if (!code) /* doesn't fully handle crypt_r(3) errors yet */
.

New Reply



(new)

You need to solve the captcha before you can post.


Parents

#2. tripex 1.1
Published: 2025-01-05 [Sun] 06:05, by taocana◆PhREAk.tEk
version 1.1, cryptography patch.
i forgot to audit the cryptography; i made a huge boneheaded mistake
with the key filter (thing that turns pure random bytes into printable
ascii) where it was skewing a lot. now it uses an 85 character subset
(256 % 85 = 1) which has a very tiny amount of skew but doesn't lose
as much entropy as an unskewed 64 character subset of ascii would.
the default key length is also increased to 10, so that it would be
~64 shannons of entropy total (a tripcode has 60 shannons.)

here is the patch file, apply it to the original as follows:
patch tripex.c tripex-1.1.patch

then recompile the program as follows:
gcc tripex.c -o tripex -O3 -lcrypt

-----BEGIN FILE tripex-1.1.patch-----
36c36
< size_t key_len = 8;
---
> size_t key_len = 10;
67c67
< printf("tripex 1.0 by taocana\n");
---
> printf("tripex 1.1 by taocana\n");
167a168,175
> /* we must get printable ascii from a random byte,
> * but 256 % 94 = 68 which leaves too much skew.
> * quantizing into 64 chars won't skew at all, but
> * it only has 6 shannons of entropy per character.
> * an 85 character quantization only skews by a
> * remainder of one, which is miniscule enough and
> * we average 6.41 shannons per character.
> */
169,176c177,192
< "{dDOFByx8Jdo=C.{hFw:'p%m+]E-*}~4"
< "O)YiM99y?%A)tldRIN4!fat`J|(iI+}h"
< "]59P#T_Qx#h0q8w+F,$}Vo5Gq;<rw]Y~"
< "k6>O~Ge,.DW9`hqhaSf#A.vrnhy`[2Ct"
< "Bb6|7Mr+iJZG5.&7>?K@{D~6*Vs'H_*>"
< "$Mh3R-F$Sp^.E5R-W1DnQzXC@Tf']xxt"
< "o`GLO'Ui`S/v,aegU2HkE3Y6y!WZm%?k"
< "aD/H=yH4vQg7dC*(Gx$vV[<vV?jw8s^d";
---
> "!#$%&'()*+,-./012"
> "3456789:;<=>?@ABC"
> "DEFGHIJKLMNOPQRST"
> "UVWXYZ^abcdefghij"
> "klmnopqrstuvwxyz~"
> "!#$%&'()*+,-./012"
> "3456789:;<=>?@ABC"
> "DEFGHIJKLMNOPQRST"
> "UVWXYZ^abcdefghij"
> "klmnopqrstuvwxyz~"
> "!#$%&'()*+,-./012"
> "3456789:;<=>?@ABC"
> "DEFGHIJKLMNOPQRST"
> "UVWXYZ^abcdefghij"
> "klmnopqrstuvwxyz~"
> "~";
.

#1. tripex tripcode finding software
Published: 2025-01-05 [Sun] 00:04, by taocana◆PhREAk.tEk
releasing version 1.0 of my tripcode finding program, 'tripex'

compile the program as follows:
gcc tripex.c -o tripex -O3 -lcrypt

example #1; find tripcodes containing 'nice' (case insensitive):
./tripex -n $(nproc) -i nice

example #2; find tripcodes starting with either 'giko' or 'mona':
./tripex -n $(nproc) ^giko ^mona

example #3; find fully lowercase tripcodes with quads:
./tripex -s -n $(nproc) "^[a-z]*$" "\(.\)\1\{3,\}"

untested on anything but GNU/Linux with glibc, but it would probably work on FreeBSD too.
don't trust any update posts unless they have my tripcode or you can audit them yourself!

-----BEGIN FILE tripex.c-----
/* CC0-1.0 */

#include <err.h>
#include <crypt.h>
#include <regex.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <sys/random.h>

#define ARRAY_SIZE(x) (sizeof((x)) / sizeof((x)[0]))

static unsigned char saltFilter[256];
static unsigned char rngFilter[256];
char *tripcode(const char *key);

void usage(void)
{
fprintf(stderr, "usage: tripex [-Ehilnmsv] expressions\n"
" -E\tuse extended regular expressions\n"
" -h\tshow usage\n"
" -i\tignore case\n"
" -l\tkey length\n"
" -n\tnumber of threads\n"
" -m\tmax number of tries (per thread!)\n"
" -s\tstack expressions (logical AND)\n");
}

int main(int argc, char *argv[])
{
int re_flags = 0;
int sflag = 0;
size_t n_procs = 1;
size_t key_len = 8;
size_t max_tries = 0;

int opt;
while ((opt = getopt(argc, argv, "E:hil:m:n:sv")) != -1) {
switch(opt) {
case 'E':
re_flags |= REG_EXTENDED;
break;
case 'i':
re_flags |= REG_ICASE;
break;
case 'l':
key_len = atol(optarg);
if (key_len < 1)
errx(EXIT_FAILURE, "key length must be at least 1");
break;
case 'n':
n_procs = atol(optarg);
if (n_procs < 1)
errx(EXIT_FAILURE, "need at least one process");
break;
case 'm': /* ! PER THREAD ! */
max_tries = atol(optarg);
if (max_tries < 1)
errx(EXIT_FAILURE, "need at least one try");
break;
case 's':
sflag = 1;
break;
case 'v':
printf("tripex 1.0 by taocana\n");
return EXIT_SUCCESS;
case 'h':
/* FALLTHROUGH */
default:
usage();

return EXIT_FAILURE;
}
}

argc -= optind;
argv += optind;

if (argc < 1) {
usage();
errx(EXIT_FAILURE, "need at least one expression");
}

size_t n_exps = argc;
regex_t *exps = malloc(sizeof(regex_t) * n_exps);
for (size_t i = 0; i < n_exps; i++)
if (regcomp(&exps[i], argv[i], re_flags))
errx(EXIT_FAILURE, "failed to compile regex");

for (int i = 1; i < n_procs; i++)
if (!fork())
break;

regmatch_t pmatch[1];
unsigned char key[key_len + 1]; /* dynamic array, bad form but i'm lazy */
key[key_len] = 0;

for (size_t n = 0; !max_tries || n < max_tries ; n++) {
if (getrandom(key, key_len, 0) < 0)
err(EXIT_FAILURE, "failed to get random key");

for (int i = 0; i < key_len; i++)
key[i] = rngFilter[key[i]];

char *trip = tripcode(key);
if (!trip)
err(EXIT_FAILURE, "failed to generate tripcode");

for (size_t i = 0; i < n_exps; i++)
if (regexec(&exps[i], trip, ARRAY_SIZE(pmatch), pmatch, 0))
if (sflag)
break;
else
continue;
else if (!sflag || i >= n_exps - 1)
printf("%s %s\n", trip, key);

free(trip);
}

for (size_t i = 0; i < n_exps; i++)
regfree(&exps[i]);
free(exps);
return EXIT_SUCCESS;
}

char *tripcode(const char *key)
{
/* we don't do any sjis conversion, but who cares anyway? */
if (strlen(key) == 0)
return NULL;

unsigned char *tempKey = malloc(strlen(key) + 2);
if (!tempKey)
return NULL;
strcpy(tempKey, key);
strcat(tempKey, "H.");

unsigned char salt[3];
for (int i = 0; i < 3; i++)
salt[i] = saltFilter[tempKey[i+1]];
salt[2] = 0;
free(tempKey);

struct crypt_data data;
bzero(&data, sizeof(struct crypt_data));

char *tempCode = crypt_r(key, salt, &data);
unsigned char *code = malloc(strlen(tempCode) - 3);
if (!code)
return NULL;
strcpy(code, tempCode + 3);
return code;
}

static unsigned char saltFilter[256] =
"................................"
".............../0123456789......"
".ABCDEFGHIJKLMNOPQRSTUVWXYZ....."
".abcdefghijklmnopqrstuvwxyz....."
"................................"
"................................"
"................................"
"................................";

static unsigned char rngFilter[256] =
"{dDOFByx8Jdo=C.{hFw:'p%m+]E-*}~4"
"O)YiM99y?%A)tldRIN4!fat`J|(iI+}h"
"]59P#T_Qx#h0q8w+F,$}Vo5Gq;<rw]Y~"
"k6>O~Ge,.DW9`hqhaSf#A.vrnhy`[2Ct"
"Bb6|7Mr+iJZG5.&7>?K@{D~6*Vs'H_*>"
"$Mh3R-F$Sp^.E5R-W1DnQzXC@Tf']xxt"
"o`GLO'Ui`S/v,aegU2HkE3Y6y!WZm%?k"
"aD/H=yH4vQg7dC*(Gx$vV[<vV?jw8s^d";
.
Pohon BBS