Cyber Security Quiz: Log Parsing Scripts
9 questions · exam conditions
0:00
Log Parsing ScriptsQuestion 1 of 9

Two systems record related events using ISO 8601 timestamps:

2026-07-08T12:02:00+02:00 source=203.0.113.8 action=connect

2026-07-08T10:04:00Z source=203.0.113.8 action=download

A script must determine whether the events occurred within five minutes of one another.

Which timestamp-handling method produces a reliable result?

Sort the original timestamp strings lexicographically, then subtract only their displayed minute components.
Remove the offsets, parse both timestamps as local time, and compare the resulting naive datetime values.
Parse both timestamps as offset-aware values, normalize them to UTC, and compare their elapsed time.
Treat the Z value as local time and add the other record's offset before comparing the hour fields.
← Back to quizzes

Cyber Security Quiz

Cyber Security Quiz: Log Parsing Scripts

Practice Log Parsing Scripts in Cyber Security with focused quiz questions that help you check what you know, review explanations, and build confidence with test-style prompts.

What this quiz covers

This quiz focuses on Log Parsing Scripts, giving you a quick way to practice the rules, question types, and explanations that matter most for Cyber Security.

How to use this quiz

Try each quiz question before looking at the correct answer. Use the explanations to review missed ideas, then come back to similar questions until the pattern feels familiar.

All questions

Question 1

Two systems record related events using ISO 8601 timestamps:

2026-07-08T12:02:00+02:00 source=203.0.113.8 action=connect

2026-07-08T10:04:00Z source=203.0.113.8 action=download

A script must determine whether the events occurred within five minutes of one another.

Which timestamp-handling method produces a reliable result?

  1. Sort the original timestamp strings lexicographically, then subtract only their displayed minute components.
  2. Remove the offsets, parse both timestamps as local time, and compare the resulting naive datetime values.
  3. Parse both timestamps as offset-aware values, normalize them to UTC, and compare their elapsed time. (correct answer)
  4. Treat the Z value as local time and add the other record's offset before comparing the hour fields.
Explanation: Whenever you see a question involving timestamps from multiple sources, your first instinct should be: are these timestamps in the same time zone? If they aren't, any comparison that skips normalization will produce garbage results. Look at the two timestamps: 2026-07-08T12:02:00+02:00 is noon in a UTC+2 zone, which equals 10:02:00Z in UTC. The second timestamp is 2026-07-08T10:04:00Z, already in UTC. The true difference is 10:0410:02=2 minutes|10{:}04 - 10{:}02| = 2 \text{ minutes}, well within the five-minute window. Option C is correct precisely because it parses both values as offset-aware datetimes, converts them to a common baseline (UTC), and then computes the actual elapsed time — giving you that reliable 2-minute result. Option A fails on two levels: lexicographic string sorting doesn't respect time zones, and extracting only the "minute component" (02 vs. 04) ignores hours entirely, making cross-hour comparisons completely wrong. Option B strips the offsets before converting, turning both timestamps into naive datetimes — the +02:00 offset disappears, so the script incorrectly treats 12:02 and 10:04 as if they share the same zone, yielding a false 118-minute gap. Option D invents its own ad hoc arithmetic by treating Z as local time and manually adding the other offset, which is backwards and produces nonsensical results; Z means UTC, not local time. Study tip: In any forensic or log-correlation scenario, always normalize timestamps to UTC before comparing. The phrase "offset-aware" in answer choices is a strong signal you're on the right track — naive datetimes are a classic trap on security exam questions involving multi-source event correlation.

Question 2

A log contains these IPv6 indicators:

2001:0db8:0:0:0:0:0:1

2001:db8::1

::ffff:192.0.2.10

::ffff:c000:20a

The script must emit each distinct IP address once, even when equivalent addresses use different valid textual forms.

Which deduplication method best satisfies the requirement?

  1. Convert each extracted string to lowercase and use the resulting text as the set key.
  2. Remove every zero and colon from each address and use the remaining characters as the set key.
  3. Parse each string as an IP address and deduplicate on its normalized numeric value. (correct answer)
  4. Preserve the original strings and deduplicate only when two log entries are textually identical.
