---
title: "Convertir un e-reader en tu sistema: ingeniería inversa del Kobo Libra 2"
url: "https://quantarmy.com/ingenieria-inversa-kobo-libra-2-plato/"
description: "Hardware hacking de un Kobo Libra 2: ingeniería inversa del arranque, un selector de arranque propio verificado por sha256, kernel propio y Plato convertido en el sistema operativo entero. Con el modelo de amenazas y cifras medidas en el aparato."
lang: "es"
---

# Convertir un e-reader en tu sistema: ingeniería inversa del Kobo Libra 2

Un lector de libros de 512 MB con un SoC i.MX6SLL, sin secure boot y con una partición de usuario montable por USB. Le hicimos ingeniería inversa al arranque, escribimos un init propio que verifica el sistema por sha256 en cada boot y convertimos Plato en el sistema operativo entero. Esto es el proceso, los resultados y lo que se rompió por el camino.

4 nov 2026 · 21 min de lectura · [Read in English](https://quantarmy.com/en/reverse-engineering-kobo-libra-2-plato/)

- [sec](https://quantarmy.com/tag/sec/)

Es un lector de libros. Pantalla e-ink, Wi-Fi, 512 MB de RAM, un SoC que NXP dejó de considerar nuevo hace casi una década. La clase de aparato que nadie mira con ojos de atacante porque "no tiene nada dentro". Y sin embargo tiene todo lo que hace interesante a un objetivo de hardware: una cadena de arranque **sin secure boot**, un mecanismo de actualización OTA que aplica paquetes con confianza implícita, una partición de usuario que se monta por USB como una memoria cualquiera, y un contador en el MBR que decide si el aparato se borra solo.

Este artículo es el registro de lo que le hicimos a un **Kobo Libra 2**: ingeniería inversa de su arranque y su mecanismo de actualización, un selector de arranque propio en C que verifica el sistema por sha256 en cada boot, un kernel propio, y la conversión de **Plato** —un lector de documentos open-source— en el sistema operativo entero del dispositivo. El resultado público se llama **PlatoX** y es software libre (AGPL-3.0); la versión personal, con más cosas enganchadas, se llamó **KoboX**. Vamos a separar las dos con cuidado, porque la seguridad está en los detalles y mezclar ediciones es mentir con precisión.

No es un tutorial de jailbreak. Es un caso de estudio de seguridad del hardware: qué se puede aprender de un dispositivo cerrado leyendo su propio firmware, dónde están los límites reales de confianza, y por qué "integridad" y "autenticidad" no son la misma palabra.

## El ecosistema que había que entender antes de tocar nada

La primera regla de cualquier intervención sobre hardware ajeno: reconstruir el sistema de serie antes de cambiar un solo byte. No se puede defender —ni romper con control— lo que no se entiende.

El aparato es un **Kobo Libra 2**, nombre interno `io`, placa **E70K10**, confirmado leyendo la tabla de PCB de `kobo_config.sh` del propio firmware. Dentro: un SoC **NXP i.MX6SLL** (ARM Cortex-A9), PMIC Rohm **BD71828**, Wi-Fi **Realtek RTL8723DS** por SDIO, pantalla e-ink de **1264×1680** y **512 MB** de RAM. El stack de software de serie, reconstruido pieza a pieza desde el firmware extraído, es un museo de Linux embebido de 2015:

El stack de serie: de U-Boot a Nickel, sin un solo eslabón firmado

- **Arranque:** U-Boot de NXP (`2016.03-00128` en la rama 4.38), **sin verificación de firma**. Quien controle lo que el kernel ejecuta como init, controla el aparato.
- **Kernel:** Linux **4.1.15**, build exacto de Kobo `-00868-g58a2758be07`, compilado con GCC 5.3.0.
- **Userland:** `busybox 1.31.1` como PID 1, **glibc 2.19**, libstdc++ de GCC 4.9. udev 142, `wpa_supplicant 2.9` sobre **OpenSSL 1.0.1u**.
- **El lector:** **Nickel**, la aplicación Qt de Kobo, con su tienda y su cuenta.
- **`pickel`:** un wrapper de shell que ejecuta `pickel-imx` (un ELF). Guárdalo en la cabeza: `pickel` es quien decide si el aparato hace factory-reset o acepta una actualización. Es, sin saberlo, una pieza de seguridad.

El almacenamiento es un eMMC `/dev/mmcblk0` con tres particiones y varias zonas crudas fuera de ellas:

| Zona        | Qué es                                        | Tamaño / posición |
| ----------- | --------------------------------------------- | ----------------- |
| `mmcblk0p1` | `rootfs` (donde corre Nickel)                 | 256 MB ext4       |
| `mmcblk0p2` | `recoveryfs`                                  | 384 MB ext4       |
| `mmcblk0p3` | `KOBOeReader` (el "onboard", visible por USB) | 29,1 GB vfat      |
| zImage      | kernel crudo                                  | sector 2048       |
| hwconfig    | config de hardware                            | sector 1024       |
| waveform    | tabla e-ink                                   | sector 14336      |

Ese `256 MB` de la rootfs y ese `vfat` de la partición de usuario no son detalles: los dos nos mordieron más adelante. El firmware de referencia quedó fijado a la versión **4.38.23828** (los hashes de kernel que el sistema acepta están anclados a ella).

## Ingeniería inversa: proceso y resultados

Con el mapa en la mano, la pregunta operativa es una sola: **¿cómo se mete código propio sin abrir el aparato ni tocar U-Boot?** La respuesta estaba en el propio mecanismo de actualización de Kobo.

### El vector: `KoboRoot.tgz` y la confianza implícita

Kobo actualiza así: si el init de serie encuentra un fichero `.kobo/KoboRoot.tgz` en el almacenamiento, lo desempaqueta sobre `/` como root y reinicia. En el `rcS` de serie eso ocurre alrededor de las líneas 251–269, con `pickel can-upgrade` como guardián. No hay firma. No hay verificación de origen. Es un tar/gzip de ficheros propiedad de root que se extrae sobre el sistema, y los binarios tienen que ir en modo **755**.

Dicho en lenguaje de amenazas: **el actualizador es el vector**. Cualquiera que pueda escribir en la partición de usuario —que se monta por USB sin credenciales— puede colocar un `KoboRoot.tgz` que el sistema aplicará como root en el siguiente arranque. Toda la cadena de confianza del dispositivo se apoya en que nadie meta un fichero en una carpeta. Ese es el eslabón que convierte un lector cerrado en un sistema abierto, y el que un diseño con secure boot cerraría.

### El contador de arranque en el MBR

El hallazgo más bonito de toda la ingeniería inversa no estaba en un binario, sino en cinco bytes del MBR. En `/dev/mmcblk0`, offsets **0x133–0x137**, Kobo guarda un **contador de arranque**. En cada boot, `pickel should-factory-reset` lo incrementa; cuando el índice llega a **4**, el aparato muestra la pantalla de factory-reset y se borra. Lo único que resetea ese contador es **Nickel**, que escribe la secuencia `8d ef 02 d2 00` cuando arranca bien.

La consecuencia de seguridad es profunda: **un contador en disco es estado de seguridad**, y si tu sistema sustituye a Nickel, hereda su obligación. Un sistema propio que arranque en lugar de Nickel y no resetee ese contador se autodestruye en cuatro reinicios. Tuvimos que replicar el gesto exacto de Nickel —escribir `8d ef 02 d2 00` en el offset `307`, releer y registrar— solo cuando Plato llevaba vivo más de un umbral de tiempo. Un test de mutación (escribir en el offset `308`) debía fallar, y fallaba. Eso llegó en la versión 1.0.3, después de verlo borrarse en el banco de pruebas.

### Los bricks, contados como lo que son: resultados

La parte honesta de cualquier trabajo sobre hardware es la lista de veces que lo dejaste inservible. Cada brick fue un hallazgo sobre el sistema:

- **Permisos (`EACCES`):** empaquetamos `rcS` en modo `644`. `busybox init` lo invoca con `execv`, que exige el bit de ejecución → `EACCES` → no arranca nada. Se corrigió enviándolo en `755` con un `check_exec` de guarda. (fix 1.0.1)
- **Espacio (`ENOSPC`):** metimos 44,5 MB en una rootfs de 256 MB que ya iba al 93%. El `etc/` se extendió a medias y el aparato se quedó en el splash sin llegar a Plato. La solución fue mover Plato al **onboard** (vfat) y dejar la rootfs con un delta de **29 KB**, con un límite duro de ≤ 256 KB en la partición de sistema. (fix 1.0.2)
- **El factory-reset autoinfligido:** una fase de *debloat* temprana metió todo lo de `/usr/local/Kobo/*` en la lista de borrado… incluido `pickel-imx`. Siguiente arranque: `pickel should-factory-reset` devuelve 127, el sistema interpreta eso como "hay que resetear", entra en recovery, reflashea el firmware **4.33.19747** y **borra el onboard**. De ahí nació la regla más importante del proyecto: una **protect-list** que nunca deja tocar `pickel*`, `udev`, `init.d`, las imágenes de U-Boot ni `ld.so.preload`. El debloat, además, pasó a hacerse con **placeholders de 0 bytes** dentro del `KoboRoot.tgz`, nunca con `rm` sobre el sistema vivo.

Expande

**Cuando el aparato ya no arranca: recuperación por RAM sobre fastboot.**

Tras uno de esos bricks hubo que construir un salvavidas que no exigiera abrir el aparato. El Kobo, como muchos i.MX6, expone un modo **fastboot** que enumera como USB `18d1:0d02` ("USB download gadget"), pero su comando `boot` llama a la rutina `boota` de NXP y **espera una imagen Android `boot.img` v0**, no un uImage clásico. Con `mkbootimg` (kernel en `0x80008000`, ramdisk en `0x83800000`, DTB como *second* en `0x83000000`) el aparato enumera como "KoboRescue" en cuatro segundos y arranca un sistema de rescate desde RAM, sin tocar el eMMC.

El detalle que convirtió la herramienta de rescate en una herramienta peligrosa: desensamblando U-Boot encontramos que `_detect_bootmode` corre dentro de `bootz`, y que mantener *power* + *page* un par de segundos tras entrar en fastboot dispara "recovery cus 9" → `root=/dev/mmcblk0p2` → el `rcS` de recovery reflashea U-Boot y kernel de la 4.33 **y formatea la p1 y el onboard, sin preguntar**. El contador del MBR no interviene aquí. La herramienta se corrigió para reclamar la interfaz al instante y mandar `getvar:version`, desarmando el timeout de un segundo que provocaba ese camino.

### Kernel y módulos: confianza reconstruida desde el binario

Querer cargar módulos propios (zram, tun) en el kernel de Kobo obliga a reconstruir la confianza que Kobo no publica. El kernel verifica `vermagic` y los **CRC** de cada símbolo; un módulo compilado contra cabeceras que no cuadran al bit se rechaza con `Invalid argument`.

El proceso fue arqueología de binarios:

- Extraer del aparato su propio `config.gz` (vía `IKCONFIG_PROC`) y su tabla `kallsyms`: **75.337 símbolos**.
- Reconstruir el `Module.symvers` del kernel de serie directamente desde el zImage oficial, con un **descompresor LZO1X propio** para abrirlo y localizando `__ksymtab`/`__kcrctab` con kallsyms: **6.847 símbolos**, todos contrastados contra `kallsyms`.
- Verificar cada módulo con `check-module.py` (identidad de `vermagic`) y `verify-crcs.sh`, recomputando los CRC desde fuentes propias: **186 iguales, 0 distintos**.

El árbol de kernel de la Libra 2 (2021) no traía los drivers de esta placa, pero el de la **Clara 2E** (2023) encajaba con la config del aparato salvo una opción. Las compilaciones salieron **reproducibles**: `tun.ko` y `zsmalloc.ko` idénticos byte a byte entre builds. Esa es la diferencia entre "parece que funciona" y "sé exactamente qué estoy cargando en ring 0".

## Qué es Plato, y qué es PlatoX

**Plato** es un lector de documentos open-source para e-readers, escrito en **Rust** por Bastien Dejean, pensado como alternativa a Nickel: rápido, sin tienda, sin cuenta. Es el lector; no es el sistema.

**PlatoX** es la idea que da sentido a todo lo anterior: coger Plato y convertirlo en el **sistema operativo entero** del Kobo. En vez de parchear Nickel, lo sustituimos del todo. El aparato arranca un pequeño sistema **Buildroot desde RAM**, verificado por sha256, y cae directamente en Plato: sin tienda, sin cuenta, sin servicio de sincronización. Técnicamente, PlatoX es **Plato 0.9.45 más una serie de nueve parches** (`plato-patches/0001–0009`) y un puñado de *crates* de Rust propios. Nickel se queda instalado e intacto: si algo falla, el Kobo arranca Nickel como siempre.

Conviene fijar los dos nombres antes de seguir, porque de aquí en adelante importa:

- **KoboX** (y su evolución KoboX 2 / "0.2 Master Edition") es el **firmware personal completo**, con cosas que dependen de infraestructura propia: Tailscale, una terminal, mercados, tiempo, noticias, Home Assistant, sincronización de biblioteca.
- **PlatoX 0.1** es la **destilación pública** (AGPL-3.0): Plato como sistema, las optimizaciones, el asistente de IA y la calculadora. Todo lo personal se quitó a propósito, y con ello buena parte de la superficie de ataque.

Tres capas: arranque verificado, Plato como UI, y los crates de Rust detrás

## Las funcionalidades nuevas de Plato

Sobre Plato se añadieron funciones que lo convierten en un entorno completo. Las clasifico por edición, porque un lector de seguridad querrá saber exactamente qué código corre en la versión pública.

### En PlatoX público (open source)

- **Plato como launcher** (parche 0001): rutas desde el arrancador, entradas por nombre. Es lo que permite que Plato *sea* el sistema y no una app más.
- **Panel de red y selector de Wi-Fi** (parche 0002): un `view/network_panel.rs` nuevo (+281 líneas) que abre, desde cualquier vista, un panel con el estado del Wi-Fi en frases legibles (`Apagado / Buscando una red conocida… / Conectado a X / No hay ninguna red conocida cerca`), IP y señal. El icono de la barra tiene cuatro estados (`wifi-off`, `wifi-connecting`, `wifi`, `wifi-secure`) y un hilo *poller* lo actualiza cada 2 s, nunca desde el hilo de la UI.
- **Asistente de IA** (parches 0004 y 0009): sobre una selección de texto, **Resumir, Traducir o Explicar**; sobre un libro, *insights* —reseña corta, reseña extendida, resumen o un **mapa de conceptos** navegable (`view/concept_map.rs`, +801 líneas)—. Funciona **con tu propia clave**: OpenAI, **Claude** (vía la Messages API nativa con *streaming* por SSE, con `claude-opus-5-5` preseleccionado si tu clave lo lista), DeepSeek o cualquier servidor compatible en tu red. Las respuestas se **cachean offline** y el Wi-Fi solo se enciende cuando una petición lo necesita, apagándose tras cinco minutos de inactividad.
- **Calculadora estilo teléfono** (parche 0006): reemplaza la vieja calculadora de línea de comandos de Plato por una de teclas. Detrás va el crate `platox-calc`, con un **decimal exacto** (`0,1 + 0,2 = 0,3`, no `0,30000000000000004`), porcentaje y descuento (`120 − 15 % = 102`, con la línea "Descuento: 18"), raíz cuadrada y división por cero controlada.
- **Menú limpio, About y System Info** (parche 0005): el menú cabe en una página, Reiniciar y Apagar quedan siempre visibles, y la gestión de Wi-Fi se va entera al panel de red. De paso, System Info **arregla un bug del propio Plato**, que mostraba la carga del sistema multiplicada por 100 con un signo de "%", y la memoria libre en vez de la disponible.
- **Herramientas de desarrollo** (parche 0007): *Test All* y *Benchmark*, detrás de un marcador de desarrollador, con **redacción de secretos** en los diagnósticos (nada de api-keys, tokens o PSK en los logs).

### En KoboX (firmware personal, fuera de la versión pública)

Esto existe y funciona, pero depende de infraestructura propia y se quitó del público para reducir superficie: **Tailscale** (primero en modo usuario, luego con TUN y módulo propio), una **terminal** (shell de busybox sobre un pty, con `fastfetch` y `ssh`), **Markets** (datos de Yahoo), **Weather** (Open-Meteo), **News** (un generador propio con `trafilatura` en un contenedor endurecido contra SSRF), **Home Assistant** (luz y clima por un túnel CONNECT) y **sincronización de PDF** contra un Calibre-Web propio.

## La optimización final: más rápido, más robusto, más responsive, más actualizado

Un lector que tarda dos segundos en cambiar de capítulo es inusable, por muy elegante que sea su arquitectura. La última fase fue una campaña de rendimiento con una regla estricta: **medir en el aparato, no en el host**. Estas son las medianas, iteración a iteración, de la versión 1.4:

| Métrica (mediana)            | Antes (beta7) | Después (beta12) |
| ---------------------------- | ------------- | ---------------- |
| Pasar página (EPUB)          | 231 ms        | **31 ms**        |
| Cambio de capítulo           | 2967 ms       | **46 ms**        |
| Abrir / reabrir libro        | 1265 ms       | **74 ms**        |
| Primer *paint* tras encender | 9,4 s         | **6,9 s**        |
| Wi-Fi conectado              | 12–13 s       | **5,0 s**        |

El cambio de capítulo, de 2967 a 46 ms: dónde cayó y por qué

### Más rápido

El trabajo (parche 0003) ataca cada capa del coste:

- **Pasar página:** una copia directa de gray8 a RGB565 con una tabla de 256 entradas (`framebuffer/fast16.rs`) y el *prerender* de la página vecina en un hilo aparte (nice 5). El *page turn* de beta8 cayó de 230,7 a 42,8 ms.
- **Texto y layout:** caché de *shaping* por palabra, buffers de HarfBuzz reutilizados, patrones de guionado cargados en diferido por idioma, CSS parseado una sola vez por documento.
- **Capítulos sin esperas:** layout del siguiente capítulo en un *worker* y **caché de layout en disco** (`prefetch.rs`, `layoutcache.rs`, `dlcodec.rs`), con verificación por dev/inode/tamaño/mtime. Esa es la barra que se desploma en el gráfico.
- **Compilación:** MuPDF, HarfBuzz, FreeType y DjVuLibre compilados desde fuente con **LTO y NEON** (el layout bajó de 13,4 a **9,8 ms/KB**), y el perfil de release con `lto` *fat* y `codegen-units = 1` y `target-cpu=cortex-a9`. El binario encogió de 10.494.280 a 8.851.200 bytes (−16 %).
- **E-ink:** refresco parcial entre páginas y refresco completo cada 20 para controlar el *ghosting*, más `zram` para estirar los 512 MB.

### Más responsive

La responsividad no es solo la UI. El Wi-Fi tardaba 10 segundos en escanear por un *timeout* fijo del driver `wext`; cambiándolo a `nl80211,wext`, el escaneo bajó de 10,5 a **1,4 s** y la autoconexión a **5,0 s**. El apagado y reinicio se midió en **0,18–0,23 s** entre la petición y el desmontaje limpio del onboard.

### Más robusto

La robustez es, en este proyecto, una propiedad de seguridad. El corazón es `platox-boot`, un programa en **C estático** instalado como PID 1 en la partición de sistema de Kobo. En cada arranque verifica el kernel, un `boot.manifest` y el **sha256** de la imagen del sistema; y si algo falla —o si se encadenan **tres arranques que no llegan a Plato**— cede el control al init de serie, Nickel. El primer *paint* de Plato resetea ese contador.

El selector de arranque: tres comprobaciones y una red de seguridad

El escritor de la ranura del kernel es igual de cuidadoso: escribe con `dd conv=notrunc,fsync`, vuelve a leer y comprueba el sha256, y si no cuadra **restaura la copia verificada previa** sin reiniciar, todo bajo `timeout 300` y solo con la batería al 30 % o cargando. El init propio de KoboX 1.4, además, **rechaza paquetes de actualización ajenos**: solo aplica los suyos, con manifiesto (sha256, tamaño, rutas, espacio, batería), y aparta cualquier `KoboRoot.tgz` extraño sin ejecutarlo. La versión estable (Master Edition) remató esto con escrituras atómicas de configuración y `clippy -D warnings` limpio en los ocho crates.

### Más actualizado

Donde el sistema de serie era un museo de 2015, el userland propio es de hoy: **Buildroot 2025.02 LTS**, glibc 2.41, busybox 1.37, `wpa_supplicant 2.12` con **mbedTLS** y soporte de **WPA3/SAE/OWE** — y **sin OpenSSL, sin udev y sin systemd**. Hay incluso un kernel propio **4.1.15** recompilado desde las fuentes GPL de Kobo con suspensión fiable: el aparato se colgaba al suspender, y por **bisección de configuración** encontramos que la causa era, paradójicamente, *quitar* `CONFIG_PM_DEBUG`; esos mensajes de depuración ocultaban una *race* en la suspensión de la placa, así que la solución fue dejarlo como en stock.

## Nota de método y modelo de amenazas

Lo que esto es y lo que no es, dicho sin adornos:

- **Hay integridad, no autenticidad.** `platox-boot` verifica el sha256 del sistema en cada arranque, pero **no hay firmas**. Un atacante local que pueda escribir en la partición onboard puede sustituir a la vez el `cpio` y su manifiesto. El modelo de amenazas de este diseño es **anti-brick y anti-corrupción**, no anti-atacante con acceso físico y permiso de escritura. Cerrar eso exigiría lo único que no tocamos: U-Boot y una raíz de confianza en el SoC.
- **La clave de API va en claro**, en `.platox/config/ai.toml`, en el almacenamiento del propio Kobo. Está documentado así y la recomendación es explícita: usa una clave revocable y con límite de gasto. La UI la enmascara a sus últimos cuatro caracteres y nunca llega a los logs; el diagnóstico redacta secretos antes de escribir nada.
- **No llama a casa.** No hay telemetría, ni cuenta, ni comprobación de actualizaciones. El aparato habla con el proveedor de IA que tú configures, solo cuando se lo pides, y con `pool.ntp.org` para la hora. El Wi-Fi está apagado salvo que una acción lo necesite.
- **El debloat no borra, oculta.** Se hace con placeholders de 0 bytes dentro del paquete de actualización y una protect-list que jamás toca las piezas críticas. Es reversible y no puede, por construcción, repetir el brick que lo inspiró.
- **Cadena de suministro:** fuentes fijadas por versión y sha256, kernel y paquetes reproducibles, y un `check-public.sh` que rechaza datos personales, infraestructura privada y ficheros propietarios de Kobo antes de cada publicación.

## Lo que nos llevamos

- **El actualizador es el vector.** Un mecanismo OTA que aplica paquetes con confianza implícita —sin firma, sobre una partición que se monta por USB— es la puerta de entrada, no una pieza secundaria. Si diseñas hardware, ahí es donde va la firma.
- **El estado en disco es estado de seguridad.** Cinco bytes en el MBR decidían si el aparato se borraba. Quien sustituye al sistema, hereda sus invariantes; descubrirlas tarde cuesta un dispositivo.
- **Integridad no es autenticidad.** Un sha256 por boot te protege de la corrupción y del brick, no de un atacante que controle el bit. Saber cuál de los dos problemas estás resolviendo es la mitad del trabajo.
- **Los bricks son datos.** Cada aparato que dejamos inservible —permisos, espacio, un `pickel-imx` de más en una lista de borrado— enseñó una invariante del sistema que ninguna documentación contaba.

Un lector de 512 MB resultó ser un objetivo de hardware security completo: cadena de arranque sin firmar, actualizador de confianza implícita, estado de seguridad en disco y un modo de recuperación con los dientes afilados. Convertirlo en un sistema propio, verificado y rápido fue la excusa; el mapa de confianza que salió del proceso es lo que nos llevamos.

## Recursos

- **Plato**, de Bastien Dejean — el lector open-source en el corazón de todo: [github.com/baskerville/plato](https://github.com/baskerville/plato).
- **PlatoX** — la edición pública (AGPL-3.0) de este trabajo; sin repositorio público por ahora.
- **Buildroot** — el sistema embebido que arranca en RAM: [buildroot.org](https://buildroot.org/).

// English version · [Turning an e-reader into your own system: reverse-engineering the Kobo Libra 2](https://quantarmy.com/en/reverse-engineering-kobo-libra-2-plato/)

## Más en sec

4 nov 2026 · 17 min

### [¿De quién es tu router? Ingeniería inversa de un Comtrend GRG-4355u de Digi](https://quantarmy.com/ingenieria-inversa-router-digi-comtrend-grg-4355u/)

El router que te deja el ISP es un pequeño OpenWrt que no controlas del todo: una cuenta de bajo privilegio que puede reescribir sus propios permisos, un hash root en DES, y un agente TR-069 por el que el operador reconfigura el aparato a distancia. Esto es la ingeniería inversa, lo que encontramos y cómo recuperamos el control, sin secretos ni recetas.

[sec](https://quantarmy.com/tag/sec/)
