CTF – 2 : Good Kitty

CTF Challenge: Good Kitty - Writeup Challenge Overview This is a reverse engineering CTF challenge where we need to find the correct password by analyzing a binary that: Calculates a value based on Project Euler problem #3 Encodes it using a custom algorithm Compares user input against the encoded value Initial Analysis Decompiled Code Structure undefined8 main(void) { byte bVar1; ssize_t bytes_read; long input_len; int iVar2; long in_FS_OFFSET; double dVar3; undefined1 local_be; byte is_correct; uint index; long flag; undefined8 local_b0; undefined8 local_a8 [4]; undefined8 local_88; undefined8 uStack_80; undefined8 local_78; char user_input [72]; long local_20; local_20 = *(long *)(in_FS_OFFSET + 0x28); flag = ppeuler_3(); dVar3 = cbrt((double)flag); flag = (long)dVar3; flag = factorial(flag); input_len = 0; do { bVar1 = *(byte *)((long)&flag + input_len); if ((0x19 < (byte)((bVar1 & 0xdf) + 0xbf)) && (9 < (byte)(bVar1 - 0x30))) { bVar1 = bVar1 % 0x3e; if ((byte)(bVar1 - 10) < 0x1a) { *(byte *)((long)&flag + input_len) = bVar1 + 0x37; } else if ((byte)(bVar1 + 0x30) < 0x54) { *(byte *)((long)&flag + input_len) = bVar1 + 0x30; } else { *(byte *)((long)&flag + input_len) = bVar1 + 0x3d; } } input_len = input_len + 1; } while (input_len != 8); // ... rest of code validates input } Key Concepts Learned 1. Understanding Pointer Arithmetic on Stack Variables Question: flag is declared as long flag; (not an array), so what does &flag + index mean? ...

November 9, 2025 · 5 min

GDB Notes – Basics & Practical Usage

GDB Notes — Basics, Navigation & Memory Inspection These are concise notes on how to use GDB (GNU Debugger) effectively for analyzing ELF binaries and debugging at both C source and assembly levels. 1. Starting GDB Basic invocation gdb ./a.out gdb -q ./program # Quiet mode (no banner) With arguments gdb --args ./program arg1 arg2 From inside GDB (gdb) run arg1 arg2 2. Compiling for Debugging Compile with the -g flag to include debug symbols: ...

November 9, 2025 · 5 min

GDB print Command

GDB Print Command Reference Guide Basic Print Command print variable_name p variable_name # Short form Print with Format Specifiers Use /format after print to specify output format: Hexadecimal print/x variable # Hex (lowercase) print/x value # Example: 0x5 p/x 255 # Output: 0xff Decimal print/d variable # Signed decimal print/u variable # Unsigned decimal p/d 0xff # Output: 255 Octal print/o variable # Octal format p/o 64 # Output: 0100 Binary print/t variable # Binary (t = "two") p/t 5 # Output: 101 Character print/c variable # As ASCII character p/c 65 # Output: 'A' Floating Point print/f variable # Floating point p/f 3.14159 Address/Pointer print/a variable # As address p/a 0x555555555189 # Shows as address String print/s pointer # Interpret as C string p/s argv[1] Working with Pointers print pointer # Shows address print *pointer # Dereference (shows value) print &variable # Shows address of variable # Example print argv # Address of argv array print *argv # First element (argv[0]) print argv[1] # Second element print *argv[1] # First char of argv[1] Array and String Operations # Print entire array print buffer_one print buffer_two # Print specific elements print buffer_one[0] print buffer_one[3] # Print array slice (if supported) print buffer_one@8 # Print 8 elements starting at buffer_one # View string with length x/8c buffer_one # First 8 chars x/s buffer_one # Until null terminator Type Casting # Cast to different types print (int *)buffer_one # Treat as int pointer print *(int *)buffer_one # Dereference as int print (unsigned char)value # Cast to unsigned char # Example: View buffer as integers print *(int *)&buffer_one print *(long *)&buffer_two Expressions and Calculations # Arithmetic print value + 10 print sizeof(buffer_one) print strlen(buffer_one) # Address calculations print &buffer_one - &buffer_two print (long)&value - (long)&buffer_one # Pointer arithmetic print argv[0] print *(argv + 1) Display Commands (Auto-Print) Set up variables to display automatically after each step: ...

November 9, 2025 · 4 min

GDB Layouts

Debugging Souce Code with Assembly If we compile C program with -g flag, it tells GCC to include debugging symbols inside the resulting binary (a.out by default). These symbols live in a special section of the ELF file (like .debug_info, .debug_line, .debug_str, etc.) and contain metadata that maps machine instructions back to your original source code. This allows us to see corresponding source along with assembly while debugging with GDB. ...

November 4, 2025 · 4 min

GDB x Command

Examining Memory with x Command The x (examine) command is more powerful for raw memory: x/[count][format][size] address Size Modifiers b = byte (1 byte) h = halfword (2 bytes) w = word (4 bytes) g = giant word (8 bytes) Format Modifiers x = hexadecimal d = decimal u = unsigned decimal o = octal t = binary c = character s = string i = instruction (disassembly) count: how many units to display ...

November 4, 2025 · 1 min

Radare2 Basic Commands

Reverse Engineering with Radare2 A powerful framework for reverse engineering. Core Analysis Commands r2 Command Description r2 ./binary Open the binary for analysis. aaa Analyze All Automatically. Finds functions, symbols, etc. afl Analyze Function List. Shows all identified functions. s <address/name> Seek to a specific address or function name (e.g., s main). pdf Print Disassembled Function. Shows assembly code. pdg Print Decompiled Ghidra. Shows decompiled C-like code. afv Analyze Function Variables. Shows local variables, arguments, and their stack offsets. Additional Useful Commands r2 Command Description i Show general information about the binary (imports, exports, strings). ps Print a summary of the binary’s sections. V Enter visual mode for interactive navigation. VV Enter visual graph mode to see the control flow graph. ? / ?? Get help on commands.

November 4, 2025 · 1 min

CTF – 1 : Matryoshka

Reverse Engineering and CTF Challenge Notes Reverse engineering is the process of understanding how software works without access to its original source code. In security challenges (CTFs), the goal is often to recover hidden data or logic by dissecting a binary. This walkthrough documents my first attempt at such a challenge, focusing on ELF-based reverse engineering and the reasoning process behind each step. 1. Static Analysis Static analysis means inspecting the binary without running it. ...

November 1, 2025 · 4 min

ELF Format: Part 3

ELF Format: Sections and Section Header Table In the previous post, we explored Program Headers and Segments - the runtime view of an ELF file. Now we’ll look at Section Headers and Sections - the link-time and debugging view. What Are Sections? Sections are the link-time view of an ELF file. While segments tell the operating system how to load and execute a program, sections organize the file’s contents for: ...

October 15, 2025 · 43 min

ELF Format: Part 2

ELF Format: Segments and Program Header Table After understanding the ELF Header, the next critical component is the Program Header Table. This table describes segments - the portions of the file that will be loaded into memory when the program executes. What Are Segments? Segments are the runtime view of an ELF file. While sections (which we’ll cover later) are used during linking and debugging, segments are what the operating system cares about when loading and executing a program. ...

October 13, 2025 · 9 min

ELF Format: Part 1

ELF Format: ELF Header What is ELF? ELF (Executable and Linkable Format) is the standard binary format used by Unix-like systems (Linux, BSD, etc.) for: Executable files (a.out, /bin/ls) Object files (.o) Shared libraries (.so) Core dumps It’s a container format that describes: What parts of the file get loaded into memory, Where execution starts, How relocations and dynamic linking are handled. Contains useful information for the debuggers. General Structure of an ELF File An ELF file is organized into several key components that serve different purposes during compilation, linking, and execution. ...

October 1, 2025 · 8 min