JPEG 위조하기
(ty-penguin.org.uk)- 글쓴이는 Spigot이라는 가짜 웹페이지 계층 구조 생성기를 운영하며, 공격적인 웹 크롤러를 상대로 무작위로 생성된 페이지를 노출함
- 최근에는 이미지 크롤러가 jpg 이미지를 찾기 위해 사이트를 집중적으로 탐색하는 것을 발견함
- 실시간 이미지 생성을 최소한의 CPU 자원으로 처리하기 위해, 실제 JPEG 파일의 구조화된 부분만을 모아 템플릿으로 활용하고, 압축된 부분에는 무작위 데이터를 삽입하는 방식을 제안함
- 실험 결과, 이러한 방식으로 만들어진 JPEG는 오류가 있음에도 대부분의 이미지 뷰어에서 이미지를 표시할 수 있고, 크롤러에게도 충분히 그럴듯하게 보임
- 이 방식은 서버 자원 소모는 적게, 크롤러에게는 부담을 주며 Spigot의 약 60% 페이지에 적용됨
Spigot과 JPEG 위조의 배경
- Spigot은 Markov Chain 기반으로 가짜 웹 페이지 계층을 실시간으로 생성하여, 공격적인 웹 크롤러에게 무의미한 데이터를 제공함
- 몇몇 크롤러는 정체를 감추기 위해 무작위 브라우저 시그니처와 IP를 사용, 봇넷을 통한 불법적 디바이스 남용 가능성 발견
- 트래픽 분석을 통해 새로운 크롤러인 "ImageSiftBot"이 이미지 수집을 위해 집중적으로 Spigot 페이지를 요청함을 확인함
- Spigot의 주요 목표는 서버 CPU 사용량 최소화 및 효율적인 동작 유지임
저렴한 이미지 생성 방법의 고민
- 동적으로 이미지를 생성하는 것은 압축 때문에 CPU 소모가 크므로, 효율적인 방법이 필요함
- JPEG 파일은 파일 구조(크기, 색상 등)와 압축된 픽셀 데이터 구역으로 구성된다는 점에 착안
- 여러 JPEG에서 구조화된 헤더 정보만 추출한 뒤, 픽셀 데이터 영역은 랜덤 데이터로 채우는 방식이 고안됨
- 이렇게 하면 매번 이미지를 압축할 필요 없이 즉석에서 생성 가능, 서버 부담 최소화 실현
JPEG 파일구조와 실제 구현
- JPEG 파일은 여러 개의 청크(마커와 길이가 있음)로 이뤄짐
- 헤더/메타정보는 남기고, 압축된 픽셀 데이터 길이만 기록→이 영역에만 난수 데이터 삽입
- 514개의 JPEG 샘플 활용 시, 전체 헤더 정보와 필요한 구조화 데이터 크기는 약 500KB에 불과해 메모리 부담 미미함
- 코드 예시: 각 템플릿의 픽셀 데이터 청크에 난수를 채워 넣는 방식으로 이미지 생성
실사용 결과와 오픈소스 공개
- 실제 이미지 뷰어는 픽셀 구역이 완전 난수이어도 어느 정도 이미지를 표시할 수 있음
- 웹 크롤러는 오류를 식별하기 어렵고, 데이터 수집 시 비용이 증가하게 됨
- 1280x960, 200~300KB 사이즈 JPEG 기준 초당 약 900장 생성, 실시간 처리에 무리 없음
- Spigot 전체 페이지의 60%에 이 방식 적용, URL 기반 난수 시드를 사용해 재요청 시 동일 이미지 반환
- ImageSiftBot, Meta, AmazonBot, GPTBot 등에서 높은 요청량 관측됨
- 핵심 목적은 적은 서버 리소스로 크롤러에게 부담을 주는 것
Huffman 코드와 추가 최적화
- JPEG의 픽셀 데이터는 Huffman 부호화를 사용해, 완전한 난수 삽입 시 일부 뷰어에서 오류 발생 가능성 존재
- 간단한 비트 마스킹(0x6D) 기법을 추가해 연속 3개 이상 1이 발생하지 않도록 하여, 잘못된 Huffman 코드 발생 확률 90%→4% 미만으로 낮춤
- 완전히 유효한 Huffman 스트림을 만들 수도 있으나, 서버 자원과 개발 시간 대비 이점이 미미함
결론
- Spigot의 가짜 JPEG 생성 방식은, 압도적인 효율로 서버 리소스를 아끼면서도 크롤러에게 혼란과 리소스 낭비를 유도함
- 관련 코드는 100줄 이하로, GitHub에 공개됨
- 단순하면서도 창의적인 웹 트래픽 방어・분산 기법임
Hacker News 의견
-
robots.txt 파일이 /spigot/ 트리에 대한 로봇 접근을 차단하고 있음은 예상했던 부분임, 그러나 URL에서 /spigot/만 빼도 여전히 Spigot에 접속 가능함을 발견함, /~auj 네임스페이스는 robots.txt로 차단된 게 아니기 때문에, 선의의 크롤러라도 우연히 해당 경로에 접속하면 무한 페이지 루프에 빠질 수 있음, 이는 썩 유쾌하지 않은 상황임 robots.txt 참고링크
-
이전에 작성자의 코멘트에서 robots.txt를 따로 구성하지 않았다는 내용이 있었음, 자신은 이렇게 극단적으로 선택한 것에 대해, 웹사이트 운영자가 크롤러로 인한 DOS를 막으려 일부러 설정을 해야 한다는 개념을 좋아하지 않는다고 밝힘, 정당한 크롤러라면 초당 15회 이상 한 사이트를 지속적으로 긁는 짓은 안 해야 한다는 입장임
-
심지어 선의의 크롤러라도 무한 페이지 루프에 빠진다는 점에 대해, 웹사이트 운영자가 웹사이트를 긁는 사람들에게 '친절해야 할' 의무가 어떤 건지 회의적임, 꼭 그래야 하는지 모르겠음
-
-
크롤러가 robots.txt를 무시할 경우 식별해낸다면, '쓰레기' 정보를 던져주는 방식 대신 네트워크 연결을 점유시켜 방치하는 게 더 효율적이라는 생각임, 엔드포인트에 무한정 쓰레기를 제공하는 쪽이 왜 필요한지 잘 모르겠음
-
AI 입력용 스크래퍼를 교란하려면 이미지마다 가짜 캡션을 달아두는 건 어떨까 하는 아이디어가 떠올랐음, 예를 들어 초록색 덩어리 이미지에는 "고양이가 캣닢 공을 가지고 노는 중"이라고, 파란 이미지에는 "울새가 둥지 틀고 있음"이라고 다르게 달아두는 식임
- 잘 만들어진 스크래퍼라면 이미지 자체를 CLIP 모델이나 다른 캡션 모델로 분석해 텍스트 설명과 이미지가 실제로 일치하는지 재확인 가능함
-
가장 심한 사례는 meta(페이스북)가 운영하는 facebookexternalhit bot임, 심지어 이 봇은 공식적으로 robots.txt를 무시한다고 문서화되어 있음, 페이스북에서 악성 링크 탐지용이라는 명목이지만, 실제로 악의적인 사용자가 페이스북에 값비싼 엔드포인트에 대한 URL만 반복 제출하면 페이스북이 대신 트래픽 폭탄을 날리는 효과가 남, 그래서 매달 며칠씩 하루 10 r/s 이상으로 사이트에 트래픽이 쏟아짐
- 근데 10 r/s가 과연 "트래픽 폭탄" 수준인지 의문임, 심지어 단일 서버에 해도 거의 표시도 안 나는 수준임
-
Spigot에 관한 글을 읽다보니 Project Honeypot이 생각났음, 20년 전 이 프로젝트의 스크립트와 기부한 MX 레코드가 내 사이트의 이메일 하베스터 잡는 데 도움됐다는 이메일을 받을 때마다 상당히 신났었음, 예를 들어, 나의 MX 덕분에 미확인 스팸 발송자(IP: 172.180.164.102)를 잡았다고 통보받는 식임
- honeypot 스크립트가 멋지긴 한데, 요즘 시점엔 상당히 옛날 방식임, (TOS 상으로 수정도 안 되고) 파이썬 스크립트도 CGI, Zope만 기본 지원이라, WSGI 앱 만드는 사람은 래퍼로 우회해야 할 것 같음
-
JPEG을 가짜로 만드는 것은 제대로 만드는 것보다 CPU 부담이 훨씬 적음, 게다가 이 과정 자체가 상대방 악성코드 측에서 JPEG 디코딩이 허술할 경우 충돌(crash)이 발생하게 하는 일종의 fuzzing(퍼징) 역할도 할 수 있음
-
최근 유입 트래픽이 수천 개의 가정용 IP에서 발생했다고 해서 반드시 전형적인 봇넷은 아닐 수 있음, 오히려 많은 사람들이 '무료 VPN', 혹은 '수동 소득 생성' 툴에 가입하면 자신의 장치가 다른 사용자들의 트래픽 출구 노드가 되는 식의 '프록시웨어(proxyware)' 구조일 수도 있음, 이 경우 본인도 모르게 AI 크롤러의 트래픽 통로가 되어줄 수 있음, 관련 참고자료
-
결국 이런 프록시웨어도 사용자가 자발적으로 가입한 봇넷 변형임, 이런 사용자들이 HN 같은 곳에서 자신의 IP가 문제임을 알게 될 리도 적으니, 누군가는 IP를 따로 '너는 봇넷의 일부임'이라는 경고 페이지로 안내하는 것도 괜찮다는 생각임, 현실적으로는 그냥 무조건 차단하는 것이 가장 편리함
-
이런 것도 충분히 봇넷 범주에 해당하는 구조라는 의견임
-
-
봇을 만족시키는 방법에 대해 말하는 방식이 인상적임, 재밌는 글이었고 프로젝트도 흥미로움
-
"주어진 임무를 고군분투하는 봇이 안쓰러워서 즐겁게 해줄 방법을 고민했다"는 태도가 참 참신하고 재밌게 느껴짐, 보통은 화냄이나 불평이 가득한 쓰레드와는 확연히 다름
- 이런 긍정적 자세가 가능한 건, 나쁜 크롤러들에게 고통과 쓰레기를 가할 수 있다는 여유로움 덕도 있음
-
이 링크의 결과물(이미지)이 마음에 듦 이미지 보기, 일종의 메시지가 담긴 아트피스 느낌임
-
진정한 Spigot 경험을 원하면, Firefox에서는 F12 > Network > No Throttling을 GPRS로 변경, Chromium에서는 F12 > Network > Custom profile을 20kbps로 만들어 속도 제한을 거는 식으로 실감나게 느낄 수 있음
-
혹시 여기에 셰익스피어(Shakespeare) 관련 콘텐츠도 있는지 궁금함
-