Descifrando el script bash ofuscado de una camiseta de Uniqlo
(tris.sherliker.net)- La camiseta diseñada por Akamai que se vendió en tiendas Uniqlo llevaba impreso código bash ofuscado que ejecutaba con
evalel resultado debase64 --decode, pero en realidad era un easter egg para la campañaPeace for All - Al decodificar la Here string codificada en Base64, aparece un script que imprime repetidamente la frase
♥PEACE♥FOR♥ALL♥en la terminal como una animación de onda sinusoidal - Como Base64 no tiene corrección de errores, transcribirlo fue complicado; tras verificar el padding de la cadena y que coincidieran comillas y llaves, se compararon y organizaron resultados de OCR de Android, Tesseract y Claude
- El script decodificado combina
tput,bcy secuencias de escape ANSI de 256 colores para calcular posiciones y colores según el tamaño de la terminal, y restaura el cursor al salir conCTRL+C - Akamai explicó el código real del reverso como una referencia a Linux, y la tipografía se corrigió de la suposición inicial de Consolas a Roboto Mono
Código ejecutable en la parte trasera de la camiseta
- La parte frontal de la camiseta Uniqlo x Akamai
Peace for Alltiene corazones entre llaves, y en la parte trasera viene impreso un gran bloque alfanumérico - Visto de cerca, el bloque es código bash que empieza con un shebang y sigue una estructura donde una Here string codificada en Base64 se decodifica con
base64 --decodey se pasa aeval - A simple vista podría parecer una “forma de distribuir virus”, pero su propósito real es mostrar un mensaje easter egg
- La camiseta es un producto diseñado por Akamai para apoyar la campaña Peace for All de Uniqlo
Proceso de OCR y transcripción
- Como Base64 no tiene mecanismo de corrección de errores, para convertir la cadena impresa en algo ejecutable se necesitaba una transcripción perfecta
- La cadena terminaba con el padding esperado y también coincidían las comillas y las llaves, así que era muy probable que fuera código completo
- Para transcribirla se usaron en conjunto tres métodos
- OCR integrado de circle-to-search en Android
- Tesseract con algunas opciones y ajustes
- OCR mediante Claude y generación de una tabla de posiciones
- Se compararon los tres resultados con
diffpara detectar puntos de discrepancia, y el resto se depuró manualmente - Otros diseños de camisetas de la misma línea Uniqlo x Akamai parecen haber quedado recortados de bloques de código más amplios; sus imports están truncados y
returntermina comoretu, por lo que no pueden compilar
Cómo funciona el script bash decodificado
- Al decodificar el Base64 aparece un easter egg en bash con comentarios bien puestos
- Al inicio del script hay mensajes de felicitación en inglés y japonés
Congratulations! You found the easter egg! ❤️おめでとうございます!隠されたサプライズを見つけました!❤️
- La cadena animada se repite con la forma
♥PEACE♥FOR♥ALL♥PEACE♥FOR♥ALL... - El tamaño de la terminal se obtiene con
tput colsytput lines, y la longitud del texto se calcula con${#text}de bash - El cursor se oculta con
tput civis, y al recibirSIGINTse restaura contput cnorm; exit
Forma de implementar la animación
- El loop sigue ejecutándose como un bucle infinito con la forma
for (( t=0; ; t+=1 )) - En cada iteración se toma de
textel carácter que se va a imprimir en ese momento - El cálculo de posición usa
bc -lpara obtener el valor del senoangle = t * 0.2sine_value = s(angle)x = (cols / 2) + (cols / 4) * sine_value
- El valor calculado de
xse ajusta para que no se salga del rango de la terminal: mínimo 0 y máximocols - 1 - El color se calcula como un gradiente entre 12, correspondiente a cyan, y 208, correspondiente a orange, dentro de la paleta de 256 colores
- La salida usa secuencias de escape ANSI y
tput cuppara dibujar cada carácter coloreado en la posición indicada, bajando línea por línea - Como resultado, el mensaje de la campaña
Peace for Allaparece en la terminal como un loop sinusoidal continuo
Tipografía y explicación del diseño por parte de Akamai
- La estimación inicial de la tipografía fue Consolas, pero después de la confirmación del usuario de Hacker News ralphinus se corrigió a Roboto Mono
- Entre las razones de la estimación equivocada se mencionaron el
0ligeramente inclinado, el1sin serifas y las curvas redondeadas deBDygy del número2 - Akamai explicó el mensaje del diseño cuando lanzó la camiseta mediante un comunicado de prensa
- El tono beige brillante alude a las carcasas plásticas “beige box” de las primeras computadoras conectadas a internet, y el corazón del frente representa el uso de internet para el bien en todo el mundo
- El código real del reverso es una referencia a Linux, y Akamai lo vincula con “el lenguaje open source de internet” y con un lenguaje común hacia un mundo más seguro y conectado
- Otro caso de interés por esta misma camiseta es el texto de Wen Chuan Lee, que a su vez enlaza a otra publicación relacionada
1 comentarios
Opiniones de Hacker News
“Otra playera que venden en la misma línea de Uniqlo x Akamai tiene código que claramente es un diseño incompleto”
Da risa imaginar que la playera falle y tengas que devolverla
“¿Por qué la devuelve, no le quedó la talla o no le gustó?”
“No, es que tiene un error de sintaxis en la línea 37 y no corre, y me preocupa que la gente en la calle piense que estoy promoviendo scripting inseguro en Bash”
Si te gusta esto, quizá también te guste el trabajo de Martin Kleppe. Por ejemplo, Quine Clock
https://aem1k.com/qlock/
Hace unos años también hice ingeniería inversa de una versión sin ofuscar
https://gist.github.com/olooney/a89db3932b089925b71b68d7e9f2...
También ha hecho muchas otras visualizaciones ASCII excelentes
https://aem1k.com/
Es muy impresionante, sí, pero aun así
La fuente no es Consolas, es Roboto Mono
Lo más raro es que la fuente en sí es monoespaciada de verdad, pero la composición tipográfica de la playera no lo es. Tiene kerning, especialmente notable en el par “Iy”, y los caracteres angostos como “i” parecen ocupar menos espacio horizontal. Mi conjetura es que lo compusieron con alguna herramienta como el “optical kerning” de InDesign
La razón para usar una fuente monoespaciada es que encaja bien en una cuadrícula. Pero incluso dentro de esa cuadrícula hay margen para mover las letras un poco a la izquierda o a la derecha, y eso podría dar una fuente monoespaciada más legible. Claro que también hay una probabilidad similar de que termine siendo horrible, porque cada vez que una letra se mueve a la izquierda deja más espacio a la derecha
Esta playera está buenísima. Hay un buen video en el que el diseñador real explica el proceso de producción. Incluye cómo hicieron difícil el OCR a propósito: https://youtu.be/jocGLiecpjU?t=526
https://archive.org/details/1983-01-compute-magazine/page/96...
En un Samsung S24U, mantuve presionado el botón “circle to search” de la pantalla de inicio para abrir la interfaz de herramientas de IA, luego mantuve presionado el texto y copié todo de una vez. No sé cuál es el nombre oficial, pero tardó unos 2 segundos
Hacer OCR de esto es una pesadilla, y es un buen benchmark para cosas que dicen ser buenos modelos de OCR/visión
Aunque si le das la imagen a una herramienta tipo agente con un buen modelo de visión moderno como Claude o GPT, y le pides que la divida por líneas y haga OCR de cada línea por separado, creo que saldría bastante fácil
También me pregunto si el script en sí fue escrito con un LLM antes de ofuscarlo. Parece tener muchos comentarios, aunque en este caso está bien :)
El mensaje de felicitación está tanto en inglés como en japonés, y hay un emoji de corazón. Había una intención de hacer un degradado de turquesa a naranja, pero el rango empieza en el bloque ANSI y termina a mitad del bloque de 256 colores, y los 256 colores de terminal ni siquiera están ordenados como un degradado. Además, no hay un sleep al final del loop; creo que un LLM lo habría agregado de forma defensiva
Los caracteres se separan fácilmente y no hay un fondo estructural que confunda al lector, a diferencia de, por ejemplo, la fecha de caducidad en la tapa de aluminio de un yogur. Tampoco hay texturas casi textuales que ensucien el resultado, y la fuente es limpia y estándar
Ahora no recuerdo el nombre. Han pasado demasiadas cosas que distraen la mente desde entonces
Curiosamente, si intentas copiar la cadena completa incluyendo la parte del hashbang, el rendimiento empeora mucho. Me pregunto qué estará haciendo internamente para que funcione tan bien
Llamarle ofuscación a la codificación base64
Esperaba técnicas geniales de desofuscación de JS, y, por decirlo amablemente, mi decepción es inconmensurable y me arruinó el día
Wow, vi esa camiseta en la tienda y le dije a mi novia: “ese script no puede funcionar de verdad, seguro es solo decorativo”. Debí haber investigado más
Está bien. Mi única queja con el script es que probablemente le habría metido un
sleep 0.1
dentro del loop. Así, cuando se imprime en la terminal, realmente se puede leer. Las terminales modernas scrollean demasiado rápido y no se alcanza a ver pasar el mensaje.
Si lo ralentizas a algo como una actualización a 10 Hz, se ve muy bien.
Me dio risa ver cómo el autor probó varias herramientas de OCR y, tras obtener resultados irregulares, terminó corrigiendo manualmente durante mucho rato el mejor resultado, en vez de simplemente tipearlo directamente.
El OCR de Google usando Google Lens en el teléfono también lo extrajo bastante bien, aunque no con 100% de precisión. Aun así, habría tomado mucho menos tiempo corregirlo que transcribirlo a mano. No sé qué usó el autor, pero habría estado bien que compartiera cómo le fue con los intentos de OCR; probablemente probó alguna herramienta de OCR sencilla.
Yo también elegiría OCR, obviamente. Hay que prepararse para la próxima camiseta de Bash que aparezca.
Un excompañero tenía una camiseta con un programa en Go, y siempre me pareció bastante genial.
[0] https://github.com/GL-Kageyama/UNIQLO_Akamai_T-shirt_Code