Thursday, May 14, 2026

Arduino Nano Beginner Embedded Reverse Engineering CTF

This document explains how to create and solve a beginner-friendly embedded reverse engineering Capture The Flag (CTF) challenge using an Arduino Nano. The challenge teaches firmware extraction, reverse engineering with Ghidra, basic binary patching, and reflashing modified firmware.

1. Learning Objectives

·         Extract firmware from an Arduino Nano

·         Open and inspect firmware inside Ghidra

·         Locate LED blink logic

·         Identify timing and conditional instructions

·         Patch firmware behavior

·         Reflash modified firmware back to the board

·         Recover a hidden flag

2. Hardware Requirements

·         Arduino Nano (ATmega328P)

·         USB cable

·         LED connected to pin 13 (built-in LED also works)

·         Optional ISP programmer or another Arduino board

3. Software Requirements

·         Arduino IDE

·         avrdude

·         Ghidra

·         Hex editor (optional)

4. Challenge Concept

The firmware continuously blinks an LED. The player must extract the firmware, reverse engineer the LED timing logic, modify the blink speed, reflash the patched firmware, and trigger the hidden flag.

5. Original Firmware Example

#define LED_PIN 13

int blinkDelay = 500;

void setup() {
  pinMode(LED_PIN, OUTPUT);
  Serial.begin(9600);
  Serial.println("SYSTEM LOCKED");
}

void loop() {

  digitalWrite(LED_PIN, HIGH);
  delay(blinkDelay);

  digitalWrite(LED_PIN, LOW);
  delay(blinkDelay);

  if(blinkDelay == 100) {
    Serial.println("FLAG{patched_the_firmware}");
    while(1);
  }
}

6. Challenge Behavior

·         The LED blinks slowly at startup.

·         The hidden flag only appears if blinkDelay becomes 100.

·         Players do not initially know this condition exists.

·         The firmware must be analyzed and patched.

7. Exporting the Firmware

1.       Compile the Arduino sketch.

2.       Locate the generated .hex firmware file.

3.       Alternatively extract firmware using avrdude.

4.       Save the firmware image for analysis.

avrdude -c arduino -p m328p -P COM3 -b 115200 -U flash:r:firmware.hex:i

8. Opening Firmware in Ghidra

5.       Create a new Ghidra project.

6.       Import the firmware HEX file.

7.       Select AVR 8-bit architecture.

8.       Run automatic analysis.

9.       Inspect functions and strings.

9. Reverse Engineering Process

Step 1 — Locate Strings

Search for the string "SYSTEM LOCKED". This usually helps identify the main firmware logic.

Step 2 — Find LED Logic

Locate references to digitalWrite and delay functions. The delay value controls blink speed.

Step 3 — Identify the Condition

Inspect comparisons involving the blinkDelay variable. The firmware checks whether blinkDelay equals 100.

10. Beginner-Friendly Patching Methods

Method A — Modify the Delay Value

Players can patch the delay value from 500 to 100. This causes the LED to blink faster and triggers the hidden flag.

Method B — Patch the Conditional Jump

Instead of changing the delay, players can modify the comparison logic so the flag is always revealed.

11. Why Changing LED Speed Is Better Than Turning It Off

·         The player gets visible physical feedback.

·         Behavioral changes are easier to notice.

·         It feels more realistic and interactive.

·         Players can visually confirm their patch worked.

·         It teaches timing analysis instead of only bypass logic.

12. Reflashing the Patched Firmware

10.   Export the modified binary.

11.   Use avrdude to upload the patched firmware.

12.   Restart the Arduino Nano.

13.   Observe the faster LED blinking.

14.   Open the serial monitor to recover the flag.

avrdude -c arduino -p m328p -P COM3 -b 115200 -U flash:w:patched.hex

13. Expected Final Result

·         LED blink speed changes from slow to fast.

·         Serial monitor displays the hidden flag.

