Browse CTFs New CTF Sign in

Reconstructing IRC Sessions via Protocol PCAP Analysis and Channel Message Content Recovery

osint_collection Difficulty 1–5 30 min certifiable

Theory

Why This Matters

IRC remains the protocol of choice for legacy botnets (Storm, Conficker, Mirai precursors) and underground communities. Forensic captures from compromised systems in APT investigations and CTF challenges frequently contain IRC sessions where attackers issued commands, exfiltrated data in PRIVMSG payloads, or coordinated activity through shared channels. The plaintext nature of standard IRC makes captures highly readable once filtered — analysts who know the protocol's command structure can reconstruct an entire attacker interaction from a TCP stream in minutes.

Core Concept

IRC (Internet Relay Chat) is a plaintext line-oriented protocol typically running on port 6667 (unencrypted) or 6697 (TLS). Each line is a message terminated by . Key commands:

  • NICK <nickname> — client sets its display name.
  • USER <username> <mode> * :<realname> — client registration.
  • JOIN #<channel> — client joins a channel.
  • PRIVMSG #<channel> :<message> — client sends a message to a channel or user.
  • PART #<channel> — client leaves a channel.
  • QUIT :<reason> — client disconnects.
  • MODE #<channel> +o <nick> — grant operator status.
  • TOPIC #<channel> :<topic> — set channel topic (often used by bots for C2 commands).

Server responses use numeric codes: 001 (RPL_WELCOME), 332 (RPL_TOPIC), 353 (RPL_NAMREPLY — channel member list), 433 (ERR_NICKNAMEINUSE).

Bot behaviour indicators: identical PRIVMSG content sent to multiple channels in rapid succession; automated NICK registration with a pattern (e.g., bot_[random]); JOIN immediately followed by PRIVMSG to the channel without any human typing delay; TOPIC changes carrying commands (e.g., !exec cmd, !flood target); multiple TCP sessions from the same IP with different nicknames.

Technical Deep-Dive

# Display all IRC traffic from a PCAP
tshark -r capture.pcap -Y "irc" 
  -T fields -e frame.number -e frame.time_relative 
  -e ip.src -e ip.dst 
  -e irc.request -e irc.response 
  -E header=y

# Extract PRIVMSG content specifically
tshark -r capture.pcap 
  -Y "irc.request contains "PRIVMSG"" 
  -T fields -e frame.time_relative -e ip.src 
  -e irc.request

# Extract all client commands (requests only)
tshark -r capture.pcap -Y "irc.request" 
  -T fields -e frame.time_relative -e ip.src -e irc.request 
  | sort

# Follow a specific IRC TCP stream to read the full session
# First identify the stream index:
tshark -r capture.pcap -Y "tcp.port == 6667" 
  -T fields -e tcp.stream | sort -u

# Then export that stream as text:
tshark -r capture.pcap -q -z "follow,tcp,ascii,<stream_index>"
# Extract all channel names and nicknames
tshark -r capture.pcap -Y "irc.request contains "JOIN"" 
  -T fields -e irc.request | grep -oP "JOIN KS+"

tshark -r capture.pcap -Y "irc.request contains "NICK"" 
  -T fields -e irc.request | grep -oP "NICK KS+"

# Detect bot timing: measure inter-PRIVMSG delta for same source IP
tshark -r capture.pcap 
  -Y "irc.request contains "PRIVMSG"" 
  -T fields -e frame.time_epoch -e ip.src 
  | awk 'BEGIN{prev=0; previp=""}
    {
      if ($2==previp && prev>0) printf "delta=%.3fs src=%s
", $1-prev, $2
      prev=$1; previp=$2
    }'
#!/usr/bin/env python3
"""
Parse IRC TCP stream (raw text extracted via tshark follow) and
reconstruct per-channel conversation with timestamps.
"""
import re, sys

# Input: output of tshark -q -z "follow,tcp,ascii,N" piped to stdin
PRIVMSG_RE = re.compile(r':(?P<nick>[^!]+)![^s]+ PRIVMSG (?P<target>S+) :(?P<msg>.+)')
JOIN_RE    = re.compile(r':(?P<nick>[^!]+)![^s]+ JOIN :?(?P<channel>S+)')
TOPIC_RE   = re.compile(r':(?P<nick>[^!]+)![^s]+ TOPIC (?P<channel>S+) :(?P<topic>.+)')

channels = {}   # channel -> list of (nick, msg)
nicks_seen = set()

