Vulnerability Development mailing list archives
Re: Audio fingerprinting (was Re: hacksdmi?)
From: Thierry <thierry () PURGE-IT COM>
Date: Mon, 14 Aug 2000 11:36:32 +0100
An Attempt on hacking HackSDMI by SnakeByte [ SnakeByte () kryptocrew de ] Introduction: This is more or less a logfile how I tried to get rid of the protection from www.hacksdmi.com. When I saw this contest on packetstorm, my first thought was that this is one of the normal break-into-our-server contest, at which the server has neither a deamon running or something else :P But playing around with watermarks seems interesting, so I tried, and I think I succeeded to remove it, so a decoder would just see waste and the sound quality did not change to my ears. I don't know if i also fullfilled the things they want, because I did not submit anything, if I had submitted anything I would not be allowed to publish this, and I think it is better to keep information free for everyone than making profit. In addition to this the contest is really unfair, so why should I help them, if they don't help me ;) Maybe the language I use is not very technical, but I think you will understand what I say. If you got any comments or want to discuss with me about this, feel free to send me a mail. I hope I can help some people with more endurance to make their attack successfull, but as I will mention later, in my opinion the watermark will be completely cracked, when they remove this stuff and the contest is more fair. The Log: First of all SDMI is playing not fair, by blowing the downloads to 50 MB a piece a lot of people are not able to take part in the challenge, because they can't pay for such a download or just have a modem which means they have to download 10h. The next problem provided by the huge files is that i had to search some hours for a hexeditor which is able to view them ( NEXT-Soft Hex-Editor 2000 did it well ). Ok, let's see what is inside the zip file ? A readme and three wav files. Ok, while downloading some descriptions of the RIFF WAV Format I took a look at the readme. Not nice, they just tell me what this files are and nothing about the technique they used. Seems like another security by obscurity challenge. This sucks ! Why do they not look for a real protection, instead of just trying to hide some things. Sure it is not easy to get rid of it, but this is just because they provide no tool to check ( so we could disasm it and see what it checks for ), they files are that huge and we got just 3 to analyze. Ok, let's see what we got here. Technology A Files: samp1a.wav - 21397736 Bytes - Without Watermark samp2a.wav - 21397548 Bytes - Watermarked Version of 1a samp3a.wav - 21405740 Bytes - Watermarked example without clean counterpart Ok, first of all we should have a look at samp1a.wav and samp2a.wav . He, whats this ? The version without the watermark is bigger than the one without. How can this happen ? By the time I asked this question, there was noone around to answer ( Fear and Loathing rocks ). So I took my Hexeditor and took a look at both. We found a small signature at the end of sample 1a. ( 188 Bytes ) ------8<------------- 4C4953544C000000494E464F494352440B000000323030302D30392D3038 000049454E47130000004172636869766520546563686E6F6C6F67790000 4953465410000000536F756E6420466F72676520342E3500637565201C00 000001000000010000000000000064617461000000000000000000000000 4C4953543C0000006164746C6C747874140000000100000000A051007267 6E2000000000000000006C61626C14000000010000005265636F72642054 616B652030303100 LISTL INFOICRD 2000-09-08 IENG Archive Technology ISFT Sound Forge 4.5 cue data LIST> adtlltxt Q rgn labl Record Take 001 ------8<------------- I quickly removed this stuff to have 2 files which are equal in size. Ok, let's have a look at the other differences of the two files. The first difference is at offset 00000004h. A quick glance at the wav file format description tell us that this double word is the lenght of the file. When we subtract the both values, we see that the difference is exactly 0bch Bytes ( 188d Bytes ) so we can let this difference as it is. ( This is no Watermark, we could add some of our data, at the end to remove this as well *g* ) Ok, we do a little comparison of both files: | Offset | Value File1 | Value File2 | Difference | |--------+--------------+---------------+--------------| | 4eh | a8h | a7h | +1 | | 50h | 0eh | 0fh | +1 | | 56h | a4h | a5h | +1 | | 58h | 4ah | 49h | -1 | | 6eh | 71h | 70h | +1 | | 74h | 93h | 94h | +1 | | 80h | ebh | ech | +1 | | 86h | 5ah | 59h | -1 | | [...] | [...] | [...] | [...] | We quickly notice that the values always differ by +1, 0 or -1. This means they just influenced the last bit, the least significant bit. Thats exactly what I expected *eg* The Format Chunk tells us that this is a stereo recorded file. 44100 Hz is the sample rate with 176400 Bytes per second in 16 Bit stereo with 16 Bits per Sample. ( I also don't know what this all means but we'll see if we need this. ) Let's have another look at the wav file format to see what exactly they changed. At offset 24h starts the data section. So we are right inside ;) So offset 2ch is the beginning of the real data. This is what is changed. Quote from http://technology.niagarac.on.ca/courses/comp630/WavFileFormat.html : "The data is a value from 0x00 to 0xFF. In the example above 0x80 would represent "0" or silence on the output since the DAC used to playback samples is a bipolar device (i.e. a value of 0x00 would output a negative voltage and a value of 0xFF would output a positive voltage at the output of the DAC on the sound card)." Ok, so if we change one of the least significant bits here, the listener will not notice anything. So we simply change the LSB to a 0 or 1 at random, an we will have wiped out at least 50% of the watermark and we have changed some other values where a watermark might have been ( we don't know how they hide it, it may be different on every encoded file, thats why it sucks that they don't have provided any technical information ) Hmm, whats this ? At offset 23324d ( 5b1ch ) the differences are 3h. offset 23324d : 56h --> 59h offset 23326d : EEh --> F1h offset 23328d : EDh --> F0h offset 23330d : 60h --> 63h offset 23336d : 4h --> 1h offset 23338d : 7Fh --> 7Ch Then there is a difference of 5 : offset 23340d : 90h --> 8Bh offset 23342d : 18h --> 13h And finally changes between 3 and 5 offset 23344d : B6h --> B3h offset 23346d : 45h --> 41h offset 23352d : 84h --> 86h offset 23354d : C9h --> CCh offset 23356d : C1h --> C3h offset 23368d : 45h --> 49h offset 23370d : A9h --> AEh offset 23372d : F1h --> F6h offset 23374d : CBh --> D1h Ok whats happening here ? Seems as if they do no longer only change the least significant bit. They change the last 5 bits. offset 24316d : 76h --> D6h offset 24318d : 90h --> 40h offset 24320d : 2Dh --> 36h offset 24322d : 29h --> F3h offset 24324d : E5h --> 7Eh offset 24326d : A4h --> 85h offset 24328d : 61h --> E7h Now it seems as if they change the values completely. This confuses me a bit. No, this confuses me a byte... a word !! This may be the solution. The data is stored in words. The always change the lower part of the word, never the upper part. I'll have a look in the wav reference again and go on writing later. Ok, this is still the same section and there are no hints in the reference that the data is stored there in a different way. I took another wav file I got on my computer and changed the second byte of several words ( The Microsoft Sound.wav ) I heard no difference exept on the places where has been an 80h ( silence ). If you change them you will hear a difference, because a knack inside the silence is very easy to hear ;) So me might want to change the second byte of every word. How could we do this ? When we always change the second byte to a random number the sound quality would go to hell. I think that it will be ok, to change the last 5 Bytes. ( 0 - 7 ) When we generate a random number ( 1-7 ) and make an exlusive or with this value we will remove the watermark so much that it will be no longer visible. Why do we need a random value ? Since we don't know how they generate the watermark ( as I said earlyer this contest is not fair :P ) we can't use a static value, otherwise they may come and say, heh they just added 1 to each word, if you remove it you see our watermark. This way they can't say, if you add 1 to the first, subtract 2 of the second, add 4 to the next and subtract 2 of the ... etc If i would do something like this, I could transform the bible into an diabolic manifest ;) Example: 76h = 1110110b xor 1 = 1110111b --> 77h 2 = 1110100b --> 74h 3 = 1110101b --> 75h 4 = 1110010b --> 72h 5 = 1110011b --> 73h 6 = 1110000b --> 70h 7 = 1110001b --> 71h This way we just change every word by 0,0107 percent. I don't think that anyone will hear this ;) Now we write a little program which exactly does this. We read the data section word by word, change the second byte and write it back. ---------8<------------------- .486p locals jumps .model flat,STDCALL extrn CreateFileA:PROC ;Open files extrn ExitProcess:PROC ;termination of program extrn ReadFile:PROC ;read a file.. extrn CloseHandle:PROC ;closing files extrn SetFilePointer:PROC ;move filepointer extrn WriteFile:PROC ;changing files extrn MessageBoxA:PROC ;communikation *g* extrn GetTickCount:PROC ;random number .DATA Filename db 'samp2a.wav',0 ;our target Filename2 db 'newsamp2a.wav',0 Fine db 'Ok',0 MSG db 'we did it',0 FirstChunk equ 2ch ;size till we are in the data section FileSize equ 21397548d - FirstChunk Handle dd ? Read dd ? Write dd ? Handle2 dd ? Filemem db 30h dup (?) ;buffer to read file .CODE code: push 0 push 080h ;normal attribs push 3 ;open an existing file push 0 push 0 push 0C0000000h ;read + write push offset Filename Call CreateFileA ;open target mov Handle,eax cmp eax, 0FFFFFFFFh je End push 0 push offset Read ;number of bytes read.. push 2ch ;how many bytes to read push offset Filemem ;where to store ? push Handle ;filehandle Call ReadFile ;we read 2ch to get to the start of the ;real data ( i am too lazy to use the ;setfilepointer push 0 ;open the output file push 080h ;normal attribs push 2 ;open an existing file push 0 push 0 push 0C0000000h ;read + write push offset Filename2 ;output file Call CreateFileA mov Handle2,eax push 0 push offset Write push 2ch ;write the first stub to the output file push offset Filemem push Handle2 Call WriteFile ChangeIt: mov ebx, offset Filemem ;point to the second byte push 0 push offset Read push 100d push offset Filemem push Handle Call ReadFile cmp dword ptr [Read],0 ;we do this to the end of the file je End_Close_File mov ecx, 100d ChangeIt2: push ecx mov al, byte ptr [ebx] ;get the byte we want to change in eax cmp al, 80h ;silence ? je NextWord call GetRand ;generate a random number in ecx xor eax, ecx mov byte ptr [ebx], al ;save an write to file NextWord: add ebx, 2h pop ecx loop ChangeIt2 push 0 push offset Write push dword ptr [Read] push offset Filemem push Handle2 Call WriteFile jmp ChangeIt End_Close_File: push Handle Call CloseHandle push Handle2 Call CloseHandle Success: push 10h push offset Fine push offset MSG push 0 call MessageBoxA End: push 0h call ExitProcess jmp End GetRand: ;generate a random number between 1 and 7 ;in ecx push eax push edx call GetTickCount add eax, ebx ;generate pseudo-random number ;P add eax, ecx ;good enough for this task xor eax, edx add eax, ebp push 7h pop ecx xor edx, edx ;clean edx ( needed to be able to divide later ) div ecx ;Random Numer is in EAX xchg eax, ecx inc ecx pop edx pop eax ret Ends End code ---------8<------------- Well, it works :) Seems as if we beat technology A ... Technology B Baah, it is the same fucking song, not very creative, let's see if the protection is something better. Hmm.. here they also just changed the second byte, so me are able to use the same "attack".. strange, did I misunderstood something, let's take another look at the readme.. "You must remove or alter the audio watermark in eight consecutive 15 second windows." Ok, I think we did this. "The initial test of your attack will only be considered a success if the decoder is not able to detect any of the watermark bits." Hmm.. this confuses me, "any of the watermark bits" .. do they mean we should change every _Bit_ of the watermark ??? Heh, this is not possible without an analysis of the decoder. We don't know how they hide and we don't know what they hide... If we got more samples, we could try a to find common things, we could try to detect the algorithm. But this way ? If the decrypter detect some Bits of the Original Watermark, they are no real proof that there has ever been a watermark. If we take the original file and change the second byte by XOR-ing it with 0FFh, the decoder would also detect lots of Bits of the watermark. Just take a look at the last bit of a byte. We set this bit to 1 and see how many letters there are, which have it set.. ;) 256 / 2 ( all uneven numbers ) = 128 If they would complain we need to remove all Bits, we change our code this way: ----8<------ mov al, byte ptr [ebx] ;get the byte we want to change in eax xor al, 0ffh ;xor with 0ffh mov byte ptr [ebx], al ;save an write to file ----8<------ And remove the GetRand Procedure ( no longer nessecairy ) This way I hear a small difference, we could get it better, if we would have at least 2 originals and 2 watermarked examples, to check for regularities in the way they change the bytes. Then we could guess about their watermark algorithm and just defeat the right bits. Then we would be able to create a more effektive attack. This way, we could make a guess, submit the file, wait some days for the answer and then go on... not really worth thinking about this. "In addition, the sound quality of the attacked sample cannot have been degraded below that of MP3 encoding at 64 Kbps for a stereo signal or a comparative analysis using PEAQ." Dont really know what they mean by this, but I also think we succeeded in this, the sound quality does not change, and if it would, we just decrease the random value to get it better :) Same applies to Technology C, here they always just changed the last Bit... This whole thing starts to get boring. I will stop my analysis here, because trying to guess byte patterns is not very exciting ;) I hope they choose on of the technologys and I can sometime get my hand on more examples, because if I would think I have found something I can't really test it that way. So whatever method they used, if you just put some noise above it you can hide or remove the watermark, but to write down a complete analysis, we either need the player ( which decodes the watermark ) and reverse engineer it, or we would need more examples to generate some statistics. If they decide for one of the technologys they also have nessecairily to provide us both ;) So as far as I see the situation, they can tell their customers after the contest, that it is save, but when they release the things it just takes some weeks until it is broken. Thats all for now.
Current thread:
- Audio fingerprinting (was Re: hacksdmi?) Geoff Schmidt (Oct 13)
- Re: Audio fingerprinting (was Re: hacksdmi?) Thierry (Oct 14)
- Re: Audio fingerprinting (was Re: hacksdmi?) Geoff Schmidt (Oct 14)
- Re: Audio fingerprinting (was Re: hacksdmi?) Bluefish (P.Magnusson) (Oct 16)
- Re: Audio fingerprinting (was Re: hacksdmi?) Geoff Schmidt (Oct 14)
- Re: Audio fingerprinting (was Re: hacksdmi?) Lincoln Yeoh (Oct 15)
- Re: Audio fingerprinting (was Re: hacksdmi?) Geoff Schmidt (Oct 16)
- Re: Audio fingerprinting (was Re: hacksdmi?) Thierry (Oct 14)