mirror of https://github.com/dirtbags/moth.git
Add in pwnables, start at octopus & tokencli
This commit is contained in:
parent
e46bff58d0
commit
48caa26556
9
Makefile
9
Makefile
|
@ -10,7 +10,12 @@ endef
|
||||||
|
|
||||||
include */*.mk
|
include */*.mk
|
||||||
|
|
||||||
packages: $(addsuffix -package, $(PACKAGES))
|
packages: $(addsuffix .pkg, $(PACKAGES))
|
||||||
|
|
||||||
|
install: $(addsuffix -install, $(PACKAGES))
|
||||||
|
|
||||||
clean: $(addsuffix -clean, $(PACKAGES))
|
clean: $(addsuffix -clean, $(PACKAGES))
|
||||||
rm -rf build *.pkg
|
rm -rf build *.pkg *-install *-build
|
||||||
|
|
||||||
|
%.pkg: %-install
|
||||||
|
mksquashfs build/$* $*.pkg -all-root -noappend
|
||||||
|
|
|
@ -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
|
|
@ -0,0 +1,97 @@
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <values.h>
|
||||||
|
|
||||||
|
#ifndef CTF_BASE
|
||||||
|
#define CTF_BASE "/var/lib/ctf"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct arc4_ctx {
|
||||||
|
uint8_t S[256];
|
||||||
|
uint8_t i;
|
||||||
|
uint8_t j;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define swap(a, b) do {int _swap=a; a=b, b=_swap;} while (0)
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
arc4_crypt(struct arc4_ctx *ctx,
|
||||||
|
uint8_t *obuf, uint8_t const *ibuf, size_t buflen)
|
||||||
|
{
|
||||||
|
int i = ctx->i;
|
||||||
|
int j = ctx->j;
|
||||||
|
size_t k;
|
||||||
|
|
||||||
|
for (k = 0; k < buflen; k += 1) {
|
||||||
|
uint8_t mask;
|
||||||
|
|
||||||
|
i = (i + 1) % 256;
|
||||||
|
j = (j + ctx->S[i]) % 256;
|
||||||
|
swap(ctx->S[i], ctx->S[j]);
|
||||||
|
mask = ctx->S[(ctx->S[i] + ctx->S[j]) % 256];
|
||||||
|
obuf[k] = ibuf[k] ^ mask;
|
||||||
|
}
|
||||||
|
ctx->i = i;
|
||||||
|
ctx->j = j;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
read_token(char *name,
|
||||||
|
uint8_t const *key, size_t keylen,
|
||||||
|
char *buf, size_t buflen)
|
||||||
|
{
|
||||||
|
char path[PATH_MAX];
|
||||||
|
int pathlen;
|
||||||
|
int fd;
|
||||||
|
ssize_t ret;
|
||||||
|
|
||||||
|
pathlen = snprintf(path, sizeof(path) - 1,
|
||||||
|
CTF_BASE "/tokens/%s", name);
|
||||||
|
path[pathlen] = '\0';
|
||||||
|
|
||||||
|
fd = open(path, O_RDONLY);
|
||||||
|
if (-1 == fd) return -1;
|
||||||
|
|
||||||
|
ret = read(fd, buf, buflen);
|
||||||
|
close(fd);
|
||||||
|
if (-1 != ret) {
|
||||||
|
arc4_crypt_buffer(key, keylen, (uint8_t *)buf, (size_t)ret);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
#ifndef __TOKEN_H__
|
||||||
|
#define __TOKEN_H__
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* ARC4 functions, in case anybody wants 'em */
|
||||||
|
struct arc4_ctx;
|
||||||
|
void arc4_init(struct arc4_ctx *ctx,
|
||||||
|
uint8_t const *key, size_t keylen);
|
||||||
|
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);
|
||||||
|
|
||||||
|
ssize_t read_token(char *name,
|
||||||
|
uint8_t const *key, size_t keylen,
|
||||||
|
char *buf, size_t buflen);
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,9 +1,7 @@
|
||||||
MCP_PKGDIR = build/mcp
|
MCP_PKGDIR = build/mcp
|
||||||
MCP_PACKAGE = mcp.pkg
|
MCP_PACKAGE = mcp.pkg
|
||||||
|
|
||||||
mcp-package: $(MCP_PACKAGE)
|
mcp-install: mcp-build
|
||||||
|
|
||||||
$(MCP_PACKAGE): mcp-build
|
|
||||||
mkdir -p $(MCP_PKGDIR)
|
mkdir -p $(MCP_PKGDIR)
|
||||||
|
|
||||||
cp mcp/setup $(MCP_PKGDIR)
|
cp mcp/setup $(MCP_PKGDIR)
|
||||||
|
@ -20,8 +18,7 @@ $(MCP_PACKAGE): mcp-build
|
||||||
cp mcp/src/puzzler.cgi $(MCP_PKGDIR)/www/
|
cp mcp/src/puzzler.cgi $(MCP_PKGDIR)/www/
|
||||||
cp mcp/src/claim.cgi $(MCP_PKGDIR)/www/
|
cp mcp/src/claim.cgi $(MCP_PKGDIR)/www/
|
||||||
|
|
||||||
mksquashfs $(MCP_PKGDIR) $(MCP_PACKAGE) -all-root -noappend
|
touch $@
|
||||||
|
|
||||||
|
|
||||||
mcp-test: mcp-build
|
mcp-test: mcp-build
|
||||||
mcp/test.sh
|
mcp/test.sh
|
||||||
|
|
|
@ -1,59 +0,0 @@
|
||||||
#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 @@
|
||||||
|
../../common/arc4.c
|
|
@ -1,16 +0,0 @@
|
||||||
#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
|
|
|
@ -0,0 +1 @@
|
||||||
|
../../common/arc4.h
|
|
@ -1,92 +0,0 @@
|
||||||
#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;
|
|
||||||
}
|
|
|
@ -0,0 +1 @@
|
||||||
|
../../tokencli/src/tokencli.c
|
|
@ -0,0 +1,18 @@
|
||||||
|
OCTOPUS_PKGDIR = build/octopus
|
||||||
|
OCTOPUS_PACKAGE = octopus.pkg
|
||||||
|
|
||||||
|
octopus-install: octopus-build
|
||||||
|
mkdir -p $(OCTOPUS_PKGDIR)/bin/
|
||||||
|
|
||||||
|
$(call COPYTREE, octopus/service, $(OCTOPUS_PKGDIR)/service)
|
||||||
|
|
||||||
|
cp octopus/src/octopus $(OCTOPUS_PKGDIR)/bin/
|
||||||
|
|
||||||
|
octopus-clean:
|
||||||
|
rm -rf $(OCTOPUS_PKGDIR) $(OCTOPUS_PACKAGE)
|
||||||
|
$(MAKE) -C octopus/src clean
|
||||||
|
|
||||||
|
octopus-build:
|
||||||
|
$(MAKE) -C octopus/src build
|
||||||
|
|
||||||
|
PACKAGES += octopus
|
|
@ -0,0 +1,3 @@
|
||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
exec logger -t octopus
|
|
@ -0,0 +1,4 @@
|
||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
exec 2>&1
|
||||||
|
exec /opt/octopus/bin/octopus
|
|
@ -0,0 +1,3 @@
|
||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
mkdir -p /var/lib/ctf/tokens
|
|
@ -0,0 +1,7 @@
|
||||||
|
# Octopus / Some kind of octopus / Tearing my shell apart / Letting the
|
||||||
|
# sea get in / You make my insides outside
|
||||||
|
|
||||||
|
octopus: octopus.o token.o
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f octopus *.o
|
|
@ -0,0 +1,373 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sysexits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/select.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <netinet/tcp.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include "token.h"
|
||||||
|
|
||||||
|
#define OUTPUT_MAX 1024
|
||||||
|
#define INPUT_MAX 1024
|
||||||
|
|
||||||
|
#ifndef max
|
||||||
|
#define max(a,b) (((a)>(b))?(a):(b))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint8_t const key[] = {0x7d, 0x47, 0x84, 0x28,
|
||||||
|
0x09, 0x87, 0xb5, 0xd2,
|
||||||
|
0xd8, 0xab, 0x1c, 0xf3,
|
||||||
|
0xf2, 0x96, 0xd6, 0x68};
|
||||||
|
|
||||||
|
char const octopus[] =
|
||||||
|
(" ___\n"
|
||||||
|
" .-' `'.\n"
|
||||||
|
" / \\\n"
|
||||||
|
" | ;\n"
|
||||||
|
" | | ___.--,\n"
|
||||||
|
" _.._ |8) ~ (8) | _.---'`__.-( (_.\n"
|
||||||
|
" __.--'`_.. '.__.\\ '--. \\_.-' ,.--'` `""`\n"
|
||||||
|
" ( ,.--'` ',__ /./; ;, '.__.'` __\n"
|
||||||
|
" _`) ) .---.__.' / | |\\ \\__..--\"\" \"\"\"--.,_\n"
|
||||||
|
" `---' .'.''-._.-'`_./ /\\ '. \\ _.-~~~````~~~-._`-.__.'\n"
|
||||||
|
" | | .' _.-' | | \\ \\ '. `~---`\n"
|
||||||
|
" \\ \\/ .' \\ \\ '. '-._)\n"
|
||||||
|
" \\/ / \\ \\ `=.__`~-.\n"
|
||||||
|
" jgs / /\\ `) ) / / `\"\".`\\\n"
|
||||||
|
" , _.-'.'\\ \\ / / ( ( / /\n"
|
||||||
|
" `--~` ) ) .-'.' '.'. | (\n"
|
||||||
|
" (/` ( (` ) ) '-;\n"
|
||||||
|
" ` '-; (-'\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
const char *friends[8] = {
|
||||||
|
("Help Olive Octopus visit all 8 of her friends to receive a prize!\n"
|
||||||
|
"Hurry though, things change quickly!\n"
|
||||||
|
"Next friend: %08o\n"
|
||||||
|
"%s"
|
||||||
|
),
|
||||||
|
("Thanks for stopping by, Olive! Good luck finding that prize!\n"
|
||||||
|
"Next friend: %08o\n"
|
||||||
|
" ,__\n"
|
||||||
|
" | `'.\n"
|
||||||
|
"__ |`-._/_.:---`-.._\n"
|
||||||
|
"\\='. _/..--'`__ `'-._\n"
|
||||||
|
" \\- '-.--\"` === / o `',\n"
|
||||||
|
" )= ( .--_ | _.'\n"
|
||||||
|
" /_=.'-._ {=_-_ | .--`-.\n"
|
||||||
|
"/_.' `\\`'-._ '-= \\ _.'\n"
|
||||||
|
" jgs ) _.-'`'-.. _..-'`\n"
|
||||||
|
" /_.' `/\";';`|\n"
|
||||||
|
" \\` .'/\n"
|
||||||
|
" '--'\n"
|
||||||
|
),
|
||||||
|
("Snap, snap! Good luck on your quest, Olive!\n"
|
||||||
|
"Next friend: %08o\n"
|
||||||
|
" .\"\".-._.-.\"\".\n"
|
||||||
|
" | \\ | / |\n"
|
||||||
|
" \\ \\.T./ /\n"
|
||||||
|
" '-./ \\.-'\n"
|
||||||
|
" / \\\n"
|
||||||
|
" ; ;\n"
|
||||||
|
" | |\n"
|
||||||
|
" | |\n"
|
||||||
|
" / \\\n"
|
||||||
|
" | . |\n"
|
||||||
|
" __.| : |.__\n"
|
||||||
|
" .-'` | : | `'-.\n"
|
||||||
|
" /` .\"\\ 0 : 0 /\". `\\\n"
|
||||||
|
" | _/ './ : \\.' \\_ |\n"
|
||||||
|
" | / /`\"\"\"`\\ \\ |\n"
|
||||||
|
" \\ \\ .-' '._ / /\n"
|
||||||
|
" jgs '-._\\ /_.-'\n"
|
||||||
|
),
|
||||||
|
("Nice talking with you, Olive. I'd best get back to my babies now!\n"
|
||||||
|
"Next friend: %08o\n"
|
||||||
|
" , ,\n"
|
||||||
|
" \\:.|`._\n"
|
||||||
|
" /\\/;.:':::;;;._\n"
|
||||||
|
" < .' ':::;(\n"
|
||||||
|
" < ' _ '::;>\n"
|
||||||
|
" \\ (9) _ :::;(\n"
|
||||||
|
" | / \\ ::;`>\n"
|
||||||
|
" | / | :;(\n"
|
||||||
|
" | ( <=- .::;>\n"
|
||||||
|
" ( a) )=- .::;(\n"
|
||||||
|
" '-' <=- .::;>\n"
|
||||||
|
" )==- ::::( ,\n"
|
||||||
|
" <==- :::(,-'(\n"
|
||||||
|
" )=- ':: _.->\n"
|
||||||
|
" <==- ':.' _(\n"
|
||||||
|
" <==- .:'_ (\n"
|
||||||
|
" )==- .::' '->\n"
|
||||||
|
" <=- .:;(`'.(\n"
|
||||||
|
" `) ':;> `\n"
|
||||||
|
" .-. < :;(\n"
|
||||||
|
" <`.':\\ ) :;>\n"
|
||||||
|
" < :/<_/ < .:;>\n"
|
||||||
|
" < '`---'` .::(`\n"
|
||||||
|
" jgs < .:;>'\n"
|
||||||
|
" `-..:::-'`\n"
|
||||||
|
),
|
||||||
|
("Spshhh! Good to see you, Olive! You're on the right track!\n"
|
||||||
|
"Next friend: %08o\n"
|
||||||
|
" ,_\n"
|
||||||
|
" \\::,\n"
|
||||||
|
" |::::\\\n"
|
||||||
|
" |:::::\\\n"
|
||||||
|
" __/:::::::\\,____\n"
|
||||||
|
" _.-::::::::::::::::::::==..,____\n"
|
||||||
|
" .-::::::::::::::::::::::::::::::::::::.,__\n"
|
||||||
|
" .:::::::::::::::::::::::::::::::::::::::::::::)\n"
|
||||||
|
" .:::::'```'-::::::::::::::::::::::(__,__`)::::-'\n"
|
||||||
|
" .;;;;;;::. ':::::::::::::::::::-:::::@::-'\"\"-,\n"
|
||||||
|
" .------:::::::::::' '-::::::::::' / `'--'\"\"\"\".-'\n"
|
||||||
|
"/:::::::::/:::/` _,..-----.,__ `''''`/ ;__,..--''--'`\n"
|
||||||
|
"`'--::::::::::|-'` `'---'| |\n"
|
||||||
|
" `\\::::\\ \\ /\n"
|
||||||
|
" |:::::| '-'\n"
|
||||||
|
" \\::::|\n"
|
||||||
|
" jgs `\\::|\n"
|
||||||
|
" \\/\n"
|
||||||
|
),
|
||||||
|
("You're getting close, Olive!\n"
|
||||||
|
"Next friend: %08o\n"
|
||||||
|
" .-------------'```'----......,,__ _,\n"
|
||||||
|
" | `'`'`'`'-.,.__ .'(\n"
|
||||||
|
" | `'--._.' )\n"
|
||||||
|
" | `'-.<\n"
|
||||||
|
" \\ .-'`'-. -. `\\\n"
|
||||||
|
" \\ -.o_. _ _,-'`\\ |\n"
|
||||||
|
" ``````''--.._.-=-._ .' \\ _,,--'` `-._(\n"
|
||||||
|
" (^^^^^^^^`___ '-. | \\ __,,,...--' `\n"
|
||||||
|
" ````````` `'--..___\\ |`\n"
|
||||||
|
" jgs `-.,'\n"
|
||||||
|
),
|
||||||
|
("Hi, Olive! Not much further now!\n"
|
||||||
|
"Next friend: %08o\n"
|
||||||
|
" , ,\n"
|
||||||
|
" /(_, ,_)\\\n"
|
||||||
|
" \\ _/ \\_ /\n"
|
||||||
|
" // \\\\\n"
|
||||||
|
" \\\\ (@)(@) //\n"
|
||||||
|
" \\'=\"==\"='/\n"
|
||||||
|
" ,===/ \\===,\n"
|
||||||
|
" \",===\\ /===,\"\n"
|
||||||
|
" \" ,==='------'===, \"\n"
|
||||||
|
" jgs \" \"\n"
|
||||||
|
),
|
||||||
|
("Aha! You found me!\n"
|
||||||
|
"Prize: %.*s\n"
|
||||||
|
" (\\.-./)\n"
|
||||||
|
" / \\\n"
|
||||||
|
" .' : '.\n"
|
||||||
|
" _.-'` ' `'-._\n"
|
||||||
|
" .-' : '-.\n"
|
||||||
|
" ,'_.._ . _.._',\n"
|
||||||
|
" '` `'-. ' .-'` `'\n"
|
||||||
|
" '. : .'\n"
|
||||||
|
" \\_. ._/\n"
|
||||||
|
" \\ |^|\n"
|
||||||
|
" | jgs | ;\n"
|
||||||
|
" \\'.___.' /\n"
|
||||||
|
" '-....-'\n")
|
||||||
|
};
|
||||||
|
|
||||||
|
const char invalid[] = "Who are you? Go away!\n";
|
||||||
|
|
||||||
|
#ifdef EASY
|
||||||
|
# define PORTS 15
|
||||||
|
#else
|
||||||
|
# define PORTS 8
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct bound_port {
|
||||||
|
int fd;
|
||||||
|
char output[OUTPUT_MAX];
|
||||||
|
size_t output_len;
|
||||||
|
} bound_ports[PORTS];
|
||||||
|
|
||||||
|
int
|
||||||
|
bind_port(int fd, uint16_t port) {
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
addr.sin_port = htons(port);
|
||||||
|
addr.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
return bind(fd, (struct sockaddr *)&addr, sizeof(addr));
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rebind()
|
||||||
|
{
|
||||||
|
static int offset = 0;
|
||||||
|
char token[200];
|
||||||
|
size_t tokenlen;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
tokenlen = read_token("octopus",
|
||||||
|
key, sizeof(key),
|
||||||
|
token, sizeof(token));
|
||||||
|
if (-1 == tokenlen) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 1; i < 8; i += 1) {
|
||||||
|
int ret;
|
||||||
|
int last_guy;
|
||||||
|
in_port_t port;
|
||||||
|
|
||||||
|
if (-1 != bound_ports[i + offset].fd) {
|
||||||
|
while (-1 == close(bound_ports[i + offset].fd)) {
|
||||||
|
if (errno != EINTR) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bind to a port */
|
||||||
|
bound_ports[i + offset].fd = socket(PF_INET, SOCK_DGRAM, 0);
|
||||||
|
do {
|
||||||
|
port = (random() % 56635) + 10000;
|
||||||
|
ret = bind_port(bound_ports[i + offset].fd, port);
|
||||||
|
} while (-1 == ret);
|
||||||
|
|
||||||
|
/* Set the last guy's port number */
|
||||||
|
last_guy = i + offset - 1;
|
||||||
|
switch (i) {
|
||||||
|
case 1:
|
||||||
|
/* Always change the port 8888 one */
|
||||||
|
last_guy = 0;
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
case 4:
|
||||||
|
case 5:
|
||||||
|
case 6:
|
||||||
|
case 7:
|
||||||
|
bound_ports[last_guy].output_len =
|
||||||
|
snprintf(bound_ports[last_guy].output, OUTPUT_MAX,
|
||||||
|
friends[i - 1], port, octopus);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bound_ports[7 + offset].output_len =
|
||||||
|
snprintf(bound_ports[7 + offset].output, OUTPUT_MAX,
|
||||||
|
friends[7], tokenlen, token);
|
||||||
|
|
||||||
|
if (offset == 0) {
|
||||||
|
offset = PORTS - 8;
|
||||||
|
} else {
|
||||||
|
offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
do_io(int which)
|
||||||
|
{
|
||||||
|
struct bound_port *bp = &bound_ports[which];
|
||||||
|
char input[INPUT_MAX];
|
||||||
|
ssize_t inlen;
|
||||||
|
struct sockaddr from;
|
||||||
|
socklen_t fromlen = sizeof(from);
|
||||||
|
|
||||||
|
inlen = recvfrom(bp->fd, input, INPUT_MAX, 0,
|
||||||
|
&from, &fromlen);
|
||||||
|
if (-1 == inlen) {
|
||||||
|
/* Well don't that just beat all. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (which > 0) {
|
||||||
|
if ((inlen != sizeof(octopus) - 1) ||
|
||||||
|
(0 != memcmp(input, octopus, inlen))) {
|
||||||
|
/* Didn't send the octopus */
|
||||||
|
sendto(bp->fd, invalid, sizeof(invalid), 0,
|
||||||
|
&from, fromlen);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sendto(bp->fd, bp->output, bp->output_len, 0,
|
||||||
|
&from, fromlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
loop()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int nfds = 0;
|
||||||
|
fd_set rfds;
|
||||||
|
struct timeval timeout;
|
||||||
|
|
||||||
|
timeout.tv_sec = 1;
|
||||||
|
timeout.tv_usec = 0;
|
||||||
|
|
||||||
|
FD_ZERO(&rfds);
|
||||||
|
for (i = 0; i < PORTS; i += 1) {
|
||||||
|
nfds = max(nfds, bound_ports[i].fd);
|
||||||
|
FD_SET(bound_ports[i].fd, &rfds);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait forever. There's no need to switch ports if nobody's doing
|
||||||
|
anything. */
|
||||||
|
while (-1 == select(nfds+1, &rfds, NULL, NULL, &timeout)) {
|
||||||
|
if (EINTR == errno) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < PORTS; i += 1) {
|
||||||
|
if (FD_ISSET(bound_ports[i].fd, &rfds)) {
|
||||||
|
do_io(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
int i;
|
||||||
|
time_t last = time(NULL);
|
||||||
|
|
||||||
|
/* The random seed isn't super important here. */
|
||||||
|
srand(8);
|
||||||
|
|
||||||
|
bound_ports[0].fd = socket(PF_INET, SOCK_DGRAM, 0);
|
||||||
|
ret = bind_port(bound_ports[0].fd, 8888);
|
||||||
|
if (-1 == ret) {
|
||||||
|
perror("bind port 8888");
|
||||||
|
return EX_IOERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 1; i < PORTS; i += 1) {
|
||||||
|
bound_ports[i].fd = -1;
|
||||||
|
}
|
||||||
|
if (-1 == rebind()) {
|
||||||
|
perror("initial binding");
|
||||||
|
return EX_IOERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (loop()) {
|
||||||
|
time_t now = time(NULL);
|
||||||
|
|
||||||
|
if (last + 4 < now) {
|
||||||
|
last = now;
|
||||||
|
if (-1 == rebind()) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
perror("main loop");
|
||||||
|
return EX_IOERR;
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
../../common/token.c
|
|
@ -0,0 +1 @@
|
||||||
|
../../common/token.h
|
|
@ -3,12 +3,17 @@ PUZZLES += forensics hackme net-re sequence skynet webapp
|
||||||
|
|
||||||
-include puzzles/*/*.mk
|
-include puzzles/*/*.mk
|
||||||
|
|
||||||
puzzles/%-package:
|
puzzles/%-install:
|
||||||
mkdir -p build/$*
|
mkdir -p build/$*
|
||||||
puzzles/mkpuzzles puzzles/$* build/$*
|
puzzles/mkpuzzles puzzles/$* build/$*
|
||||||
mksquashfs build/$* $*.pkg -all-root -noappend
|
touch $@
|
||||||
|
|
||||||
puzzles/%-clean:
|
puzzles/%-clean:
|
||||||
rm -rf build/$*
|
rm -rf build/$* puzzles/$*-install
|
||||||
|
|
||||||
PACKAGES += $(addprefix puzzles/, $(PUZZLES))
|
%.pkg: puzzles/%-install
|
||||||
|
mksquashfs build/$* $*.pkg -all-root -noappend
|
||||||
|
|
||||||
|
packages: $(addsuffix .pkg, $(PUZZLES))
|
||||||
|
install: $(patsubst %, puzzles/%-install, $(PUZZLES))
|
||||||
|
clean: $(patsubst %, puzzles/%-clean, $(PUZZLES))
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
PWNABLES_PKGDIR = build/pwnables
|
||||||
|
PWNABLES_PACKAGE = pwnables.pkg
|
||||||
|
|
||||||
|
pwnables-install: pwnables-build
|
||||||
|
mkdir -p $(PWNABLES_PKGDIR)
|
||||||
|
|
||||||
|
cp pwnables/setup $(PWNABLES_PKGDIR)
|
||||||
|
|
||||||
|
mkdir -p $(PWNABLES_PKGDIR)/bin/
|
||||||
|
$(MAKE) -C pwnables/src install DESTDIR=$(CURDIR)/$(PWNABLES_PKGDIR)
|
||||||
|
|
||||||
|
$(call COPYTREE, pwnables/service, $(PWNABLES_PKGDIR)/service)
|
||||||
|
|
||||||
|
pwnables-clean:
|
||||||
|
rm -rf $(PWNABLES_PKGDIR) $(PWNABLES_PACKAGE)
|
||||||
|
$(MAKE) -C pwnables/src clean
|
||||||
|
|
||||||
|
pwnables-build:
|
||||||
|
$(MAKE) -C pwnables/src build
|
||||||
|
|
||||||
|
PACKAGES += pwnables
|
|
@ -0,0 +1,3 @@
|
||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
exec logger -t pwnables
|
|
@ -0,0 +1,4 @@
|
||||||
|
.::7777::-.
|
||||||
|
/:'////' `::>/|/
|
||||||
|
.', |||| `/( e\
|
||||||
|
-==~-'`-Xm````-mr' `-_\
|
|
@ -0,0 +1,4 @@
|
||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
[ -f motd ] && cat motd
|
||||||
|
exec chroot /mnt/pwnables-root login -f alice
|
|
@ -0,0 +1,3 @@
|
||||||
|
#! /bin/sh -e
|
||||||
|
|
||||||
|
exec tcpsvd -C 5:"Let's not be greedy" 0 23 /sbin/telnetd -l ./pwnie
|
|
@ -0,0 +1,35 @@
|
||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
if [ ! -d /opt/mcp ]; then
|
||||||
|
hostname pwnables
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Set up a chroot environment by duplicating the base
|
||||||
|
# image
|
||||||
|
if [ ! -x /mnt/pwnables-root/bin/busybox ]; then
|
||||||
|
mkdir -p /mnt/pwnables-root
|
||||||
|
mount -o bind / /mnt/pwnables-root
|
||||||
|
mount -t tmpfs -o size=5m,mode=0755 pwnables-var /mnt/pwnables-root/var
|
||||||
|
mount -t tmpfs -o size=15k pwnables-tmp /mnt/pwnables-root/tmp
|
||||||
|
mount -t tmpfs -o size=5m pwnables-home /mnt/pwnables-root/home
|
||||||
|
|
||||||
|
# Make some skeleton junk
|
||||||
|
install -o root -m 0755 -d /mnt/pwnables-root/var/lib
|
||||||
|
install -o root -m 0755 -d /mnt/pwnables-root/var/log
|
||||||
|
install -o root -m 0755 -d /mnt/pwnables-root/var/spool
|
||||||
|
install -o root -m 0755 -d /mnt/pwnables-root/var/cache
|
||||||
|
install -o root -m 0777 -d /mnt/pwnables-root/var/run
|
||||||
|
install -o root -m 0777 -d /mnt/pwnables-root/var/cache
|
||||||
|
|
||||||
|
install -o root -d /mnt/pwnables-root/home/alice/
|
||||||
|
install -o root -m 0111 bin/* /mnt/pwnables-root/home/alice/
|
||||||
|
|
||||||
|
# ltrace needs to read the binary
|
||||||
|
chmod +r /mnt/pwnables-root/home/alice/ltraceme
|
||||||
|
|
||||||
|
# strace needs to be suid
|
||||||
|
chown bob /mnt/pwnables-root/home/alice/straceme
|
||||||
|
chmod 04511 /mnt/pwnables-root/home/alice/straceme
|
||||||
|
fi
|
||||||
|
|
||||||
|
cp -r service/* /var/service/
|
|
@ -0,0 +1,18 @@
|
||||||
|
CFLAGS = -Wall -Werror
|
||||||
|
TARGETS = gimmie ltraceme straceme killme
|
||||||
|
|
||||||
|
all: build
|
||||||
|
|
||||||
|
build: $(TARGETS)
|
||||||
|
|
||||||
|
gimmie: gimmie.o token.o
|
||||||
|
octopus: octopus.o token.o
|
||||||
|
ltraceme: ltraceme.o token.o
|
||||||
|
straceme: straceme.o token.o
|
||||||
|
killme: killme.o token.o
|
||||||
|
|
||||||
|
install: $(TARGETS)
|
||||||
|
install -m 0755 $(TARGETS) $(DESTDIR)/bin
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o $(TARGETS)
|
|
@ -0,0 +1,49 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sysexits.h>
|
||||||
|
#include "arc4.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
struct arc4_ctx ctx;
|
||||||
|
|
||||||
|
/* Read key and initialize context */
|
||||||
|
{
|
||||||
|
uint8_t key[256];
|
||||||
|
size_t keylen = 0;
|
||||||
|
FILE *f;
|
||||||
|
|
||||||
|
if (argc == 2) {
|
||||||
|
if (! (f = fopen(argv[1], "r"))) {
|
||||||
|
perror(argv[0]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
f = fdopen(3, "r");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (f) {
|
||||||
|
keylen = fread(key, 1, sizeof(key), f);
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 == keylen) {
|
||||||
|
fprintf(stderr, "Usage: %s [KEYFILE] <PLAINTEXT\n", argv[0]);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
fprintf(stderr, "You can also pass in the key on fd 3; omit\n");
|
||||||
|
fprintf(stderr, "KEYFILE in this case.\n");
|
||||||
|
return EX_IOERR;
|
||||||
|
}
|
||||||
|
arc4_init(&ctx, key, (size_t)keylen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Encrypt */
|
||||||
|
while (1) {
|
||||||
|
int c = getchar();
|
||||||
|
|
||||||
|
if (EOF == c) break;
|
||||||
|
putchar(c ^ arc4_pad(&ctx));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "token.h"
|
||||||
|
|
||||||
|
uint8_t const key[] = {0x5f, 0x64, 0x13, 0x29,
|
||||||
|
0x2e, 0x46, 0x76, 0xcd,
|
||||||
|
0x65, 0xff, 0xe8, 0x03,
|
||||||
|
0xa4, 0xa9, 0x4f, 0xd9};
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
char token[200];
|
||||||
|
ssize_t tokenlen;
|
||||||
|
|
||||||
|
tokenlen = read_token("gimmie",
|
||||||
|
key, sizeof(key),
|
||||||
|
token, sizeof(token) - 1);
|
||||||
|
if (-1 == tokenlen) {
|
||||||
|
return 69;
|
||||||
|
}
|
||||||
|
|
||||||
|
token[tokenlen++] = '\n';
|
||||||
|
write(1, token, tokenlen);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include "token.h"
|
||||||
|
|
||||||
|
#define SIGS 20
|
||||||
|
|
||||||
|
uint8_t const key[] = {0x51, 0x91, 0x6d, 0x81,
|
||||||
|
0x14, 0x21, 0xf8, 0x95,
|
||||||
|
0xb8, 0x09, 0x87, 0xa6,
|
||||||
|
0xa8, 0xb0, 0xa0, 0x46};
|
||||||
|
|
||||||
|
int lastsig;
|
||||||
|
|
||||||
|
void
|
||||||
|
handler(int signum)
|
||||||
|
{
|
||||||
|
lastsig = signum;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
{
|
||||||
|
/* Seed random number generator */
|
||||||
|
FILE *f;
|
||||||
|
int seed;
|
||||||
|
|
||||||
|
f = fopen("/dev/urandom", "r");
|
||||||
|
if (f) {
|
||||||
|
fread(&seed, sizeof(seed), 1, f);
|
||||||
|
srandom(seed);
|
||||||
|
} else {
|
||||||
|
srandom(getpid() * time(NULL));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 1; i < 8; i += 1) {
|
||||||
|
signal(i, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < SIGS; i += 1) {
|
||||||
|
int desired = (random() % 7) + 1;
|
||||||
|
|
||||||
|
lastsig = 0;
|
||||||
|
printf("%d\n", desired);
|
||||||
|
fflush(stdout);
|
||||||
|
if (i == 0) {
|
||||||
|
sleep(5);
|
||||||
|
} else {
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
if (0 == lastsig) {
|
||||||
|
printf("Too slow.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (lastsig != desired) {
|
||||||
|
printf("Wrong one.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
char token[200];
|
||||||
|
size_t tokenlen;
|
||||||
|
|
||||||
|
tokenlen = read_token("killme",
|
||||||
|
key, sizeof(key),
|
||||||
|
token, sizeof(token) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "token.h"
|
||||||
|
|
||||||
|
/* This hopefully requires an LD_PRELOAD */
|
||||||
|
|
||||||
|
uint8_t const key[] = {0x94, 0xf2, 0x92, 0x45,
|
||||||
|
0x12, 0x44, 0x80, 0xe1,
|
||||||
|
0x95, 0x64, 0xcd, 0xe4,
|
||||||
|
0xff, 0x0a, 0x00, 0x10};
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
char token[200];
|
||||||
|
size_t tokenlen;
|
||||||
|
|
||||||
|
/* Do some bullshit. Override with:
|
||||||
|
*
|
||||||
|
* void strcmp(char *a, char *b)
|
||||||
|
* {
|
||||||
|
* return 0;
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
FILE *f = fopen("/dev/urandom", "r");
|
||||||
|
unsigned int seed;
|
||||||
|
char seed_str[50];
|
||||||
|
|
||||||
|
printf("Checking credentials...\n");
|
||||||
|
fread(&seed, sizeof(seed), 1, f);
|
||||||
|
sprintf(seed_str, "%d", seed);
|
||||||
|
if ((argc != 2) || strcmp(seed_str, argv[1])) {
|
||||||
|
printf("Ah ah ah! You didn't say the magic word!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tokenlen = read_token("ltraceme",
|
||||||
|
key, sizeof(key),
|
||||||
|
token, sizeof(token) - 1);
|
||||||
|
if (-1 == tokenlen) {
|
||||||
|
printf("Unable to read token.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
token[tokenlen++] = '\0';
|
||||||
|
|
||||||
|
/* You could override this with:
|
||||||
|
*
|
||||||
|
* void printf(char *fmt, size_t len, char *buf)
|
||||||
|
* {
|
||||||
|
* if (fmt[0] == 'T') write(1, buf, len);
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
printf("Token length %u at %p.\n", tokenlen, token);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,91 @@
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <sysexits.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include "token.h"
|
||||||
|
|
||||||
|
uint8_t const key[] = {0x30, 0x00, 0x55, 0x0f,
|
||||||
|
0xc2, 0xf6, 0x52, 0x2a,
|
||||||
|
0x31, 0xfd, 0x00, 0x92,
|
||||||
|
0x9d, 0x49, 0x24, 0xce};
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
/* Check argv[1].
|
||||||
|
*
|
||||||
|
* If no args, argv[1] will be NULL, which causes a segfault.
|
||||||
|
* This is what we want.
|
||||||
|
*
|
||||||
|
* To pass this, run ./straceme $$.
|
||||||
|
* But you have to do it from a shell script, because if you run
|
||||||
|
* strace ./straceme $$
|
||||||
|
* getppid() will return the PID of strace!
|
||||||
|
*/
|
||||||
|
if (getppid() != atoi(argv[1])) {
|
||||||
|
write(2, "argv[1] incorrect\n", 18);
|
||||||
|
return EX_USAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read an rc file.
|
||||||
|
*
|
||||||
|
* To pass this, set $HOME to someplace you have access.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
char fn[128];
|
||||||
|
char bs[1000];
|
||||||
|
int len;
|
||||||
|
|
||||||
|
len = snprintf(fn, sizeof(fn) - 1, "%s/.stracemerc", getenv("HOME"));
|
||||||
|
if (len < 0) {
|
||||||
|
len = 0;
|
||||||
|
}
|
||||||
|
fn[len] = '\0';
|
||||||
|
|
||||||
|
if (-1 == (fd = open(fn, O_RDONLY))) {
|
||||||
|
fd = open("/etc/stracemerc", O_RDONLY);
|
||||||
|
}
|
||||||
|
if (-1 == fd) {
|
||||||
|
return EX_NOINPUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We don't actually care about contents */
|
||||||
|
read(fd, bs, sizeof(bs));
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read in category name from fd 2 (stderr!)
|
||||||
|
*
|
||||||
|
* echo -n straceme > foo.txt
|
||||||
|
* ./straceme $$ 2< foo.txt
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
char cat[50];
|
||||||
|
int catlen;
|
||||||
|
char token[200];
|
||||||
|
size_t tokenlen;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
catlen = read(2, cat, sizeof(cat) - 1);
|
||||||
|
for (i = 0; i < catlen; i += 1) {
|
||||||
|
if (! isalnum(cat[i])) break;
|
||||||
|
}
|
||||||
|
cat[i] = '\0';
|
||||||
|
|
||||||
|
tokenlen = read_token(cat,
|
||||||
|
key, sizeof(key),
|
||||||
|
token, sizeof(token));
|
||||||
|
if (-1 == tokenlen) {
|
||||||
|
return EX_NOINPUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
write(1, token, tokenlen);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
../../common/token.c
|
|
@ -0,0 +1 @@
|
||||||
|
../../common/token.h
|
|
@ -0,0 +1,3 @@
|
||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
exec logger -t tokencli
|
|
@ -0,0 +1,11 @@
|
||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
exec 2>&1
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
for fn in /opt/*/*.tokenkey; do
|
||||||
|
cat=$(basename $fn .tokenkey)
|
||||||
|
echo "XXX: not implemented yet"
|
||||||
|
done
|
||||||
|
sleep 60
|
||||||
|
done
|
|
@ -0,0 +1,4 @@
|
||||||
|
tokencli: tokencli.o arc4.o
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm *.o tokencli
|
|
@ -0,0 +1 @@
|
||||||
|
../../common/arc4.c
|
|
@ -0,0 +1 @@
|
||||||
|
../../common/arc4.h
|
|
@ -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;
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
TOKENCLI_PKGDIR = build/tokencli
|
||||||
|
TOKENCLI_PACKAGE = tokencli.pkg
|
||||||
|
|
||||||
|
tokencli-install: tokencli-build
|
||||||
|
mkdir -p $(TOKENCLI_PKGDIR)/bin/
|
||||||
|
|
||||||
|
$(call COPYTREE, tokencli/service, $(TOKENCLI_PKGDIR)/service)
|
||||||
|
|
||||||
|
cp tokencli/src/tokencli $(TOKENCLI_PKGDIR)/bin/
|
||||||
|
|
||||||
|
tokencli-clean:
|
||||||
|
rm -rf $(TOKENCLI_PKGDIR) $(TOKENCLI_PACKAGE)
|
||||||
|
$(MAKE) -C tokencli/src clean
|
||||||
|
|
||||||
|
tokencli-build:
|
||||||
|
$(MAKE) -C tokencli/src build
|
||||||
|
|
||||||
|
PACKAGES += tokencli
|
Loading…
Reference in New Issue