for line in sys.stdin:
    line = line.rstrip()

    m = JOIN_RE.match(line)
    if m:
        channels.setdefault(m.group("channel"), [])
        nicks_seen.add(m.group("nick"))
        continue

    m = PRIVMSG_RE.match(line)
    if m:
        target = m.group("target")
        channels.setdefault(target, []).append((m.group("nick"), m.group("msg")))
        continue

    m = TOPIC_RE.match(line)
    if m:
        print(f"[TOPIC] {m.group('channel')} set by {m.group('nick')}: {m.group('topic')}")

print(f"
Nicknames observed: {sorted(nicks_seen)}")
for channel, msgs in channels.items():
    print(f"
=== {channel} ({len(msgs)} messages) ===")
    for nick, msg in msgs:
        print(f"  <{nick}> {msg}")

Analytical Methodology

  1. Apply Wireshark display filter irc or tcp.port == 6667 to isolate IRC traffic. If the capture contains TLS on port 6697, first apply SSLKEYLOGFILE decryption.
  2. Identify the NICK and USER commands at the start of each session to determine the nickname(s) and username(s) used by the client. Multiple sessions with different nicks from the same IP are a strong bot indicator.
  3. Follow each distinct IRC TCP stream using Wireshark → Right-click → Follow → TCP Stream. The plain-text conversation appears in the stream window. Read the JOIN commands to identify channels the client entered.
  4. Extract all PRIVMSG commands. For each, note: sender nick, target (channel or user), message content, and timestamp. Messages arriving at precise intervals (< 500ms variance) suggest automation.
  5. Examine TOPIC commands. Botnets frequently encode C2 commands in channel topics — the bot master sets the topic to !attack 1.2.3.4 80 and all connected bots read the topic on join and execute the command.
  6. Identify bot command-response patterns: a PRIVMSG from the master containing !<command> followed by multiple PRIVMSG replies from different nicks within seconds. Each reply represents a separate infected host reporting back.
  7. Reconstruct the attacker interaction timeline: NICK/USER (connect), JOIN (enter C2 channel), TOPIC/PRIVMSG (issue commands), responses (bot activity), PART/QUIT (disconnect). This forms the incident narrative.
  8. Correlate IRC nicknames with source IPs. If multiple IPs share a nickname pattern (e.g., victim_ prefix) and all join the same channel, enumerate all IPs — each represents a compromised host.

Common Analytical Errors

  • Filtering only on port 6667: IRC servers commonly run on non-standard ports (7000, 8080, 31337) to evade port-based filtering. Use the irc protocol dissector filter rather than tcp.port == 6667 alone; Wireshark heuristically detects IRC on arbitrary ports.
  • Missing server numeric responses: IRC server responses (numeric codes like 001, 332, 353) contain valuable information — channel topic at join time, member list, server name. Analysts focused only on client commands miss this context.
  • Confusing NOTICE with PRIVMSG for bot commands: Some botnets use NOTICE rather than PRIVMSG to issue commands (NOTICE is not echoed back to the sender in standard IRC, making it more stealthy). Filter for irc.request contains "NOTICE" as well.
  • Overlooking DCC (Direct Client-to-Client): DCC SEND in a PRIVMSG establishes a direct TCP file transfer. A DCC SEND <filename> <ip_decimal> <port> <size> message in a PRIVMSG indicates a file transfer offer — extract the IP, port, and filename from the DCC parameters and correlate with other TCP streams in the PCAP.

NICE Framework Alignment

Code Knowledge/Skill/Task Statement How This Card Develops It
K0046 Knowledge of intrusion detection systems and methodologies IRC C2 channel detection is a foundational botnet IDS detection use case
K0093 Knowledge of network protocols Understanding IRC message format, numeric codes, and client-server exchange structure
K0221 Knowledge of OSI model and network layers IRC operates at layer 7 over TCP at layer 4; stream reassembly is required for complete message recovery
S0046 Skill in performing packet-level analysis Applying IRC-specific tshark filters and TCP stream following to reconstruct bot command interactions
T0023 Collect intrusion artifacts for use in forensic analysis IRC channel logs and bot command records are forensic artifacts establishing attacker objectives and botnet scope

Further Reading

  • RFC 1459: Internet Relay Chat Protocol — original IRC specification with full command reference
  • SANS ISC: "IRC Botnet Traffic Analysis" handler diary entries
  • Wireshark Wiki: IRC protocol dissector documentation
  • Mandiant/FireEye: "IRC Botnets — Anatomy of a Classic C2 Infrastructure" (threat report)
  • CTF Wiki: IRC protocol challenge techniques and common encoding patterns in PRIVMSG payloads

Challenge Lab

Reinforce your learning with a hands-on generated challenge based on this card's competency.