Recently, I downloaded NSRL's RDS and associated files (version 2.0) from NIST's ftp site. # fetch ftp://ftp.nist.gov/pub/itl/div897/nsrl/ver_2_0/hashes.txt # fetch ftp://ftp.nist.gov/pub/itl/div897/nsrl/ver_2_0/nsrl_2_0.iso # fetch ftp://ftp.nist.gov/pub/itl/div897/nsrl/ver_2_0/nsrl_2_0.txt # fetch ftp://ftp.nist.gov/pub/itl/div897/nsrl/ver_2_0/read_me.txt # fetch ftp://ftp.nist.gov/pub/itl/div897/nsrl/ver_2_0/version.txt # openssl sha1 nsrl_2_0.iso SHA1(nsrl_2_0.iso)= 70ca66760007394f0dfcd98d92b5749ff7963502 # openssl md5 nsrl_2_0.iso MD5(nsrl_2_0.iso)= 41471e57cc72f6f935b7da1e7ba46d59 When I tried to mount the iso image file using FreeBSD's vnode support, I ran into trouble. Here are the commands I used and the associated error message: # vnconfig -e /dev/vn0c nsrl_2_0.iso # mount_cd9660 /dev/vn0c /cdrom mount_cd9660: /dev/vn0c: Invalid argument # vnconfig -u /dev/vn0c Needless to say, that got me fired up, and I decided that it was time to dig in and bash some bits. In situations like this, hexdump is my primary reconnaissance tool -- I use it to survey the landscape. In this particular case, the objective was to get an idea of what files are entombed in nsrl_2_0.iso. Once that was known, I could try to figure out how to extract any files of interest. # hexdump -C nsrl_2_0.iso | more ... 0000d360 00 00 89 00 00 00 89 00 30 00 17 00 00 00 00 00 |........0.......| 0000d370 00 17 00 08 00 00 00 00 08 00 67 04 07 0d 03 24 |..........g....$| 0000d380 00 02 00 00 01 00 00 01 01 00 00 00 00 00 8d 55 |...............U| 0000d390 58 41 78 00 00 00 00 00 30 00 17 00 00 00 00 00 |XAx.....0.......| 0000d3a0 00 17 00 08 00 00 00 00 08 00 67 04 07 0d 03 24 |..........g....$| 0000d3b0 00 02 00 00 01 00 00 01 01 01 00 00 00 00 8d 55 |...............U| 0000d3c0 58 41 78 00 00 00 00 00 3c 00 19 00 00 00 00 00 |XAx.....<.......| 0000d3d0 00 19 a8 00 00 00 00 00 00 a8 67 02 04 09 08 24 |..........g....$| 0000d3e0 00 00 00 00 01 00 00 01 0c 48 41 53 48 45 53 2e |.........HASHES.| 0000d3f0 54 58 54 3b 31 00 00 00 00 00 09 11 58 41 00 00 |TXT;1.......XA..| 0000d400 00 00 00 00 38 00 1a 00 00 00 00 00 00 1a f1 b6 |....8...........| 0000d410 c2 19 19 c2 b6 f1 67 02 04 08 0b 15 00 00 00 00 |......g.........| 0000d420 01 00 00 01 09 52 44 53 2e 5a 49 50 3b 31 00 00 |.....RDS.ZIP;1..| 0000d430 00 00 09 11 58 41 00 00 00 00 00 00 3c 00 71 38 |....XA......<.q8| 0000d440 03 00 00 03 38 71 07 05 00 00 00 00 05 07 67 02 |....8q........g.| 0000d450 04 09 08 24 00 00 00 00 01 00 00 01 0d 52 45 41 |...$.........REA| 0000d460 44 5f 4d 45 2e 54 58 54 3b 31 00 00 00 00 09 11 |D_ME.TXT;1......| 0000d470 58 41 00 00 00 00 00 00 3c 00 72 38 03 00 00 03 |XA......<.r8....| 0000d480 38 72 4d 00 00 00 00 00 00 4d 67 03 03 04 3b 12 |8rM......Mg...;.| 0000d490 00 00 00 00 01 00 00 01 0d 56 45 52 53 49 4f 4e |.........VERSION| 0000d4a0 2e 54 58 54 3b 31 00 00 00 00 09 11 58 41 00 00 |.TXT;1......XA..| 0000d4b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| ... After a bit of searching, I could see the string "RDS.ZIP" -- this was a good indication that there was also a zip file by that name somewhere in the image. Therefore, RDS.ZIP became my first extraction target. Knowing that zip files can potentially be identified by their file magic (0x504b0304), I constructed a DigString and used FTimes to find all offsets in the image that matched that value. # echo "digstring=PK%03%04" | ftimes --digauto - -l 6 nsrl_2_0.iso > dig.out # cat dig.out name|offset|string "/db/tmp/nsrl_2_0/nsrl_2_0.iso"|61176|PK%03%04 "/db/tmp/nsrl_2_0/nsrl_2_0.iso"|114208|PK%03%04 "/db/tmp/nsrl_2_0/nsrl_2_0.iso"|119520|PK%03%04 "/db/tmp/nsrl_2_0/nsrl_2_0.iso"|120997|PK%03%04 "/db/tmp/nsrl_2_0/nsrl_2_0.iso"|16965043|PK%03%04 "/db/tmp/nsrl_2_0/nsrl_2_0.iso"|496404907|PK%03%04 Assuming that the zip file is laid down on the CD in a sequential form and unzip ignores trailing garbage, I decided to grab everything starting at the first identified offset. The dd utility is great for this kind of thing. I did the extraction in two steps -- doing the entire extraction with bs=1 would have taken a long time. In phase one, I took just enough bytes to get to the next 512 byte boundary. In phase two, I set bs to 512 and skipped over the piece recovered in phase one. # dd if=nsrl_2_0.iso of=piece1 bs=1 skip=61176 count=`echo "2^16 - 61176" | bc` # dd if=nsrl_2_0.iso of=piece2 bs=512 skip=`echo "2^16 / 512" | bc` # cat piece[12] > whole.zip If my hypothesis was right, I should have been able to do the following: # unzip -l whole.zip Archive: whole.zip warning [whole.zip]: 64153120 extra bytes at beginning or within zipfile (attempting to process anyway) Length Date Time Name -------- ---- ---- ---- 292264 02-04-03 10:06 NSRLProd.txt 13870 02-04-03 10:07 NSRLMfg.txt 4517 02-04-03 10:07 NSRLOS.txt 1679204456 02-04-03 10:34 NSRLFile.txt 77 02-04-03 10:47 version.txt -------- ------- 1679515184 5 files That looks promising, but it's not quite right -- do you see the warning. Next, I decided to pass the dig output to ftimes-dig2ctx.pl. This was done so that I could cull out some context around each match. The hope was that there'd be some zip header information that could be used to figure out how things were put together. # ftimes-dig2ctx.pl -e hex -i 1 -c 64 -f dig.out "/db/tmp/nsrl_2_0/nsrl_2_0.iso"|61176|PK%03%04|61176|0|4|60|504b0304140000000800da50442e381aab0adeb40000a87504000c0000004e53524c50726f642e747874b47d5b73e2bab6eefba9daff418b87557bd74e686c63 "/db/tmp/nsrl_2_0/nsrl_2_0.iso"|114208|PK%03%04|114208|0|4|60|504b0304140000000800ee50442e381c69e6371200002e3600000b0000004e53524c4d66672e7478747d5b4b7322b9b2dedf88f31f7467d12bda31714ec4dd63 "/db/tmp/nsrl_2_0/nsrl_2_0.iso"|119520|PK%03%04|119520|0|4|60|504b0304140000000800f250442e3863a0876d040000a51100000a0000004e53524c4f532e7478748d974b53e3381080ef5bb5ff41c5198cfc901d1fb3400dd9 "/db/tmp/nsrl_2_0/nsrl_2_0.iso"|120997|PK%03%04|120997|0|4|60|504b03041400000008005454442e668baa2b6ce8c11968a016640c0000004e53524c46696c652e747874ccbd4b971cc79135b89f73e63ff0c36256a53af676f3 "/db/tmp/nsrl_2_0/nsrl_2_0.iso"|16965043|PK%03%04|16965043|0|4|60|504b0304cd38f79af639754f346368e4bde19609db8149420f400b86bca6dd4162e963d122887e4d427cd77c153a267bfd1b434bfaff090de5f9068601f8839d "/db/tmp/nsrl_2_0/nsrl_2_0.iso"|496404907|PK%03%04|496404907|0|4|60|504b03040a0000000000ea55442ea7e6b8f74d0000004d0000000b00000076657273696f6e2e747874225348412d31222c2252445356657273696f6e220d0a22 Since I only wanted the context, I repeated that step again and piped the output through awk. # ftimes-dig2ctx.pl -e hex -i 1 -c 64 -f dig.out | awk -F\| '{print $8}' 504b0304140000000800da50442e381aab0adeb40000a87504000c0000004e53524c50726f642e747874b47d5b73e2bab6eefba9daff418b87557bd74e686c63 504b0304140000000800ee50442e381c69e6371200002e3600000b0000004e53524c4d66672e7478747d5b4b7322b9b2dedf88f31f7467d12bda31714ec4dd63 504b0304140000000800f250442e3863a0876d040000a51100000a0000004e53524c4f532e7478748d974b53e3381080ef5bb5ff41c5198cfc901d1fb3400dd9 504b03041400000008005454442e668baa2b6ce8c11968a016640c0000004e53524c46696c652e747874ccbd4b971cc79135b89f73e63ff0c36256a53af676f3 504b0304cd38f79af639754f346368e4bde19609db8149420f400b86bca6dd4162e963d122887e4d427cd77c153a267bfd1b434bfaff090de5f9068601f8839d (false hit) 504b03040a0000000000ea55442ea7e6b8f74d0000004d0000000b00000076657273696f6e2e747874225348412d31222c2252445356657273696f6e220d0a22 Looking at that output, I could clearly see structure. Working with it a bit and doing some Web searches (relevant snippets are included below), I could reasonably get to the output shown below. --- http://www.doc.xceedsoft.com/Doc/ZipCompL/sources/Brief_introduction_to_the_zip_file_format.htm --- Structurally, a zip file consists of one or more sections, each containing a file header followed by a file's compressed or raw uncompressed data. The file headers contain information such as the file's filename, file attributes and size. Following these sections is a compact "central directory" section, which contains (mostly redundant) information about each file stored in the zip file. This central directory is very useful for quickly determining what the contents of the zip file are, because it eliminates the need to scan through the entire zip file in order to find the file headers. At the very end of the zip file, an optional "zip comment" section can be provided and can be as large as 64K. --- http://www.doc.xceedsoft.com/Doc/ZipCompL/sources/Brief_introduction_to_the_zip_file_format.htm --- --- http://www.linuxhq.com/kernel/v1.0/0/zBoot/unzip.c --- /* PKZIP header definitions */ #define LOCSIG 0x04034b50L /* four-byte lead-in (lsb first) */ #define LOCFLG 6 /* offset of bit flag */ #define CRPFLG 1 /* bit for encrypted entry */ #define EXTFLG 8 /* bit for extended local header */ #define LOCHOW 8 /* offset of compression method */ #define LOCTIM 10 /* file mod time (for decryption) */ #define LOCCRC 14 /* offset of crc */ #define LOCSIZ 18 /* offset of compressed size */ #define LOCLEN 22 /* offset of uncompressed length */ #define LOCFIL 26 /* offset of file name field length */ #define LOCEXT 28 /* offset of extra field length */ #define LOCHDR 30 /* size of local header, including sig */ #define EXTHDR 16 /* size of extended local header, inc sig */ --- http://www.linuxhq.com/kernel/v1.0/0/zBoot/unzip.c --- magic bflag meth datetime crc c_size u_size nlen extra name data 504b0304 1400 0000 0800 da50442e 381aab0a deb40000 a8750400 0c00 0000 4e53524c50726f642e747874 b47d5b73e2bab6eefba9daff418b87557bd74e686c63 504b0304 1400 0000 0800 ee50442e 381c69e6 37120000 2e360000 0b00 0000 4e53524c4d66672e747874 7d5b4b7322b9b2dedf88f31f7467d12bda31714ec4dd63 504b0304 1400 0000 0800 f250442e 3863a087 6d040000 a5110000 0a00 0000 4e53524c4f532e747874 8d974b53e3381080ef5bb5ff41c5198cfc901d1fb3400dd9 504b0304 1400 0000 0800 5454442e 668baa2b 6ce8c119 68a01664 0c00 0000 4e53524c46696c652e747874 ccbd4b971cc79135b89f73e63ff0c36256a53af676f3 504b0304 cd38 f79a f639 754f3463 68e4bde1 9609db81 49420f40 0b86 bca6 dd4162e963d122887e4d427cd77c153a267bfd1b434bfaff090de5f9068601f8839d (false hit) 504b0304 0a00 0000 0000 ea55442e a7e6b8f7 4d000000 4d000000 0b00 0000 76657273696f6e2e747874 225348412d31222c2252445356657273696f6e220d0a22 This was interesting, but it did not get me much closer to the objective. Next, I turned to the format of the CD. Somewhere on the Net (see snippet below), I found information indicating that each block on a CDROM FS is 2352 bytes long. Of that, 304 are used for error detection and correction. Hmm... time for some more hexdumps. --- http://www.pcguide.com/ref/cd/formatDigital-c.html --- Mode 1: This is the standard data storage mode used by virtually all standard data CDs. The data is laid out in basically the same way as it is in standard audio CD format, except that the 2,352 bytes of data in each block are broken down further. 2,048 of these bytes are for "real" data. The other 304 bytes are used for an additional level of error detecting and correcting code. This is necessary because data CDs cannot tolerate the loss of a handful of bits now and then, the way audio CDs can. --- http://www.pcguide.com/ref/cd/formatDigital-c.html --- # hexdump -C whole.zip | more 00000000 50 4b 03 04 14 00 00 00 08 00 da 50 44 2e 38 1a |PK.........PD.8.| 00000010 ab 0a de b4 00 00 a8 75 04 00 0c 00 00 00 4e 53 |.......u......NS| 00000020 52 4c 50 72 6f 64 2e 74 78 74 b4 7d 5b 73 e2 ba |RLProd.txt.}[s..| 00000030 b6 ee fb a9 da ff 41 8b 87 55 7b d7 4e 68 6c 63 |......A..U{.Nhlc| 00000040 2e f3 8d 40 d2 a1 3b 24 cc 40 77 7a cd 3a 55 a7 |...@..;$.@wz.:U.| 00000050 14 a3 04 ad 18 8b e5 4b 12 e6 af 3f 1e 92 ef c8 |.......K...?....| 00000060 b6 6c e8 da 97 d9 01 c6 e7 21 59 1a 1a 1a d7 ce |.l.......!Y.....| 00000070 d2 65 9b c0 f2 a7 6c 43 3a 17 f1 5f f7 78 97 f9 |.e....lC:.._.x..| 00000080 eb 27 71 3d ca 9c f0 83 87 fd ea e0 f9 64 17 fd |.'q=.........d..| 00000090 7a f1 f2 1a fd eb 0e 3b af 01 7e 85 7f 4e f6 7b |z......;..~..N.{| 000000a0 9b 5a d8 0f 29 d6 87 3d e9 fc d7 ff d1 2e 3a f7 |.Z..)..=......:.| 000000b0 cc f5 99 83 7e f8 d4 a6 3e 25 5e f8 3b bd db 43 |....~...>%^.;..C| 000000c0 4f d4 b9 5f a3 7e b7 17 fe fd 34 bf bf 5f 87 ff |O.._.~....4.._..| 000000d0 5d fd 6b 11 fe ff 6b e7 d5 a6 de 36 fc 97 a0 39 |].k...k....6...9| 000000e0 84 38 fa 45 67 fa b8 e6 a4 fd f0 ff 7f 25 c0 d2 |.8.Eg........%..| 000000f0 0f e7 cd 61 1f 4e 8e 64 4d 6c 87 f8 21 c5 f0 a2 |...a.N.dMl..!...| 00000100 73 8b dd 77 ec 6e d0 57 17 ef b7 d4 82 27 1b e1 |s..w.n.W.....'..| 00000110 93 7f ec 5f 5d cc 59 9f 3d ac e0 a9 cb 69 0e 62 |..._].Y.=....i.b| 00000120 e9 12 8f 38 3e 1f 46 08 34 0a 7f 61 b9 84 38 ab |...8>.F.4..a..8.| 00000130 2d fb 08 bf be ff 32 29 25 15 3f 44 2b fc 4e dc |-.....2)%.?D+.N.| 00000140 90 74 2c 1d fd 48 8c b8 72 bc e5 94 62 e8 6d 28 |.t,..H..r...b.m(| 00000150 23 96 4b 29 b5 fe 45 e7 06 7b fe da c5 d6 db ca |#.K)..E..{......| 00000160 da 92 4d 60 c3 2c 3d 51 67 c3 3e bc 84 eb c9 75 |..M`.,=Qg.>....u| 00000170 7e d0 53 6c 13 67 83 61 c0 da e0 a2 f3 48 f6 e1 |~.Sl.g.a.....H..| 00000180 f3 d1 93 4b 7d e2 26 f3 b5 61 de 40 d7 e0 d7 77 |...K}.&..a.@...w| 00000190 93 1c b5 f8 b9 57 49 1c 72 ae 77 b5 d3 a8 db 13 |.....WI.r.w.....| 000001a0 1b 5d a3 3d f1 29 8f 35 5b 12 2f 56 21 79 5b 62 |.].=.).5[./V!y[b| 000001b0 fe e4 9a d9 1a 86 7f fd f3 11 15 01 fa b9 67 cf |..............g.| 000001c0 56 2d c8 43 e2 41 57 d7 4f a1 8f b8 6f 4b de 9a |V-.C.AW.O...oK..| 000001d0 36 5d e1 ed 47 6e 9c 36 f0 13 c9 6b 5e db e8 a2 |6]..Gn.6...k^...| 000001e0 d3 25 bf 16 77 e1 a7 1a 9f 63 2e b6 85 04 bf fe |.%..w....c......| 000001f0 35 bd be 7b b8 cf 91 92 ab c0 a3 0e f1 38 f1 38 |5..{.........8.8| 00000200 24 ba d4 2f 0d 74 89 c8 3b b6 03 2e 5d 91 c5 f6 |$../.t..;...]...| 00000210 07 fe 10 9b 60 8f a0 7e 22 63 ee 98 1f 78 79 d1 |....`..~"c...xy.| 00000220 ba 77 09 de 78 5b c2 a5 bb ae 5f 74 6e 42 f0 a5 |.w..x[...._tnB..| 00000230 4b 1d 9f 33 a4 27 b2 31 fb b9 f4 2c 31 b3 32 cd |K..3.'.1...,1.2.| 00000240 88 87 62 c0 7f 17 d4 72 99 c7 5e f2 b4 0f 7b e2 |..b....r..^...{.| 00000250 86 0c 3b af 48 9c 81 00 32 0c 89 98 bb 59 12 f7 |..;.H...2....Y..| 00000260 85 58 f0 73 93 03 89 15 94 ff 26 05 82 cf d1 d2 |.X.s......&.....| 00000270 65 16 f1 3c 06 02 53 1f 83 cc b5 c8 1d e5 8f d4 |e..<..S.........| 00000280 f9 64 0a 8c 2b ea 7b 7e 38 e6 5d 0e e1 86 39 3e |.d..+.{~8.]...9>| 00000290 4a c7 62 68 fc a8 b6 d8 6e 87 96 36 9f b2 a2 c8 |J.bh....n..6....| 000002a0 8c be ce 8b ec f0 83 c0 89 8e 6a af 06 47 cc d0 |..........j..G..| 000002b0 c9 30 27 63 24 1b ec 64 56 f4 33 8c 28 11 74 27 |.0'c$..dV.3.(.t'| 000002c0 73 23 b6 fd 19 5e d3 59 b8 31 ce c3 4d 24 c5 d5 |s#...^.Y.1..M$..| 000002d0 70 f4 8b ce ca 77 09 f1 d1 c4 b7 b1 87 7e ac 00 |p....w.......~..| 000002e0 25 d1 0d f9 ce 9c 91 3b e6 72 d5 54 b6 a7 eb 20 |%......;.r.T... | 000002f0 c6 a3 d3 21 cc 93 21 ea 01 0c 10 86 3b f6 4e 2e |...!..!.....;.N.| 00000300 e7 fe 25 67 5a cc a8 20 fe 33 c0 ae 4f dc 0d b1 |..%gZ.. .3..O...| 00000310 de 5a 00 f0 bf 4e 83 e0 6f e2 44 2e 4c 35 88 fe |.Z...N..o.D.L5..| 00000320 45 67 19 fe 88 c2 22 59 e0 57 6a 15 c4 e3 92 7d |Eg...."Y.Wj....}| 00000330 10 f7 cf 80 78 65 62 be 02 41 cc e6 29 08 e2 a4 |....xeb..A..)...| 00000340 39 91 07 3e 15 f5 18 26 dc b1 f6 77 d4 81 b9 1a |9..>...&...w....| 00000350 e4 36 c5 da c5 ef c4 a6 ce 6b 33 5a fe e0 96 b4 |.6.......k3Z....| 00000360 2a 94 83 70 58 53 b4 66 cc ce dc 3d 06 00 30 25 |*..pXS.f...=..0%| 00000370 8e ef 62 7b c9 ca 8f 67 63 98 2c 1e 0a bf 31 9a |..b{...gc.,...1.| 00000380 ad 9b 11 9f f1 f0 31 1e fa 33 a0 1b 82 7c 86 16 |......1..3...|..| 00000390 cc 21 87 c2 5e 9a 3b 7e 40 4b 79 18 5f 74 56 2c |.!..^.;~@Ky._tV,| 000003a0 70 36 e8 ca c6 5e f8 44 a4 0d 8e f6 c1 d4 25 d8 |p6...^.D......%.| 000003b0 a7 ef f9 bd 2c a8 a6 d8 dd d4 c1 88 25 74 22 48 |....,.......%t"H| 000003c0 3c 31 27 c2 24 af a7 16 a6 df bb e8 dc 4d ee fd |<1'.$........M..| 000003d0 10 82 2f e6 41 bc 25 85 96 30 71 7d 7a a4 3e a5 |../.A.%..0q}z.>.| 000003e0 f3 2a a7 8e 27 b4 15 b1 98 c6 3a 52 2d fc c9 e3 |.*..'.....:R-...| 000003f0 d4 23 ee 3b f9 b2 62 36 e3 db 50 4b 15 b6 e9 96 |.#.;..b6..PK....| 00000400 1c 88 e3 94 c9 e5 be ce 75 b7 37 7e c4 a5 6b 48 |........u.7~..kH| 00000410 ae 2d 66 c8 8c 8b ce af b5 4b c8 57 66 6f 22 4d |.-f......K.Wfo"M| 00000420 3b 59 3d f5 3b a1 df 0f 3f c7 de 01 4d 67 88 bf |;Y=.;...?...Mg..| 00000430 19 e6 1e bd f8 c9 06 ef 7d 62 95 21 98 b0 67 a8 |........}b.!..g.| 00000440 f5 86 7e 52 f2 11 1f d2 fd 6e 2f 56 7a 39 c6 dc |..~R.....n/Vz9..| 00000450 f1 58 19 c0 20 7c 44 38 c8 67 ec a3 47 82 37 e2 |.X.. |D8.g..G.7.| 00000460 c2 90 c8 91 5f 9c 03 f6 5c 3a 6f 95 e4 f1 e5 a1 |...._...\:o.....| 00000470 3d 42 1d f1 f0 a2 73 e3 e2 1d e1 c3 e7 a4 c9 8a |=B....s.........| 00000480 d3 7b bd da 67 57 90 9f 40 aa 34 ec 32 fa 5f a7 |.{..gW..@.4.2._.| 00000490 3d bb fe 8d 55 10 ff 5a 9e 40 bc 98 df dd 9d 42 |=...U..Z.@.....B| 000004a0 7e 5d 47 3c 8a 88 17 f8 4d 75 be 0b 96 be 72 88 |~]G<....Mu....r.| 000004b0 68 ab b5 a3 5f 60 eb 04 ea 48 be b5 e7 bd 74 a1 |h..._`...H....t.| 000004c0 17 11 c6 59 84 ff 5d 7d e5 37 fd 73 c3 9c 01 42 |...Y..]}.7.s...B| 000004d0 fd 7d 56 e3 a8 bd 54 b3 77 d1 b9 7d 58 cf 1e be |.}V...T.w..}X...| 000004e0 66 55 b7 0a 63 c1 13 79 46 57 01 b5 41 54 95 91 |fU..c..yFW..AT..| 000004f0 f3 47 b7 27 57 25 86 53 ef 6a 8a 6e 6c f6 31 dd |.G.'W%.S.j.nl.1.| 00000500 72 cd 49 98 c0 8b 63 78 05 03 f9 67 c9 c6 32 f5 |r.I...cx...g..2.| 00000510 48 49 8d 8f aa 7e 2d 1b c5 29 34 42 3e 5e c2 a7 |HI...~-..)4B>^..| 00000520 5f bf 80 45 44 1c 41 5a c5 7a 88 0c f6 5f 66 2e |_..ED.AZ.z..._f.| 00000530 fe 00 35 b3 1a a2 7c 3d 34 c3 e1 f7 14 25 10 ae |..5...|=4....%..| 00000540 d5 bf 66 b6 9a 19 1f ad f5 d2 b9 9a 58 e5 6c a8 |..f.........X.l.| 00000550 46 a8 95 f0 a6 09 27 fe 8c 78 f4 15 24 8b c6 cd |F.....'..x..$...| 00000560 06 d5 db 2a 78 86 7f 45 83 2f 21 6f 4f 59 2e 59 |...*x..E./!oOY.Y| 00000570 54 a8 4b de 5a 9e 16 2e 24 5b e6 33 6f cb f6 dc |T.K.Z...$[.3o...| 00000580 54 57 c5 b4 e4 85 97 d1 37 5a 7a 65 20 25 72 a8 |TW......7Zze %r.| 00000590 09 82 f2 ca 1d f2 cd b9 a3 c4 25 89 c9 b2 72 1c |..........%...r.| 000005a0 3f e9 86 b0 0a ca 12 e6 eb c8 aa 89 c6 21 ef ec |?............!..| 000005b0 4e dc 43 14 b4 c5 82 d4 93 52 b7 26 2c 99 db 3c |N.C......R.&,..<| 000005c0 e9 a0 77 d1 99 db 76 e0 f9 6e a4 a5 8f eb d9 3e |..w...v..n.....>| 000005d0 7e 3d 15 30 a7 23 94 6e b3 46 28 ca 4b 6d a0 25 |~=.0.#.n.F(.Km.%| 000005e0 9b 90 4b a9 e9 0c cd 88 1d 7c 92 ba b3 23 bb 71 |..K......|...#.q| 000005f0 07 fa 45 07 5e c8 82 f1 a3 24 73 f9 29 1d 0d bc |..E.^....$s.)...| 00000600 98 54 d8 95 03 54 2f 27 15 84 93 88 2b 96 55 86 |.T...T/'....+.U.| 00000610 dc 2c ba 12 06 5d 2d 72 5f a3 19 f5 de 12 46 ee |.,...]-r_.....F.| 00000620 d9 3b b1 ed 3c 54 d1 d7 30 18 85 4f dc 11 97 5a |.;..>,..V....| 00000790 6b e8 dc a8 69 20 c3 6f 40 16 4e 8b df 00 fc bb |k...i .o@.N.....| 000007a0 d8 35 7e 0f f0 e0 b7 00 c7 ab f7 f7 2c 09 05 60 |.5~.........,..`| 000007b0 0d 82 6b 76 d4 3e 20 70 c2 a0 23 d3 28 c8 64 97 |..kv.> p..#.(.d.| 000007c0 6d 88 fb 1c 14 4e ae 54 07 d7 20 d4 68 81 ff 4d |m....N.T.. .h..M| 000007d0 bc f0 4f f0 df ef 58 83 a1 95 d1 fe 3a 81 76 a4 |..O...X.....:.v.| 000007e0 40 6b 14 ac c1 46 66 c8 fc 8b d2 d1 f6 2f 3a e0 |@k...Ff....../:.| 000007f0 b8 7d 13 be d7 58 67 10 b6 c2 ef ab 52 32 13 0e |.}...Xg.....R2..| 00000800 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00000920 00 00 00 00 00 00 00 00 00 00 08 00 00 00 08 00 |................| 00000930 2e ea f8 68 25 6c 13 f3 ab c5 97 35 76 36 87 dc |...h%l.....5v6..| ... I saw a hunk of empty space starting at offset 0x00000800? To me, it didn't look like zip data -- I expected zip data to be dense. Therefore, I decided to calculate its size. # echo "ibase = 16; 930 - 800" | bc 304 That figure matched the number for error detection and correction. This led me to hypothesize that there would be a similar clump of data at 0x00001130. I checked, and there was. ... 00001120 0c 3a d5 a1 00 73 cc e4 c4 b5 b6 e1 b3 2c bf 35 |.:...s.......,.5| 00001130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00001250 00 00 00 00 00 00 00 00 00 00 08 00 00 00 08 00 |................| 00001260 87 46 de 3a ed 15 14 83 a7 92 ec f0 a2 45 1b 72 |.F.:.........E.r| ... Then, I verified that this offset minus the last one matched the CDROM block size, and it did. # echo "ibase = 16; 1130 - 800" | bc 2352 Based on that information, I hypothesized that removing the first 304 bytes from each block would be sufficient to clean up the zip file. To test that theory, I wrote the following program: --- squish304.c --- #include #include #include #define BLOCK_SIZE 2352 #define ERROR_SIZE 304 #define PROGRAM "squish304" /* gcc -o squish304 squish304.c -Wall */ int main(int ac, char *av[]) { char aucData[BLOCK_SIZE]; FILE *pFile; int iNRead; if (ac != 2) { fprintf(stderr, "\nUsage: %s file\n\n", PROGRAM); return -1; } pFile = fopen(av[1], "rb"); if (pFile == NULL) { fprintf(stderr, "%s: File='%s' Error='%s'\n", PROGRAM, av[1], strerror(errno)); return -1; } iNRead = fread(aucData, 1, BLOCK_SIZE - ERROR_SIZE, pFile); if (iNRead != BLOCK_SIZE - ERROR_SIZE) { fprintf(stderr, "%s: File='%s' Error='Read %d bytes, needed %d.'\n", PROGRAM, av[1], iNRead, BLOCK_SIZE - ERROR_SIZE); fclose(pFile); return -1; } fwrite(aucData, 1, iNRead, stdout); while((iNRead = fread(aucData, 1, BLOCK_SIZE, pFile)) == BLOCK_SIZE && !feof(pFile)) { fwrite(&aucData[ERROR_SIZE], 1, iNRead - ERROR_SIZE, stdout); } if (ferror(pFile)) { fprintf(stderr, "%s: File='%s' Error='%s'\n", PROGRAM, av[1], strerror(errno)); fclose(pFile); return -1; } if (iNRead > ERROR_SIZE) { fwrite(&aucData[ERROR_SIZE], 1, iNRead - ERROR_SIZE, stdout); } fclose(pFile); return 0; } --- squish304.c --- The following sed command will extract the C code to a file. sed -e '1,/^--- squish304.c ---$/d; /^--- squish304.c ---$/,$d' ftimes-dig-extract-zip-from-iso.txt > squish304.c Running squish304 on whole.zip produced the following: # gcc -o squish304 squish304.c -Wall # squish304 whole.zip > rds.zip # unzip -l rds.zip Archive: rds.zip Length Date Time Name -------- ---- ---- ---- 292264 02-04-03 10:06 NSRLProd.txt 13870 02-04-03 10:07 NSRLMfg.txt 4517 02-04-03 10:07 NSRLOS.txt 1679204456 02-04-03 10:34 NSRLFile.txt 77 02-04-03 10:47 version.txt -------- ------- 1679515184 5 files That looked pretty good, so I tried to unzip it. Here are the results: # unzip -d rds rds.zip Archive: rds.zip inflating: rds/NSRLProd.txt inflating: rds/NSRLMfg.txt inflating: rds/NSRLOS.txt inflating: rds/NSRLFile.txt extracting: rds/version.txt Next, I verified the hash for NSRLFile.txt et al. # openssl sha1 rds/*.txt SHA1(rds/NSRLFile.txt)= d897f39dcf9bcfa2027ba9b0996fc344acacda9c SHA1(rds/NSRLMfg.txt)= c17fcdc0d0dbc2d48a6053953c149d3371ac6315 SHA1(rds/NSRLOS.txt)= 09f26cfea47d83aa2c85cceb65999c5c566cef91 SHA1(rds/NSRLProd.txt)= 9d35a5d8c229803ad402260e8a1e1fc808170047 SHA1(rds/version.txt)= 913441fa61278af5a69ccf689bd7e48bf41a9b4f The file, hashes.txt, was obtained from NIST's ftp site. # cat hashes.txt | tr "A-F" "a-f" 9d35a5d8c229803ad402260e8a1e1fc808170047 c17fcdc0d0dbc2d48a6053953c149d3371ac6315 09f26cfea47d83aa2c85cceb65999c5c566cef91 d897f39dcf9bcfa2027ba9b0996fc344acacda9c Clearly, the last hash in hashes.txt matches the one for NSRLFile.txt. SHA1(rds/NSRLFile.txt)= d897f39dcf9bcfa2027ba9b0996fc344acacda9c d897f39dcf9bcfa2027ba9b0996fc344acacda9c Running head on NSRLFile.txt revealed data that was consistent with my expectations. # head -10 NSRLFile.txt "SHA-1","MD5","CRC32","FileName","FileSize","ProductCode","OpSystemCode","SpecialCode" "0000004DA6391F7F5D2F7FCCF36CEBDA60C6EA02","0E53C14A3E48D94FF596A2824307B492","AA6A7B16","00br2026.gif",2226,228,"WIN","" "00000142988AFA836117B1B572FAE4713F200567","9B3702B0E788C6D62996392FE3C9786A","05E566DF","J0180794.JPG",32768,2322,"WIN","" "00000142988AFA836117B1B572FAE4713F200567","9B3702B0E788C6D62996392FE3C9786A","05E566DF","J0180794.JPG",32768,2575,"WIN","" "00000142988AFA836117B1B572FAE4713F200567","9B3702B0E788C6D62996392FE3C9786A","05E566DF","J0180794.JPG",32768,2583,"WIN","" "0000051C1E5A5DECF28FE8B57ABFE2B82A3EDD1C","11A6E2A7EF1273F93ECCB22ACCC15267","9314EB02","EPLQL2PC.PBD",6076,2866,"Unix","" "0000053DD188DB497821D216D9AA50DD0F1529BD","5AEC257B5EEB4AA386C28C52AE7EEC2B","E8C1285A","CMBIZ097.ccx",19818,388,"WIN","" "0000053DD188DB497821D216D9AA50DD0F1529BD","5AEC257B5EEB4AA386C28C52AE7EEC2B","E8C1285A","CMBIZ097.ccx",19818,228,"WIN","" "00000919F26D1C937ED963F82DEA47273422A922","F6A61F8884BACECCD2D2624859DEA78C","E59C68BB","SPEAK_FR.RPM",529598,285,"Linux","" "00000A632E3C93BADDBFB0A0002C6A012B5485F1","6570C310A8F22A8C2B980AF0ED569328","995D8612","mapindex.xml",127048,2429,"Gen","" It was a bit of work, but the end result was worth it -- being that I was in a bind and needed the hashes in short order. The next time you get an iso image that you can't mount, maybe you can apply a technique like this to keep the ball rolling.