Skip to content

Latest commit

 

History

10 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Lab_Runner

A generic engine for graded student lab exercises on the WiFi Pineapple Pager. It doesn't do any detection/recon itself — it turns any existing payload or built-in tool in the library into a checkable, scored exercise by wrapping it with instructions, an optional hint, and a shell command that decides pass/fail.

Why this exists

Every payload in the official library is a tool built for someone who already knows what they're doing. None of them are a lesson: something with a stated objective, step-by-step guidance, a way to verify the student actually did it, and a score. Lab_Runner is that missing piece — a thin layer over the existing tools, not a replacement for any of them.

How it works

  • payload.sh is the engine. It scans labs/*.lab, shows a menu of available labs, captures a student name/ID, walks the student through each step of the chosen lab, and writes a report.
  • Each .lab file is a small, trusted (professor-authored) bash script. It defines three metadata variables and a run_lab() function made of lab_step calls.
  • A step's "check" is just a shell command. If it exits 0, the step passes. This can be anything already on the device: ls /root/loot/handshakes/*.pcap, grep -q SomeVendor /root/loot/..., checking recon.db, whatever fits the exercise.

Because the check is a live shell command against the device's real state, a lab step naturally fails until the student actually does the thing — there's no separate "answer key" to keep in sync with reality.

Authoring a new lab

Create labs/NN_your_lab_id.lab, where NN is a two-digit number controlling menu order. The engine lists labs/*.lab in plain filename order (alphabetical, which for a shell glob means numeric prefixes sort correctly) -- without one, a new lab's position in the picker menu depends on how its name happens to alphabetize against the others, not on where it actually belongs in the sequence. Existing labs are numbered 01-05; leave gaps (06, 07, ...) or renumber as needed if you want to insert one in the middle.

LAB_ID="your_lab_id"
LAB_TITLE="Shown in the lab-picker menu"
LAB_OBJECTIVE="One or two sentences shown before the lab starts."

run_lab() {
    lab_step "Instructions shown to the student for this step." \
        "Hint text -- pass \"\" for no hint." \
        'shell command; exit 0 = pass, nonzero = fail'

    lab_step "Next step's instructions." \
        "Another hint." \
        'another check command' \
        'optional: a command that runs automatically when the step starts'

    lab_complete "Closing message shown when every step is done (or skipped)."
}

Rules that matter:

  • LAB_ID, LAB_TITLE, LAB_OBJECTIVE must stay simple one-line KEY="value" assignments (no command substitution, no multi-line). The engine greps LAB_TITLE out of every .lab file to build the menu without running any of them — only the one the student actually picks gets sourced and executed. Keeping the metadata lines simple is what makes that safe.
  • The check command (and the optional 4th action command, see below) runs via eval, in its own subshell. Either can use anything available on the device, and can see $STUDENT_ID / $LAB_ID if useful (e.g. naming a file after the student). There's no sandboxing beyond the subshell isolation — this is the same trust level as writing any other payload.sh, since you're the one authoring both.
  • The subshell means exit is safe to use inside a check as an early-bailout idiom ([ -z "$x" ] && exit 1) — it only ends that one check attempt, not the student's whole session. This was tested deliberately (a bare eval without the subshell does not have this property — exit inside it kills the entire engine).
  • A check can call the same DuckyScript UI commands the engine itself uses — e.g. ans=$(TEXT_PICKER "What's the gateway IP?" "") — to ask the student a question as part of the check, then validate the answer against real device state. See labs/subnet_gateway_map.lab for a full example of this pattern.
  • 4th argument, "action": a command that runs automatically the moment a step starts, before the check menu appears. Use this to launch an existing payload directly (bash /root/payloads/user/reconnaissance/some_payload/payload.sh) as part of the step, instead of telling the student to go find and launch it themselves. This matters on this device specifically: backing out of a running payload to launch a different one kills the running one rather than pausing it (confirmed live) — there's no way to "go do something else and come back," so a step that needs another payload's work has to launch it itself. When an action is set, the step's menu gains a "Re-run" option, in case the launched payload's own flow gets cancelled or needs a second attempt.
  • 5th argument, "manual": makes the action available on demand instead of auto-firing it. The menu item is labeled "Get help" instead of "Re-run" in this mode. Use this when the action would hand the student the answer to what the step is actually asking them to figure out — e.g. subnet_gateway_map.lab's gateway-identification step offers the route payload as an optional "Get help," but doesn't run it automatically, since doing that would spoil the exercise before the student's even tried.
  • A step's instructions should describe what the student needs to go do, not just something to read. The engine's UI is deliberately minimal: instructions → hint/action/skip/check-my-work menu.
  • Every step's menu also has an "Exit payload" option (confirmed before it actually exits), regardless of what the lab file defines. This exists because backing out via the device's own navigation doesn't pause Lab_Runner or return you to it -- it just returns an unrecognized response that the menu silently loops on, which looks like it's hung. "Exit payload" is the only reliable way out of a step. The in-progress attempt isn't saved when used this way.
  • Keep checks idempotent and re-runnable — a student will hit "Check my work" multiple times while they work, so the check shouldn't have side effects beyond what it's actually verifying.

Running a lab session

  1. Launch Lab_Runner, pick a lab from the menu.
  2. Enter the student's name/ID (shown in the report and gradebook).
  3. Confirm the objective and start.
  4. For each step: read the instructions (shown as a pop-up), go do the thing, then pick "Check my work." "Show hint" is available anytime and is tracked (doesn't block progress, just recorded). "Skip step" moves on and marks it skipped.
  5. At the end, a report is written and the engine loops back to the lab menu — ready for the next student without relaunching the payload.

Grading artifacts

  • Per-attempt report: /root/loot/lab_runner/<lab_id>_<student_id>_<timestamp>.txt — objective, a table of every step's result/time/hints, and a final score line.
  • Running gradebook: /root/loot/lab_runner/gradebook.csv — one row appended per completed attempt (timestamp,lab_id,student_id,steps_passed,steps_total,hints_used,seconds_total), so a whole class's results across a session end up in one importable CSV. Pair this with the existing USB_Mount_Loot_Transfer or handshake_2_usb-style payload to pull it off the device, or USB_Mount_Loot_Transfer's general pattern for any loot export.

Included labs: a beginner-to-advanced sequence

Meant to be assigned roughly in this order — each stage assumes the vocabulary/comfort the previous one built:

  1. 01_orientation.lab — zero networking content. Just the UI itself: what LOG/ALERT mean, where loot lives, how hints work, how a typed-answer check feels. For a student who's never touched the device.
  2. 02_know_your_network.lab — IP address, MAC address, subnet prefix — by inspecting the Pager's own state only, no scanning of anything else. Builds the vocabulary every later lab assumes.
  3. 03_passive_recon.lab — first real recon concept: a short, purely passive BLE scan (only listens for advertisements already being broadcast — no active probing, nothing authorization-sensitive). Written directly with hciconfig/hcitool rather than launching the existing bluetooth or live_probe payloads — both had real risk for a beginner's first exercise (bluetooth auto-chains into a second payload via source at the end; live_probe depends on a monitor-mode interface that isn't guaranteed to exist and exits via a non-standard raw-input loop instead of the normal button API). Written from the same primitives Flock_Sky_Spy already proved reliable instead.
  4. 04_subnet_gateway_map.lab — pairs with the official nmap_host_discovery payload, which it launches directly via the action-argument pattern above rather than asking the student to find it themselves. Confirms the student is on a real subnet, runs the host-discovery sweep, then asks the student to identify the gateway's IP address (via TEXT_PICKER inside the check itself) and cross-validates their answer against both the system's actual default route and the scan's own "Host is up" result for that address — so a lucky guess doesn't pass, and neither does a right answer with no scan to back it up. Also demonstrates the manual/"Get help" pattern: offers the route payload as an on-demand helper for the gateway question, without auto-running it and spoiling the exercise.
  5. 05_first_handshake.lab — the advanced tier: find a (professor-controlled test) AP via Recon, capture its handshake, and confirm the capture. Requires an isolated test AP you control — standard setup for a wireless security course, and a natural moment to reinforce the authorization/scope point (the hint on the deauth step says so explicitly, deliberately).

Ideas for more labs (not included, straightforward to add given the pattern above)

  • Pair with wpa_handshake_quality_check — a follow-on lab checking the captured handshake actually has a full 4-way EAPOL exchange, not just any pcap.
  • Pair with Fuzz_Finder/Flock_Detect — "identify N distinct device types in your environment" using existing BLE detectors' loot output as the check.

About

Pager Lab Runner — A graded student-lab engine for the Hak5 WiFi Pineapple Pager. Wraps any existing payload/recon tool with instructions, hints, and a pass/fail check, then generates per-student reports and a class gradebook — for cybersecurity course labs.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages