Turn a findings export into a fix-first list
Task
Take a set of vulnerability findings, add the context a base score lacks -- known exploitation, exposure, asset criticality and compensating controls -- and produce a ranked list whose order you can defend. Then judge one threat feed against the four tests from the lesson.
Steps
- Write
/tmp/findings.csvwith the headerid,host,cvss,kev,internet_facing,asset_criticality,compensatingand at least ten rows.cvssis a base score;kevis yes or no (listed as known exploited);internet_facingis yes or no;asset_criticalityis 1 to 3, where 3 means it holds regulated data or runs something the business stops without;compensatingnames an existing control or saysnone. - Make sure the set contains the pair the exam likes: at least one internet-facing, known-exploited medium (4.0 to 6.9) and at least one internal critical (9.0 or above) with no known exploitation.
- Sort by
cvssalone, highest first, and write the ids in that order to/tmp/order-score.txt, one per line. - Write
/tmp/rank.py: compute a priority for each row from the context, not just the score, and write the ids in priority order to/tmp/order-context.txt. Any weighting you can defend is acceptable, provided known exploitation and internet exposure each outweigh a difference of a few CVSS points, and a named compensating control lowers urgency without removing it. - For the top three in your context order, write one sentence each in
/tmp/rationale.mdsaying why it outranks the highest-scoring finding it beat. Add a line saying which of your context columns move likelihood and which move impact. - Choose one feed or advisory source you could realistically use -- a national CERT's advisories, a vendor's bulletins, your sector's sharing group -- and review it in
/tmp/feed-review.mdunder four headings: Timeliness, Relevance, Accuracy and Confidence. One paragraph each: what you would check, and what would make you stop trusting it.
Verify
head -4 /tmp/order-score.txt /tmp/order-context.txt
python3 - <<'PY'
import csv
rows = {r['id']: r for r in csv.DictReader(open('/tmp/findings.csv'))}
assert len(rows) >= 10, 'fewer than ten findings'
score = [l.strip() for l in open('/tmp/order-score.txt') if l.strip()]
ctx = [l.strip() for l in open('/tmp/order-context.txt') if l.strip()]
assert sorted(score) == sorted(ctx) == sorted(rows), 'both orders must rank exactly the same findings'
assert score != ctx, 'context changed nothing - the ranking is still score order'
def yes(r, k):
return r[k].strip().lower() in ('yes', 'y', 'true')
med = [i for i, r in rows.items() if yes(r, 'kev') and yes(r, 'internet_facing') and 4.0 <= float(r['cvss']) < 7.0]
crit = [i for i, r in rows.items() if not yes(r, 'kev') and not yes(r, 'internet_facing') and float(r['cvss']) >= 9.0]
assert med and crit, 'the exploited exposed medium / quiet internal critical pair is missing'
assert max(ctx.index(i) for i in med) < min(ctx.index(i) for i in crit), 'an internal critical still outranks an exploited, exposed medium'
print('top three by score:', score[:3], '| top three by context:', ctx[:3])
PY
grep -ciE "^#+ *(timeliness|relevance|accuracy|confidence)" /tmp/feed-review.md
The assertions test the lesson's central claim against your own ranking: the context order must differ from the score order, and every exploited, internet-facing medium must sit above every quiet internal critical. If that last assertion fails, your weighting still lets the base score win. The grep must print 4, one heading for each test of a feed.
Notes
Look at which columns moved items furthest. Known exploitation and exposure change likelihood; asset criticality changes impact; a compensating control changes likelihood without fixing anything. That split is how the risk register in Domain 5 will ask you to think, and the vulnerability management lesson in Domain 4 takes the ranked list on to remediation and validation.
This is an independent study companion for CompTIA Security+ SY0-801 and is not produced by or endorsed by CompTIA.