From 8c0ed9e471562e35a7e0e50a4524441fad3c6140 Mon Sep 17 00:00:00 2001 From: Neale Pickett Date: Tue, 5 Oct 2010 11:55:32 -0600 Subject: [PATCH] Add printf category, plus a better stream cipher (unused) --- common/isaac.c | 156 +++++++++++++++++++++++++++++ common/isaac.h | 55 ++++++++++ common/token.c | 31 ++++-- common/token.h | 8 +- mcp/tokend.keys/printf | 1 + printf/printf.mk | 21 ++++ printf/service/printf/log/run | 3 + printf/service/printf/run | 11 ++ printf/service/printf/run-printf | 8 ++ printf/src/Makefile | 14 +++ printf/src/printf.c | 105 +++++++++++++++++++ printf/src/token.c | 1 + printf/src/token.h | 1 + printf/tokens/printf0/category | 1 + printf/tokens/printf0/category.key | 1 + printf/tokens/printf0/enc.key | 1 + printf/tokens/printf1/category | 1 + printf/tokens/printf1/category.key | 1 + printf/tokens/printf1/enc.key | 1 + printf/tokens/printf2/category | 1 + printf/tokens/printf2/category.key | 1 + printf/tokens/printf2/enc.key | 1 + printf/tokens/printf3/category | 1 + printf/tokens/printf3/category.key | 1 + printf/tokens/printf3/enc.key | 1 + printf/tokens/printf4/category | 1 + printf/tokens/printf4/category.key | 1 + printf/tokens/printf4/enc.key | 1 + 28 files changed, 419 insertions(+), 11 deletions(-) create mode 100644 common/isaac.c create mode 100644 common/isaac.h create mode 100644 mcp/tokend.keys/printf create mode 100644 printf/printf.mk create mode 100755 printf/service/printf/log/run create mode 100755 printf/service/printf/run create mode 100755 printf/service/printf/run-printf create mode 100644 printf/src/Makefile create mode 100644 printf/src/printf.c create mode 120000 printf/src/token.c create mode 120000 printf/src/token.h create mode 100644 printf/tokens/printf0/category create mode 100644 printf/tokens/printf0/category.key create mode 100644 printf/tokens/printf0/enc.key create mode 100644 printf/tokens/printf1/category create mode 100644 printf/tokens/printf1/category.key create mode 100644 printf/tokens/printf1/enc.key create mode 100644 printf/tokens/printf2/category create mode 100644 printf/tokens/printf2/category.key create mode 100644 printf/tokens/printf2/enc.key create mode 100644 printf/tokens/printf3/category create mode 100644 printf/tokens/printf3/category.key create mode 100644 printf/tokens/printf3/enc.key create mode 100644 printf/tokens/printf4/category create mode 100644 printf/tokens/printf4/category.key create mode 100644 printf/tokens/printf4/enc.key diff --git a/common/isaac.c b/common/isaac.c new file mode 100644 index 0000000..e095d94 --- /dev/null +++ b/common/isaac.c @@ -0,0 +1,156 @@ +/* +------------------------------------------------------------------------------ +rand.c: By Bob Jenkins. My random number generator, ISAAC. Public Domain. +MODIFIED: + 960327: Creation (addition of randinit, really) + 970719: use context, not global variables, for internal state + 980324: added main (ifdef'ed out), also rearranged randinit() + 010626: Note that this is public domain +------------------------------------------------------------------------------ +*/ +#include +#include "rand.h" + +#define ind(mm,x) (*(uint32_t *)((uint8_t *)(mm) + ((x) & ((RANDSIZ-1)<<2)))) +#define rngstep(mix,a,b,mm,m,m2,r,x) \ +{ \ + x = *m; \ + a = (a^(mix)) + *(m2++); \ + *(m++) = y = ind(mm,x) + a + b; \ + *(r++) = b = ind(mm,y>>RANDSIZL) + x; \ +} + +void isaac(struct randctx *ctx) +{ + register uint32_t a, b, x, y, *m, *mm, *m2, *r, *mend; + mm = ctx->randmem; + r = ctx->randrsl; + a = ctx->randa; + b = ctx->randb + (++ctx->randc); + for (m = mm, mend = m2 = m + (RANDSIZ / 2); m < mend;) { + rngstep(a << 13, a, b, mm, m, m2, r, x); + rngstep(a >> 6, a, b, mm, m, m2, r, x); + rngstep(a << 2, a, b, mm, m, m2, r, x); + rngstep(a >> 16, a, b, mm, m, m2, r, x); + } + for (m2 = mm; m2 < mend;) { + rngstep(a << 13, a, b, mm, m, m2, r, x); + rngstep(a >> 6, a, b, mm, m, m2, r, x); + rngstep(a << 2, a, b, mm, m, m2, r, x); + rngstep(a >> 16, a, b, mm, m, m2, r, x); + } + ctx->randb = b; + ctx->randa = a; +} + + +#define mix(a,b,c,d,e,f,g,h) \ +{ \ + a^=b<<11; d+=a; b+=c; \ + b^=c>>2; e+=b; c+=d; \ + c^=d<<8; f+=c; d+=e; \ + d^=e>>16; g+=d; e+=f; \ + e^=f<<10; h+=e; f+=g; \ + f^=g>>4; a+=f; g+=h; \ + g^=h<<8; b+=g; h+=a; \ + h^=a>>9; c+=h; a+=b; \ +} + +/* if (flag==TRUE), then use the contents of randrsl[] to initialize mm[]. */ +void randinit(struct randctx *ctx, uint_fast8_t flag) +{ + uint_fast32_t i; + uint32_t a, b, c, d, e, f, g, h; + uint32_t *m, *r; + ctx->randa = ctx->randb = ctx->randc = 0; + m = ctx->randmem; + r = ctx->randrsl; + a = b = c = d = e = f = g = h = 0x9e3779b9; /* the golden ratio */ + + for (i = 0; i < 4; ++i) { /* scramble it */ + mix(a, b, c, d, e, f, g, h); + } + + if (flag) { + /* initialize using the contents of r[] as the seed */ + for (i = 0; i < RANDSIZ; i += 8) { + a += r[i]; + b += r[i + 1]; + c += r[i + 2]; + d += r[i + 3]; + e += r[i + 4]; + f += r[i + 5]; + g += r[i + 6]; + h += r[i + 7]; + mix(a, b, c, d, e, f, g, h); + m[i] = a; + m[i + 1] = b; + m[i + 2] = c; + m[i + 3] = d; + m[i + 4] = e; + m[i + 5] = f; + m[i + 6] = g; + m[i + 7] = h; + } + /* do a second pass to make all of the seed affect all of m */ + for (i = 0; i < RANDSIZ; i += 8) { + a += m[i]; + b += m[i + 1]; + c += m[i + 2]; + d += m[i + 3]; + e += m[i + 4]; + f += m[i + 5]; + g += m[i + 6]; + h += m[i + 7]; + mix(a, b, c, d, e, f, g, h); + m[i] = a; + m[i + 1] = b; + m[i + 2] = c; + m[i + 3] = d; + m[i + 4] = e; + m[i + 5] = f; + m[i + 6] = g; + m[i + 7] = h; + } + } else { + /* fill in m[] with messy stuff */ + for (i = 0; i < RANDSIZ; i += 8) { + mix(a, b, c, d, e, f, g, h); + m[i] = a; + m[i + 1] = b; + m[i + 2] = c; + m[i + 3] = d; + m[i + 4] = e; + m[i + 5] = f; + m[i + 6] = g; + m[i + 7] = h; + } + } + + isaac(ctx); /* fill in the first set of results */ + ctx->randcnt = RANDSIZ; /* prepare to use the first set of results */ +} + + +#ifdef NEVER + +#include + +int main() +{ + uint32_t i, j; + struct randctx ctx; + ctx.randa = ctx.randb = ctx.randc = (uint32_t) 0; + for (i = 0; i < 256; ++i) + ctx.randrsl[i] = (uint32_t) 0; + randinit(&ctx, 1); + for (i = 0; i < 2; ++i) { + isaac(&ctx); + for (j = 0; j < 256; ++j) { + printf("%.8x", ctx.randrsl[j]); + if ((j & 7) == 7) + printf("\n"); + } + } +} +#endif diff --git a/common/isaac.h b/common/isaac.h new file mode 100644 index 0000000..14e9adb --- /dev/null +++ b/common/isaac.h @@ -0,0 +1,55 @@ +/* +------------------------------------------------------------------------------ +rand.h: definitions for a random number generator +By Bob Jenkins, 1996, Public Domain +MODIFIED: + 960327: Creation (addition of randinit, really) + 970719: use context, not global variables, for internal state + 980324: renamed seed to flag + 980605: recommend RANDSIZL=4 for noncryptography. + 010626: note this is public domain + 101005: update to C99 (neale@lanl.gov) +------------------------------------------------------------------------------ +*/ + +#ifndef __ISAAC_H__ +#define __ISAAC_H__ + +#include + +#define RANDSIZL (8) +#define RANDSIZ (1<randcnt-- ? \ + (isaac(r), (r)->randcnt=RANDSIZ-1, (r)->randrsl[(r)->randcnt]) : \ + (r)->randrsl[(r)->randcnt]) + +#endif /* RAND */ + + +#endif /* __ISAAC_H__ */ diff --git a/common/token.c b/common/token.c index bbbf0cd..4edd897 100644 --- a/common/token.c +++ b/common/token.c @@ -72,14 +72,29 @@ arc4_crypt_buffer(uint8_t const *key, size_t keylen, ssize_t -read_token(char *name, +read_token_fd(int fd, + uint8_t const *key, size_t keylen, + char *buf, size_t buflen) +{ + ssize_t ret; + + ret = read(fd, buf, buflen); + if (-1 != ret) { + arc4_crypt_buffer(key, keylen, (uint8_t *)buf, (size_t)ret); + } + return ret; +} + + +ssize_t +read_token(char const *name, uint8_t const *key, size_t keylen, char *buf, size_t buflen) { - char path[PATH_MAX]; - int pathlen; - int fd; - ssize_t ret; + char path[PATH_MAX]; + int pathlen; + int fd; + ssize_t ret; pathlen = snprintf(path, sizeof(path) - 1, CTF_BASE "/tokens/%s", name); @@ -87,11 +102,7 @@ read_token(char *name, fd = open(path, O_RDONLY); if (-1 == fd) return -1; - - ret = read(fd, buf, buflen); + ret = read_token_fd(fd, key, keylen, buf, buflen); close(fd); - if (-1 != ret) { - arc4_crypt_buffer(key, keylen, (uint8_t *)buf, (size_t)ret); - } return ret; } diff --git a/common/token.h b/common/token.h index 3f4e30a..ac4f95b 100644 --- a/common/token.h +++ b/common/token.h @@ -5,6 +5,8 @@ #include #include +#define TOKEN_MAX 80 + /* ARC4 functions, in case anybody wants 'em */ struct arc4_ctx; void arc4_init(struct arc4_ctx *ctx, @@ -14,7 +16,11 @@ void arc4_crypt(struct arc4_ctx *ctx, void arc4_crypt_buffer(uint8_t const *key, size_t keylen, uint8_t *buf, size_t buflen); -ssize_t read_token(char *name, +ssize_t read_token_fd(int fd, + uint8_t const *key, size_t keylen, + char *buf, size_t buflen); + +ssize_t read_token(char const *name, uint8_t const *key, size_t keylen, char *buf, size_t buflen); diff --git a/mcp/tokend.keys/printf b/mcp/tokend.keys/printf new file mode 100644 index 0000000..6089383 --- /dev/null +++ b/mcp/tokend.keys/printf @@ -0,0 +1 @@ +‚»ÞIŠ[^,5àÆÚO½Ì \ No newline at end of file diff --git a/printf/printf.mk b/printf/printf.mk new file mode 100644 index 0000000..52c2b69 --- /dev/null +++ b/printf/printf.mk @@ -0,0 +1,21 @@ +PRINTF_PKGDIR = build/printf +PRINTF_PACKAGE = printf.pkg + +printf-install: printf-build + mkdir -p $(PRINTF_PKGDIR) + + mkdir -p $(PRINTF_PKGDIR)/bin/ + $(MAKE) -C printf/src install DESTDIR=$(CURDIR)/$(PRINTF_PKGDIR) + + $(call COPYTREE, printf/tokens, $(PRINTF_PKGDIR)/tokens) + + $(call COPYTREE, printf/service, $(PRINTF_PKGDIR)/service) + +printf-clean: + rm -rf $(PRINTF_PKGDIR) $(PRINTF_PACKAGE) + $(MAKE) -C printf/src clean + +printf-build: + $(MAKE) -C printf/src build + +PACKAGES += printf diff --git a/printf/service/printf/log/run b/printf/service/printf/log/run new file mode 100755 index 0000000..6be042c --- /dev/null +++ b/printf/service/printf/log/run @@ -0,0 +1,3 @@ +#! /bin/sh + +exec logger -t printf diff --git a/printf/service/printf/run b/printf/service/printf/run new file mode 100755 index 0000000..512dcab --- /dev/null +++ b/printf/service/printf/run @@ -0,0 +1,11 @@ +#! /bin/sh + +exec 2>&1 + +# So I say to him, "Alex, what's a good high port number for a CTF category?" +# And he says, "6" +# And I say, "no, it has to be bigger than 1000" +# And he says, "how about 9001, because that's bigger than 9000" +# So, okay. + +exec tcpsvd 0 9001 ./run-printf diff --git a/printf/service/printf/run-printf b/printf/service/printf/run-printf new file mode 100755 index 0000000..716baf7 --- /dev/null +++ b/printf/service/printf/run-printf @@ -0,0 +1,8 @@ +#! /bin/sh + +chpst -u 9001 -/ /opt/printf/bin ./printf \ + 3< /var/lib/ctf/tokens/printf0 \ + 4< /var/lib/ctf/tokens/printf1 \ + 5< /var/lib/ctf/tokens/printf2 \ + 6< /var/lib/ctf/tokens/printf3 \ + 7< /var/lib/ctf/tokens/printf4 diff --git a/printf/src/Makefile b/printf/src/Makefile new file mode 100644 index 0000000..15f1b4d --- /dev/null +++ b/printf/src/Makefile @@ -0,0 +1,14 @@ +CFLAGS = -Wall -Werror +LDFLAGS = -static +TARGETS = printf + +all: build +build: $(TARGETS) + +printf: printf.o token.o + +install: $(TARGETS) + install -m 0755 $(TARGETS) $(DESTDIR)/bin + +clean: + rm -f *.o $(TARGETS) \ No newline at end of file diff --git a/printf/src/printf.c b/printf/src/printf.c new file mode 100644 index 0000000..5b97ef3 --- /dev/null +++ b/printf/src/printf.c @@ -0,0 +1,105 @@ +#include +#include +#include +#include "token.h" + +void +record(char *buf) { + char *p; + char *ip = getenv("TCPREMOTEIP"); + + fprintf(stderr, "%s: ", ip); + for (p = buf; *p; p += 1) { + if (isprint(*p)) { + fputc(*p, stderr); + } else { + fprintf(stderr, "%%%02x", *p); + } + } + fputc('\n', stderr); +} + +uint8_t const key[] = {0x98, 0x37, 0x92, 0x7d, + 0xa5, 0x6d, 0xc9, 0x61, + 0xca, 0x97, 0xf8, 0xa5, + 0xfe, 0x0f, 0xf6, 0xfc}; + +#define NTOKENS 5 + +/* Storage space for tokens */ +char token[NTOKENS][TOKEN_MAX]; + +/* Make this global so the stack isn't gigantic */ +char global_fmt[8000] = {0}; + + +/* Since this runs in a chroot jail, and setting up all the symlinks is + * a pain in the butt, we just read from file discriptors passed in. + * Pipes are the best thing. :D + */ +void +read_tokens() +{ + int i; + ssize_t len; + + for (i = 0; i < NTOKENS; i += 1) { + len = read_token_fd(i + 3, key, sizeof(key), token[i], sizeof(token[i])); + if (len >= sizeof(token[i])) abort(); + token[i][len] = '\0'; + printf("Token %d: %s\n", i, token[i]); + } +} + +int +main(int argc, char *argv[], char *env[]) +{ + char *t0 = token[0]; + int t1[TOKEN_MAX]; + char *fmt = global_fmt; + char *datacomp = "welcome datacomp"; + int token4_flag = 0; + int i; + + /* Make stderr buffer until lines */ + setlinebuf(stderr); + + /* So the compiler won't complain about unused variables */ + i = datacomp[0] ^ t0[0]; + + read_tokens(); + + /* Token 0 just hangs out on the stack */ + + /* Set up token 1 (%c%c%c%c...) */ + for (i = 0; '\0' != token[1][i]; i += 1) { + t1[i] = token[1][i]; + } + t1[i-1] = '\n'; + + /* Stick token 2 into the environment */ + for (i = 0; env[i]; i += 1); + env[i-1] = token[2]; + + /* token 3 is pretty much a gimmie */ + + /* token 4 will only be printed if you set token4_flag to non-zero */ + + if (NULL == fgets(global_fmt, sizeof(global_fmt), stdin)) { + return 0; + } + + record(fmt); + + printf(fmt, + "Welcome to the printf category.\n", + "There are multiple tokens hiding here.\n", + "Good luck!\n", + token[3], + "token4_flag (@ ", &token4_flag, "): ", token4_flag, "\n"); + if (token4_flag) { + printf("%s\n", token[4]); + } + + return 0; +} diff --git a/printf/src/token.c b/printf/src/token.c new file mode 120000 index 0000000..8c6738e --- /dev/null +++ b/printf/src/token.c @@ -0,0 +1 @@ +../../common/token.c \ No newline at end of file diff --git a/printf/src/token.h b/printf/src/token.h new file mode 120000 index 0000000..25f916f --- /dev/null +++ b/printf/src/token.h @@ -0,0 +1 @@ +../../common/token.h \ No newline at end of file diff --git a/printf/tokens/printf0/category b/printf/tokens/printf0/category new file mode 100644 index 0000000..f3be370 --- /dev/null +++ b/printf/tokens/printf0/category @@ -0,0 +1 @@ +printf diff --git a/printf/tokens/printf0/category.key b/printf/tokens/printf0/category.key new file mode 100644 index 0000000..6089383 --- /dev/null +++ b/printf/tokens/printf0/category.key @@ -0,0 +1 @@ +‚»ÞIŠ[^,5àÆÚO½Ì \ No newline at end of file diff --git a/printf/tokens/printf0/enc.key b/printf/tokens/printf0/enc.key new file mode 100644 index 0000000..ef2e9f9 --- /dev/null +++ b/printf/tokens/printf0/enc.key @@ -0,0 +1 @@ +˜7’}¥mÉaÊ—ø¥þöü \ No newline at end of file diff --git a/printf/tokens/printf1/category b/printf/tokens/printf1/category new file mode 100644 index 0000000..f3be370 --- /dev/null +++ b/printf/tokens/printf1/category @@ -0,0 +1 @@ +printf diff --git a/printf/tokens/printf1/category.key b/printf/tokens/printf1/category.key new file mode 100644 index 0000000..6089383 --- /dev/null +++ b/printf/tokens/printf1/category.key @@ -0,0 +1 @@ +‚»ÞIŠ[^,5àÆÚO½Ì \ No newline at end of file diff --git a/printf/tokens/printf1/enc.key b/printf/tokens/printf1/enc.key new file mode 100644 index 0000000..ef2e9f9 --- /dev/null +++ b/printf/tokens/printf1/enc.key @@ -0,0 +1 @@ +˜7’}¥mÉaÊ—ø¥þöü \ No newline at end of file diff --git a/printf/tokens/printf2/category b/printf/tokens/printf2/category new file mode 100644 index 0000000..f3be370 --- /dev/null +++ b/printf/tokens/printf2/category @@ -0,0 +1 @@ +printf diff --git a/printf/tokens/printf2/category.key b/printf/tokens/printf2/category.key new file mode 100644 index 0000000..6089383 --- /dev/null +++ b/printf/tokens/printf2/category.key @@ -0,0 +1 @@ +‚»ÞIŠ[^,5àÆÚO½Ì \ No newline at end of file diff --git a/printf/tokens/printf2/enc.key b/printf/tokens/printf2/enc.key new file mode 100644 index 0000000..ef2e9f9 --- /dev/null +++ b/printf/tokens/printf2/enc.key @@ -0,0 +1 @@ +˜7’}¥mÉaÊ—ø¥þöü \ No newline at end of file diff --git a/printf/tokens/printf3/category b/printf/tokens/printf3/category new file mode 100644 index 0000000..f3be370 --- /dev/null +++ b/printf/tokens/printf3/category @@ -0,0 +1 @@ +printf diff --git a/printf/tokens/printf3/category.key b/printf/tokens/printf3/category.key new file mode 100644 index 0000000..6089383 --- /dev/null +++ b/printf/tokens/printf3/category.key @@ -0,0 +1 @@ +‚»ÞIŠ[^,5àÆÚO½Ì \ No newline at end of file diff --git a/printf/tokens/printf3/enc.key b/printf/tokens/printf3/enc.key new file mode 100644 index 0000000..ef2e9f9 --- /dev/null +++ b/printf/tokens/printf3/enc.key @@ -0,0 +1 @@ +˜7’}¥mÉaÊ—ø¥þöü \ No newline at end of file diff --git a/printf/tokens/printf4/category b/printf/tokens/printf4/category new file mode 100644 index 0000000..f3be370 --- /dev/null +++ b/printf/tokens/printf4/category @@ -0,0 +1 @@ +printf diff --git a/printf/tokens/printf4/category.key b/printf/tokens/printf4/category.key new file mode 100644 index 0000000..6089383 --- /dev/null +++ b/printf/tokens/printf4/category.key @@ -0,0 +1 @@ +‚»ÞIŠ[^,5àÆÚO½Ì \ No newline at end of file diff --git a/printf/tokens/printf4/enc.key b/printf/tokens/printf4/enc.key new file mode 100644 index 0000000..ef2e9f9 --- /dev/null +++ b/printf/tokens/printf4/enc.key @@ -0,0 +1 @@ +˜7’}¥mÉaÊ—ø¥þöü \ No newline at end of file