·         Player successfully completes the challenge.

14. Additional Beginner Challenge Ideas

·         Unlock hidden serial commands

·         Extract EEPROM secrets

·         Patch login attempt counters

·         Reverse XOR-encoded flags

·         Modify buzzer frequencies

·         Enable hidden debug menus

15. Safety and Ethics

This project is intended for education and laboratory practice only. Use isolated hardware that you own or are authorized to analyze.

16. Conclusion

This challenge introduces real embedded reverse engineering concepts in a beginner-friendly way. Using an Arduino Nano keeps the firmware small and understandable while still teaching important concepts such as firmware extraction, analysis, binary patching, and reflashing.

ESP8266 NodeMCU Beginner Capture The Flag (CTF) Guide

 

This guide explains how to build a beginner-friendly offline Capture The Flag (CTF) challenge using an ESP8266 NodeMCU. It includes challenge design, setup instructions, firmware examples, challenge walkthroughs, and solutions.

1. Project Overview

·         The ESP8266 acts as a Wi-Fi access point and hosts a small web server.

·         Players connect to the Wi-Fi network and interact with challenge pages.

·         Each challenge teaches a basic web or embedded security concept.

·         No internet connection is required.

·         The project is suitable for classrooms, workshops, or beginner cybersecurity demonstrations.

2. Hardware Requirements

·         1× ESP8266 NodeMCU board

·         1× Micro USB cable

·         Computer with Arduino IDE installed

·         Optional: Power bank for portable demonstrations

·         Optional: LED connected to GPIO2 or built-in LED

3. Software Requirements

·         Arduino IDE

·         ESP8266 board package

·         ESP8266WiFi library

·         ESP8266WebServer library

4. Installing ESP8266 Board Support

1.       Open Arduino IDE.

2.       Go to File → Preferences.

3.       Add the ESP8266 board manager URL.

4.       Open Tools → Board → Boards Manager.

5.       Search for ESP8266 and install it.

6.       Select NodeMCU 1.0 (ESP-12E Module) from the board list.

5. Network Design

The ESP8266 creates its own Wi-Fi network named HackMe_AP. Players connect to the network and browse to 192.168.4.1.

Setting

Value

SSID

HackMe_AP

Password

None (Open Network)

IP Address

192.168.4.1

Port

80

6. Complete Firmware Example

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

const char* ssid = "HackMe_AP";

ESP8266WebServer server(80);

const char MAIN_PAGE[] PROGMEM = R"rawliteral(
<!DOCTYPE html>
<html>
<head>
<title>ESP8266 CTF</title>
</head>
<body>
<h1>Welcome Challenger</h1>
<p>Find the hidden flags.</p>

<!-- FLAG{inspect_the_source} -->

</body>
</html>
)rawliteral";

void handleRoot() {
  server.sendHeader("X-Hint", "admin:esp8266");
  server.send(200, "text/html", MAIN_PAGE);
}

void handleRobots() {
  server.send(200, "text/plain",
              "Disallow: /hidden-panel");
}

void handleHiddenPanel() {
  server.send(200, "text/plain",
              "FLAG{robots_reveal_paths}");
}

void handleLogin() {

  String user = server.arg("username");
  String pass = server.arg("password");

  if(user == "admin" && pass == "esp8266") {
    server.send(200, "text/plain",
                "FLAG{headers_leak_information}");
  } else {
    server.send(401, "text/plain",
                "Invalid login");
  }
}

void setup() {

  Serial.begin(115200);

  WiFi.softAP(ssid);

  Serial.println("CTF Started");
  Serial.println(WiFi.softAPIP());

  server.on("/", handleRoot);

  server.on("/robots.txt", handleRobots);

  server.on("/hidden-panel", handleHiddenPanel);

  server.on("/login", HTTP_POST, handleLogin);

  server.begin();
}

void loop() {
  server.handleClient();
}

