The Solfa Cipher (NSEC17 Write-Up)

Share

Introduction

Between May 19th and 21st, 2017, I’ve participated to the NSEC 17 Capture-the-Flag (CtF) event held annually in Montreal, QC. As usual, the team and I had a blast spending days and nights solving challenges and drinking free beer. Among the challenges was a two-part cryptographic puzzle printed on the first and last pages of the passport of Rao’s Intricate Kingdom – the country part of the story line of the event. The challenge was divided in two parts: a Braille encoded message and the second part was encrypted using the Solfa cipher, which I had never heard of before. As such I decided to learn more about it and complete a write-up for the challenge at the same time. I’ll first quickly cover the Braille part of the challenge, then move on to the Solfa part of it and the decryption process.

The Second Half of the Flag

Upon entrance at the NSEC competition this year, participants received a passport designed to be stamped based on events happening during the CtF. The back of the front cover contains a sequence of dotted symbols which can be recognized quickly as Braille as shown in the figure below:

Braille-encoded message in Rao's Passport
Figure 1: Braille-encoded message in Rao’s Passport at NSEC’17

As most of you probably know, the Braille writing system was developed for the blind and visually impaired individuals to be able to read using touch. Examples of braille can often be found on elevators. The system is based on a matrix of 3×2 dots which can be blank or filled. Each dot is numbered from 1 to 6 as shown below:

Braille Matrix Numbers
Figure 2: A matrix of the 6 dots representing an individual character Braille

Each character of a natural alphabet can then be associated with a specific matrix configuration. For example, a simple Braille-English translation is shown below:

The Braille Alphabet
Figure 3: The Braille Alphabet (linked from pharmabraille.com)

Additional “shortcut” symbols are used for specific sounds, punctuation, symbols and words. The figure below shows some examples of common words in Braille:

Braille for words and abbreviations
Figure 4: Braille for words and abbreviations (from the Tennessee Council of the Blind)

Additional abbreviations can be found in [1]. Going back to the passport, we can obtain the transcription using Unicode:

⠠⠮⠀⠎⠑⠒⠙⠀⠓⠁⠇⠋⠀⠷⠀⠮⠀⠋⠇⠁⠛⠀⠊⠎⠀⠮⠀⠘⠺
⠠⠏⠇⠁⠞⠽⠏⠥⠎⠲⠀⠠⠁⠙⠙⠀⠭⠀⠁⠋⠀⠮⠀⠋⠌⠀⠓⠁⠇⠋⠀⠞⠕
⠕⠃⠞⠁⠔⠀⠁⠀⠉⠕⠍⠏⠇⠑⠞⠑⠀⠋⠇⠁⠛⠲⠀⠠⠛⠇⠕⠗⠽⠀⠞⠕
⠀⠠⠠⠗⠁⠕

We then translate into English and obtain the following translation from Braille to English.:

(Cap) THE S E CON D H A L F OF THE F L A
G I S THE  (Cap) P L A T Y P U S
. (Cap) A D D X A FTER THE F IRST H A L F
T O O B T A  IN  A  C O M P L E T
E F L A G . (Cap) G L O R Y T O
 (Cap) R A O

Table 1: Resulting message from translating from Braille to English.

Putting everything together, we obtain the first part of the flag included in the passport:

The second half of the flag is the word Platypus. Add x after the first half to obtain a complete flag. Glory to Rao

First Half of the Flag

The second part of the flag is much more obscure and less documented than the first one. The inside of cover page contains a small partition holding a total of 4 staves: the first one appears to be a chord while the last 3 are simply a sequence of notes. We noticed that the first staff contains a treble clef, the label “KEY-997” and is shorter than the other staves. Furthermore it contains the type of notes

Music Sheet in the Rao's Passport
Figure 5: Scanned copy of the lullaby on the last page of Rao’s passport.

Clearly, there is something in there, but how do we extract a flag out of this? My knowledge of music theory is extremely low and was basically non-existent prior to this challenge. As such feel free correct me in the comments if I misrepresent a musical concept or term.

The Cipher

Googling for words relating to music and cryptography will return a limited set of relevant sites, the first relating to musical cryptograms, which is not quite was we are looking for at the moment. The second page is about the Solfa Cipher. Once you’ve found the latter website, you’re almost at the solution, but let’s take a better look at it.

