From ab5e4c64b8ff81922ffce666e9c6354f84704170 Mon Sep 17 00:00:00 2001 From: michaelaurelio Date: Sun, 19 Oct 2025 04:48:58 +0700 Subject: [PATCH 1/2] Adding remote ip in solver --- Binary Exploitation/BeeChat/src/solve.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Binary Exploitation/BeeChat/src/solve.py b/Binary Exploitation/BeeChat/src/solve.py index a0d8f33..2a12659 100755 --- a/Binary Exploitation/BeeChat/src/solve.py +++ b/Binary Exploitation/BeeChat/src/solve.py @@ -25,7 +25,7 @@ def start(argv=[], *a, **kw): if args.GDB: return gdb.debug([ld.path, elf.path] + argv, gdbscript=gdb_script, *a, **kw) elif args.REMOTE: - return remote("localhost", 31346) + return remote("31.97.187.222", 31346) else: return process([ld.path, elf.path] + argv, *a, **kw) From 8a5d93be118335cf80642710df3f6cfeca2a1730 Mon Sep 17 00:00:00 2001 From: michaelaurelio Date: Sun, 19 Oct 2025 05:04:29 +0700 Subject: [PATCH 2/2] Adding rev / Flact Check --- Reverse Engineering/flact-check/challenge.yml | 29 ++ .../flact-check/dist/dependencies.txt | 15 + .../flact-check/dist/flact-check | Bin 0 -> 40392 bytes .../flact-check/src/CMakeLists.txt | 13 + .../flact-check/src/build/flact-check | Bin 0 -> 40392 bytes Reverse Engineering/flact-check/src/solve.py | 56 +++ .../flact-check/src/src/main.cpp | 343 ++++++++++++++++++ 7 files changed, 456 insertions(+) create mode 100644 Reverse Engineering/flact-check/challenge.yml create mode 100644 Reverse Engineering/flact-check/dist/dependencies.txt create mode 100755 Reverse Engineering/flact-check/dist/flact-check create mode 100644 Reverse Engineering/flact-check/src/CMakeLists.txt create mode 100755 Reverse Engineering/flact-check/src/build/flact-check create mode 100755 Reverse Engineering/flact-check/src/solve.py create mode 100644 Reverse Engineering/flact-check/src/src/main.cpp diff --git a/Reverse Engineering/flact-check/challenge.yml b/Reverse Engineering/flact-check/challenge.yml new file mode 100644 index 0000000..9b595a1 --- /dev/null +++ b/Reverse Engineering/flact-check/challenge.yml @@ -0,0 +1,29 @@ +name: "Flact Check" +category: Reverse Engineering +description: |- + Yep this is a simple flag checker, no doubt + + Author: Lyo + +##### DON'T CHANGE +value: 500 +type: dynamic +extra: + initial: 500 + decay: 30 + minimum: 100 +##### DON'T CHANGE + +flags: + - BEECTF{vM_0p5_kEEp_enc0d3d_byt35_f10w1ng_un71l_V1r7u4l_cmp_un10ck5_h1dd3n_5ignal_gu4rd14n5_57andby4} + +tags: + - hard + +files: + - dist/flact-check + - dist/dependencies.txt + +state: hidden + +version: "0.1" diff --git a/Reverse Engineering/flact-check/dist/dependencies.txt b/Reverse Engineering/flact-check/dist/dependencies.txt new file mode 100644 index 0000000..414386d --- /dev/null +++ b/Reverse Engineering/flact-check/dist/dependencies.txt @@ -0,0 +1,15 @@ +Flact-Check Challenge Dependencies +================================= + +Runtime libraries (shared): + - FLTK 1.3 stack: libfltk, libfltk_forms, libfltk_images, libfltk_gl + - X11 stack: libX11, libXext, libXt, libxcb (plus common X extensions) + - Fonts: libfontconfig, libfreetype, libexpat + - Image/Compression: libpng, libjpeg, libz + - Runtime: libstdc++, libgcc_s + +Tested on: + - Ubuntu 22.04 (x86_64) with default desktop packages + +Notes: + - Requires an X11-capable environment (desktop session or X server) diff --git a/Reverse Engineering/flact-check/dist/flact-check b/Reverse Engineering/flact-check/dist/flact-check new file mode 100755 index 0000000000000000000000000000000000000000..41e980bfef4e06d88241201f0cf30c5ae5a1ca62 GIT binary patch literal 40392 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 jn*47^JEyN0KX~H2%vb8tZzq$bFW +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace { + +enum : unsigned char { + OP_MOV_IMM = 0x10, + OP_ADD_IMM = 0x11, + OP_SUB_IMM = 0x12, + OP_XOR_IMM = 0x13, + OP_CMP_INPUT = 0x20, +}; + +class FlagVm { + public: + static constexpr std::size_t kFlagLength = 100; + + FlagVm() { Reset(); } + + void Reset() { + pc_offset_ = 0; + progress_ = 0; + } + + std::size_t progress() const { return progress_; } + + bool Execute(char input) { + if (progress_ >= kFlagLength) { + return false; + } + + if (pc_offset_ >= kProgram.size()) { + return false; + } + + const std::size_t segment_start = pc_offset_; + const unsigned char segment_len = kProgram[pc_offset_++]; + if (segment_len == 0 || + pc_offset_ + segment_len > kProgram.size()) { + return false; + } + + std::size_t cursor = pc_offset_; + const std::size_t segment_end = pc_offset_ + segment_len; + unsigned char acc = 0; + bool cmp_result = false; + + while (cursor < segment_end) { + const unsigned char opcode = kProgram[cursor++]; + switch (opcode) { + case OP_MOV_IMM: + if (cursor >= segment_end) return false; + acc = kProgram[cursor++]; + break; + case OP_ADD_IMM: + if (cursor >= segment_end) return false; + acc = static_cast( + (acc + kProgram[cursor++]) & 0xFFu); + break; + case OP_SUB_IMM: + if (cursor >= segment_end) return false; + acc = static_cast( + (acc - kProgram[cursor++]) & 0xFFu); + break; + case OP_XOR_IMM: + if (cursor >= segment_end) return false; + acc = static_cast( + acc ^ kProgram[cursor++]); + break; + case OP_CMP_INPUT: + cmp_result = (acc == static_cast(input)); + break; + default: + return false; + } + } + + if (cmp_result) { + pc_offset_ = segment_end; + ++progress_; + return true; + } + pc_offset_ = segment_start; + return false; + } + + static constexpr std::array kProgram = { + 0x07, 0x10, 0x3f, 0x12, 0x8f, 0x13, 0xf2, 0x20, 0x07, 0x10, 0xac, 0x11, 0xbd, 0x13, 0x2c, 0x20, + 0x07, 0x10, 0xd8, 0x12, 0x44, 0x13, 0xd1, 0x20, 0x07, 0x10, 0x00, 0x12, 0xc8, 0x13, 0x7b, 0x20, + 0x07, 0x10, 0x97, 0x12, 0x6e, 0x13, 0x7d, 0x20, 0x07, 0x10, 0xc5, 0x12, 0x44, 0x13, 0xc7, 0x20, + 0x07, 0x10, 0x83, 0x11, 0x7e, 0x13, 0x7a, 0x20, 0x07, 0x10, 0x29, 0x12, 0xfa, 0x13, 0x59, 0x20, + 0x07, 0x10, 0x34, 0x12, 0xd1, 0x13, 0x2e, 0x20, 0x07, 0x10, 0xc9, 0x12, 0xcf, 0x13, 0xa5, 0x20, + 0x07, 0x10, 0x58, 0x12, 0x3a, 0x13, 0x2e, 0x20, 0x07, 0x10, 0xfc, 0x12, 0x30, 0x13, 0xbc, 0x20, + 0x07, 0x10, 0x6f, 0x12, 0x6f, 0x13, 0x35, 0x20, 0x07, 0x10, 0x75, 0x11, 0xe6, 0x13, 0x04, 0x20, + 0x07, 0x10, 0x52, 0x12, 0x4a, 0x13, 0x63, 0x20, 0x07, 0x10, 0x0b, 0x12, 0x89, 0x13, 0xc7, 0x20, + 0x07, 0x10, 0x21, 0x11, 0x65, 0x13, 0xc3, 0x20, 0x07, 0x10, 0x33, 0x12, 0x92, 0x13, 0xd1, 0x20, + 0x07, 0x10, 0x0f, 0x12, 0x65, 0x13, 0xf5, 0x20, 0x07, 0x10, 0x10, 0x12, 0x1d, 0x13, 0x96, 0x20, + 0x07, 0x10, 0xe3, 0x12, 0x71, 0x13, 0x1c, 0x20, 0x07, 0x10, 0xe5, 0x12, 0xc3, 0x13, 0x41, 0x20, + 0x07, 0x10, 0x03, 0x12, 0x37, 0x13, 0xfc, 0x20, 0x07, 0x10, 0x3f, 0x11, 0x87, 0x13, 0xa2, 0x20, + 0x07, 0x10, 0x38, 0x11, 0xa5, 0x13, 0xee, 0x20, 0x07, 0x10, 0xb0, 0x12, 0xa3, 0x13, 0x69, 0x20, + 0x07, 0x10, 0x4c, 0x11, 0xf2, 0x13, 0x61, 0x20, 0x07, 0x10, 0x5b, 0x12, 0xa6, 0x13, 0xd7, 0x20, + 0x07, 0x10, 0x28, 0x11, 0x6d, 0x13, 0xec, 0x20, 0x07, 0x10, 0x83, 0x11, 0xf9, 0x13, 0x08, 0x20, + 0x07, 0x10, 0xdc, 0x11, 0xf9, 0x13, 0xe6, 0x20, 0x07, 0x10, 0x1f, 0x11, 0x5d, 0x13, 0x49, 0x20, + 0x07, 0x10, 0xd4, 0x11, 0xe3, 0x13, 0xe8, 0x20, 0x07, 0x10, 0xff, 0x11, 0xf8, 0x13, 0x91, 0x20, + 0x07, 0x10, 0x82, 0x11, 0x5c, 0x13, 0xef, 0x20, 0x07, 0x10, 0x29, 0x11, 0x38, 0x13, 0x51, 0x20, + 0x07, 0x10, 0x52, 0x11, 0x32, 0x13, 0xf3, 0x20, 0x07, 0x10, 0x98, 0x11, 0xc9, 0x13, 0x50, 0x20, + 0x07, 0x10, 0xb2, 0x11, 0x4a, 0x13, 0x92, 0x20, 0x07, 0x10, 0xe3, 0x11, 0xf1, 0x13, 0xb3, 0x20, + 0x07, 0x10, 0xa3, 0x12, 0x0b, 0x13, 0xc7, 0x20, 0x07, 0x10, 0x67, 0x12, 0x86, 0x13, 0x94, 0x20, + 0x07, 0x10, 0x3f, 0x11, 0xcf, 0x13, 0x60, 0x20, 0x07, 0x10, 0x86, 0x11, 0xe7, 0x13, 0x5a, 0x20, + 0x07, 0x10, 0x98, 0x11, 0x2c, 0x13, 0xf5, 0x20, 0x07, 0x10, 0xe0, 0x11, 0x66, 0x13, 0x2a, 0x20, + 0x07, 0x10, 0xa5, 0x12, 0xe4, 0x13, 0x9e, 0x20, 0x07, 0x10, 0xce, 0x12, 0xbd, 0x13, 0x47, 0x20, + 0x07, 0x10, 0x54, 0x11, 0x53, 0x13, 0x96, 0x20, 0x07, 0x10, 0x26, 0x11, 0x45, 0x13, 0x19, 0x20, + 0x07, 0x10, 0x4d, 0x12, 0xf4, 0x13, 0x6e, 0x20, 0x07, 0x10, 0x6a, 0x12, 0x9f, 0x13, 0xbe, 0x20, + 0x07, 0x10, 0xc5, 0x12, 0x5c, 0x13, 0x5d, 0x20, 0x07, 0x10, 0x6e, 0x12, 0x8a, 0x13, 0x88, 0x20, + 0x07, 0x10, 0x83, 0x11, 0x7c, 0x13, 0xa0, 0x20, 0x07, 0x10, 0xfc, 0x11, 0xe3, 0x13, 0xbc, 0x20, + 0x07, 0x10, 0x98, 0x12, 0x5c, 0x13, 0x51, 0x20, 0x07, 0x10, 0x04, 0x11, 0x3f, 0x13, 0x33, 0x20, + 0x07, 0x10, 0x8c, 0x11, 0xec, 0x13, 0x27, 0x20, 0x07, 0x10, 0xf5, 0x12, 0x02, 0x13, 0x86, 0x20, + 0x07, 0x10, 0xee, 0x11, 0x8c, 0x13, 0x14, 0x20, 0x07, 0x10, 0xcb, 0x11, 0x21, 0x13, 0xdd, 0x20, + 0x07, 0x10, 0x72, 0x11, 0x74, 0x13, 0xd6, 0x20, 0x07, 0x10, 0x3e, 0x11, 0x12, 0x13, 0x33, 0x20, + 0x07, 0x10, 0x6f, 0x12, 0xce, 0x13, 0xca, 0x20, 0x07, 0x10, 0xee, 0x12, 0x61, 0x13, 0xb8, 0x20, + 0x07, 0x10, 0x70, 0x11, 0xb0, 0x13, 0x7f, 0x20, 0x07, 0x10, 0x17, 0x12, 0x95, 0x13, 0xea, 0x20, + 0x07, 0x10, 0x4c, 0x11, 0xc8, 0x13, 0x25, 0x20, 0x07, 0x10, 0x5e, 0x12, 0x10, 0x13, 0x2a, 0x20, + 0x07, 0x10, 0xd0, 0x12, 0x4d, 0x13, 0xe7, 0x20, 0x07, 0x10, 0x42, 0x11, 0x6f, 0x13, 0x82, 0x20, + 0x07, 0x10, 0x27, 0x11, 0x77, 0x13, 0xf0, 0x20, 0x07, 0x10, 0x84, 0x11, 0xcb, 0x13, 0x10, 0x20, + 0x07, 0x10, 0xb4, 0x11, 0xa9, 0x13, 0x68, 0x20, 0x07, 0x10, 0x9f, 0x11, 0x0c, 0x13, 0xc2, 0x20, + 0x07, 0x10, 0xa3, 0x12, 0x74, 0x13, 0x48, 0x20, 0x07, 0x10, 0x40, 0x12, 0x61, 0x13, 0xb1, 0x20, + 0x07, 0x10, 0x34, 0x11, 0xff, 0x13, 0x52, 0x20, 0x07, 0x10, 0xff, 0x11, 0x08, 0x13, 0x6b, 0x20, + 0x07, 0x10, 0x68, 0x11, 0x4d, 0x13, 0xea, 0x20, 0x07, 0x10, 0xa9, 0x11, 0xa6, 0x13, 0x28, 0x20, + 0x07, 0x10, 0x14, 0x11, 0xd3, 0x13, 0x92, 0x20, 0x07, 0x10, 0x7e, 0x12, 0x1a, 0x13, 0x50, 0x20, + 0x07, 0x10, 0x1e, 0x11, 0x18, 0x13, 0x44, 0x20, 0x07, 0x10, 0xa9, 0x11, 0x81, 0x13, 0x4e, 0x20, + 0x07, 0x10, 0x9a, 0x12, 0xc2, 0x13, 0xe9, 0x20, 0x07, 0x10, 0xaf, 0x12, 0xed, 0x13, 0xf6, 0x20, + 0x07, 0x10, 0xe1, 0x11, 0x0a, 0x13, 0x85, 0x20, 0x07, 0x10, 0x84, 0x11, 0x81, 0x13, 0x30, 0x20, + 0x07, 0x10, 0x65, 0x12, 0xd1, 0x13, 0xcb, 0x20, 0x07, 0x10, 0x70, 0x11, 0x8f, 0x13, 0xca, 0x20, + 0x07, 0x10, 0x8b, 0x11, 0x0b, 0x13, 0xa1, 0x20, 0x07, 0x10, 0xa5, 0x11, 0x79, 0x13, 0x7f, 0x20, + 0x07, 0x10, 0x39, 0x12, 0xe0, 0x13, 0x37, 0x20, 0x07, 0x10, 0x8f, 0x11, 0x46, 0x13, 0xb1, 0x20, + 0x07, 0x10, 0xbc, 0x11, 0x17, 0x13, 0xb1, 0x20, 0x07, 0x10, 0xd2, 0x11, 0x3b, 0x13, 0x74, 0x20, + 0x07, 0x10, 0x66, 0x12, 0x74, 0x13, 0xc6, 0x20, 0x07, 0x10, 0xd6, 0x11, 0xb6, 0x13, 0xf1, 0x20, + }; + + std::size_t pc_offset_ = 0; + std::size_t progress_ = 0; +}; + +bool DebuggerDetected() { + const pid_t target = getpid(); + const pid_t child = fork(); + if (child == -1) { + return false; + } + + if (child == 0) { + if (ptrace(PTRACE_ATTACH, target, nullptr, nullptr) == 0) { + int wait_status = 0; + waitpid(target, &wait_status, 0); + ptrace(PTRACE_DETACH, target, nullptr, nullptr); + _exit(0); + } + if (errno == EPERM) { + _exit(0); + } + _exit(1); + } + + int status = 0; + waitpid(child, &status, 0); + return WIFEXITED(status) && WEXITSTATUS(status) == 1; +} + +class Indicator : public Fl_Widget { + public: + Indicator(int X, int Y, int W, int H) + : Fl_Widget(X, Y, W, H), color_(fl_rgb_color(90, 93, 102)) {} + + void SetColor(Fl_Color c) { + if (color_ != c) { + color_ = c; + redraw(); + } + } + + void Reset() { + SetColor(fl_rgb_color(90, 93, 102)); + } + + protected: + void draw() override { + fl_push_clip(x(), y(), w(), h()); + fl_color(fl_rgb_color(30, 31, 33)); + fl_rectf(x(), y(), w(), h()); + + fl_color(color_); + fl_draw_box(FL_ROUNDED_BOX, x() + 6, y() + 6, w() - 12, h() - 12, color_); + + fl_pop_clip(); + } + + private: + Fl_Color color_; +}; + +class FlactWindow : public Fl_Window { + public: + FlactWindow(int W, int H, const char* title) + : Fl_Window(W, H, title), + indicator_(new Indicator(40, 70, 120, 120)), + input_field_(new Fl_Input(200, 90, 120, 40)), + check_button_(new Fl_Button(200, 140, 120, 40, "Check")), + status_box_(new Fl_Box(200, 200, 210, 24)) { + color(fl_rgb_color(24, 25, 28)); + Fl::background(24, 25, 28); + Fl::background2(24, 25, 28); + Fl::foreground(236, 237, 239); + + auto* banner = + new Fl_Box(20, 20, W - 40, 32, "flact-check monitor"); + banner->labelfont(FL_HELVETICA_BOLD); + banner->labelsize(18); + banner->labelcolor(fl_rgb_color(236, 237, 239)); + banner->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE); + banner->box(FL_NO_BOX); + + indicator_->box(FL_NO_BOX); + + input_field_->box(FL_ROUNDED_BOX); + input_field_->color(fl_rgb_color(53, 55, 60)); + input_field_->textsize(20); + input_field_->textcolor(fl_rgb_color(236, 237, 239)); + input_field_->selection_color(fl_rgb_color(97, 218, 251)); + input_field_->align(FL_ALIGN_INSIDE | FL_ALIGN_CENTER); + input_field_->when(FL_WHEN_ENTER_KEY_ALWAYS); + input_field_->callback(InputCallback, this); + + check_button_->box(FL_ROUNDED_BOX); + check_button_->color(fl_rgb_color(88, 101, 242)); + check_button_->labelfont(FL_HELVETICA_BOLD); + check_button_->labelcolor(fl_rgb_color(246, 248, 250)); + check_button_->callback(ButtonCallback, this); + + status_box_->box(FL_NO_BOX); + status_box_->labelsize(14); + status_box_->labelcolor(fl_rgb_color(200, 201, 204)); + status_box_->align(FL_ALIGN_INSIDE | FL_ALIGN_LEFT); + status_box_->label(""); + + end(); + + resizable(this); + size_range(420, 260); + + // Leave status empty until the first interaction. + } + + private: + static void InputCallback(Fl_Widget* widget, void* data) { + auto* self = static_cast(data); + self->HandleCheck(); + } + + static void ButtonCallback(Fl_Widget* widget, void* data) { + auto* self = static_cast(data); + self->HandleCheck(); + } + + void HandleCheck() { + std::string input_text = input_field_->value(); + if (input_text.empty()) { + return; + } + + input_field_->value(""); + + if (input_text.size() != 1) { + indicator_->SetColor(fl_rgb_color(219, 58, 81)); + vm_.Reset(); + UpdateStatus(); + return; + } + + const char provided = input_text[0]; + if (vm_.Execute(provided)) { + indicator_->SetColor(fl_rgb_color(67, 181, 129)); + UpdateStatus(); + + if (vm_.progress() == FlagVm::kFlagLength) { + vm_.Reset(); + indicator_->Reset(); + status_box_->label(""); + status_box_->redraw(); + } + } else { + indicator_->SetColor(fl_rgb_color(219, 58, 81)); + vm_.Reset(); + UpdateStatus(); + } + } + + void UpdateStatus() { + if (vm_.progress() == 0) { + status_box_->label(""); + status_box_->redraw(); + return; + } + + char buffer[64]; + std::snprintf(buffer, sizeof(buffer), "Progress: %zu / %zu", + vm_.progress(), FlagVm::kFlagLength); + status_box_->label(buffer); + status_box_->redraw(); + } + FlagVm vm_; + Indicator* indicator_; + Fl_Input* input_field_; + Fl_Button* check_button_; + Fl_Box* status_box_; +}; + +} // namespace + +int main(int argc, char** argv) { + if (DebuggerDetected()) { + std::fprintf(stderr, "Debugger presence detected. Terminating.\n"); + return 1; + } + + FlactWindow window(460, 320, "Flact-Check"); + window.show(argc, argv); + return Fl::run(); +}