24 of 365 catalog rows 404 on 'get' (LOCATION typos + filename mismatches); 1 sample missing
Verified at commit 48515e492013bc5bb2769249ea539436bb3e733f (v0.7.1 'Moat').
Summary
Updater.get_malware() builds a raw URL as {LOCATION}/{basename}.zip from conf/maldb.db.
For 25 / 365 rows (6.8%) that path does not exist in the repo, so get fails and prints the
tool's own diagnostic "Probably path name in git vs. sqlite does not match."
Proof (live HEAD probes against raw.githubusercontent.com/ytisf/theZoo/master/):
| path probed | result |
|---|---|
malware/Binraies/Win32.Vobfus/Win32.Vobfus.zip (DB) |
HTTP 404 |
malware/Binaries/Win32.Vobfus/Win32.Vobfus.zip |
HTTP 200 |
malware/Binaries/WinX.SignSight/WinX.SignSight.zip (DB-named) |
HTTP 404 |
malware/Binaries/WinX.SignSight/WinX.%20SignSight.zip (real, contains a space) |
HTTP 200 |
Class A — directory typo Binraies (5 rows)
LOCATION says malware/Binraies/…; the real directory is malware/Binaries/….
Transposition breaks all four sidecars for:
| ID | Name |
|---|---|
| 93 | Vobfus (Win32.Vobfus) |
| 94 | Wirenet (Linux.Wirenet) |
| 95 | Wirenet (OSX.Wirenet) |
| 96 | Narilam (Win32.Narilam) |
| 107 | Asprox (Trojan.Asprox) |
Class B — inner filename does not equal directory name (19 rows)
get derives the archive name from the last path segment, so any mismatch 404s:
| ID | DB LOCATION |
archive on disk |
|---|---|---|
| 2 | …/ExploitKit.Crimepack.3.1.3 |
ExploitKit.CrimePack.3.1.3.zip |
| 62 | malware/Binaries/ZeroLocker |
Zerolocker.zip |
| 68 | …/ExploitKit.Blackhole.100 |
ExploitKit.BlackHole.100.zip |
| 69 | …/ExploitKit.Blackhole.102 |
ExploitKit.BlackHole.102.zip |
| 77 | malware/Binaries/Trojan.AlienSpy |
Trojan.Alienspy.zip |
| 98 | …/ExploitKit.Fargus |
ExploitKit.Fragus.zip |
| 115 | malware/Source/Reversed/Whore_Feb2006 |
Win32.Whore_Feb2006/Win32.Whore.Feb.2006.zip |
| 143 | …/EngRat |
EngRat.0.1.0.zip |
| 148 | …/ZIB_Trojan |
ZIB-Trojan.zip |
| 168 | malware/Binaries/OSX.AdWare.MacSecurity |
OSX.MacSecurity/OSX.MacSecurity.zip |
| 174 | …/Win32.APT32.Windshield |
Win32.APT32.Windshield/Win32.APT32.WindShield.zip |
| 187 | …/Win32.GravityRAT |
Win32.GravityRat/Win32.GravityRAT.zip |
| 199 | …/Win32.LeoxBot1.3 |
Win32.LoexBot1.3/Win32.LoexBot1.3.zip |
| 297 | …/Win32.Turla.V1 |
Win32.Turla.V1/Win32.Turla.v1.zip |
| 311 | malware/Binaries/Coll.Coll.DarkHydrus |
Coll.DarkHydrus/Coll.DarkHydrus.zip (prefix doubled) |
| 322 | malware/Source/Reversed/SpyNote_5.0 |
SpyNote5.0.zip |
| 336 | malware/Binaries/WinX.SignSight |
WinX. SignSight.zip (space in filename) |
| 350 | …/Win32.Talerat |
Win32.Taleret/Win32.Taleret.zip |
Class C — no archive present (1 row) / ambiguous (1 row)
- ID 337
StealthyTrident(malware/Binaries/Win64.StealthyTrident) — no archive exists in the tree at this commit. (Win32.Salityis an unrelated family; not a rename.) - ID 192
Dendroid(malware/Source/Original/Android.Dendroid) — ambiguous: the tree hasAndroid.Dendriod/Android.Dendroid.zip(dir typo),Android.Dendroid.B/Android.Dendroid.B.zipandDendroid/Dendroid.zip.
Suggested fix
- Correct the 24
LOCATIONvalues above, or makegetresilient: resolve{LOCATION}/*.zipfrom the tree (case-insensitive, whitespace-tolerant) instead of assumingbasename. - Add a CI check that every
LOCATIONresolves to an archive, so this cannot regress. - Separately:
get_malware()downloads.md5/.sha256but never verifies the digest against the archive — worth adding before reporting success.
Reproduce with analyze_zoo.py / report_zoo.py; the full machine-readable map (25 rows, with
per-row tree_location, tree_archive, and class) is in broken-locations.json.
Counts: 5 (Class A, IDs 93/94/95/96/107) + 18 (Class B) + 1 absent (337) + 1 ambiguous (192) = 25 rows = 6.8% of the 365-row catalogue. Repairable: 24 (23 clear + the ambiguous 192).
Source: ytisf/theZoo