Ciberseguretat Nintendo Switch 2 homebrew ROP ASLR

L’exploit ROP de Nintendo Switch 2: què demostra i què encara no permet fer

Una prova de concepte encadena fragments de codi de la Switch 2, supera l’ASLR amb una filtració d’adreces i mostra un error personalitzat.

Una nova prova de concepte de seguretat a Nintendo Switch 2 mostra una cadena ROP capaç de reutilitzar codi del sistema, localitzar biblioteques a la memòria i cridar algunes funcions. El vídeo de NinTricks explica per què és un avenç tècnic, però també deixa clar que no equival encara a un jailbreak, a control del nucli ni a una via directa per executar còpies de jocs.

Què és ROP

ROP són les sigles de «return-oriented programming», programació orientada al retorn. La tècnica va aparèixer com a resposta a una defensa bàsica dels sistemes moderns: impedir que una zona de memòria destinada a dades, com la pila, pugui executar instruccions.

En un atac clàssic de desbordament, un error permet escriure més dades de les previstes i sobreescriure informació contigua. Històricament, l’atacant podia col·locar un programa propi a la pila i modificar l’adreça de retorn perquè el processador saltés fins aquell codi. Quan el sistema marca la pila com a no executable, aquest camí deixa de funcionar.

ROP evita introduir instruccions noves. En lloc d’això, busca fragments molt curts de codi que ja existeixen en biblioteques legítimes i que acaben amb un retorn. Aquests fragments s’anomenen «gadgets». Encadenats en l’ordre adequat, poden sumar valors, moure dades o cridar funcions. La guia d’Arm descriu la idea com la construcció d’un programa nou a partir de peces de codi legal ja presents en regions executables.

El paper de la pila i les adreces de retorn

Quan una funció acaba, consulta una adreça guardada per saber on ha de continuar el programa. Si una vulnerabilitat permet modificar aquesta informació, és possible dirigir cada retorn cap a un gadget diferent. La pila es converteix així en una mena de guió que indica quina peça s’executa després.

La dificultat no és només escriure la cadena. També cal saber on es troba cada fragment en memòria. Un salt a una adreça equivocada normalment provoca que l’aplicació es tanqui.

ASLR: moure el mapa a cada execució

L’ASLR, o aleatorització de l’espai d’adreces, carrega el programa i les biblioteques en posicions variables. Una cadena preparada amb adreces fixes deixa de ser reutilitzable si aquestes canvien en reiniciar el procés.

Per superar aquesta defensa, una explotació acostuma a necessitar una filtració d’informació que reveli almenys una adreça real. A partir de la base d’un mòdul i dels desplaçaments coneguts dins del seu codi, es poden calcular les ubicacions dels gadgets. És el que fa rellevant que la demostració mostri valors identificats com «main base» i «SDK base».

Què ensenya la prova

Segons l’anàlisi del vídeo, la seqüència comença obtenint una primitiva de lectura i escriptura. Al principi és inestable i després passa a un estat estable, condició necessària per preparar la pila sense corrompre la mateixa cadena.

La demostració localitza les bases del programa i del kit de desenvolupament, prepara la cadena ROP i intenta cridar una funció relacionada amb sockets. Aquesta crida retorna un error, possiblement perquè falten paràmetres o permisos, però el fet que arribi a la funció és el senyal tècnic important.

Després es localitza una funció del sistema que mostra errors d’aplicació. La prova aconsegueix obrir la pantalla i introduir-hi un text personalitzat. Això és una evidència visual que la cadena pot reutilitzar funcions existents i controlar-ne almenys part de les dades.

Per què no és encara un jailbreak

Executar ROP dins d’un procés d’usuari no implica haver trencat totes les capes de seguretat. La demostració no acredita control del nucli, elevació de privilegis, persistència després de reiniciar ni accés general a qualsevol recurs. Tampoc presenta un carregador complet de programes casolans.

Un socket que retorna error i una finestra personalitzada són fites útils per a la recerca, però queden lluny d’un entorn estable per a «homebrew». Encara caldria ampliar les primitives, entendre els permisos, travessar altres aïllaments i mantenir compatibilitat amb versions concretes del sistema.

PAC i altres defenses d’Arm

Els processadors Arm moderns poden incorporar autenticació de punters, coneguda com PAC. Aquesta funció associa una signatura a determinats punters i permet detectar modificacions no autoritzades abans de fer un salt. Arm la presenta expressament com una mitigació contra ROP.