Explanation: When working with IP address deduplication, the core challenge is that a single IP address can be legally represented in multiple textually different but semantically identical ways. IPv6 especially allows compressed forms, leading zeros to be omitted, and even embedded IPv4 notation — so string comparison alone will always fail you here. The right approach is C: parse each string into its underlying numeric value (a 128-bit integer for IPv6) and use that as your deduplication key. When you normalize 2001:0db8:0:0:0:0:0:1 and 2001:db8::1 this way, both resolve to the exact same 128-bit address. Similarly, ::ffff:192.0.2.10 and ::ffff:c000:20a are both IPv4-mapped IPv6 addresses pointing to 192.0.2.10 — identical numerically, different textually. Most languages expose this through socket or IP-parsing libraries (Python's ipaddress.ip_address(), for example). A fails because case normalization only helps with hex digits like A vs a — it does nothing to reconcile 0db8 vs db8 or 0:0:0:0 vs ::. These pairs remain different strings even in lowercase. B is dangerous: stripping zeros and colons destroys the address structure entirely. db8 and 0db8 may produce collisions between addresses that are actually distinct, corrupting your dataset. D is the naive approach that the question is explicitly warning against — it treats 2001:0db8::1 and 2001:db8::1 as different addresses when they are the same. The takeaway: whenever you see deduplication + IP addresses on a security exam, the answer almost always involves semantic equivalence at the network layer, not syntactic string comparison.

Question 3

After extracting an HTTP request target from a web log, a script receives:

/redirect?ioc=http%3A%2F%2Fevil.example%2Fa%252Fb&user=analyst

The script must retrieve the ioc parameter and apply the normal single layer of URL decoding. It should therefore preserve an encoded slash that was originally represented as %252F.

Which parsing sequence is most appropriate?

  1. Split the target into URL components, parse its query string, and use the once-decoded ioc value. (correct answer)
  2. Extract the ioc substring and repeatedly URL-decode it until no percent sequences remain.
  3. Search the raw target for ioc=, stop at the next &, and emit the still-percent-encoded substring without decoding.
  4. URL-decode the entire target string first, then split the decoded text at & and = characters to identify parameters.
Explanation: When parsing URLs that may contain double-encoded characters, the order of operations matters enormously. A single misplaced decode can collapse two distinct encoding layers into one, permanently losing structural information you need to preserve. The URL /redirect?ioc=http%3A%2F%2Fevil.example%2Fa%252Fb&user=analyst contains a critical detail: %252F is a percent-encoded %2F, which is itself an encoded slash. One round of decoding should yield %2F — a literal percent-slash sequence — not /. Answer A handles this correctly: you first split the target into its components (path vs. query string), then parse the query string using standard library tools that apply exactly one decoding pass. The resulting ioc value becomes http://evil.example/a%2Fb, preserving the encoded slash as intended. This is the appropriate, safe sequence. Answer B is dangerous because repeatedly decoding until no percent sequences remain would turn %252F into %2F and then into /, collapsing the double-encoding and potentially misrepresenting a path component — a classic double-decode vulnerability that attackers exploit to bypass filters. Answer C avoids decoding entirely, which sounds cautious but leaves you with raw percent sequences your downstream logic likely cannot use correctly. Skipping the decode step isn't "safe" — it just shifts the parsing error elsewhere. Answer D decodes the entire target before splitting on & and =, which is exactly backwards. Decoding first can introduce literal & or = characters from encoded values, corrupting the parameter boundaries you rely on to isolate fields. As a study tip: always structure first, decode second — parse the URL hierarchy before applying any decoding, and apply only as many decoding passes as the protocol layer requires.

Question 4

Authentication logs from several collectors are merged into one file, so records are not guaranteed to be in chronological order. A script must alert when the same source IP produces at least three failed logins within any rolling five-minute interval. Timestamps include offsets, and successful logins do not count as failures.

Which algorithm most accurately implements the rule?

  1. Process records in file order and compare each failure only with the two failures immediately preceding it.
  2. Count failures per source in fixed five-minute clock buckets and alert when a bucket reaches three.
  3. Sort all failures by normalized time and maintain one five-minute queue shared by every source address.
  4. Normalize and sort failures by time, then maintain a rolling five-minute queue separately for each source. (correct answer)
Explanation: When designing detection logic for rate-based alerts, you need to think carefully about three independent problems: time normalization, data ordering, and per-entity isolation. Collapsing any of these into a shortcut will produce missed detections or false negatives. The correct approach, answer D, handles all three. First, it normalizes timestamps (converting timezone offsets to a common reference), then sorts failures chronologically so the rolling window reflects real time rather than file order. Critically, it maintains a separate queue for each source IP. For any given source, you slide a window forward and alert the moment the queue holds three entries spanning five minutes or fewer. This precisely matches the rule as stated. Answer A fails immediately because the logs are explicitly described as out of order. Comparing only the two preceding records in file order means you could miss three failures that are chronologically adjacent but scattered throughout the file. The logic is structurally broken before it even starts. Answer B uses fixed clock buckets (e.g., 00:00–00:05, 00:05–00:10), which creates a classic boundary problem: two failures at 00:04 and one at 00:06 span only two minutes in real time but land in separate buckets and never trigger the alert. Fixed windows cannot implement a rolling interval rule. Answer C normalizes and sorts correctly but then shares one queue across all sources. This means failures from different IPs get mixed together, making it possible for IP-A's failures and IP-B's failures to collectively trigger an alert that neither source earned alone. The strategy to remember: any "rolling window per entity" problem requires both time normalization and per-entity state. If either is missing, the algorithm is wrong regardless of how elegant everything else looks.

Question 5

A newline-delimited JSON file contains mostly records such as:

{"event":{"file":{"sha256":"9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"}}}

Some lines are malformed JSON, some omit event.file.sha256, and some contain a longer hexadecimal string in that field. The script should continue processing and emit only fields that consist of exactly 64 hexadecimal characters.

Which implementation strategy is most appropriate?

  1. Parse each line and directly index obj['event']['file']['sha256']; terminate when any exception occurs.
  2. Search the raw line for any run of 64 hexadecimal characters and emit the first matching substring.
  3. Retrieve the nested field with defaults and emit it whenever its string length is exactly 64 characters.
  4. Catch JSON decoding errors, safely retrieve the nested field, and apply a full-match check for 64 hexadecimal characters. (correct answer)
Explanation: When processing untrusted, potentially malformed data, you need three independent defenses: handle parse failures, handle missing fields, and validate the field's content. A question like this is testing whether you understand that each defense targets a different failure mode — and that all three are necessary. Option D combines all three correctly. It catches json.JSONDecodeError so malformed lines don't crash the program, uses safe traversal (e.g., .get() chaining) so missing nested keys return None instead of raising KeyError, and applies a full-match regex like re.fullmatch(r'[0-9a-fA-F]{64}', value) to confirm the field is exactly 64 hex characters — not just any 64-character string. Option A fails immediately because directly indexing obj['event']['file']['sha256'] raises KeyError if any key is absent, and the instruction to terminate on any exception means one bad line kills the whole job. That's the opposite of resilient processing. Option B is tempting but subtly wrong. Searching the raw line with a substring match skips JSON parsing entirely, which means you might extract a hex run from a field name, a comment, or even an unrelated value. It also matches substrings, so a 128-character hash could yield a false positive by matching its first 64 characters. Option C gets closer but is incomplete. Checking len(value) == 64 doesn't confirm the characters are hexadecimal — a 64-character string like "zzzz...zzzz" would pass. The key study takeaway: whenever you see data-pipeline questions, ask yourself whether the solution handles each failure mode independently — parsing, structure, and content validation are three separate concerns, not one.

Question 6

A script searches arbitrary log text for SHA-256 indicators. A valid indicator may be adjacent to punctuation or an underscore, as in sha256_<64 hex characters>_source. However, the script must not extract a 64-character substring from a run of 65 or more hexadecimal characters.

Which regex design best enforces these requirements?

  1. Use \b[0-9A-Fa-f]{64}\b so word boundaries surround every accepted hash.
  2. Use [0-9A-Fa-f]{64} and keep the first match found on each physical line.
  3. Use (?<![0-9A-Fa-f])[0-9A-Fa-f]{64}(?![0-9A-Fa-f]) for candidate extraction. (correct answer)
  4. Use [^0-9A-Fa-f][0-9A-Fa-f]{64}[^0-9A-Fa-f] and return the entire match.
Explanation: When extracting fixed-length hex strings from unstructured text, your regex must solve two distinct problems simultaneously: it must tolerate non-hex neighbors (like underscores or punctuation), and it must reject runs of 65 or more hex characters. These two constraints together point directly toward lookaround assertions. Option C, (?<![0-9A-Fa-f])[0-9A-Fa-f]{64}(?![0-9A-Fa-f]), is the correct design. The negative lookbehind (?<![0-9A-Fa-f]) confirms that the character immediately before the match is not hex, and the negative lookahead (?![0-9A-Fa-f]) confirms the same after. Crucially, lookarounds are zero-width — they inspect context without consuming characters. This means a preceding underscore or punctuation mark passes freely, satisfying the adjacency requirement, while any 65th hex digit causes the entire match to be rejected. Option A fails because \b is a boundary between a word character (\w) and a non-word character. Since underscore is itself a word character, \b would not fire between an underscore and a hex digit, breaking the sha256_<hash>_source case. Option B is dangerous: keeping only the first match on a line doesn't prevent substrings being pulled from a 65-character run — it just blindly accepts the first 64 characters it sees. Option D uses consuming characters on both sides ([^0-9A-Fa-f]), which means the surrounding delimiter characters are swallowed into the match and the actual boundaries of adjacent hashes could be missed entirely. Your study tip: whenever a pattern has strict length isolation requirements, reach for negative lookaheads and lookbehinds rather than word boundaries — \b is tied to \w, which includes underscore and can silently break hex-extraction patterns.

Question 7

A security product exports CSV records with this header and data:

time,source,message,indicator

2026-07-08T12:00:00Z,192.0.2.8,"Login failed, account disabled",bad.example

The message field may contain commas, doubled quotes, or embedded line breaks permitted by CSV quoting. The script must extract the source and indicator columns.

Which approach is most reliable?

  1. Read records with a CSV parser configured for the file's dialect and access fields by header name. (correct answer)
  2. Split each physical line on commas and select the second and fourth resulting elements.
  3. Replace commas inside the first pair of double quotes, then split the modified line on commas.
  4. Use a regex that captures all noncomma text between the first, second, and third commas.
Explanation: Whenever you see a question about parsing structured data, ask yourself: does the format have an official specification, and could the data contain edge cases that break naive assumptions? CSV looks deceptively simple, but RFC 4180 explicitly allows quoted fields to contain commas, embedded newlines, and escaped quotes — all of which appear in this scenario. A proper CSV parser handles every one of these edge cases automatically because it understands the quoting rules of the dialect. Option A is the correct approach: using a purpose-built CSV library (like Python's csv module) and accessing columns by header name means your script remains correct even when the message field contains commas, doubled quotes, or spans multiple physical lines. It's robust by design. Option B fails immediately on this sample data. Splitting "Login failed, account disabled" on commas produces more than four elements, so "the fourth element" is no longer the indicator — it's a fragment of the message. This is the classic naive-split trap. Option C attempts a partial fix by replacing commas inside the first quoted region, but it only handles one quoted field, assumes the quote appears in a predictable position, and breaks entirely if quotes appear elsewhere or if the field contains escaped quotes. It's a brittle patch, not a solution. Option D shares the same fundamental flaw as B and C: a regex built around "noncomma text" cannot distinguish a comma that is a field delimiter from one that lives inside a quoted field. Study tip: On security and scripting questions, always prefer a library that implements the full specification over hand-rolled parsing. If a format has an RFC or standard, there's almost certainly a battle-tested parser available — use it.

Question 8

A log may contain the following strings:

source=198.51.100.27

peer=999.12.4.8

host=10.0.0.7.example.net

The script must extract syntactically valid IPv4 indicators, but it must not extract an address-like substring from a hostname.

Which approach best meets the requirement?

  1. Use \b(?:\d{1,3}\.){3}\d{1,3}\b and accept every match returned by the regex, since word boundaries reliably exclude hostnames.
  2. Find bounded dotted-decimal candidates, then validate each with an IP-address parser to confirm octet range and reject hostname substrings. (correct answer)
  3. Split each line at periods and accept four consecutive fields whenever every field contains only decimal digits, regardless of surrounding context.
  4. Use (?:25[0-5]\.){3}25[0-5] so that each octet is constrained and hostname substrings are automatically excluded.
Explanation: When extracting structured indicators like IP addresses from raw logs, you need to think in two stages: detection (find candidates) and validation (confirm they're real). Questions like this test whether you understand why regex alone is often insufficient for reliable data extraction. The right approach is B because it combines the strengths of pattern matching with semantic validation. A regex finds dotted-decimal candidates efficiently, but a proper IP parser then checks two things regex struggles with alone: that each octet falls within 0–255, and that the match isn't embedded inside a hostname string like 10.0.0.7.example.net. The parser can inspect surrounding context and reject malformed candidates programmatically. A is flawed because \b (word boundaries) treat dots as non-word characters, so the boundary anchors on the digits adjacent to dots — meaning a hostname like 10.0.0.7.example.net can still yield a partial match. Word boundaries do not reliably exclude hostname substrings as the distractor claims. C fails because splitting on periods and checking for four consecutive digit fields ignores surrounding context entirely. The string 10.0.0.7.example would produce digit fields mixed with non-digit fields, but variations could slip through, and there's no octet-range check whatsoever. D is tempting because it constrains the leading octet to 250–255, but this only matches a tiny fraction of valid IP addresses (those starting with 250–255). It would miss 10.0.0.7, 192.168.1.1, and most real-world addresses entirely. As a study strategy, remember: regex finds shape, parsers confirm meaning. Whenever a question asks about reliable extraction with semantic constraints, a two-phase detect-then-validate approach almost always wins over pure regex solutions.

Question 9

An application log begins each event with an ISO 8601 timestamp. Exception events continue onto unprefixed lines:

2026-07-08T11:00:00Z ERROR request failed for 198.51.100.9

Traceback (most recent call last):

File "handler.py", line 41, in run

ConnectionError: callback to bad.example failed

2026-07-08T11:00:04Z INFO request completed

The script must extract indicators and associate them with the correct event severity and timestamp.

Which record-processing design best preserves event context?

  1. Treat every physical line as an independent event and inherit no fields from neighboring lines.
  2. Buffer lines until the next timestamp-prefixed line, then parse the complete buffered event as one record. (correct answer)
  3. Join the entire log into one string and run a single greedy regex for timestamps and indicators.
  4. Discard all lines lacking a timestamp prefix before extracting indicators from the remaining records.
Explanation: When parsing structured logs, the core challenge is that a single logical event can span multiple physical lines. Your script needs to understand where one event ends and the next begins — not just read line by line blindly. Buffering lines until the next timestamp-prefixed line appears (answer B) is the right design because it respects how the log is actually structured. In the example, the traceback lines belong to the ERROR event at 11:00:00Z, even though they carry no timestamp of their own. By accumulating those lines into a single buffer and only flushing when a new timestamp header arrives, you preserve the full event context — severity, timestamp, IP address, and the multi-line traceback — as one cohesive record ready for indicator extraction. Answer A fails because treating every physical line as an independent event breaks the traceback apart. The ConnectionError line would be parsed in isolation, stripped of its ERROR severity and 11:00:00Z timestamp — exactly the context your script needs to associate indicators correctly. Answer C is dangerous because joining the entire log into one string and running a greedy regex risks cross-event contamination: a greedy pattern can easily "absorb" content from neighboring events, misattributing timestamps or indicators. Answer D quietly discards the most forensically valuable data — the traceback lines — which often contain the specific indicators (hostnames, error messages) you're trying to extract in the first place. A useful pattern to remember: whenever a log format uses a header line plus continuation lines, design your parser as a state machine that accumulates lines into a buffer and flushes on the next header. This mental model applies to email headers, HTTP chunked responses, and many SIEM log formats you'll encounter in security tooling.