Name : Gadu-Gadu
Class : Buffer Overflow
Threat level : VERY HIGH
Discovered : 2007-11-10
Published : 2007-11-22
Credit : j00ru//vx
Vulnerable : Gadu-Gadu 7.7 [Build 3669], prior versions may also be affected.
==[ Abstract ]==
Gadu-Gadu is a free internet communicator used by milions of polish people.
It allows to talk, hear and even see other internauts through the net.
It also supports the possibility to express feelings using some provided
emoticons. These emoticons' strings with associated graphic filenames are
stored in "emots.txt" file.
The GG Client is vulnerable to a buffer overflow attack, in the code
that moves the "emots.txt" file data to some local buffers. The program
doesn't check if the size of data to move is not greater than the size
of the destination buffer. Successful exploitation may lead to arbitrary
code execution or the process' denial of service (gg.exe termination).
==[ Details ]==
Function vulnerable to the attack is placed at the 0x00443CE2 address:
.text:00443CE2 HandleEmotsConfig proc near ; CODE XREF: sub_4A55F6:loc_4A5C90p
.text:00443CE2 mov eax, offset loc_561ECC
.text:00443CE7 call __EH_prolog
.text:00443CEC mov eax, 26588
.text:00443CF1 call __alloca_probe
.text:00443CF6 push ebx
.text:00443CF7 lea eax, [ebp-24h]
.text:00443CFA push esi
.text:00443CFB push eax
.text:00443CFC call sub_443A9E
.text:00443D01 xor esi, esi
It is responsible for opening the "\emots\_NUMBER_\emots.txt" files, and then reading
information about emoticons and their graphic equivalents. This is how an exemplary
line of configuration file looks like:
If there's only one string associated to a gif file, the brackets can be skipped.
Also the third part of line isn't essential - it's just the name of optional graphic
file in NETSCAPE GIF format.
During the process of copying data from currently opened file (2nd and 3rd part of
configuration line) to some local buffers, the program doesn't check the
strings' lengths, what can lead to overwriting the 500-byte buffers placed on the stack.
Vulnerable code that copies the name of first gfx file is shown below:
.text:00443E37 loc_443E37: ; CODE XREF: HandleEmotsConfig+164j
.text:00443E37 cmp al, '"'
.text:00443E39 jz short loc_443E48
.text:00443E3B mov [ecx], al
.text:00443E3D inc ecx
.text:00443E3E inc edi
.text:00443E3F mov [ebp-18h], edi
.text:00443E42 loc_443E42: ; CODE XREF: HandleEmotsConfig+153j
.text:00443E42 mov al, [edi]
.text:00443E44 cmp al, 20h
.text:00443E46 jnb short loc_443E37
As you can see, there's no size limitation of the data being moved.
It's, in fact, the same situation in the second piece of code:
.text:00443E87 loc_443E87: ; CODE XREF: HandleEmotsConfig+1B6j
.text:00443E87 cmp cl, '"'
.text:00443E8A jz short loc_443E9F
.text:00443E8C mov [eax], cl
.text:00443E8E inc eax
.text:00443E8F inc edi
.text:00443E90 loc_443E90: ; CODE XREF: HandleEmotsConfig+1A3j
.text:00443E90 mov cl, [edi]
.text:00443E92 cmp cl, ' '
.text:00443E95 mov [ebp-18h], edi
.text:00443E98 jnb short loc_443E87
A Proof of Concept file created during this research exploits bugs in filename
copying code, but it is also possible to execute arbitrary code using an buffer
overflow in other places in the fuction - responsible for moving data such as
strings describing the emoticons and so on.
When copying data using code shown above, the values of some local variables, return
addresses etc. may be overwritten. Modification of proper amount of stack data causes
an exception. There are several reasons for the exception being generated. It can happen
when the filename placed in "emots.txt" is longer than the size of stack,
or in a function under 0x0052F5D0 address, called by the emoticon parsing code:
.text:00443EEE call unknown_libname_52 ; Microsoft VisualC 2-8/net runtime
to be more precise, the instruction under 0x0052F62A causes an exception, because
of the fact that EDI register value is zero in that moment:
.text:0052F62A rep movsd
Among all the data we are able to overwrite, there is a SEH structure, which contains
an address of function being called by the system each time an exception occurs.
Since we can easily cause such an exception, having full control of the address,
where the code execution is passed to, we can make gg.exe execute any code we want.
==[ Solution ]==
The simplest and most effective solution is to place a piece of code checking if the
length of string being copied is not too big. It should be put in every data-moving loop
in the function. It is also worth thinking of moving the local buffers to global process
memory - in case of buffer overflow vulnerability there would be no possibility to
overwrite such important stack data like return/seh addresses etc.
==[ Exploit ]==
A special file exploiting described vulnerability has been created, but isn't going
to be published in any form.
==[ Vendor Status ]==
The vendor has been informed about discovered bug, and released a fixed version.
== Disclaimer ==
This document and all the information it contains is provided "as is",
without any warranty. Author is not responsible for the misuse
of the information provided in this advisory. The advisory is
provided for educational purposes only.
Permission is hereby granted to redistribute this advisory, providing
that no changes are made and that the copyright notices and
disclaimers remain intact.
Copyright (C) 2007 j00ru of the Vexillium.