mirror of https://github.com/dirtbags/moth.git
Merge in nonce work I did at home
Conflicts: mcp/src/claim.cgi.c mcp/src/common.c mcp/src/in.tokend.c mcp/src/puzzler.cgi.c mcp/src/puzzles.cgi.c mcp/src/xxtea.c mcp/src/xxtea.h
This commit is contained in:
commit
8e25c9f074
|
@ -1,11 +1,15 @@
|
||||||
Ideas for puzzles
|
Ideas for puzzles
|
||||||
=================
|
=================
|
||||||
* Hide something in a .docx zip file
|
* Hide something in a .docx zip file
|
||||||
|
* Bootable image with FreeDOS, Linux, Inferno? HURD?
|
||||||
|
* Bury puzzles in various weird locations within each OS
|
||||||
Network treasure hunt
|
* Maybe put some in the boot loader, too
|
||||||
---------------------
|
* Perhaps have some sort of network puzzle as well
|
||||||
* DHCP option
|
* Network treasure hunt
|
||||||
* Single TCP RST with token in payload
|
* DHCP option
|
||||||
* Multiple TCP RST with different payloads
|
* Single TCP RST with token in payload
|
||||||
*
|
* Multiple TCP RST with different payloads
|
||||||
|
* PXE boot some sort of points-gathering client
|
||||||
|
* Init asks for a team hash, and starts awarding points
|
||||||
|
* Broken startup scripts, when fixed award more points
|
||||||
|
* Lots of remote exploits
|
||||||
|
|
|
@ -12,7 +12,7 @@ $(PACKAGE): build
|
||||||
cp setup $(PKGDIR)
|
cp setup $(PKGDIR)
|
||||||
|
|
||||||
find bin -not -name '*~' | cpio -p $(PKGDIR)
|
find bin -not -name '*~' | cpio -p $(PKGDIR)
|
||||||
cp src/in.tokend src/pointscli $(PKGDIR)/bin
|
cp src/in.tokend src/tokencli src/pointscli $(PKGDIR)/bin
|
||||||
|
|
||||||
find service -not -name '*~' -not -name '#*' | cpio -p $(PKGDIR)
|
find service -not -name '*~' -not -name '#*' | cpio -p $(PKGDIR)
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
CFLAGS = -Wall -Werror
|
CFLAGS = -Wall -Werror
|
||||||
TARGETS = in.tokend pointscli claim.cgi puzzler.cgi puzzles.cgi
|
TARGETS = in.tokend tokencli claim.cgi
|
||||||
|
TARGETS += puzzler.cgi puzzles.cgi
|
||||||
|
TARGETS += pointscli
|
||||||
|
|
||||||
all: build
|
all: build
|
||||||
|
|
||||||
build: $(TARGETS)
|
build: $(TARGETS)
|
||||||
|
|
||||||
in.tokend: in.tokend.o xxtea.o common.o
|
in.tokend: in.tokend.o arc4.o common.o
|
||||||
|
tokencli: tokencli.o arc4.o
|
||||||
pointscli: pointscli.o common.o
|
pointscli: pointscli.o common.o
|
||||||
|
|
||||||
puzzles.cgi: puzzles.cgi.o common.o
|
puzzles.cgi: puzzles.cgi.o common.o
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "arc4.h"
|
||||||
|
|
||||||
|
#define swap(a, b) do {int _swap=a; a=b, b=_swap;} while (0)
|
||||||
|
|
||||||
|
struct arc4_ctx {
|
||||||
|
uint8_t S[256];
|
||||||
|
uint8_t i;
|
||||||
|
uint8_t j;
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
arc4_init(struct arc4_ctx *ctx, uint8_t const *key, size_t keylen)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int j = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < 256; i += 1) {
|
||||||
|
ctx->S[i] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 256; i += 1) {
|
||||||
|
j = (j + ctx->S[i] + key[i % keylen]) % 256;
|
||||||
|
swap(ctx->S[i], ctx->S[j]);
|
||||||
|
}
|
||||||
|
ctx->i = 0;
|
||||||
|
ctx->j = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t
|
||||||
|
arc4_pad(struct arc4_ctx *ctx)
|
||||||
|
{
|
||||||
|
ctx->i = (ctx->i + 1) % 256;
|
||||||
|
ctx->j = (ctx->j + ctx->S[ctx->i]) % 256;
|
||||||
|
swap(ctx->S[ctx->i], ctx->S[ctx->j]);
|
||||||
|
return ctx->S[(ctx->S[ctx->i] + ctx->S[ctx->j]) % 256];
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
arc4_crypt(struct arc4_ctx *ctx,
|
||||||
|
uint8_t *obuf, uint8_t const *ibuf, size_t buflen)
|
||||||
|
{
|
||||||
|
size_t k;
|
||||||
|
|
||||||
|
for (k = 0; k < buflen; k += 1) {
|
||||||
|
obuf[k] = ibuf[k] ^ arc4_pad(ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
arc4_crypt_buffer(uint8_t const *key, size_t keylen,
|
||||||
|
uint8_t *buf, size_t buflen)
|
||||||
|
{
|
||||||
|
struct arc4_ctx ctx;
|
||||||
|
|
||||||
|
arc4_init(&ctx, key, keylen);
|
||||||
|
arc4_crypt(&ctx, buf, buf, buflen);
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
#ifndef __ARC4_H__
|
||||||
|
#define __ARC4_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
struct arc4_ctx;
|
||||||
|
|
||||||
|
void arc4_init(struct arc4_ctx *ctx, uint8_t const *key, size_t keylen);
|
||||||
|
uint8_t arc4_pad(struct arc4_ctx *ctx);
|
||||||
|
void arc4_crypt(struct arc4_ctx *ctx,
|
||||||
|
uint8_t *obuf, uint8_t const *ibuf, size_t buflen);
|
||||||
|
void arc4_crypt_buffer(uint8_t const *key, size_t keylen,
|
||||||
|
uint8_t *buf, size_t buflen);
|
||||||
|
|
||||||
|
#endif
|
|
@ -64,7 +64,7 @@ main(int argc, char *argv[])
|
||||||
category[i] = '\0';
|
category[i] = '\0';
|
||||||
|
|
||||||
{
|
{
|
||||||
char line[TEAM_MAX + TOKEN_MAX + 1];
|
char line[200];
|
||||||
|
|
||||||
my_snprintf(line, sizeof(line),
|
my_snprintf(line, sizeof(line),
|
||||||
"%s %s", team, token);
|
"%s %s", team, token);
|
||||||
|
|
|
@ -282,6 +282,29 @@ fgrepx(char const *needle, char const *filename)
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t
|
||||||
|
my_random()
|
||||||
|
{
|
||||||
|
static int urandom = -2;
|
||||||
|
int len;
|
||||||
|
int32_t ret;
|
||||||
|
|
||||||
|
if (-2 == urandom) {
|
||||||
|
urandom = open("/dev/urandom", O_RDONLY);
|
||||||
|
srandom(time(NULL) * getpid());
|
||||||
|
}
|
||||||
|
if (-1 == urandom) {
|
||||||
|
return (int32_t)random();
|
||||||
|
}
|
||||||
|
|
||||||
|
len = read(urandom, &ret, sizeof(ret));
|
||||||
|
if (len != sizeof(ret)) {
|
||||||
|
return (int32_t)random();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
my_snprintf(char *buf, size_t buflen, char *fmt, ...)
|
my_snprintf(char *buf, size_t buflen, char *fmt, ...)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define __COMMON_H__
|
#define __COMMON_H__
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#define TEAM_MAX 40
|
#define TEAM_MAX 40
|
||||||
#define CAT_MAX 40
|
#define CAT_MAX 40
|
||||||
|
@ -17,6 +18,7 @@ void cgi_error(char *fmt, ...);
|
||||||
|
|
||||||
|
|
||||||
int fgrepx(char const *needle, char const *filename);
|
int fgrepx(char const *needle, char const *filename);
|
||||||
|
int32_t my_random();
|
||||||
int my_snprintf(char *buf, size_t buflen, char *fmt, ...);
|
int my_snprintf(char *buf, size_t buflen, char *fmt, ...);
|
||||||
char *state_path(char const *fmt, ...);
|
char *state_path(char const *fmt, ...);
|
||||||
char *package_path(char const *fmt, ...);
|
char *package_path(char const *fmt, ...);
|
||||||
|
|
|
@ -9,8 +9,9 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <sysexits.h>
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "xxtea.h"
|
#include "arc4.h"
|
||||||
|
|
||||||
#define itokenlen 3
|
#define itokenlen 3
|
||||||
|
|
||||||
|
@ -69,21 +70,19 @@ bubblebabble(char *out, char const *in, const size_t inlen)
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
char service[50];
|
char service[50];
|
||||||
size_t servicelen;
|
size_t servicelen;
|
||||||
char token[80];
|
char token[80];
|
||||||
size_t tokenlen;
|
size_t tokenlen;
|
||||||
uint32_t key[4];
|
uint8_t key[256];
|
||||||
|
size_t keylen;
|
||||||
/* Seed the random number generator. This ought to be unpredictable
|
|
||||||
enough for a contest. */
|
|
||||||
srand((int)time(NULL) * (int)getpid());
|
|
||||||
|
|
||||||
/* Read service name. */
|
/* Read service name. */
|
||||||
{
|
{
|
||||||
ssize_t len;
|
ssize_t len;
|
||||||
|
|
||||||
len = read(0, service, sizeof(service) - 1);
|
len = read(0, service, sizeof(service));
|
||||||
|
if (0 >= len) return 0;
|
||||||
for (servicelen = 0;
|
for (servicelen = 0;
|
||||||
(servicelen < len) && isalnum(service[servicelen]);
|
(servicelen < len) && isalnum(service[servicelen]);
|
||||||
servicelen += 1);
|
servicelen += 1);
|
||||||
|
@ -91,35 +90,46 @@ main(int argc, char *argv[])
|
||||||
|
|
||||||
/* Read in that service's key. */
|
/* Read in that service's key. */
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
size_t len;
|
int ret;
|
||||||
|
|
||||||
fd = open(state_path("token.keys/%.*s", (int)servicelen, service), O_RDONLY);
|
fd = open(state_path("token.keys/%.*s", (int)servicelen, service), O_RDONLY);
|
||||||
if (-1 == fd) {
|
if (-1 == fd) {
|
||||||
write(1, "!nosvc", 6);
|
perror("Open key");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = read(fd, &key, 16);
|
ret = read(fd, &key, sizeof(key));
|
||||||
close(fd);
|
if (-1 == ret) {
|
||||||
|
perror("Read key");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
keylen = (size_t)ret;
|
||||||
|
|
||||||
if (16 != len) {
|
close(fd);
|
||||||
write(1, "!shortkey", 9);
|
}
|
||||||
|
|
||||||
|
/* Send a nonce, expect it back encrypted */
|
||||||
|
{
|
||||||
|
int32_t nonce = my_random();
|
||||||
|
int32_t enonce = 0;
|
||||||
|
|
||||||
|
write(1, &nonce, sizeof(nonce));
|
||||||
|
arc4_crypt_buffer(key, keylen, (uint8_t *)&nonce, sizeof(nonce));
|
||||||
|
read(0, &enonce, sizeof(enonce));
|
||||||
|
if (nonce != enonce) {
|
||||||
|
write(1, ":<", 2);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create the token. */
|
/* Create the token. */
|
||||||
{
|
{
|
||||||
uint8_t crap[itokenlen];
|
int32_t crap = my_random();
|
||||||
char digest[bubblebabble_len(itokenlen)];
|
char digest[bubblebabble_len(itokenlen)];
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Digest some random junk. */
|
/* Digest some random junk. */
|
||||||
for (i = 0; i < itokenlen; i += 1) {
|
bubblebabble(digest, (char *)&crap, itokenlen);
|
||||||
crap[i] = (uint8_t)random();
|
|
||||||
}
|
|
||||||
bubblebabble(digest, (char *)crap, itokenlen);
|
|
||||||
|
|
||||||
/* Append digest to service name. */
|
/* Append digest to service name. */
|
||||||
tokenlen = (size_t)snprintf(token, sizeof(token),
|
tokenlen = (size_t)snprintf(token, sizeof(token),
|
||||||
|
@ -158,19 +168,14 @@ main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Encrypt the token. Note that now tokenlen is in uint32_ts, not
|
/* Encrypt the token. */
|
||||||
chars! Also remember that token must be big enough to hold a
|
|
||||||
multiple of 4 chars, since tea will go ahead and jumble them up for
|
|
||||||
you. If the compiler aligns words this shouldn't be a problem. */
|
|
||||||
{
|
{
|
||||||
tokenlen = (tokenlen + (tokenlen % sizeof(uint32_t))) / sizeof(uint32_t);
|
arc4_crypt_buffer(key, keylen, (uint8_t *)token, tokenlen);
|
||||||
|
|
||||||
tea_encode(key, (uint32_t *)token, tokenlen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send it back. If there's an error here, it's okay. Better to have
|
/* Send it back. If there's an error here, it's okay. Better to have
|
||||||
unclaimed tokens than unclaimable ones. */
|
unclaimed tokens than unclaimable ones. */
|
||||||
write(1, token, tokenlen * sizeof(uint32_t));
|
write(1, token, tokenlen);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,7 @@ main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
char line[TEAM_MAX + CAT_MAX + sizeof(points_str) + 2];
|
char line[200];
|
||||||
|
|
||||||
my_snprintf(line, sizeof(line),
|
my_snprintf(line, sizeof(line),
|
||||||
"%s %s %ld", team, category, points);
|
"%s %s %ld", team, category, points);
|
||||||
|
|
|
@ -19,11 +19,12 @@ longcmp(long *a, long *b)
|
||||||
#define PUZZLES_MAX 100
|
#define PUZZLES_MAX 100
|
||||||
|
|
||||||
/** Keeps track of the most points yet awarded in each category */
|
/** Keeps track of the most points yet awarded in each category */
|
||||||
|
int ncats = 0;
|
||||||
struct {
|
struct {
|
||||||
char cat[CAT_MAX];
|
char cat[CAT_MAX];
|
||||||
long points;
|
long points;
|
||||||
} points_by_cat[PUZZLES_MAX];
|
} points_by_cat[PUZZLES_MAX];
|
||||||
int ncats = 0;
|
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
read_until_char(FILE *f, char *buf, size_t buflen, char delim)
|
read_until_char(FILE *f, char *buf, size_t buflen, char delim)
|
||||||
|
@ -70,8 +71,6 @@ main(int argc, char *argv[])
|
||||||
read_until_char(f, points_str, sizeof(points_str), '\n');
|
read_until_char(f, points_str, sizeof(points_str), '\n');
|
||||||
points = atol(points_str);
|
points = atol(points_str);
|
||||||
|
|
||||||
printf("%s %ld\n", cat, points);
|
|
||||||
|
|
||||||
for (i = 0; i < ncats; i += 1) {
|
for (i = 0; i < ncats; i += 1) {
|
||||||
if (0 == strcmp(cat, points_by_cat[i].cat)) break;
|
if (0 == strcmp(cat, points_by_cat[i].cat)) break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sysexits.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "arc4.h"
|
||||||
|
|
||||||
|
/* I don't feel compelled to put all the TCP client code in here
|
||||||
|
* when it's so simple to run this with netcat or ucspi. Plus, using
|
||||||
|
* stdin and stdout makes it simpler to test.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
read_key(char *filename, uint8_t *key, size_t *keylen)
|
||||||
|
{
|
||||||
|
int fd = open(filename, O_RDONLY);
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if (-1 == fd) {
|
||||||
|
perror("open");
|
||||||
|
return EX_NOINPUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = read(fd, key, *keylen);
|
||||||
|
if (-1 == len) {
|
||||||
|
perror("read");
|
||||||
|
return EX_NOINPUT;
|
||||||
|
}
|
||||||
|
*keylen = (size_t)len;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[]) {
|
||||||
|
uint8_t skey[200];
|
||||||
|
size_t skeylen = sizeof(skey);
|
||||||
|
char token[200];
|
||||||
|
size_t tokenlen;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (argc != 3) {
|
||||||
|
fprintf(stderr, "Usage: %s SERVICE SERVICEKEY 3>TOKENFILE\n", argv[0]);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
fprintf(stderr, "SERVICEKEY is a filenames.\n");
|
||||||
|
fprintf(stderr, "Tokens are written to file descriptor 3.\n");
|
||||||
|
return EX_USAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read in keys */
|
||||||
|
ret = read_key(argv[2], skey, &skeylen);
|
||||||
|
if (0 != ret) return ret;
|
||||||
|
|
||||||
|
/* write service name */
|
||||||
|
write(1, argv[1], strlen(argv[1]));
|
||||||
|
|
||||||
|
/* read nonce, send back encrypted version */
|
||||||
|
{
|
||||||
|
uint8_t nonce[80];
|
||||||
|
int noncelen;
|
||||||
|
|
||||||
|
noncelen = read(0, nonce, sizeof(nonce));
|
||||||
|
if (0 >= noncelen) {
|
||||||
|
perror("read");
|
||||||
|
return EX_IOERR;
|
||||||
|
}
|
||||||
|
arc4_crypt_buffer(skey, skeylen, nonce, (size_t)noncelen);
|
||||||
|
write(1, nonce, (size_t)noncelen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read token */
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
|
||||||
|
len = read(0, token, sizeof(token));
|
||||||
|
if (0 >= len) {
|
||||||
|
perror("read");
|
||||||
|
return EX_IOERR;
|
||||||
|
}
|
||||||
|
tokenlen = (size_t)len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* decrypt it */
|
||||||
|
arc4_crypt_buffer(skey, skeylen, (uint8_t *)token, tokenlen);
|
||||||
|
|
||||||
|
/* write it to fd 3 */
|
||||||
|
write(3, token, tokenlen);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -1,51 +0,0 @@
|
||||||
#include <stdint.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#define DELTA 0x9e3779b9
|
|
||||||
#define MX ((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (k[(p&3)^e] ^ z));
|
|
||||||
|
|
||||||
void
|
|
||||||
btea(uint32_t *v, int n, uint32_t const k[4])
|
|
||||||
{
|
|
||||||
uint32_t y, z, sum;
|
|
||||||
unsigned p, rounds, e;
|
|
||||||
|
|
||||||
if (n > 1) { /* Coding Part */
|
|
||||||
rounds = 6 + 52/n;
|
|
||||||
sum = 0;
|
|
||||||
z = v[n-1];
|
|
||||||
do {
|
|
||||||
sum += DELTA;
|
|
||||||
e = (sum >> 2) & 3;
|
|
||||||
for (p=0; p<n-1; p++)
|
|
||||||
y = v[p+1], z = v[p] += MX;
|
|
||||||
y = v[0];
|
|
||||||
z = v[n-1] += MX;
|
|
||||||
} while (--rounds);
|
|
||||||
} else if (n < -1) { /* Decoding Part */
|
|
||||||
n = -n;
|
|
||||||
rounds = 6 + 52/n;
|
|
||||||
sum = rounds*DELTA;
|
|
||||||
y = v[0];
|
|
||||||
do {
|
|
||||||
e = (sum >> 2) & 3;
|
|
||||||
for (p=n-1; p>0; p--)
|
|
||||||
z = v[p-1], y = v[p] -= MX;
|
|
||||||
z = v[n-1];
|
|
||||||
y = v[0] -= MX;
|
|
||||||
} while ((sum -= DELTA) != 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
tea_encode(uint32_t const key[4], uint32_t *buf, size_t buflen)
|
|
||||||
{
|
|
||||||
btea(buf, buflen, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
tea_decode(uint32_t const key[4], uint32_t *buf, size_t buflen)
|
|
||||||
{
|
|
||||||
btea(buf, -buflen, key);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
void tea_encode(uint32_t const key[4], uint32_t *buf, size_t buflen);
|
|
||||||
void tea_decode(uint32_t const key[4], uint32_t *buf, size_t buflen);
|
|
|
@ -88,8 +88,8 @@ fi
|
||||||
mkdir -p $CTF_BASE/token.keys
|
mkdir -p $CTF_BASE/token.keys
|
||||||
echo -n '0123456789abcdef' > $CTF_BASE/token.keys/tokencat
|
echo -n '0123456789abcdef' > $CTF_BASE/token.keys/tokencat
|
||||||
|
|
||||||
# in.tokend uses a random number generator
|
mkfifo $CTF_BASE/nancy
|
||||||
echo -n 'tokencat' | src/in.tokend > /dev/null
|
src/tokencli tokencat $CTF_BASE/token.keys/tokencat < $CTF_BASE/nancy 3>$CTF_BASE/t | src/in.tokend > $CTF_BASE/nancy
|
||||||
|
|
||||||
if ! grep -q 'tokencat:x....-....x' $CTF_BASE/tokens.db; then
|
if ! grep -q 'tokencat:x....-....x' $CTF_BASE/tokens.db; then
|
||||||
die "in.tokend didn't write to database"
|
die "in.tokend didn't write to database"
|
||||||
|
@ -103,11 +103,11 @@ if src/claim.cgi t=$hash k=tokencat:xanax-xanax | grep -q success; then
|
||||||
die "claim.cgi gave points for a bogus token"
|
die "claim.cgi gave points for a bogus token"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! src/claim.cgi t=$hash k=$(cat $CTF_BASE/tokens.db) | grep -q success; then
|
if ! src/claim.cgi t=$hash k=$(cat $CTF_BASE/t) | grep -q success; then
|
||||||
die "claim.cgi didn't give me any points"
|
die "claim.cgi didn't give me any points"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if src/claim.cgi t=$hash k=$(cat $CTF_BASE/tokens.db) | grep -q success; then
|
if src/claim.cgi t=$hash k=$(cat $CTF_BASE/t) | grep -q success; then
|
||||||
die "claim.cgi gave me points twice for the same token"
|
die "claim.cgi gave me points twice for the same token"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue