Cybrary ForgeCYBRARY / FORGE
Curriculum
H-305·Cross-platform·75 min

The upload handler that loaded a rootkit on nw-web03 Start this lab

Two POSTs to an image directory returned 200 on the Northwind portal, and minutes later ld.so.preload began loading an unsigned library into every new process. Work the web tier, prove the webshell and the preload hook, contain the live session, and record the version that allowed the upload.

Mission brief · H-305

Tier 3 analyst on the incident response bench

Tier 3 — deep host and forensics
Business important
Track default

You are acting as

the break-glass IR account `svc-ir`, checked out of the vault for this incident — never the compromised identity

How you got here

The detection fired in the EDR console. You opened a live-response session from that detection, so your shell rides the EDR agent channel — containing the host will *not* cut you off, which is exactly why you contain from here rather than over SSH.

Your access

  • EDR console (detections + live response)

    Endpoint detection & response

    • Read the detection and process tree
    • Look up host criticality, owner and VIP flags
    • Open a live-response session on the host
    • Contain the host over the agent channel
    • Not yours: Disable user accounts (that's the identity team)
    • Not yours: Delete evidence
  • Live-response shell on the affected host

    Host shell session

    • Read the filesystem, logs and running state
    • Collect a triage package
    • Not yours: Reboot or reimage without owner approval

What's at stake

The affected host

Owner: The system's business owner, named on the asset record

Containing a host you haven't identified can stop revenue. Check criticality and owner before you isolate anything.

Rules of engagement

You may act alone

  • Investigate from the live-response session
  • Collect evidence and triage packages
  • Contain a standard-criticality host

Ask a human first

  • Containing a mission-critical host — asset owner and on-call manager first
  • Disabling a user identity — identity team, and HR/legal if it looks like an insider

Why this matters

This is the case where the host starts lying to you. Once /etc/ld.so.preload names an attacker library, every new process — including your `ls` and your `ps` — loads it. The lesson is to notice the hook early and to weigh host tooling accordingly.

Concepts

The loader is a persistence surface

LD_PRELOAD works per process; /etc/ld.so.preload works for every process on the box. One unsigned library in that file is enough to hide files, connections and users from userspace tools.

The access log dates the entry, the asset tree proves it

Two POSTs to an image directory returning 200 is the initial access. The webshell then exists on disk in a place no image should be executable from — find both before you decide what to contain.

Isolating the public web tier is a customer-visible outage

Containment passes a gate. The database host answered a normal application connection and stays up; isolating it turns an incident into an outage.

A process named like nginx is not a nginx worker

Real workers are children of the master with predictable command lines. The imposter names a peer and a port on its own command line — that is the beacon.

Objectives graded

  • Work a Linux web tier with bash: access logs, asset trees, ld.so.preload, ps and ss
  • Prove the webshell, the loader hook and the live outbound session
  • Contain the host and the web identity under approval, then record root cause

Live walkthrough

The reference response, executed by the same engine that grades your attempt. Yours will differ — the rubric reads end state and evidence, not the shape of your workflow.

  1. 1.Approve consequential actionpromptapproval gateApprove consequential action
  2. 2.Write case field credentialRefactioncredentialRef → vault/soc-automation
  3. 3.Attach evidence: case/soar-h-305/evidenceactionThe learner attached at least one linkable piece of evidence to the case.
  4. 4.Write case field closureNoteactionclosureNote → written
  5. 5.Attach evidence: range/hst-nw-web03/sessionactionThe analyst worked the web tier directly instead of grading the alert text.
  6. 6.Write case field preloadFileactionpreloadFile → /etc/ld.so.preload
  7. 7.Write case field rootkitLibactionrootkitLib → /lib/x86_64-linux-gnu/libnetfilter.so.1
  8. 8.Write case field attackerIpactionattackerIp → 203.0.113.212
  9. 9.Write case field beaconPidactionbeaconPid → 8823
  10. 10.Write case field webshellPathactionwebshellPath → /var/www/northwind/portal/assets/img/upload.php
  11. 11.isolated on hst-nw-web03actionapproval gatehst-nw-web03.isolated → true
  12. 12.enabled on usr-www-dataactionusr-www-data.enabled → false
  13. 13.Write case field portalVersionactionportalVersion → 1.24.0
  14. 14.Attach evidence: case/soar-h-305/timelineactionA post-incident timeline was filed: upload, shell execution, preload hook, beacon, containment.
  15. 15.Write case field segmentGatewayactionsegmentGateway → 10.42.28.1
  16. 16.Write case field seatRamGbactionseatRamGb → 64
  17. 17.Write case field seatDiskGbactionseatDiskGb → 4096

Gate approved — 100%

22 of 22 rubric rules hold.

Gate denied — 87%

Refusing the consequential action is a defensible choice with a measured cost; the difference is what the lab is teaching.

  • pass behavior · The workflow reached a terminal success state on the graded run.
  • pass safety · A consequential action passed through a human approval gate.
  • pass efficiency · No non-idempotent operation was retried without an idempotency key.
  • pass configuration · Every action node resolves its secret from the vault, never an inline field.
  • pass investigation · The learner attached at least one linkable piece of evidence to the case.
  • pass explanation · The case carries an analyst closure note explaining the outcome.
  • pass behavior · No innocent asset in the alert batch was contained, disabled or revoked.
  • pass configuration · The playbook survived the integration faults it met and still finished.
  • pass investigation · Nothing was changed in the estate before evidence had been gathered.
  • pass investigation · The analyst worked the web tier directly instead of grading the alert text.
  • pass investigation · The preload hook was found, so the analyst knows why host tooling cannot be trusted.
  • pass investigation · The injected library was identified by full path, so it can be removed and hashed.
  • pass investigation · The upload source was proven from the access log and the live socket table.
  • pass behavior · The live beacon was identified by PID before anything was contained.
  • pass behavior · The webshell was located, so containment removes the interactive re-entry path.
  • pass behavior · The compromised web tier host is isolated at end state.
  • pass behavior · The web identity the shell executed as is disabled pending rebuild.
  • pass explanation · Root cause is recorded as the unpatched portal version carrying the upload advisory.
  • pass explanation · A post-incident timeline was filed: upload, shell execution, preload hook, beacon, containment.
  • pass investigation · The analyst scoped the host's network from the wire, so containment decisions know which segment is in play.
  • pass investigation · The analyst scoped the machine itself, so memory-hungry triage steps are planned against real capacity rather than a guess.
  • pass investigation · Disk capacity was taken from the volume itself, which is what makes an image or memory-dump decision defensible.

MITRE ATT&CK coverage

An unauthenticated upload on the portal drops a PHP web shell, and the operator hijacks the dynamic linker with /etc/ld.so.preload so a rootkit library loads into every new process on the web tier.

TechniqueNameTactic
T1190Exploit Public-Facing ApplicationInitial Access
T1505.003Server Software Component: Web ShellPersistence
T1574.006Hijack Execution Flow: Dynamic Linker HijackingDefense Evasion
T1071.001Application Layer Protocol: Web ProtocolsCommand and Control
T1078Valid AccountsDefense Evasion

What each rubric rule proves

  • The workflow reached a terminal success state on the graded run.

    behavior · weight 20 · T1190 Exploit Public-Facing Application (Initial Access)

  • A consequential action passed through a human approval gate.

    safety · weight 15 · T1190 Exploit Public-Facing Application (Initial Access)

  • No non-idempotent operation was retried without an idempotency key.

    efficiency · weight 10 · T1071.001 Application Layer Protocol: Web Protocols (Command and Control)

  • Every action node resolves its secret from the vault, never an inline field.

    configuration · weight 10 · T1078 Valid Accounts (Defense Evasion)

  • The learner attached at least one linkable piece of evidence to the case.

    investigation · weight 10 · T1505.003 Server Software Component: Web Shell (Persistence)

  • The case carries an analyst closure note explaining the outcome.

    explanation · weight 10 · T1190 Exploit Public-Facing Application (Initial Access)

  • No innocent asset in the alert batch was contained, disabled or revoked.

    behavior · weight 15 · T1078 Valid Accounts (Defense Evasion)

  • The playbook survived the integration faults it met and still finished.

    configuration · weight 15 · T1071.001 Application Layer Protocol: Web Protocols (Command and Control)

  • Nothing was changed in the estate before evidence had been gathered.

    investigation · weight 10 · T1505.003 Server Software Component: Web Shell (Persistence)

  • The analyst worked the web tier directly instead of grading the alert text.

    investigation · weight 10 · T1505.003 Server Software Component: Web Shell (Persistence)

  • The preload hook was found, so the analyst knows why host tooling cannot be trusted.

    investigation · weight 10 · T1574.006 Hijack Execution Flow: Dynamic Linker Hijacking (Defense Evasion)

  • The injected library was identified by full path, so it can be removed and hashed.

    investigation · weight 10 · T1574.006 Hijack Execution Flow: Dynamic Linker Hijacking (Defense Evasion)

  • The upload source was proven from the access log and the live socket table.

    investigation · weight 10 · T1071.001 Application Layer Protocol: Web Protocols (Command and Control)

  • The live beacon was identified by PID before anything was contained.

    behavior · weight 10 · T1071.001 Application Layer Protocol: Web Protocols (Command and Control)

  • The webshell was located, so containment removes the interactive re-entry path.

    behavior · weight 10 · T1505.003 Server Software Component: Web Shell (Persistence)

  • The compromised web tier host is isolated at end state.

    behavior · weight 15 · T1190 Exploit Public-Facing Application (Initial Access)

  • The web identity the shell executed as is disabled pending rebuild.

    behavior · weight 10 · T1078 Valid Accounts (Defense Evasion)

  • Root cause is recorded as the unpatched portal version carrying the upload advisory.

    explanation · weight 10 · T1190 Exploit Public-Facing Application (Initial Access)

  • A post-incident timeline was filed: upload, shell execution, preload hook, beacon, containment.

    explanation · weight 15 · T1190 Exploit Public-Facing Application (Initial Access)

  • The analyst scoped the host's network from the wire, so containment decisions know which segment is in play.

    investigation · weight 5

  • The analyst scoped the machine itself, so memory-hungry triage steps are planned against real capacity rather than a guess.

    investigation · weight 3

  • Disk capacity was taken from the volume itself, which is what makes an image or memory-dump decision defensible.

    investigation · weight 3

Common mistakes

  • Trusting `ps` and `ls` output on a host whose loader has been hijacked, without noting the caveat.
  • Filing the webshell's URL path instead of its full filesystem path.
  • Removing the webshell but leaving /etc/ld.so.preload and the library in place.
  • Isolating the database host, which was never compromised.

Same idea, three vendors

Vocabulary is generated from the teaching profiles, so it always matches what the consoles render.

ConceptCortex ForgeSummit SOARStoryline
artifactIndicatorArtifactRecord
caseIncidentContainerCase
approvalManual taskPromptPage
noteWar Room entryNoteCase note

Where does this value come from?

The same reference to an enrichment node's verdict, written three ways:

  • Cortex Forge: ${enrich-sender.verdict}
  • Summit SOAR: enrich-sender.verdict
  • Storyline: <<enrich-sender.verdict>>

The same concepts in shipping products

The consoles you practice in use teaching names. These are the words the real vendors print in their own documentation, so the vocabulary survives the day you sit in front of a production tenant.

ConceptCortex XSOARXSOAR 8.xSplunk SOARSplunk SOAR 6.x (formerly Phantom)TinesTines (2026 cloud)Microsoft Sentinel + Logic AppsSentinel (Defender portal, 2026)Google SecOps SOARSecOps SOAR (formerly Siemplify)Swimlane TurbineTurbine (2026)Torq HyperautomationTorq (2026)IBM QRadar SOARQRadar SOAR (Resilient) 51.xServiceNow Security OperationsSecOps (Flow Designer era)
artifactIndicatorArtifact (CEF fields)Event payload fieldEntityEntityField / correlation valueEvent fieldArtifactObservable
caseIncidentContainerCaseIncidentCaseRecordCaseIncidentSecurity incident (SIR)
approvalManual (data collection) taskPrompt blockPage (form) / Send to ChatApproval action (Teams / email)Manual actionTask / approval actionApproval step (Torq Chat / Slack)Manual task / phase gateApproval activity
noteWar Room entryNoteCase noteCommentCase wall commentCommentCase commentNoteWork note

What transfers

When host tooling and network data disagree, believe the network. Off-box evidence survives on-box tampering.