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
|
||||
|
||||
packages: $(addsuffix -package, $(PACKAGES))
|
||||
packages: $(addsuffix .pkg, $(PACKAGES))
|
||||
|
||||
install: $(addsuffix -install, $(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_PACKAGE = mcp.pkg
|
||||
|
||||
mcp-package: $(MCP_PACKAGE)
|
||||
|
||||
$(MCP_PACKAGE): mcp-build
|
||||
mcp-install: mcp-build
|
||||
mkdir -p $(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/claim.cgi $(MCP_PKGDIR)/www/
|
||||
|
||||
mksquashfs $(MCP_PKGDIR) $(MCP_PACKAGE) -all-root -noappend
|
||||
|
||||
touch $@
|
||||
|
||||
mcp-test: mcp-build
|
||||
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
|
||||
|
||||
puzzles/%-package:
|
||||
puzzles/%-install:
|
||||
mkdir -p build/$*
|
||||
puzzles/mkpuzzles puzzles/$* build/$*
|
||||
mksquashfs build/$* $*.pkg -all-root -noappend
|
||||
touch $@
|
||||
|
||||
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