The Solfa cipher is a substitution cipher, but rather than using an alphabet to encode keys and cipher text, it uses musical notation. The encryption/decryption key is defined using a clef, a tonic, a mode and a rhythmic unit. The links will provide a much better definition of each different item than I could ever do in this article. However, be aware that the 4 elements mentioned above can have the following values:

Clefs Tonic Mode Rhythmic Unit
Treble C, C# Minor 1/4 (Quarter)
Alto D♭, D Major 1/8 (Eighth)
Bass E♭, E Phrygian 1/16 (Sixteenth)
F, F# Dorian
G♭, G Lydian
A♭, A Mixolydian
B♭, B Locrian

Table 2: Valid values for the properties of the Solfa key.

Like any symmetric cipher, a key is needed to encrypt the message, which will have to be shared with the intended recipients of the message. In this case, the key is in musical notation rather than a sequence of characters or bytes. The first staff of the page represents the key of the cipher, as the label clearly shows. The encryption key is composed of the four elements mentioned above: a treble clef, in C minor, using 1/8 as the rhythmic unit:

Solfa Cipher Key used in NSEC17
Figure 6: Solfa Cipher Key used in the passport at NSEC ’17: treble key in C minor with a 1/8 rhythm is used.

Each note is linked to a the seven pitches of the solfege, i.e. Do (D), Re (R), Mi (M), Fa (F), Sol (S), La (L) and Si (T). The “KEY-554” is only a randomly generated label and has no significance in the algorithm. With the key known, this puzzle becomes a chain of translations from musical notes to a list of tuple of tones and rhythms using the standard matrix below:

Do (D) Re (R) Mi (M) Fa (F) So (S) La (L) Ti (T)
1:  T I A S E N O  :1
2:  K Z X J Å Æ  :2
3: R C H M D L U  :3
4: F Y G P W B V  :4

Table 3: English language translation matrix usually used for the Solfa cipher.

The columns represents the pitch, while the rows represent the duration of the note (1, 2, 3 or 4).

Let’s go through a complete example to better understand the process. Consider the staff below:

Example of a Solfa-encrypted message
Figure 7: The word “SOLFA” encrypted using the Solfa Cipher

In this case, we assume that we are using a 4/4 meter i.e. the length of a single measure.  That means that each measure has a duration of 4 units. The key used to generate this melody was in C major, with a clef of Treble and a rhythmic unit of 1/4 (Quarter). The first note is Fa and starts at the first time unit, i.e. 1. Therefore the first note can be translated to (F, 1). The Fa is 4 units long, meaning that the second note, Si, also starts at time 1, translating to (T, 1). However this time, the note is only 2 time units long and thus the third note – Sol – starts at 3 and lasts only 1 time unit. Thus the third node is translated to (S, 3) while the fourth one will be translated to (D, 4). Finally, the last note is a Mi and starts at 1 and thus is translated to (M, 1). Putting everything together we have (F, 1), (T, 1), (S, 3), (D, 4) and (M, 1). Using the matrix above, we obtain (F, 1) = “S”, (T, 1) = “O”, (S, 3) = “L”, (D, 4) = “F” and (M, 1) = “A” and thus the plain text is the word “SOLFA”. This process is better represented in the figure below:

Decryption of the Solfa-encrypted word "SOLFA"
Figure 8: Decryption of the word “SOLFA” by reading the notes and their duration.

Going back to the NSEC challenge, we have a much larger melody to decrypt. Luckily, we have the key and the same process as the one we used to decrypt the cipher text in figure 8 applies.

Solfa-encrypted Message from the Passport
Figure 9: Solfa-encrypted Message from the Passport in NSEC ’17

Let’s take the first 9 notes listed in the figure above. For each of the note, we first determine its pitch (do, re, mi, …) and then its duration. The key given specify a 1/8 rhythm, as such a Eighth note will be worth 1 time unit, a Quarter note will be worth 2 time units and the half note will be worth 4 time units. Unless specified otherwise, the meter is 4/4, i.e. a measure is 4 time units long.

First 9 notes of Solfa encrypted for NSEC
Figure 10: The first 9 notes of the Solfa-encrypted message and the initial tempo of the melody.

Using the figure above, we can then extract the notes and their time from the partition:

The note is used as the column and the time as the row to read the corresponding value defined in the translation matrix. We can put a quick script what will read these notes and find the corresponding characters. Using table 3, the notes above will be translated to

d, 1 m, 3 s, 1 d, 4 r, 1 d, 3 m, 4 d, 1 m, 3
T H E F I R S T H

