Buffer overflow exploitation

During my work with Gustavo Grieco, I occasionally have to study some vulnerability. Today I will talk about one that I recently studied, I think this one is quiteinstructive.

The vulnerability is in xa (package xa65, version 2.3.5), if you want to do the manipulation in the same environment, I suggest you to dl the VM from the ocean project : https://github.com/neuromancer/ocean-data (if you need help to configure it, you can send me a message, or directly contact the author, he is reactive)

The crash

The starting point is to launch xa with a long string as parameter :

vagrant@vagrant:~$ xa $(python -c 'print "A"*3000')

We obtain a “Segmentation fault”.

First reaction, we launch again with a tool of tracing, ltrace for example

(x/2i to print 2 instructions, 0x5 is the size of the “call ADDR ” instruction)

So know, let play with IDA, to have a better view of the whole programme (xa is open source, we could of course use the source-code, but we would lose all the fun :p )

After opening xa in IDA, we can go to the instruction 0x8048cbb (menu -> “Jump” -> “Jump to address”)

I rename the function “crash_here” (with the “rename” option, or with the shortcut “n”)

We see that fputs take as argument the same as crash_here (called “s” by IDA). The interesting point is that the second argument (the FILE pointer) comes from the bss section (call ds:stream in IDA). So we can suspect that the buffer overflow occurs in a global variable.

Let’s go see what are in the global variables with IDA (double-clicking on stream) :

We can see something that is interesting, a buffer (“s”), followed by a timer, a __IO_FILE pointer “fp”, and the FILE pointer “stream”.

What you should understand here, is “s” is full of A, but start with another string “Couldn’t open source file ‘”.

We can now calculate from which octet in the input we control the value in stream. To do this you can use the pattern technic (for people in Grenoble, we saw that in the last talk of Boyan). Or you can manually calculate it (I let you find how do this :p )

Exploit some function is quite easy (fclose for example). In other one it’s possible, but I never tried. fputs belonging of theses that I never tried. I did this exploit in a train, so at this point I wanted to find a call to fclose with a controlled pointer, and not try on fputs. (notes :With hindsight, exploit fputs is as easy as exploit a fclose. I realise this exploit in a train, and I had nothing else to do at this time, so I made a mistake by wanting to find a call to fclose, this made the exploit lightly more difficult :p More complicated it is, more funnier it is, so I decide to let this version for the article. The skilled reader would know how to do a exploit slightly easier ).Se was that during the overflow, we overwite a other pointer, called “fp” in IDA.

What would happen if fputs worked and if the program continued to run ? We know that we control stream with a padding of 2033, but we control also fp with a padding a 2029.

However because of the ending caracter added by the string “Couldn’t open source file ‘%s’!\n”, we are able to control fp without overwrite “stream” (“!\n” is added at the end of the string). We will see later how to solve this. In a first time, let’s overwrite fp without stream, so we can just write 2029 caractere, that will overwrite “fp” with “!\n”.

So our input have probably overwrite a FILE pointer that is used in a fclose before “fp”. The interesting thing, is that the value of the pointer is our ending caractere ! So this should be the variable just after “fp” ! (IDA called this one “dword_8058C50”, we will called it “ptr” in the rest of the article).