Uniqlo 티셔츠의 난독화된 bash 스크립트 해독하기
(tris.sherliker.net)- Uniqlo 매장에서 팔린 Akamai 디자인 티셔츠에는
base64 --decode결과를eval로 실행하는 난독화된 bash 코드가 인쇄돼 있었지만, 실제로는Peace for All캠페인용 이스터에그였음 - Base64로 인코딩된 Here string을 풀면 터미널에서
♥PEACE♥FOR♥ALL♥문구를 사인파 애니메이션으로 반복 출력하는 스크립트가 나옴 - Base64에는 오류 정정이 없어 전사가 까다로웠고, 문자열 패딩과 따옴표·중괄호가 맞는지 확인한 뒤 Android OCR, Tesseract, Claude 결과를 비교해 정리함
- 디코딩된 스크립트는
tput,bc, 256색 ANSI 이스케이프를 조합해 터미널 크기별 문자 위치와 색상을 계산하고,CTRL+C종료 시 커서를 복구함 - Akamai는 뒷면의 실제 코드를 Linux와 연결해 설명했으며, 글꼴은 초기 추정인 Consolas가 아니라 Roboto Mono로 정정됨
티셔츠 뒷면의 실행 가능한 코드
- Uniqlo x Akamai
Peace for All티셔츠 앞면에는 중괄호 안의 하트가 있고, 뒷면에는 큰 영숫자 블록이 인쇄돼 있음 - 가까이 보면 블록은 shebang으로 시작하는 bash 코드이며, Base64로 인코딩된 Here string을
base64 --decode로 풀어eval에 넘기는 구조임 - 겉보기에는 “바이러스 배포 방식”처럼 보일 수 있지만, 실제 목적은 이스터에그 메시지 출력임
- 티셔츠는 Akamai가 Uniqlo의 Peace for All campaign을 지원하며 디자인한 제품임
OCR과 전사 과정
- Base64에는 오류 정정 기능이 없어, 인쇄된 문자열을 실행 가능한 형태로 옮기려면 완벽한 전사가 필요했음
- 문자열은 예상되는 패딩으로 끝났고 따옴표와 중괄호도 맞아, 온전한 코드일 가능성이 높았음
- 전사에는 세 가지 방법을 함께 사용함
- Android의 circle-to-search 내장 OCR
- Tesseract와 몇 가지 옵션 및 조정
- Claude를 통한 OCR 및 위치 표 생성
- 세 결과를 diff로 비교해 불일치 지점을 찾고, 남은 부분은 수작업으로 정리함
- 같은 Uniqlo x Akamai 라인의 다른 티셔츠 디자인은 더 넓은 코드 블록에서 잘린 듯하며, imports가 잘리고
return이retu로 끝나 컴파일될 수 없는 상태임
디코딩된 bash 스크립트의 동작
- Base64를 디코딩하면 주석이 잘 붙은 bash 이스터에그가 나타남
- 스크립트 시작 부분에는 영어와 일본어 축하 메시지가 들어 있음
Congratulations! You found the easter egg! ❤️おめでとうございます!隠されたサプライズを見つけました!❤️
- 애니메이션 대상 문자열은
♥PEACE♥FOR♥ALL♥PEACE♥FOR♥ALL...형태로 반복됨 - 터미널 크기는
tput cols,tput lines로 가져오고, 문자열 길이는 bash의${#text}로 계산함 - 커서는
tput civis로 숨기며,SIGINT를 받으면tput cnorm; exit으로 커서를 되돌림
애니메이션 구현 방식
- 루프는
for (( t=0; ; t+=1 ))형태의 무한 루프로 계속 실행됨 - 각 반복마다 현재 출력할 문자를
text에서 한 글자씩 가져옴 - 위치 계산은
bc -l로 사인값을 구해 처리함angle = t * 0.2sine_value = s(angle)x = (cols / 2) + (cols / 4) * sine_value
- 계산된
x는 터미널 범위를 벗어나지 않도록 0 이상,cols - 1이하로 보정됨 - 색상은 256색 팔레트에서 cyan에 해당하는 12와 orange에 해당하는 208 사이의 그라디언트로 계산됨
- 출력은 ANSI 이스케이프와
tput cup을 사용해 지정 위치에 색이 입혀진 문자를 찍고, 줄바꿈으로 아래로 내려가는 방식임 - 결과적으로
Peace for All캠페인 메시지가 터미널에서 연속적인 사인파 루프로 나타남
글꼴과 Akamai의 디자인 설명
- 글꼴에 대한 초기 추정은 Consolas였지만, Hacker News 사용자 ralphinus의 확인 뒤 Roboto Mono로 정정됨
- 잘못된 추정의 근거로는 얕게 사선 처리된
0, 세리프가 없는1,BDyg와 숫자2의 둥근 곡선 등이 언급됨 - Akamai는 티셔츠 출시 당시 보도자료를 통해 디자인 메시지를 설명함
- 밝은 황갈색은 초기 인터넷 컴퓨터의 “beige box” 플라스틱 케이스를 가리키고, 앞면의 하트는 인터넷이 전 세계에서 선한 목적으로 쓰인 것을 나타냄
- 뒷면의 실제 코드는 Linux에 대한 참조이며, Akamai는 이를 “인터넷의 오픈소스 언어”이자 더 안전하고 연결된 세계를 향한 공통 언어로 연결함
- 같은 티셔츠에 관심을 가진 다른 사례로 Wen Chuan Lee의 글이 있으며, 해당 글은 또 다른 관련 글로 이어짐
댓글과 토론
Hacker News 의견들
-
“Uniqlo x Akamai가 같은 라인에서 파는 다른 셔츠는 코드가 명백히 완성되지 않은 디자인임”
티셔츠가 오작동해서 반품해야 한다고 상상해 보라니 웃김
“왜 반품하시나요, 사이즈가 안 맞았나요 아니면 마음에 안 드셨나요?”
“아뇨, 37번째 줄에 문법 오류가 있어서 실행이 안 되고, 길거리 사람들이 제가 안전하지 않은 Bash 스크립팅을 홍보한다고 생각할까 봐 걱정돼서요”- Uniqlo 고객센터 직원들에게: 누가 인쇄된 컴퓨터 코드 오류를 이유로 셔츠를 반품하려 하면 거절하고, “진짜 스크립트 키디라면 사기 전에 그 오류를 알아봤을 겁니다”라고 답하면 됨
- 품질 보증이 이렇게 부족하다니 shell-shocked 상태임. 최소한 패치라도 적용해 줄 수 있나?
-
이런 걸 좋아한다면 Martin Kleppe의 작업도 마음에 들 수 있음. 예를 들면 Quine Clock이 있음
https://aem1k.com/qlock/
몇 년 전에 난독화되지 않은 형태로 역공학해 둔 것도 있음
https://gist.github.com/olooney/a89db3932b089925b71b68d7e9f2...
그 외에도 훌륭한 ASCII 시각화를 많이 만들었음
https://aem1k.com/- 저게 정말 Quine인가?
엄청 인상적이긴 한데, 그래도
- 저게 정말 Quine인가?
-
글꼴은 Consolas가 아니라 Roboto Mono임
더 이상한 점은, 글꼴 자체는 제대로 된 고정폭 글꼴인데 셔츠의 조판은 그렇지 않다는 것임. 커닝이 들어가 있고, 특히 ‘Iy’ 쌍에서 눈에 띄며, ‘i’ 같은 좁은 문자는 가로 공간을 덜 차지하는 것처럼 보임. 추측하자면 InDesign의 “optical kerning” 같은 도구로 조판한 듯함- 동적 커닝이 들어간 고정폭 글꼴을 만든 사람이 있을까? 위 댓글을 읽기 전까지는 생각도 못 한 좀 엉뚱한 아이디어임. 처음엔 말이 안 되는 것처럼 들리지만 들어봐 달라
고정폭 글꼴을 쓰는 이유는 격자에 잘 맞기 때문임. 하지만 그 격자 안에서도 글자를 조금 왼쪽이나 오른쪽으로 이동시킬 여지는 있고, 그러면 더 읽기 좋은 고정폭 글꼴이 될 수도 있음. 물론 글자가 왼쪽으로 밀릴 때마다 오른쪽 공간이 더 커져서 끔찍한 결과가 될 가능성도 비슷하게 큼 - 맞는 것 같음. 글에 정정을 추가했고, 이 댓글도 인용했음
- 동적 커닝이 들어간 고정폭 글꼴을 만든 사람이 있을까? 위 댓글을 읽기 전까지는 생각도 못 한 좀 엉뚱한 아이디어임. 처음엔 말이 안 되는 것처럼 들리지만 들어봐 달라
-
이 셔츠 정말 좋음. 실제 디자이너가 제작 과정을 설명한 좋은 영상이 있음. 일부러 OCR을 어렵게 만든 과정도 포함됨: https://youtu.be/jocGLiecpjU?t=526
- OCR 방법을 찾는 것보다 그냥 직접 타이핑하는 게 더 빠를 수도 있음. 45년 전 COMPUTE! 잡지에서 게임 코드를 베껴 치던 느낌일 듯함
https://archive.org/details/1983-01-compute-magazine/page/96... - 글쓴이임. 못 봤던 링크인데 정말 고마움. 이걸 보니 기쁘고, OCR이 어려웠던 게 나만의 문제가 아니라 의도된 설계였다는 점도 반가움
- 링크를 봤는데 OCR을 어렵게 만들었다고 말하는 부분을 못 찾았음. 정확히 무엇을 해서 OCR이 어려워진 건가?
- 그런데 OCR이 어렵지 않음. 글이 왜 그 부분에 섹션 하나를 통째로 할애했는지도 모르겠음
Samsung S24U에서 홈 화면의 “circle to search” 버튼을 길게 눌러 AI 도구 인터페이스를 띄운 뒤, 텍스트를 길게 눌러 전체를 한 번에 복사했음. 공식 명칭은 모르겠지만 2초 정도 걸렸음
- OCR 방법을 찾는 것보다 그냥 직접 타이핑하는 게 더 빠를 수도 있음. 45년 전 COMPUTE! 잡지에서 게임 코드를 베껴 치던 느낌일 듯함
-
이걸 OCR하는 건 악몽이고, 스스로 좋은 OCR/비전 모델이라고 주장하는 것들에 좋은 벤치마크가 됨
다만 최신 Claude나 GPT 같은 좋은 비전 모델을 붙인 에이전트식 도구에 이미지를 주고, 줄 단위로 나눈 뒤 각 줄을 따로 OCR하라고 하면 꽤 쉽게 될 것 같음
난독화 전에 이 스크립트 자체가 LLM으로 작성됐는지도 궁금함. 주석이 꽤 많아 보이는데, 이 경우엔 그래도 괜찮음 :)- LLM이 쓴 것 같지는 않음. 몇 가지가 눈에 띔
축하 문구가 영어와 일본어로 모두 들어 있고, 하트 이모지가 하나 있음. 청록색에서 주황색으로 이어지는 그라데이션 의도가 있었지만, 범위가 ANSI 블록에서 시작해 256색 블록 중간에서 끝나며, 256 터미널 색상은 애초에 그라데이션처럼 배열되어 있지 않음. 또 루프 끝에 sleep이 없는데, LLM이라면 방어적으로 추가했을 것 같음 - 그렇게 어렵지는 않음. 우리 산업용 OCR 모델은 기본 매개변수로 첫 시도에 정확히 읽었음
문자들이 쉽게 분리되고, 판독기를 헷갈리게 하는 구조적 배경도 없음. 예를 들면 요구르트 알루미늄 뚜껑의 유통기한 같은 경우와 다름. 결과를 어지럽힐 거의-텍스트 같은 질감도 없고, 글꼴도 깔끔하고 표준적임 - 인터넷 사람들이 마지막으로 어떤 base64를 OCR하느라 집착했던 건 몇 달 전이었음. DoJ가 어떤 사망한 사람의 이메일을 대량 공개했는데, 래스터화된 PDF로 공개됐던 때임
지금은 이름이 기억 안 남. 그동안 정신을 빼앗는 일이 너무 많았음 - Safari의 이미지에서 텍스트 복사 기능은 문자열의 base64 부분 전체를 거의 처리함. 첫 글자만 T가 아니라 I로 잘못 읽었음
이상하게도 hashbang 부분까지 포함해 전체 문자열을 복사하려고 하면 성능이 훨씬 나빠짐. 내부에서 뭘 하길래 이렇게 잘 되는지 궁금함 - 정말 악몽인가? 셔츠의 첫 번째 축소 이미지를 ChatGPT에 붙여 넣었더니 한 번에 해독하고, Bash 스크립트가 뭘 하는지도 알려줬음
- LLM이 쓴 것 같지는 않음. 몇 가지가 눈에 띔
-
base64 인코딩을 난독화라고 부르다니
멋진 JS 역난독화 기법을 기대했는데, 좋게 말하자면 실망이 이루 말할 수 없고 하루를 망쳤음 -
와, 매장에서 그 티셔츠를 보고 여자친구에게 “저 스크립트가 실제로 동작할 리 없어, 그냥 장식용일 거야”라고 했었음. 더 파고들었어야 했음
- 놓치기 쉬움. 대부분의 시간에 우리는 차분하지 않아서 생각이 자동 조종 상태에 있음
-
괜찮음. 스크립트에 대한 유일한 아쉬움은 루프 안에
sleep 0.1
을 넣었을 것 같다는 점임. 그래야 터미널에 출력될 때 실제로 읽을 수 있음. 현대 터미널은 너무 빠르게 스크롤돼서 메시지가 지나가는 모습을 볼 수 없음
10Hz 갱신 정도로 늦추면 아주 보기 좋음- 그럼 거기에 패치를 꿰매 넣을 수 있을지도?
-
작성자가 여러 OCR 도구를 써 보며 결과가 들쭉날쭉한 뒤, 제일 나은 출력물을 오래 수동으로 고치는 모습이 웃겼음. 그냥 직접 타이핑하지 않고 말임
- 나도 같은 생각이었음. 하지만 나는 잡지와 책에 실린 “게임”을 몇 시간씩 고무 키보드로 베껴 치며 자란 세대임. 그다음엔 오타 고치느라 또 몇 시간이 걸렸고
- PaddlePaddle OCR에 돌렸더니 완벽하게 처리했음
휴대폰의 Google Lens로 쓰는 Google OCR도 꽤 잘 추출했지만 100% 정확하진 않았음. 그래도 손으로 베껴 치는 것보다 고치는 시간이 훨씬 적게 들었을 것임. 작성자가 뭘 썼는지는 모르겠지만 OCR 시도가 어땠는지 공유했으면 좋았을 듯하고, 아마 단순한 OCR 도구를 써 본 것 같음 - 4줄 입력하는 데 거의 2분 걸렸고, 그중 한 글자를 놓쳤음
나라도 당연히 OCR을 고를 것임. 다음에 마주칠 Bash 티셔츠에 대비해야 하니까 - 기업 환경에서의 작업 자동화 현실이 떠오름. 초급자가 10분이면 수동으로 할 수 있고 주 1회만 필요한 일을 자동화하느라 엔지니어들이 40시간 넘게 쓰는 일이 흔함. 무조건 자동화가 미래인 듯함
- “그냥 타이핑”은 평균적인 사람에게는 오류가 더 많이 날 가능성이 큼
-
예전 동료가 Go 프로그램이 들어간 셔츠를 가지고 있었는데, 늘 꽤 멋지다고 생각했음
[0] https://github.com/GL-Kageyama/UNIQLO_Akamai_T-shirt_Code- Go 풀이 프로그램을 말한 건지, Go 언어를 말한 건지 확신이 안 섰음. 누군가 Go로 Go 프로그램을 만들면 재미있을 듯함
- 올해 Go 코드가 들어간 걸 하나 샀음. 실제 코드라고는 전혀 생각 못 했고, 그냥 무작위 내용인 줄 알았음