Table 4: First 9 characters decrypted from the partition at the back of the passport.

Applying this process to every note in the figure 9, we obtain the following message:

THEFIRSTHALFOFTHEFLAGISTHEWORDSUBDERMALCONCATENATEWITHTHESECONDHALFTOOBTAINACOMPLETEFLAGGLORYTORAO

Or with spaces and punctuation added: “The first half of the flag is the word subdermal. Concatenate with the second half to obtain a complete flag. Glory to Rao“. Mixing the 2 halfs of the flag, we get the string “SUBDERMALxPlatypus” and get 5 points out of it.

In case you are wondering what the melody in figure 9 sounds like, you can download the resulting MIDI file here: A Revolutionary Lullaby.

Conclusion

Braille and Solfa are quick and fun ways to encode/encrypt data in unusual ways. While they obviously should not be used for serious application, they could potentially be used as novel ways to exfiltrate data and bypass some filters. For example, a text file could be Base32 encoded and the padding character (“=”) could be replace with the number 1 for example. Then the resulting string could be encrypted using the Solfa cipher, transformed into a MIDI file and then uploaded to a remote location. I highly suspect that most network security appliances would not pick up on MIDI file being uploaded, although it would probably strike a careful analyst as suspicious. Feel free to experiment with it. A partial Python implementation can be found here.

References

[1] Simpson, C,  The Rules of Unified English Braille, Second Edition, 2013, International Council on English Braille, https://www.pharmabraille.com/wp-content/uploads/2015/11/Rules-of-Unified-English-Braille-2013.pdf, Visited on 2017-06-05

[2] Chambers, John, An ABC primer, http://trillian.mit.edu/~jc/doc/doc/ABCprimer.html, Visited on 2017-06-04

[3] Solfa Cipher, 2013, http://www.wmich.edu/mus-theo/solfa-cipher/index.html, visited on 2017-06-06

Additional Readings

Schneier, Bruce. Applied cryptography: protocols, algorithms, and source code in C. john wiley & sons, 2007.

Carter, Nicholas. Music Theory: From Absolute Beginner to Expert: The Ultimate Step-by-step Guide to Learning Music Theory Effortlessly. United States: CreateSpace Independent Platform, 2016. Print.

CTF Code : Javascript Code to Quickly Process Data on a Webpage

In quite a few Capture the Flag (CTF) exercises, I’ve seen this challenge – a coding one – which asks the participant to process some information on a webpage in less than X seconds, short enough so that no manual processing can be done. One way to do so is using Javascript.

Share

Introduction

In quite a few Capture the Flag (CTF) exercises, I’ve seen this challenge – a coding one – which asks the participant to process some information on a webpage in less than X seconds, short enough so that no manual processing can be done. One way to do so is using Javascript. In one case, the participant is asked to crack a SHA1 encrypted word.

Method

By first doing manually searching for the hash using a search engine, the plaintext will be found and after doing it 2 or 3 times for different hash, a pattern will emerge in the random plaintext. In this case, random integers between 1000 and 9999 are generated. As such, to solve the challenge, one need to hash all integers from 1000 to 9999 and compare it with the one on the page. Once we have a match, we use the plaintext with a provided URL to get the flag. So in summary:

    1. Figure out the plaintext used to generate the hash. Use Google.
    2. Find a pattern in the plaintext, or boundaries [x,y] in the values used.
    3. Extract the SHA1 from the HTML
    4. Generate a SHA1 hash for each possible value in [x,y]
    5. Compare the 2 hashes. If they match, go to the flag retrieval page.

Code Explanation

Below is the code used for the particular CTF. I used Javascript to prevent managing all the cookies and session stuff. I also used CryptoJS for SHA1 encryption.

Then we iterate all integers between 1000 and 9999. For each, we calculate the SHA1 digest using the Crypto.SHA1() function. Once we find a match, we relocate to the flag retrieval URL.

Full Code

Conclusion

This code can be used with GreaseMonkey or simply by using the developers’ tool included in Google Chrome or Mozilla Firefox.

Removing Debugging Information from Visual C++/C# Projects

It’s often surprising how many malware programmers forget to do the simplest things. Mostly because many are so concerned with functionality, stealthiness and other production concerns, that details slip easily of their minds – a clear advantage to forensics. One of these details is the Program DataBase (PDB) information added by Visual Studio, which most malware authors used for Windows development. While it may seem innocuous, this string reveals a lot about the operating system used by the author, its user name and most notably, symbols that can be used by IDA and ease understanding of the disassembly.

Share

Introduction

It’s often surprising how many malware programmers forget to do the simplest things. Mostly because many are so concerned with functionality, stealthiness and other production concerns, that details slip easily of their minds – a clear advantage to forensics. One of these details is the Program DataBase (PDB) information added by Visual Studio, which most malware authors used for Windows development. While it may seem innocuous, this string reveals a lot about the operating system used by the author, its user name and most notably, symbols that can be used by IDA and ease understanding of the disassembly. This information allows to link multiple pieces of malware together, by using the username for example. Of course, this also allows for the creation of signatures. Thus, removing this information will add a hurdle to the analysts.

Contents

The Program Database File

The Program Database (PDB) is a binary file used to store debugging information about DLL and EXE files. The PDB file is created when you build your project and stores a list of symbols  their addresses along with the name of the file and the line number on which the symbol was declared. PDB files is also used for services collecting crash data to send it to developers for resolution.

Debugging Information

In Visual Studio, you can select to build your project in Debug or Release mode. In Debug mode, VS will include debugging information with your executable. In Release mode, no debug information is included by default, but in some cases is enabled so that if the program crashes, information can be retrieved and sent to the author for fixing. However for some reasons, some developers don’t really bother to use the Release mode, and simply use the executable generated by the Debug mode. Generally, you don’t want that if you are making malware (or any program really!). If left within the executable, a path to the PDB file will be included and can be extracted:

Path to the PDB file
Path to the Program Database (PDB) file used by Visual Studio for debugging purposes, extracted using the “strings” program.

Within the strings, you can determine that:

  1. The program was developed on Windows 7+ (because of C:\Users folder),
  2. The username of the developer is SUPPORT_23e45RT
  3. The source, or part of it, can be found on Github
  4. The original name of the program is CaitSithTest

These indicators can be useful to link this specific program with others and provide a common link between multiple malware. Additionally, the username could potentially be used to conduct open source research and find linked accounts or forum posts. But wait, there’s more…

If you leave the debugging information, you may be able to restore all the original names of variables and functions of the source code using IDA. IDA will first detect debugging information and ask the analyst if he wants to retrieve it, either via Microsoft – http://msdl.microsoft.com/download/symbols (not browseable)- or by looking locally.

IDA detected that debugging information is available and ask if the user wishes to retrieve it.
IDA detected that debugging information is available and ask if the user wishes to retrieve it.

If for some reason, the user is able to retrieve the information, he will have access to the names of the original symbols, which will make reverse engineering much more easier.

Since symbol information is available, the original names of the variables are displayed.
Since symbol information is available, the original names of the variables are displayed.

Compare the information from the figure above to the figure below, in which debugging information has been stripped at build time:

IDA could not find any debugging information and thus used its own labelling system to identify variables.
IDA could not find any debugging information and thus used its own labelling system to identify variables.

You can see that the variables defined in the first figure, such as ClipboardData, isProcessElevated and isDebugged have been preserved. By keeping information about the symbols, reverse engineering is much more easier compared to figure 2, in which information about the code is lost.

Disabling Debugging Information

To prevent VC from including this information in your executable, right click on your project, go to Project Properties > Linker > Debugging configuration menu. Select No in the Generate Debug Info option.

Removing debugging information in Visual Studio.
Removing debugging information in Visual Studio.

After doing this, rebuild your project and rerun the string extraction program against your binary, the path to the PDB file should not be present in the executable anymore.

no_debug_info
The path to the PDB file is not included in the executable once debugging information has been omitted.

Doing so makes it a bit more difficult to fingerprint the malware and hides information about the author’s system.

Conclusion

This is a simple tactic that is often omitted not only by malware author, but penetration testers, which are often Google programmers, i.e. copy-pasting code snippets from Stack Overflow or googling functions 😉 If you attempt to hide your malware into the System32 folder, looking for this information in the EXE or DLL files will quickly tell you which files are bad, since legitimate files will rarely have this info, or have legitimate looking one. As such, if you want to make sure, create a legitimate-Microsoft-looking user (Bill.Gates) on your machine and put your code into a Microsoft-looking project and path (C:\users\Bill Gates\Documents\HTA\Release\).

Gears of (Cyber)War – C++ Code to Detect Version of Windows

A common structure in malware, and also in many legitimate software is to recognize what is the underlying operating system (OS). Depending on the version of it, the virus may want to take different route to execute its activities. This functionality can be reused across different programs and is therefore useful to create and optimize. In this post, we design a function to detect the version of the Windows OS on which the program is currently running.

Share

Introduction

A common structure in malware, and also in many legitimate software is to recognize what is the underlying operating system (OS). Depending on the version of it, the virus may want to take different route to execute its activities. This functionality can be reused across different programs and is therefore useful to create and optimize. In this post, we coded a function to detect the version of the Windows OS on which the program is currently running.

Windows Versions

The Windows OS is known to have a confusing version system, which is often the result of marketing pressure. As such, while all software usually follow a version number specifying the major version, the minor version and the revision (and sometimes the build), Windows swings between years of release (ex. Windows 2000), fancy names (Windows Vista) or some designated number (Windows 7). However, in the underlying machinery of Windows are defined standard version numbers, ex. 5.1. Below is the correspondance between Windows operating systems and standard versions.

When programming in C/C++, the version number of Windows can be obtained via the OSVERSIONINFO structure (or OSVERSIONINFOEX) and the GetVersionEx Windows API function:

The version information described in the table above is stored in the dwVersionMajor and dwVersionMinor of the OSVERSIONINFO structure. All version of Windows in the table above will store the value VER_PLATFORM_WIN32_NT (0x2) in the variable dwPlatformId of the structure.

Branching C++ Code Based on Version

Based on the description above, we can create a reusable function to detect the version of the Windows OS:

Note that in many cases, we won’t know if the OS is the workstation version of Windows or the server version of it. Also, there is no details for other versions of Windows, i.e. Windows CE, Windows 95 (…should it still be used somewhere..). That’s where OSVERSIONINFOEX is useful. The wProductType variable will be set to VER_NT_WORKSTATION if the current OS is the workstation version. Furthermore, you can retrieve service packs numbers and edition information with wServicePackMajorwServicePackMinor and wSuiteMask. So if you need more details about the Windows OS, you can include these as well:

For a full version of the procedure, visit this GitHub page, you’ll find the C/C++ code.

Conclusion

Practically any malware at some point will need to check the version of the operating system being infected in order to enable specific functions or exploit certain vulnerability. Rarely will this check go as far as getting the suite, but Remote Access Tool (RAT) and bots will report the operating system, the version and the service pack. If you are a malware analyst, expeect this function to be present in whatever piece of code you’re analyzing.

Starting in Exploit Development – Day 02

Share

Using Kali and Virtual Box Guest Additions

Hopeful that I’ll waste a lot less time than yesterday, I’ve setup a Kali virtual machine. I had one problem while installing: as soon as the actual installation started, I had a “The failing step is ‘Install the System'” error message. This was solved when I created a 15GB Virtual Hard Drive (VHD) rather than a 10GB Virtual Box Drive. I also had to setup Kali so it works with VirtualBox Guest Additions. You’ll first need to update the sources in /etc/apt/sources.list by including the second repositorty(http://http.kali.org);

Once done, update the package lists by running apt-get update and then install the the linux-headers for Kali:

Finally, install the guest additions as described in the Kali FAQ [1]….and realize it doesn’t work. According to the log file, 2 errors occured:

This can be solved by using the latest version of VirtualBox. Once I’ve upgraded to 4.3.8, I was able to compile the Guest additions with no trouble.

The Fun Finally Begins…Exploitin’

Continuing Part 2 of Fuzzy Security exploit tutorial. So now, I can finally use the pattern_create.rb script to find out at which position in the payload I need to put the return address in EIP. In the latest version of Metasploit, pattern_create.rb is in the following directory:

After creating the pattern and putting it in the python script, the EIP registers overflows with value 0x69413269, which correspond to offset 247 of the payload.  So far so good.

Metasploit Pattern in EIP
Metasploit Pattern in EIP
Offset Required to Overwrite EIP
Using Mona.py to find the offset of the Metasploit pattern required to overwrite EIP

Once confirmed, then we need to redirect the program’s execution flow to the ESP, the stack pointer, according to tutorial of Fuzzy Security. Good enough, but why ? Well the ESP always points to the top of the stack, which contains an address. If you look at the screenshot above, you’ll notice that the address contained in ESP, 0x00C7FC2C contains our “C”s, i.e. a value we control as well.