Que una cadena funcioni en un context concret no vol dir que totes les proteccions estiguin absents. Les defenses poden aplicar-se de manera diferent segons el procés, el tipus de punter o la versió del programari. Per això, a partir d’un vídeo curt no es pot concloure que tota la Switch 2 sigui vulnerable de la mateixa manera.

Recerca, actualitzacions i divulgació responsable

Nintendo manté avisos de seguretat per a Switch i Switch 2 i adverteix que alguns detalls poden ometre’s per evitar facilitar l’explotació. També disposa d’un canal de comunicació de vulnerabilitats. Per als usuaris, la recomanació prudent continua sent mantenir el sistema actualitzat i no executar eines d’origen desconegut.

El valor de la prova és mostrar una cadena tècnica coherent: corrupció de memòria, lectura i escriptura, filtració de bases, localització de gadgets i crides controlades. És més que una imatge decorativa, però menys que una ruptura completa de la consola. Aquesta diferència és la clau per entendre l’entusiasme del vídeo sense convertir-lo en una promesa prematura.

Contrast i context

Fonts consultades

4 fonts
  1. 01
  2. 02
  3. 03
  4. 04

Font de treball

Transcripció amb marques de temps

10 fragments
Consulta la transcripció
  1. 0:01 , obre el vídeo en una pestanya nova

    Uno de los personajes más importantes de la escena de PlayStation está haciendo cosas en la Switch 2 y parece que funcionan. Esto iba a ser en origen un vídeo para bajar un poco el sufle por una noticia que ha salido, pero la verdad es que ilusiona bastante y quiero explicaros por qué. Además tengo fundamento para ilusionarme, no me ilusiono gratis. El culpable de esta ilusión se llama Gacine y es un desarrollador muy activo en la comunidad de PlayStation. Si no habéis visto el vídeo aún de hacer bagi al PlayStation 5, el método que usamos o por lo menos el exploit está desarrollado por él. él o ella, en realidad no lo sé, pero voy a decir él por decir algo, es el personaje. La cuestión es que hace unos cuantos días subí un vídeo, además comunicando que había dicho que había encontrado una vulnerabilidad en el tema de las notificaciones de la Switch y de la Switch 2. Todo esto en Switch 2, ¿vale? Diré a lo mejor Switch, pero es Switch 2. Parece algo poco reseñable, poco representativo, pero viendo el vídeo parece más serio de lo que creíamos. En este vídeo te voy a explicar la vulnerabilidad y en qué se apoya. Vamos a hablar un poco a nivel técnico, además no va a ser nada complicado de entender, pero sí que vamos a meternos un poco más adentro, más allá de decir, "Oye, mira, encontrado esto y usa R." Sin explicar qué es eso. Y es que tenéis la suerte de que vengo de estudiar esto y y un amigo mío ha hecho el TFG de esto y hemos hablado un rato acerca de esta vulnerabilidad y nos está ilusionando a los dos. Así que un abrazo a mi amigo, Shootout para él que sé que metía en RSS. Y vamos a hablar de R. ¿Qué es R? Son siglas. Returned Oriented Programming. Programación orientada al retorno. Vamos a echar un poco la vista atrás y vamos a ver un poco de historia. Y es que, ¿cómo ejecutabas antes código arbitrario escrito por ti de terceros,

  2. 1:34 , obre el vídeo en una pestanya nova

    que la consola no estaba diseñada para ejecutar ese código? ¿Cómo ejecutabas tú tu propio código? ¿Cómo lo metías? ¿Cómo hacías que el puntero que dice, "Ahora esta instrucción, después esta, después esta." ¿Cómo conseguías que ese puntero apuntara a tus instrucciones? Pues era algo relativamente relativamente sencillo. El método clásico era desbordamiento de buoofer. En inglés buofer overflow clásico. También se puede hacer con desbordamiento de pila. En este caso era stack overflow como la famosa web. Buoofer overflow es el nombre genérico porque un buoofer es una zona donde guardas datos y overflow es pasarte, desbordar. Sí, la palabra en español lo explica muy bien. Habitualmente la pila es una estructura de memoria donde los programas tienen ahí como una especie de cajón desastre donde guardan datos y simplemente eso. Datos temporales, nada serio, simplemente pues oye, tengo una variable, no me cabe en los registros del procesador, no tengo tantos almacenajes de datos, me lo guardo aquí un ratito y después ya volveré. Pero como digo, son para cosas muy temporales, variables eh muy volátiles. También sirven además para comunicar información entre procesos. Por ejemplo, yo soy una función y quiero enviarle a otra función que haga algo con un número. ¿Cómo le paso el número? Se lo puedo dejar en la pila. Lo meto en la pila y después la otra función sabrá que tiene que ir a la pila a buscar el número que le he dejado. La cosa es que muchas veces nadie se asegura de que esa pila pues eh quepa lo que tú estás metiendo en la pila. Entonces, puedes empezar a meter y vas pasándote y vas desbordando. Dentro de estos desbordamientos puedes pisar cosas que ya estaban escritas, sobreescribir información. ¿Y qué información interesante podríamos sobreecribir? Pues dos cosas muy interesantes. Una cosa llamada el payload, que es el programa que queremos ejecutar nosotros, que hemos escrito nosotros, y lo podemos escribir en la pila directamente. Y otra cosa es la dirección de retorno de la función. Y es que, muy bien, has escrito tu código, pero cómo llegamos a ejecutarlo vas a tener que saltar a él. ¿Y cómo hacemos que salte a él? haciéndole creer al programa principal que para volver, porque acaba su ejecución de la función y tiene que volver al flujo principal, que para volver tiene que volver casualmente a donde has dejado tú tu payload, tu programa. La función volverá

  3. 3:36 , obre el vídeo en una pestanya nova

    y dirá pues a seguir ejecutando lo que me toque. Y dirá, hombre, una instrucción, hombre, otra instrucción y así, así, así. y nos ha dado cuenta de que ha ejecutado tu código. Como digo, esto era un clásico, un completo clásico. Y como era un clásico, pues los sistemas empezaron a defenderse de este tipo de ejecuciones. Y es que hay una manera muy fácil de evitar que tú ejecutes el código de la pila y es hacer que la pila, que en teoría es solo para guardar información, guardar datos, pues que no puedas ejecutar nada de ahí. Con lo cual, si el puntero por alguna magia que hayas metido tú, empieza a ejecutar cosas de ahí, dice el procesador, "Ey, ey, ey, aquí no se puede ejecutar nada. y pues peta directamente. Eso, como comprenderás, querido espectador, es una putada. Y es que aún puede sobrescribir esa dirección de retorno a la que tú saltarás, pero ya no puedes saltar algo que hayas escrito tú, porque lo que escribas no lo vas a poder ejecutar. Vas a tener que saltar obligatoriamente a zonas de código que sí que se pueden ejecutar. ¿Y qué zonas son esas? pues las zonas que ya vienen en el sistema operativo. Entonces, alguien tuvo una gran idea y desarrolló, inventó y explotó la R, la return oriented programming, programación orientada retorno. Y es que dicen, hombre, si yo puedo elegir a dónde volver, puedo volver a librerías compartidas, por ejemplo, las conocemos, sabemos dónde están y podemos ejecutar nada, tres líneas y que vuelva. Por ejemplo, al final de una función de una librería, pues yo que sea, lip, una librería famosísima que se usa muchísimo, pues al final de una función coge dos registros y lo suma y tú saltas directamente a esa

  4. 5:09 , obre el vídeo en una pestanya nova

    instrucción de sumar. Entonces harás la instrucción de sumar y esa propia función, como acabará justo ahí, dirá, "Vuelvo", entonces volverás a donde estabas y dices, "Vale, te vuelvo a sobrescribir la dirección de retorno y ejecuto otro trocito de código." Encadenando esa sobrescritura y direcciones de retorno, puedes encadenar muchos de estos gadgets que se llaman. Son como trocitos de código muy pequeño que hacen funcionalidades muy concretas, como por ejemplo sumar dos números, restarlos, compararlos, eh cargar de memoria, eso es un poco más complicado, pero es eso, limitar trocitos muy pequeños de los finales de las funciones, de lo que te queda al final, justo antes de que acabe y vuelva al programa principal, usar esos trocitos para aprovecharte de ellos. Esos trocitos viven en zonas que se pueden ejecutar, con lo cual los vamos a poder ejecutar. Esos trocitos podemos saber dónde están porque en la memoria no cambian las direcciones de las cosas, ¿verdad? Ahora hablaremos. Entonces, a partir de ahí sabes a dónde saltar. Fin del problema, conseguido, funcionando. Evidentemente no es todo tan bonito. Y dijeron los los que desarrollan sistemas operativos, "Oye, por seguridad antes cargábamos siempre las librerías en el mismo sitio, con lo cual el hacker podía saltar siempre en la misma dirección. Vamos a joderle la vida." Y hay un protocolo muy sencillo y es el ASLR. Adress layer randomization, que es básicamente una aleatorización del espacio de memoria. En cristiano, tú antes tenías tu bloque de memoria, simplemente y tenías todo en orden. ¿Qué hacemos ahora? Pues vamos a separar la memoria en trozos y vamos a que aleatoriamente se guarden en distintos trozos de la memoria física. Tú como programador no te tienes que preocupar de esto. Si tú le dices que quieres a la dirección 100, el procesador se va a encargar de interpretar dónde lo ha eh barajado, dónde lo ha colado ese trozo de código, te lo busca y te lo entrega. Todo bien, pero de cara a alguien de fuera que no sabe muy bien cómo va la cosa, cada vez que ejecute el programa o cada vez que inicie el sistema operativo, depende cómo funciona la cosa, se encontrará con que ese trozo de código unos días está aquí, otras veces está allá y otros momentos está en

  5. 7:11 , obre el vídeo en una pestanya nova

    otro sitio. Con lo cual nunca vas a tener un punto concreto donde saltar porque es aleatorio donde vas a cargar los programas y las librerías, que las librerías es lo que aprovechábamos con los gadgets y esos trocitos de código finales que se encarga el ROP de explotar. Entonces, ahora tenemos un problema y es encontrar dónde están estas librerías. Habitualmente esto se hace a prueba error, entonces bien, ¿no? Si con un poco de fuerza bruta puedes encontrarlo. Y además si las librerías son lo suficientemente pequeñas suelen estar juntitas y una vez encuentras una encuentras un montón. Además el orden en el que se ponen es casi siempre el mismo porque la compilación es la que es y ya está. Y una vez encontrado el contenedor donde se encuentra todo, en general ya te has encontrado y ya sabes cómo funcionar. Así que resumen, ¿qué está pasando aquí? Estamos sobreescribiendo las direcciones de retorno para que tu programa principal crea que tiene que volver a sitios que no debería. Y esos sitios que no debería son trocitos muy concretos de funciones muy cortitos que hacen funcionalidades muy concretas. Con esos trocitos podemos encontrar eh pequeñas funcionalidades y crear un programa un poco más elaborado para intentar buscar un agujero. Parece medio fácil, pero es que para encontrar esos trocitos hay que analizar las librerías, ¿no? Es sencillo, porque la búsqueda inversa, además de eso, es muy compleja. Muchas veces ni siquiera se hacen saltos alineados según el procesador. Por ejemplo, los Intel no son alineados. En este caso de Switch, ARM es salto alineado. Es más difícil que por casualidad un byte aleatorio que signifique otra cosa porque empieza más tarde o más pronto, tú lo cojas a medias y diga, "Ostras, pero si esto si salto justo aquí cogiéndolo a medias", significa suma el número uno y el número dos. Entiendo que es un poco complicado de entender si es la primera vez que te enfrentas a estas cosas, pero básicamente es eso, reciclar código en trozos muy pequeños para hacer lo que tú quieres. Esto en PlayStation se ha hecho y lo que se hacía con estos trocitos de código era abrir sockets, abrir como canales de comunicación que se podían comunicar con el navegador y el

  6. 9:12 , obre el vídeo en una pestanya nova

    navegador con código en JavaScript clásico que podías ejecutar desde una web se comunicaba con el sistema. De esta manera, PlayStation cayó varias veces. Analicemos ahora un poco el primer fotograma. fotograma, el primer cacho de vídeo. Voy a apartarme un poco a ver si lo puedo poner un poco más grande, no ocupo yo demasiado. Empieza diciendo got unstable RW primitiva. Básicamente la primitiva RW read great leer, escribir, eh, pues no un estable, inestable. Es posible que en las primeras instancias de la ejecución pues sin querer pises cosas, eh, tengas condiciones de carrera feas, en fin, que probando pues no va. Entonces tienes que volver a intentarlo hasta que pone stable RW primitive, con lo cual significa que ya puedes leer y escribir ese trozo de pila cómodamente, sin romper nada. ¿Cómo comprenderéis? Esto es vital porque si tú pones las direcciones a las que quieres volver con los trocitos a los que quieres saltar y peta, pues no va. Y si se te corrompe ese trozo de memoria, pues tampoco va, porque dejarás de saltar a donde quieres, te lo habrán pisado. Es importante que nadie vaya a volver a escribir eso. Después vemos dos líneas muy importantes. Una dice main base y la de debajo dice SDK base, eh, software development kit. Básicamente, Mainbase te dice la dirección de memoria donde empieza el programa main, el programa base, en este caso el la prueba de concepto que está ejecutando en el vídeo para ejecutar esta pequeña magia, este pequeño truco de magia. Y SDK base te dice la dirección base donde se guardan las librerías.

  7. 10:43 , obre el vídeo en una pestanya nova

    las librerías. Como solo tenemos un vídeo, no lo podemos confirmar, pero por la aleatorización del espacio de memoria, cada vez que ejecutemos esto, pondrá unas direcciones distintas. Ahora el main te lo ha puesto en la 4BB0A06, pero a lo mejor en la siguiente ejecución en vez de 600 pone 500 y [resoplido] te lo pone un poquito antes en la memoria o un poquito después. Lo mismo con las librerías. va a barajar el código y lo va a mezclar todo. Lo importante aquí es que ha conseguido localizar dónde empieza el programa principal y más importante dónde dónde empiezan las librerías. Ya que una vez encontrado el inicio de las librerías, de esos trozos de código que vamos a poder ejecutar, trocitos pequeños que vamos a poder ejecutar, podemos sumar simplemente el offset, el cómo se decía offset en español, el desplazamiento. Si tú sabes que tu función a la que quieres saltar está 100 posiciones de memoria para adelante, pues tienes que encontrar dónde empiezas y contar 100 más. El problema es encontrar ese principio dónde empiezas, pero vemos que lo ha encontrado. Finalmente hace un testing de del RP de todo esto con un socket, con un canal de comunicación. Encuentra la dirección del canal de comunicación, la escribe por pantalla y pone que ha devuelto. Además, comunica que la respuesta tiene que ser fff -1. -1 es un código de error clásico de las funciones. Las funciones que te tienen que devolver cosas te las devuelven. Cuando toca, por ejemplo, la dirección del canal, el ejemplo perfecto, o el resultado de una operación o cosas así, pues te lo devuelven. Y si fallan, pues suelen devolver -1, porque las direcciones -1 no existen. Es un notación internacional, esto es estándar. Vemos que en efecto la respuesta es 0x, el -1 que he dicho las fs y dice que rop setup finished que ha acabado. Hemos visto que ha podido ejecutar un socket, que ha podido llamar a la creación de un socket, parece ser, y que devuelve -1. ¿Por qué? Pues porque faltarían parámetros, porque a lo mejor no tenía los permisos necesarios para ejecutar esa función, eh, en general porque no ha hecho algo adecuadamente. Pero, ¿qué significa esto? Que ha conseguido ejecutar la función, ha conseguido

  8. 12:46 , obre el vídeo en una pestanya nova

    saltar a donde quería. Y eso es lo importante en este vídeo de hoy. Finalmente, aparecen tres líneas más. una que dice show application error address, que es la dirección de la función creemos show application error y llama a esa función encuentra, digamos la ubicación de la función de errores de la Switch. Cuando te salta un error, pues a qué llama para que te aparezcan la pantallita, los botones, el código error y toda esa vaina. Y después vemos que sube aplication error, return lo que toque, el valor que devuelve. Vemos además en el vídeo que aparece el mensaje de error. Tapa el código de error. No sé si para evitar que Nintendo vea exactamente el código de error que salta o por algún otro motivo, no lo tengo muy claro, pero vemos que ha podido escribir sus propios detalles de error. Esto es muy interesante. ¿Por qué? Pues porque hemos visto que ha conseguido llamar a una función de librería, en este caso la de mostrar error, que no creo que sea especialmente interna del kernel, pero desde luego es importante, es del sistema operativo y ha conseguido escribir lo que le ha dado la gana. En este caso da agradecimientos a gente de la comunidad de PlayStation y también a otra gente de la comunidad de Switch. En resumen, podemos ver que ha hecho cosas muy importantes. Cuatro. La primera, corrupción inicial para conseguir eh escritura y lectura de la pila. escribir lo que tú quieras, en este caso las direcciones de retorno de estos trocitos de código. Segundo, encontrar dónde está el trocito de código, esa fuga de información que consigue destruir la la aleatorización del espacio de direcciones, consiguiendo que ya sabes dónde está cada cosa o por lo menos cada cosa que vas a usar. Consigues además preparar la pila efectivamente con esa información, los

  9. 14:18 , obre el vídeo en una pestanya nova

    saltitos y más importante localizar los trozos de código que tienes que ejecutar. Eso es muy importante y es algo serio. Y por último, la ejecución secuencial, en este caso, una detrás de otra, de funciones. Eh, pues crear un socket o lanzar un mensaje de error. El socket, como hemos visto, ha dado error, pues porque a lo mejor no ha puesto la información necesaria, porque no la conoce, porque no le deja el sistema, ya que no tiene los permisos suficientes. Obtet saber por qué. Y después vemos que el mensaje de error sí que ha podido añadir información, información del error, los detalles y además se ha ejecutado perfectamente. Es un error perfectamente es que te sal la pantalla y le dices okay y okay. Y ese es el resumen de lo que ha pasado hoy. Eh, puede ser una puerta de acceso. Puede ser, puede ser. Y hemos visto que esto es más serio que una notificación de fulanito está en línea. Hemos ejecutado código, hemos escrito, bueno, hemos se ha ejecutado código, se ha ejecutado eh el código que se ha escrito en la pila para saltar a trozos de memoria y reutilizarlos y se ha hecho R en la Nintendo Switch 2. Ya alguno me dirá, pero Nintrix, esto ya se vio el día uno con un cuadradito de colores. Eh, sí, pero eh hola, soy el Nintrix editor en la penumbra de de un día de verano. Rápidamente acaba de publicar un tweet el propio Gacin el primer tweet de su vida. La cuenta no tiene Twitch, no le seguía, con lo cual mucho ruido no habrá hecho en Twitter porque lo seguiría. y confirma algo muy interesante. El exploit sirve para Switch 1 y Switch 2, esto es importante. Y no emplea ni el webkit ni cosas que tengan que ver con los archivos de guardado. No se modifican archivos de guardado. Esto es aún más importante porque él mismo hace referencia a ese cuadrado blanco y negro del que he hablado o hablaré en el vídeo, pero ya teníamos esto el día 1. La diferencia es que ese exploit necesitaba, estoy aquí con el móvil como un predicador, necesitaba pasar una copia de seguridad con los servicios online de Nintendo Switch, lo que te obliga a estar siempre en el último en la última versión de consola para poder usar los servicios online. Eh, seguramente si arreglaran el webkit o arreglaran el agujero, al actualizar perderíamos el agujero y no se podría ejecutar. Y además como para usar el

  10. 16:21 , obre el vídeo en una pestanya nova

    agujero tendrías que actualizar pues la pescadilla que se muerde la cola no se podría usar. confirma que esto se puede usar sin restricciones y en todas las versiones. ¿Y por qué no hackear el webkit? Pues porque en ARM lo que comentábamos de los altos, hay una cosa llamada pack. Esto he pensado durante la el desarrollo del guion que no iba a ser necesario explicar, pero lo cuento. Pack viene de Pointer Authentication Code. Básicamente es un mecanismo del procesador ARM, es muy reciente que se encarga de mirar si los saltos que estás haciendo son legales. Es decir, si tu puntero por algún motivo está empezando a saltar en funciones de librería los trocitos pequeños que hemos hablado, si empieza a hacer eso, mala señal, peta, adiós, chaval. con lo cual previene toda ejecución de código R y desactivaría este tipo de agujero. En cambio, dice, "Bueno, se echa el moco aquí una madera", dice. Entonces, evité eh hackear el webkit porque vio que iba no iba a funcionar porque estaba protegido, ya que había una manera más sencilla de explotarlo y se queda tan contento que vuelva al Nintrix con luz. En fin, considero que esto ha sido un progreso, considero que hay un avance y déjame en los comentarios qué te parece. ¿Habrá magia próximamente la Switch 2? Esperemos que sí. Pronto, pronto ni de coña. coña. Espero que no haya porque si no me voy a tener que comer mis palabras alegremente. Por lo menos vemos que el trabajo continúa, que Gacine sigue se divierte. Ha dicho PlayStation, me aburre. Vamos a la Switch, pues venga. Y en fin, que tenemos Switch 2 para ratos. De momento vamos a comprar los juegos y vamos a disfrutarlos porque de juegazos es un consolón y si no llega la magia nunca, pues mira, habremos jugado y nos lo habremos pasado bien y habremos disfrutado de todas estas eh manualidades de la informática que se están haciendo actualmente. Así que deja tu like, suscríbete, todas esas cosas que hay que hacer en YouTube y como siempre, gracias por verme.