7. Uploading the Firmware

7.       Connect the ESP8266 NodeMCU to the computer.

8.       Select the correct COM port.

9.       Paste the firmware into Arduino IDE.

10.   Click Upload.

11.   Open Serial Monitor at 115200 baud.

12.   Verify the IP address appears.

8. Challenge Walkthroughs

Level 1 — HTML Source Inspection

Challenge: The player connects to the Wi-Fi network and visits 192.168.4.1.

Goal: Find the hidden flag in the HTML source code.

Skill Learned: Viewing source code and inspecting HTML comments.

Solution

13.   Open the webpage.

14.   Right click and choose View Page Source.

15.   Find the hidden HTML comment.

16.   Recover the flag FLAG{inspect_the_source}.

Level 2 — Hidden Path Discovery

Challenge: The player must discover a hidden page.

Hint: Check robots.txt.

Solution

17.   Visit http://192.168.4.1/robots.txt

18.   Find the hidden path /hidden-panel

19.   Visit the hidden path

20.   Recover the flag FLAG{robots_reveal_paths}

Level 3 — HTTP Header Credential Leak

Challenge: A login page requires credentials.

Hint: Inspect HTTP headers.

Solution

21.   Open browser developer tools or use curl.

22.   Inspect the X-Hint HTTP header.

23.   Recover credentials admin / esp8266.

24.   Send a POST request to /login.

25.   Receive FLAG{headers_leak_information}.

9. Optional Improvements

·         Blink an LED when a player finds a flag

·         Add an OLED display for score tracking

·         Create a fake firmware update page

·         Add Base64 encoded hints

·         Add cookie-based authentication challenges

·         Store pages in SPIFFS instead of program memory

10. Safety and Ethical Notes

This project is designed for educational purposes only. It should be used in isolated environments such as classrooms, workshops, or home labs. Avoid using the project to imitate real websites or collect real credentials.

11. Troubleshooting

·         If the Wi-Fi network does not appear, restart the ESP8266.

·         If uploads fail, check the selected COM port.

·         If pages do not load, verify the IP address is 192.168.4.1.

·         If login does not work, confirm the POST request parameters are correct.

12. Conclusion

This project demonstrates how inexpensive hardware can be used to teach networking, embedded systems, and introductory cybersecurity concepts in a safe and approachable way.

Wednesday, May 13, 2026

Educational Java CRC32 Key Generator & Validator

 This version is a simplified educational serial-key system that uses:

  • CRC32 validation,
  • XOR masking,
  • scrambling,
  • Base32-style encoding,
  • embedded integrity data.

It is designed to demonstrate how many classic offline product-key systems worked.


How The System Works

Random Characters

CRC32 Calculation

XOR Secret Constant

Encode CRC32

Embed Validation Data

Scramble

Format Product Key

Validator later:

Remove Formatting

Unscramble

Extract CRC Section

Recalculate CRC32

Compare Results

1. KeyGenerator.java

import java.util.Random;
import java.util.zip.CRC32;

