Add printf category, plus a better stream cipher (unused)

This commit is contained in:
Neale Pickett 2010-10-05 11:55:32 -06:00
parent 2c35855b05
commit 8c0ed9e471
28 changed files with 419 additions and 11 deletions

156
common/isaac.c Normal file
View File

@ -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 <stdint.h>
#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 <stdio.h>
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

55
common/isaac.h Normal file
View File

@ -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 <stdint.h>
#define RANDSIZL (8)
#define RANDSIZ (1<<RANDSIZL)
/* context of random number generator */
struct randctx {
uint32_t randcnt;
uint32_t randrsl[RANDSIZ];
uint32_t randmem[RANDSIZ];
uint32_t randa;
uint32_t randb;
uint32_t randc;
};
/*
------------------------------------------------------------------------------
If (flag==TRUE), then use the contents of randrsl[0..RANDSIZ-1] as the seed.
------------------------------------------------------------------------------
*/
void randinit(struct randctx *ctx, uint_fast8_t flag);
void isaac(struct randctx *ctx);
/*
------------------------------------------------------------------------------
Call rand(/o_ randctx *r _o/) to retrieve a single 32-bit random value
------------------------------------------------------------------------------
*/
#define rand32(r) \
(!(r)->randcnt-- ? \
(isaac(r), (r)->randcnt=RANDSIZ-1, (r)->randrsl[(r)->randcnt]) : \
(r)->randrsl[(r)->randcnt])
#endif /* RAND */
#endif /* __ISAAC_H__ */

View File

@ -72,7 +72,22 @@ 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)
{
@ -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;
}

View File

@ -5,6 +5,8 @@
#include <stdlib.h>
#include <stdint.h>
#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);

1
mcp/tokend.keys/printf Normal file
View File

@ -0,0 +1 @@
偦轎奫^,5嗥贠教

21
printf/printf.mk Normal file
View File

@ -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

3
printf/service/printf/log/run Executable file
View File

@ -0,0 +1,3 @@
#! /bin/sh
exec logger -t printf

11
printf/service/printf/run Executable file
View File

@ -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

View File

@ -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

14
printf/src/Makefile Normal file
View File

@ -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)

105
printf/src/printf.c Normal file
View File

@ -0,0 +1,105 @@
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#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;
}

1
printf/src/token.c Symbolic link
View File

@ -0,0 +1 @@
../../common/token.c

1
printf/src/token.h Symbolic link
View File

@ -0,0 +1 @@
../../common/token.h

View File

@ -0,0 +1 @@
printf

View File

@ -0,0 +1 @@
偦轎奫^,5嗥贠教

View File

@ -0,0 +1 @@
<EFBFBD>7<EFBFBD>}<7D>m<EFBFBD><61><CA97><EFBFBD><0F><>

View File

@ -0,0 +1 @@
printf

View File

@ -0,0 +1 @@
偦轎奫^,5嗥贠教

View File

@ -0,0 +1 @@
<EFBFBD>7<EFBFBD>}<7D>m<EFBFBD><61><CA97><EFBFBD><0F><>

View File

@ -0,0 +1 @@
printf

View File

@ -0,0 +1 @@
偦轎奫^,5嗥贠教

View File

@ -0,0 +1 @@
<EFBFBD>7<EFBFBD>}<7D>m<EFBFBD><61><CA97><EFBFBD><0F><>

View File

@ -0,0 +1 @@
printf

View File

@ -0,0 +1 @@
偦轎奫^,5嗥贠教

View File

@ -0,0 +1 @@
<EFBFBD>7<EFBFBD>}<7D>m<EFBFBD><61><CA97><EFBFBD><0F><>

View File

@ -0,0 +1 @@
printf

View File

@ -0,0 +1 @@
偦轎奫^,5嗥贠教

View File

@ -0,0 +1 @@
<EFBFBD>7<EFBFBD>}<7D>m<EFBFBD><61><CA97><EFBFBD><0F><>