From 689693df2b530a064e467eab1f21ab34bbd14166 Mon Sep 17 00:00:00 2001 From: myitinos Date: Sat, 21 Sep 2019 08:12:44 +0800 Subject: [PATCH] adapted for slashroot 2019 --- .drone.yml | 10 --- .start.sh | 2 + Dockerfile | 8 +-- Makefile | 2 +- build-image.sh | 14 ----- docker-compose.yml | 10 +++ flag.txt | 2 +- src/system/betatest.cpp | 4 +- src/system/memory.cpp | 131 +++++++++++++++++++++------------------- version002 | Bin 46088 -> 34880 bytes 10 files changed, 88 insertions(+), 95 deletions(-) delete mode 100644 .drone.yml create mode 100644 .start.sh delete mode 100644 build-image.sh create mode 100644 docker-compose.yml diff --git a/.drone.yml b/.drone.yml deleted file mode 100644 index b9bb7c3..0000000 --- a/.drone.yml +++ /dev/null @@ -1,10 +0,0 @@ -pipeline: - build-docker: - image: docker:18.06.1-ce - volumes: - - /var/run/docker.sock:/var/run/docker.sock - commands: - - chmod +x ./build-image.sh - - ./build-image.sh - when: -event: [push] \ No newline at end of file diff --git a/.start.sh b/.start.sh new file mode 100644 index 0000000..caea46b --- /dev/null +++ b/.start.sh @@ -0,0 +1,2 @@ +#!/bin/bash +(socat TCP-LISTEN:20202,reuseaddr,fork EXEC:/chall/version002,su=nobody) diff --git a/Dockerfile b/Dockerfile index 517d4e8..3256e41 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ -# Use ubuntu 16.04 -FROM ubuntu:16.04 +# Use ubuntu 19.04 +FROM ubuntu:latest EXPOSE 20202 RUN apt-get update @@ -15,6 +15,7 @@ WORKDIR /chall # Secure ENV COPY flag.txt . COPY version002 . +COPY .start.sh /var/tmp/ RUN echo 'alias kill="echo no kill please!"' >> ~/.bashrc RUN chmod 700 /tmp /usr/bin/* /bin/* /dev/shm @@ -22,9 +23,8 @@ RUN chmod 700 /tmp /usr/bin/* /bin/* /dev/shm RUN chown root:ksl /chall/version002 RUN chmod 775 /chall/version002 +RUN chmod 775 /var/tmp/.start.sh # Run Service -RUN echo '#!/bin/bash'"\n(socat TCP-LISTEN:20202,reuseaddr,fork EXEC:"/chall/version002,su=nobody")" > /var/tmp/.start.sh && chmod +x /var/tmp/.start.sh - CMD ["/var/tmp/.start.sh"] diff --git a/Makefile b/Makefile index 77485f8..cb11d47 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ COMPILER=g++ #FLAGS=-g -I. -pedantic -Wall -Wextra -Wcast-align -Wcast-qual -Wctor-dtor-privacy -Wdisabled-optimization -Wformat=2 -Winit-self -Wlogical-op -Wmissing-declarations -Wmissing-include-dirs -Wnoexcept -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wshadow -Wsign-conversion -Wsign-promo -Wstrict-null-sentinel -Wstrict-overflow=5 -Wswitch-default -Wundef -Werror -Wno-unused #FLAGS=-g -I. -FLAGS=-I. +FLAGS=-s -I. O_DIR=obj CLASS_DIR=src/class diff --git a/build-image.sh b/build-image.sh deleted file mode 100644 index 26621cf..0000000 --- a/build-image.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh -set -e -set -o xtrace - -IMAGE_NAME=hack-the-game-v002 - -# clean old images -OLD_IMAGES=$(docker images $IMAGE_NAME -q --no-trunc) -if [ -n "${OLD_IMAGES}" ]; then - docker rmi -f ${OLD_IMAGES}; -fi - -#Build Images -docker build . -t $IMAGE_NAME diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..803aebf --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,10 @@ +version: "2" + +services: + main: + build: . + container_name: "htg2" + network_mode: "bridge" + restart: on-failure + ports: + - "30313:20202" diff --git a/flag.txt b/flag.txt index 21d4c30..b088119 100644 --- a/flag.txt +++ b/flag.txt @@ -1 +1 @@ -GKSK{H0w_d1d_I_n0t_real1ze_such_4_s7up1d_m1sT4k3} +SlashRootCTF{Th47_15_d3f1Nit3ly_a_5tup1D_m1sT4kE} diff --git a/src/system/betatest.cpp b/src/system/betatest.cpp index b8f8ef5..58ee76f 100644 --- a/src/system/betatest.cpp +++ b/src/system/betatest.cpp @@ -1,9 +1,9 @@ #include "src/system/betatest.hpp" -std::string BetaTest::betaFlag = "4re_Y0u_53ri0usly_checking_f0r_b3t4_t3sT?"; +std::string BetaTest::betaFlag = "7h1s_i5_n0t_a_b3t4_tE5t_k3y"; bool BetaTest::check(std::string input) { - return input.compare("GKSK{" + betaFlag + "}") == 0; + return input.compare("SlashRootCTF{" + betaFlag + "}") == 0; } \ No newline at end of file diff --git a/src/system/memory.cpp b/src/system/memory.cpp index fe8c340..63a2ae7 100644 --- a/src/system/memory.cpp +++ b/src/system/memory.cpp @@ -4,32 +4,33 @@ #include #include -static const std::string base64_chars = - "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "0123456789+/"; +static const std::string base64_chars = + "s1XWgtaLvfyEeYUi42Mo36NR9DKrVjbTpPuwHc5lA8dC0OSxzknm7qGJBIZFQh+/"; - -static inline bool is_base64(unsigned char c) { +static inline bool is_base64(unsigned char c) +{ return (isalnum(c) || (c == '+') || (c == '/')); } -std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) { +std::string base64_encode(unsigned char const *bytes_to_encode, unsigned int in_len) +{ std::string ret; int i = 0; int j = 0; unsigned char char_array_3[3]; unsigned char char_array_4[4]; - while (in_len--) { + while (in_len--) + { char_array_3[i++] = *(bytes_to_encode++); - if (i == 3) { + if (i == 3) + { char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); char_array_4[3] = char_array_3[2] & 0x3f; - for(i = 0; (i <4) ; i++) + for (i = 0; (i < 4); i++) ret += base64_chars[char_array_4[i]]; i = 0; } @@ -37,26 +38,25 @@ std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_ if (i) { - for(j = i; j < 3; j++) + for (j = i; j < 3; j++) char_array_3[j] = '\0'; - char_array_4[0] = ( char_array_3[0] & 0xfc) >> 2; + char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); for (j = 0; (j < i + 1); j++) ret += base64_chars[char_array_4[j]]; - while((i++ < 3)) + while ((i++ < 3)) ret += '='; - } return ret; - } -std::string base64_decode(std::string const& encoded_string) { +std::string base64_decode(std::string const &encoded_string) +{ int in_len = encoded_string.size(); int i = 0; int j = 0; @@ -64,15 +64,18 @@ std::string base64_decode(std::string const& encoded_string) { unsigned char char_array_4[4], char_array_3[3]; std::string ret; - while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) { - char_array_4[i++] = encoded_string[in_]; in_++; - if (i ==4) { - for (i = 0; i <4; i++) + while (in_len-- && (encoded_string[in_] != '=') && is_base64(encoded_string[in_])) + { + char_array_4[i++] = encoded_string[in_]; + in_++; + if (i == 4) + { + for (i = 0; i < 4; i++) char_array_4[i] = base64_chars.find(char_array_4[i]); - char_array_3[0] = ( char_array_4[0] << 2 ) + ((char_array_4[1] & 0x30) >> 4); + char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); - char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; + char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; for (i = 0; (i < 3); i++) ret += char_array_3[i]; @@ -80,14 +83,16 @@ std::string base64_decode(std::string const& encoded_string) { } } - if (i) { + if (i) + { for (j = 0; j < i; j++) char_array_4[j] = base64_chars.find(char_array_4[j]); char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); - for (j = 0; (j < i - 1); j++) ret += char_array_3[j]; + for (j = 0; (j < i - 1); j++) + ret += char_array_3[j]; } return ret; @@ -95,47 +100,47 @@ std::string base64_decode(std::string const& encoded_string) { Player *Memory::loadFromCode(std::string code) { - code = base64_decode(code); - char playerName[16] = {0}; - int playerHP = 0; - int playerAtk = 0; - int playerDef = 0; - int playerLevel = 0; - int playerExp = 0; - - int result = sscanf(code.c_str(), - "PlayerLevel=%d;PlayerExp=%d;PlayerHP=%d;PlayerAtk=%d;PlayerDef=%d;PlayerName=%15s", - &playerLevel, - &playerExp, - &playerHP, - &playerAtk, - &playerDef, - playerName); - - std::string playerTrueName = playerName; - - if (result == 6) - { - return new Player(playerTrueName, playerHP, playerAtk, playerDef, playerLevel, playerExp); - } - else - { - return nullptr; - } + code = base64_decode(code); + char playerName[16] = {0}; + int playerHP = 0; + int playerAtk = 0; + int playerDef = 0; + int playerLevel = 0; + int playerExp = 0; + + int result = sscanf(code.c_str(), + "PlayerLevel=%d;PlayerExp=%d;PlayerHP=%d;PlayerAtk=%d;PlayerDef=%d;PlayerName=%15s", + &playerLevel, + &playerExp, + &playerHP, + &playerAtk, + &playerDef, + playerName); + + std::string playerTrueName = playerName; + + if (result == 6) + { + return new Player(playerTrueName, playerHP, playerAtk, playerDef, playerLevel, playerExp); + } + else + { + return nullptr; + } } std::string Memory::saveToCode(Player *player) { - char code[256]; - snprintf(code, sizeof(code), - "PlayerLevel=%d;PlayerExp=%d;PlayerHP=%d;PlayerAtk=%d;PlayerDef=%d;PlayerName=%s", - player->getLevel(), - player->getExp(), - player->getMaxHP(), - player->getAtk(), - player->getDef(), - player->getName().c_str()); - - return base64_encode(reinterpret_cast(code), - strlen(code)); + char code[256]; + snprintf(code, sizeof(code), + "PlayerLevel=%d;PlayerExp=%d;PlayerHP=%d;PlayerAtk=%d;PlayerDef=%d;PlayerName=%s", + player->getLevel(), + player->getExp(), + player->getMaxHP(), + player->getAtk(), + player->getDef(), + player->getName().c_str()); + + return base64_encode(reinterpret_cast(code), + strlen(code)); } \ No newline at end of file diff --git a/version002 b/version002 index 7105e1b1dc6226a8c253a1f61a8113c1a08b437f..58b71933ee82b149c16b385426b3bdf9fa5c43da 100755 GIT binary patch delta 3022 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 delta 10891 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