public class KeyGenerator {

static final String ALPHABET =
"ABCDEFGHJKLMNPQRSTUVWXYZ23456789";

static final int SECRET_XOR = 0x1D8DF;

static Random random = new Random();

public static void main(String[] args) {

// Step 1: Generate random section
String randomPart = generateRandomText(12);

// Step 2: Calculate CRC32
long crc = calculateCRC32(randomPart);

// Step 3: XOR mask
crc = crc ^ SECRET_XOR;

// Step 4: Encode CRC
String crcText = encodeCRC(crc);

// Step 5: Combine
String fullKey = randomPart + crcText;

// Step 6: Scramble
fullKey = scramble(fullKey);

// Step 7: Format
fullKey = formatKey(fullKey);

System.out.println("Generated Key:");
System.out.println(fullKey);
}

static String generateRandomText(int length) {

StringBuilder sb = new StringBuilder();

for (int i = 0; i < length; i++) {

sb.append(
ALPHABET.charAt(
random.nextInt(ALPHABET.length())
)
);
}

return sb.toString();
}

static long calculateCRC32(String text) {

CRC32 crc = new CRC32();

crc.update(text.getBytes());

return crc.getValue();
}

static String encodeCRC(long value) {

char[] out = new char[6];

for (int i = 0; i < out.length; i++) {

int index =
(int)(value % ALPHABET.length());

out[i] = ALPHABET.charAt(index);

value /= ALPHABET.length();
}

return new String(out);
}

static String scramble(String text) {

char[] data = text.toCharArray();

swap(data, 1, 5);
swap(data, 2, 8);
swap(data, 4, 14);
swap(data, 7, 15);

return new String(data);
}

static void swap(char[] data, int a, int b) {

char temp = data[a];
data[a] = data[b];
data[b] = temp;
}

static String formatKey(String key) {

StringBuilder sb = new StringBuilder();

for (int i = 0; i < key.length(); i++) {

sb.append(key.charAt(i));

if ((i + 1) % 4 == 0
&& i != key.length() - 1) {

sb.append('-');
}
}

return sb.toString();
}
}

2. KeyValidator.java

import java.util.Scanner;
import java.util.zip.CRC32;

public class KeyValidator {

static final String ALPHABET =
"ABCDEFGHJKLMNPQRSTUVWXYZ23456789";

static final int SECRET_XOR = 0x1D8DF;

public static void main(String[] args) {

Scanner scanner = new Scanner(System.in);

System.out.println("Enter key:");

String key = scanner.nextLine();

boolean valid = validate(key);

if (valid) {
System.out.println("VALID KEY");
} else {
System.out.println("INVALID KEY");
}
}

static boolean validate(String key) {

// Remove dashes
key = key.replace("-", "");

// Unscramble
key = unscramble(key);

// Split sections
String randomPart = key.substring(0, 12);
String crcPart = key.substring(12, 18);

// Recalculate CRC32
long crc = calculateCRC32(randomPart);

// XOR again
crc = crc ^ SECRET_XOR;

// Encode expected CRC
String expected = encodeCRC(crc);

// Compare
return expected.equals(crcPart);
}

static long calculateCRC32(String text) {

CRC32 crc = new CRC32();

crc.update(text.getBytes());

return crc.getValue();
}

static String encodeCRC(long value) {

char[] out = new char[6];

for (int i = 0; i < out.length; i++) {

int index =
(int)(value % ALPHABET.length());

out[i] = ALPHABET.charAt(index);

value /= ALPHABET.length();
}

return new String(out);
}

static String unscramble(String text) {

char[] data = text.toCharArray();

// Reverse swaps
swap(data, 7, 15);
swap(data, 4, 14);
swap(data, 2, 8);
swap(data, 1, 5);

return new String(data);
}

static void swap(char[] data, int a, int b) {

char temp = data[a];
data[a] = data[b];
data[b] = temp;
}
}

Example Output

Generated Key:
A7QK-9PLX-W2RM-TJ8N-4K

Validator:

Enter key:
A7QK-9PLX-W2RM-TJ8N-4K

VALID KEY

Modified key:

A7QK-9PLX-W2RM-TJ8N-5K

Result:

INVALID KEY

Educational Concepts Demonstrated

ConceptPurpose
CRC32integrity verification
XOR maskinglightweight obfuscation
Base32 encodingreadable validation text
Scramblingstructure hiding
Embedded validationself-checking serials
Recalculationauthenticity checking

Important Note

This project is educational only.

It demonstrates:

  • classic offline key validation ideas,
  • integrity algorithms,
  • serial formatting concepts,
  • and historical DRM-style design patterns.

It is not secure modern licensing or cryptography.

github: https://github.com/stark9000/Educational-Java-CRC32-Key-Generator-Validator