ESP Overwritten with "C"s
ESP Overwritten with “C”s, indicating we can place our shellcode at ESP

So if we replace those “C”s with our shellcode, our objective will be to find a way to jump to the address contained in ESP. To do so, we will find an “jmp esp” instruction in memory, and put the address of the instruction in EIP – the register that contains the address of the next instruction to execute.Use “mona jmp -r esp” to locate the JMP instruction. Once Mona is finished, select View -> Log to see the result.

Pointers to a "jmp esp" instruction
Results of the search for pointers to a “jmp esp” instruction

The results I have differs from the one of the tutorials. Shouldn’t be an issue, so I’ll take the one in “ntdll.dll” (0x7C91FCD8) as it seems to be a stable DLL. In little endian form, it becomes “\xD8\xFC\x91\x7C”. To test if it works, you’ll need a breakpoint at whatever address you are pointing, otherwise the execution flow will just land somewhere in memory. To add a breakpoint, right click in the CPU view, select “Go to” -> “Expression” and in the window, type your address (big endian). After you clicked OK, you should land on your address. Then press F2 to toggle the breakpoint at this location.

Following an address in memory using Immunity Debugger
Right click on the main CPU view, select “Go To”, “Expression” and type the address.

So we have verified it worked, we can now move on. I won’t fray to far from the tutorial and just generate a local shell bind payload on port 13373. To do, we’ll need the following Metasploit tool:

Basically what this command does is generate the shellcode for binding a shell on port 13373. It then encodes it in bytes without using bytes 00, 0A and 0C. “\x00” is a terminator value for strings. If included in the shellcode, it will break the code. The same goes with 0A and 0D, which are the “New Line” and “Carriage Return” values (i.e. chr(10), chr(13)). The “-t py” option specifies that the output will be formatted in Python. I thought I could almost conclude this session, but of course, I had to hit one more hiccup. After running the exploit, the debugger throw an “Illegal Instruction” exception at 0x00C7FC28, where the first byte of the shell code is.

I’ve wonder many minutes about this issue. I’ve decided to just plain follow the tutorial and choose the same port, 9988 and regenerate the shell code. To my astonishment, the new shell code worked! The first byte is different, but I’m still not sure why the new code works while the other don’t. More to follow…

In any case, the exploit worked and opened port 9988 on the target machine, which can be connected with netcat.

[1] “Kali Linux Virtual Box Guest.” Kali Linux Official Documentation. http://docs.kali.org/general-use/kali-linux-virtual-box-guest (accessed March 14, 2014).

Firefox Javascript Vulnerability

Share

Once again, Javascript is the source of a new exploit that has been recently discovered on Firefox1. The vulnerability can be exploited by crafting malicious Javascript code on a Firefox 3.5 browser and leads to the execution of arbitrary code on the user’s machine. This is due to a vulnerability in the JIT engine of Firefox and affects machine running a x86, SPARC or arm architectures.

The vulnerability resolves around the return value of the escape function in the JIT engine. It’s exploited using the <font> tag. The code for the exploit is public and can be found at milw0rm. The exploit use a heap spraying technique to execute the shellcode.

A fix should be available soon, but the best solution is always to disable Javascript, although a lot of sites rely on it to operate. Another way is to use the NoScript plug-in, which let you enable and disable scripts easily according to a whitelist/blacklist system.

See also:

Mozilla Firefox Memory Corruption Vulnerability”, Secunia, July 14, 2009, http://secunia.com/advisories/35798/ accessed on 2009-07-15

Exploit 9137”, SBerry, July 13, 2009, http://milw0rm.com/exploits/9137 accessed on 2009-07-15

Stopgap Fix for Critical Firefox 3.5 Security Hole”, Brian Krebs, The Washington Post, July 14, 2009, http://voices.washingtonpost.com/securityfix/2009/07/stopgap_fix_for_critical_firef.html accessed on 2009-07-15

Critical JavaScript vulnerability in Firefox 3.5”, Mozilla Security Blog, July 14, 2009, http://blog.mozilla.com/security/2009/07/14/critical-javascript-vulnerability-in-firefox-35/ accessed on 2009-07-15


1 “Mozilla Foundation tackles Firefox bug”, Nick Farell, The Inquirer, Wednesday, 15, July, 2009, http://www.theinquirer.net/inquirer/news/1433480/mozilla-foundation-tackles-firefox-bug accessed on 2009-07-15