rev & pwn

This commit is contained in:
Simon Hünecke
2023-09-03 11:33:09 +02:00
parent 7e873d34b8
commit fb0e5711a0
21 changed files with 480 additions and 0 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,265 @@
#include <stdio.h>
#include <stdarg.h>
#include <inttypes.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#define MESSAGE_LEN 1024
#define USERPASS_LEN 128
#define MAX(x,y) (((x) >= (y)) ? (x) : (y))
typedef enum {
TAG_RES_MSG,
TAG_RES_ERROR,
TAG_INPUT_REQ,
TAG_INPUT_ANS,
TAG_COMMAND,
TAG_STR_PASSWORD,
TAG_STR_FROM,
TAG_STR_MESSAGE
} tag_t;
typedef struct {
tag_t tag;
unsigned long len;
} taglen_t;
void init() {
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
}
void win() {
system("cat flag.txt");
}
int read_taglen(FILE* fp, taglen_t* tlv) {
char tmpbuf[12];
fread(tmpbuf, 1, 12, fp);
tlv->tag = *((tag_t*)&tmpbuf[0]);
tlv->len = *((unsigned long*)&tmpbuf[4]);
}
void pack_taglen(tag_t tag, unsigned long len, char buf[12]) {
*(tag_t*)&buf[0] = tag;
*(unsigned long*)&buf[4] = len;
}
void print_tlv(tag_t tag, const char* fmt, ...) {
char msg[0x1000];
va_list args;
va_start(args, fmt);
vsprintf(msg, fmt, args);
va_end(args);
int len = strlen(msg);
char tmpbuf[12];
pack_taglen(tag, len, tmpbuf);
fwrite(tmpbuf, 1, 12, stdout);
fwrite(msg, 1, len, stdout);
}
FILE* get_user_save_fp(char username[USERPASS_LEN], const char* mode) {
char fname[USERPASS_LEN + 6];
snprintf(fname, USERPASS_LEN + 6, "/tmp/%s", username);
FILE* fp = fopen(fname, mode);
return fp;
}
void register_user() {
char tmpbuf[USERPASS_LEN];
char tmpbuf2[12];
taglen_t tl;
print_tlv(TAG_INPUT_REQ, "username");
read_taglen(stdin, &tl);
if(tl.tag != TAG_INPUT_ANS || tl.len >= USERPASS_LEN) {
print_tlv(TAG_RES_ERROR, "invalid username input");
return;
}
fread(tmpbuf, 1, tl.len, stdin);
tmpbuf[tl.len] = '\0';
FILE* fp = get_user_save_fp(tmpbuf, "r");
if(fp == 0) {
fp = get_user_save_fp(tmpbuf, "w+");
print_tlv(TAG_INPUT_REQ, "password");
read_taglen(stdin, &tl);
if(tl.tag != TAG_INPUT_ANS || tl.len >= USERPASS_LEN) {
print_tlv(TAG_RES_ERROR, "invalid password input");
return;
}
fread(tmpbuf, 1, tl.len, stdin);
pack_taglen(TAG_STR_PASSWORD, tl.len, tmpbuf2);
fwrite(tmpbuf2, 1, 12, fp);
fwrite(tmpbuf, 1, tl.len, fp);
fflush(fp);
print_tlv(TAG_RES_MSG, "user registered");
} else {
print_tlv(TAG_RES_ERROR, "user already exists");
}
}
FILE* handle_auth(char username[USERPASS_LEN]) {
char tmpbuf[USERPASS_LEN];
char tmpbuf2[USERPASS_LEN];
taglen_t tl;
FILE* fp = get_user_save_fp(username, "r");
if(fp == 0) {
print_tlv(TAG_RES_ERROR, "user does not exist");
return 0;
} else {
print_tlv(TAG_INPUT_REQ, "password");
read_taglen(stdin, &tl);
if(tl.tag != TAG_INPUT_ANS || tl.len >= USERPASS_LEN) {
print_tlv(TAG_RES_ERROR, "invalid password input");
return 0;
}
unsigned long t1 = tl.len;
fread(tmpbuf, 1, tl.len, stdin);
read_taglen(fp, &tl);
if(tl.tag != TAG_STR_PASSWORD || tl.len >= USERPASS_LEN) {
print_tlv(TAG_RES_ERROR, "corrupted user file, got invalid taglen %d %lld", tl.tag, tl.len);
return 0;
}
fread(tmpbuf2, 1, tl.len, fp);
if(memcmp(tmpbuf, tmpbuf2, MAX(t1, tl.len)) != 0) {
print_tlv(TAG_RES_ERROR, "incorrect password");
return 0;
}
return fp;
}
}
void view_mail() {
char tmpbuf[USERPASS_LEN + MESSAGE_LEN + 16];
char tmpbuf2[USERPASS_LEN];
taglen_t tl;
print_tlv(TAG_INPUT_REQ, "username");
read_taglen(stdin, &tl);
if(tl.tag != TAG_INPUT_ANS || tl.len >= USERPASS_LEN) {
print_tlv(TAG_RES_ERROR, "invalid username input");
return;
}
fread(tmpbuf, 1, tl.len, stdin);
tmpbuf[tl.len] = '\0';
FILE* fp = handle_auth(tmpbuf);
if(fp == 0) return;
read_taglen(fp, &tl);
if(feof(fp)) {
print_tlv(TAG_RES_MSG, "no mail");
return;
}
unsigned long t1 = tl.len;
if(tl.tag != TAG_STR_FROM || t1 >= USERPASS_LEN) {
print_tlv(TAG_RES_ERROR, "mail invalid from");
return;
}
memcpy(tmpbuf, "from: ", 6);
fread(tmpbuf + 6, 1, t1, fp);
tmpbuf[6 + t1] = '\n';
read_taglen(fp, &tl);
unsigned long t2 = tl.len;
if(tl.tag != TAG_STR_MESSAGE || (t1 + t2) >= USERPASS_LEN + MESSAGE_LEN) {
print_tlv(TAG_RES_ERROR, "mail invalid message");
return;
}
memcpy(tmpbuf + 6 + t1 + 1, "message: ", 9);
fread(tmpbuf + 6 + t1 + 1 + 9, 1, t2, fp);
pack_taglen(TAG_RES_MSG, t1 + t2 + 16, tmpbuf2);
fwrite(tmpbuf2, 1, 12, stdout);
fwrite(tmpbuf, 1, t1 + t2 + 16, stdout);
fflush(stdout);
}
void send_mail() {
char tmpbuf[MESSAGE_LEN];
char tmpbuf2[USERPASS_LEN];
taglen_t tl;
print_tlv(TAG_INPUT_REQ, "username");
read_taglen(stdin, &tl);
unsigned long t1 = tl.len;
if(tl.tag != TAG_INPUT_ANS || tl.len >= USERPASS_LEN) {
print_tlv(TAG_RES_ERROR, "invalid username input");
return;
}
fread(tmpbuf, 1, tl.len, stdin);
tmpbuf[tl.len] = '\0';
if(handle_auth(tmpbuf) == 0) return;
print_tlv(TAG_INPUT_REQ, "recipient");
read_taglen(stdin, &tl);
if(tl.tag != TAG_INPUT_ANS || tl.len >= USERPASS_LEN) {
print_tlv(TAG_RES_ERROR, "invalid recipient input");
return;
}
fread(tmpbuf2, 1, tl.len, stdin);
tmpbuf2[tl.len] = '\0';
FILE* fp = get_user_save_fp(tmpbuf2, "a+");
pack_taglen(TAG_STR_FROM, tl.len, tmpbuf+USERPASS_LEN);
fwrite(tmpbuf+USERPASS_LEN, 1, 12, fp);
fwrite(tmpbuf, 1, t1, fp);
print_tlv(TAG_INPUT_REQ, "message");
read_taglen(stdin, &tl);
if(tl.tag != TAG_INPUT_ANS || tl.len >= MESSAGE_LEN) {
print_tlv(TAG_RES_ERROR, "invalid message input");
return;
}
fread(tmpbuf, 1, tl.len, stdin);
pack_taglen(TAG_STR_MESSAGE, tl.len, tmpbuf2);
fwrite(tmpbuf2, 1, 12, fp);
fwrite(tmpbuf, 1, tl.len, fp);
fflush(fp);
print_tlv(TAG_RES_MSG, "message sent");
}
int main() {
init();
puts("binary mail v0.1.0");
taglen_t cmd_tl;
char tmpbuf[128];
while(1) {
read_taglen(stdin, &cmd_tl);
if(cmd_tl.tag != TAG_COMMAND || cmd_tl.len >= 128) {
print_tlv(TAG_RES_ERROR, "invalid command");
continue;
}
fread(tmpbuf, 1, cmd_tl.len, stdin);
if(strncmp(tmpbuf, "register", 8) == 0) {
register_user();
}
if(strncmp(tmpbuf, "view_mail", 9) == 0) {
view_mail();
}
if(strncmp(tmpbuf, "send_mail", 9) == 0) {
send_mail();
}
}
}

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,116 @@
// g++ roppenheimer.cpp -o roppenheimer -fno-stack-protector -no-pie
#include <cstdint>
#include <iostream>
#include <unordered_map>
#define MAX_ATOMS 32
#define MAX_COLLIDE 20
#define NAME_LEN 128
char username[NAME_LEN + 1];
std::unordered_map<unsigned int, uint64_t> atoms;
void useful() {
__asm__(
"pop %rax;"
"pop %rsp;"
"pop %rdi;"
);
}
void panic(const std::string& message) {
std::cerr << std::endl << "error: " << message << std::endl;
exit(1);
}
void add_atom() {
if (atoms.size() >= MAX_ATOMS) {
panic("atom capacity reached");
}
unsigned int atom;
std::cout << "atom> ";
std::cin >> atom;
if (atoms.find(atom) != atoms.end()) {
panic("atom already exists");
}
uint64_t data;
std::cout << "data> ";
std::cin >> data;
atoms[atom] = data;
}
void fire_neutron() {
unsigned int atom;
std::cout << "atom> ";
std::cin >> atom;
if (atoms.find(atom) == atoms.end()) {
panic("atom does not exist");
}
size_t bucket = atoms.bucket(atom);
size_t bucket_size = atoms.bucket_size(bucket);
std::pair<unsigned int, uint64_t> elems[MAX_COLLIDE - 1];
copy(atoms.begin(bucket), atoms.end(bucket), elems);
std::cout << "[atoms hit]" << std::endl;
for (size_t i = 0; i < bucket_size; i++) {
std::cout << elems->first << std::endl;
}
}
void quit() {
std::cout << std::endl << "goodbye!" << std::endl;
exit(0);
}
int get_choice() {
std::cout << std::endl
<< "[1] add atom" << std::endl
<< "[2] fire neutron" << std::endl
<< "[3] quit" << std::endl;
int choice;
std::cout << "choice> ";
std::cin >> choice;
if (choice < 1 || choice > 3) {
panic("invalid choice");
}
return choice;
}
int main() {
setvbuf(stdout, 0, 2, 0);
setvbuf(stdin, 0, 2, 0);
atoms.clear();
puts("atomic research lab v0.0.1");
std::cout << std::endl << "name> ";
fgets(username, NAME_LEN, stdin);
while (true) {
int choice = get_choice();
if (choice == 1) {
add_atom();
}
if (choice == 2) {
fire_neutron();
quit();
}
if (choice == 3) {
quit();
}
}
return 0;
}

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,78 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#define MAX_STR_LEN 128
typedef struct req {
unsigned char len;
char shift;
char buf[MAX_STR_LEN];
} shm_req_t;
void shift_str(char* str, int len, char shift, char out[MAX_STR_LEN]) {
for(int i = 0; i < len; i++) {
out[i] = str[i] + shift;
}
out[len] = '\0';
}
void win() {
char flag[0x100];
int fd = open("/home/ctf/chal/flag.txt", O_RDONLY);
read(fd, flag, 0x100);
printf("%s\n", flag);
}
int main(int argc, char** argv) {
char out[MAX_STR_LEN];
if(argc != 2) {
fprintf(stderr, "Usage: %s <name>\n", argv[0]);
exit(1);
}
char* name = argv[1];
mode_t old_umask = umask(0);
int fd = shm_open(name, O_CREAT | O_RDWR | O_TRUNC | O_EXCL, S_IRWXU | S_IRWXG | S_IRWXO);
umask(old_umask);
if(fd == -1) {
fprintf(stderr, "shm_open error");
exit(1);
}
if(ftruncate(fd, sizeof(shm_req_t)) == -1) {
fprintf(stderr, "ftruncate error");
exit(1);
}
shm_req_t* shm_req = mmap(NULL, sizeof(shm_req_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if(shm_req == MAP_FAILED) {
fprintf(stderr, "mmap error");
exit(1);
}
shm_req->len = -1;
shm_req->shift = 0;
usleep(10000);
close(fd);
shm_unlink(name);
while(1) {
if(shm_req->len < 0 || shm_req->len > MAX_STR_LEN) {
continue;
}
if(shm_req->len == 0) {
return 0;
}
shift_str(shm_req->buf, shm_req->len, shm_req->shift, out);
printf("%s\n", out);
}
}

Binary file not shown.

Binary file not shown.