스크레이퍼 봇과 장난치기
(herman.bearblog.dev)- 공개 웹사이트를 과도하게 요청해 DDoS처럼 작동하는 스크레이퍼 봇 문제를 다루며, 이를 역이용해 시간을 낭비시키는 실험적 접근 제시
-
Markov 연쇄 기반 텍스트 생성기를 만들어
.php파일처럼 보이는 가짜 데이터를 생성, 악성 봇이 이를 다운로드하도록 유도 - 이후 정적 콘텐츠 서버를 구축해 소설 Frankenstein 문단을 무작위로 제공, 링크 구조를 통해 크롤러가 폭발적으로 확산되도록 설계
- 모든 페이지에
noindex, nofollow속성과 요청 카운터를 추가해 정상 검색엔진은 제외하고 규칙을 어기는 봇만 포착 - 실험 결과는 흥미로웠으나, Googlebot 오탐 위험으로 실제 서비스에는 적용하지 않고, 학습·실험용 프로젝트로 유지
스크레이퍼 봇 문제와 대응 아이디어
- 스크레이퍼가 의도치 않게 소규모 웹사이트에 DDoS 수준의 부하를 유발
- 일부 운영자들이 보호 방법을 문의했으나, 이번 글은 “방어가 아닌 역공” 에 초점
- 다른 개발자가 Markov 연쇄로 무한한 가짜 데이터를 생성해 봇을 속이는 사례를 보고 직접 실험 시작
Markov 연쇄 기반 가짜 PHP 생성기
- Rust로 Markov 연쇄 학습기를 구현해 임의 텍스트 데이터를 기반으로 현실감 있는 콘텐츠 생성
-
.env,.aws,.php등 취약 경로를 노리는 악성 봇을 대상으로, 실제처럼 보이지만 무의미한 PHP 코드 제공 - 파일 크기를 2KB에서 10MB까지 늘려 봇의 리소스 낭비 유도
- 예시 출력은 WordPress 함수명과 주석이 섞인 그럴듯한 가짜 PHP 코드 형태
- 목표는 봇의 시간·자원 낭비와, 공격자가 실제 취약점을 찾으려 시간을 허비하게 만드는 것
효율성과 정적 데이터 제공 실험
- VPS에서 1MB 이상 파일을 제공하자 응답 지연과 서버 부하 증가 발생
- 이를 해결하기 위해 정적 사이트 형태의 “garbage server” 구축
- Frankenstein 소설 전체를 메모리에 로드하고, 요청마다 임의의 문단 4개를 반환
- 각 페이지 하단에 5개의 링크를 추가해 폭발적 크롤링 확산(5배수 증가) 유도
- 결과물은 https://herm.app/babbler/ 에서 확인 가능
설계 세부와 운영 방식
- 선택한 소설은 공개 도메인이며, 할로윈 시기에 작업한 점과 AI와 Frankenstein의 유사성을 이유로 사용
- 모든 페이지에
noindex,nofollow속성을 부여해 규칙을 어기는 봇만 포착 - 각 페이지 하단에는 요청 횟수 카운터 표시, 메모리 기반으로 배포 시 초기화
-
.php요청용 별도 서버도 구성해, 실제 PHP 파일을 메모리에서 무작위로 제공 - “Garbage for the garbage king!”이라는 문구로 프로젝트를 요약
위험성과 제한 사항
- 이 시스템은 실제 서비스에 적용 시 검색엔진 오탐 위험 존재
- Googlebot이 잘못된 엔드포인트를 긁으면 스팸 사이트로 분류될 가능성
- 검색 노출 저하나 Chrome 경고 표시로 이어질 수 있음
- 따라서 검색 의존 사이트에는 비추천, 실험용 프로젝트로만 운영
-
.php용 babbler는 HTML이 아니므로 Googlebot 영향 없음, 악성 봇만 대상
마무리와 개인적 결론
- 악성 스크레이퍼를 유인하기 위해 블로그에 숨겨진 링크(rel="nofollow") 추가
- VPS의 트래픽 한도 초과 시 Cloudflare 캐시 사용 고려
- 프로젝트를 통해 Markov 연쇄와 봇 동작 원리를 학습하며, 재미와 분노가 섞인 실험 진행
- 결론적으로, 모든 시도가 실용적일 필요는 없으며, 때로는 단순한 재미로도 충분함
Hacker News 의견
-
세상이 변해도 결국 비슷한 문제를 겪게 됨
10~15년 전 나는 소셜 미디어 모니터링 서비스들과 싸우고 있었음. 큰 브랜드들이 포럼의 감정을 모니터링하도록 그들에게 돈을 주었는데, 내가 운영하던 무료 커뮤니티를 무단으로 긁어가며 서버 부하를 일으켰음
그들의 봇을 차단해도 IP와 UA를 바꿔 돌아왔기에, 게시글에 무작위로 브랜드 이름을 삽입하는 필터를 만들어 그들의 데이터 품질을 망가뜨렸음. 이 조치를 켜자 이틀 만에 스크래핑이 완전히 멈췄음- 나도 비슷한 경험이 있음. 내 사이트의 기부 폼을 신용카드 테스트용으로 쓰던 봇이 있었는데, IP를 바꿔가며 계속 시도했음. 그래서 차단 대신 성공/실패 메시지를 무작위로 돌려줬더니, 그들의 데이터가 오염되어 며칠 만에 포기했음
- 헤더 분석 이야기가 정말 유용했음. 내 Fediverse 서버에서도 오래된 Chrome UA를 쓰는 봇들이 Accept-Language 헤더를 전혀 안 보내는 걸 발견했음. nginx에서 403을 반환하도록 설정하니 트래픽이 줄기 시작했음
- 영화 The Imitation Game처럼, 모든 요청에 즉각 반응하면 상대가 눈치챔. 일부 요청만 처리하거나 무작위 오류 코드를 주면 탐지하기 어려워지고, 그들의 디버깅을 훨씬 어렵게 만들 수 있음
- 대부분의 봇은 여전히 HTTP 헤더 세트를 제대로 흉내 내지 못함. 2025년에도 같은 방식으로 필터링하게 되었고, 봇들은 여전히 같은 패턴으로 진화 중임
- 왜 회사 이름을 삽입하면 봇이 사라졌는지 궁금함. 혹시 그들이 브랜드 언급을 찾는 과정에서 데이터 신호가 오염되어서 그런 것인지 묻고 싶음
-
이 봇들은 PHP 파일을 실제로 파싱하는 게 아니라, 그 존재 여부로 취약점 탐지용 지문(fingerprinting) 을 만드는 것임. 응답 코드만 보고 바로 버림
- 맞음, 이런 경우엔 fail2ban이나 crowdsec 같은 도구가 더 효과적임. crowdsec을 써보니 트래픽이 적은 서버에서도 취약점 탐색 시도가 엄청 많다는 걸 알게 되었음
- 그렇다면 일부러 가짜 취약점을 노출시켜 봇을 유인하는 전략도 가능할 듯함. 예를 들어, 자동화된 봇을 허니팟(honeybot) 으로 끌어들여 내부 동작을 관찰하는 식임. 참고: The Cuckoo’s Egg
- 만약 LLM 스크래퍼들이 이런 응답을 학습 데이터로 쓴다면, 데이터 오염(poisoning) 위험이 커질 수도 있음. 최근 논문에서도 소수의 데이터 포인트만으로도 모델을 망가뜨릴 수 있다고 했음
-
최근 AI 및 스크래퍼용 타르핏(tarpit) 이야기를 들었음. 연결을 끊지 않고 아주 느리게 무한 데이터를 흘려보내는 방식임. Nepenthes라는 도구가 흥미로워서 실험해보고 싶음
-
예전엔 HN에서 스크래퍼를 막으면 비난받았음. “내가 어떻게 접근하든 상관없다”는 논리였음
- 하지만 지금은 다름. 인간이 개인적으로 접근하는 것과, AI 기업이 대량으로 DDoS 수준의 요청을 보내는 건 완전히 별개임. 후자는 명백히 비용을 남에게 떠넘기는 행위임
- 나도 정상적인 스크래핑은 괜찮다고 생각함. UA를 명시하고 robots.txt를 지키면 됨. 하지만 지금처럼 초당 수십 요청을 보내며 옛 Chrome 버전으로 위장하는 건 용납 불가임
- 나는 학술 프로젝트로 하루 한 번씩 구인 사이트를 스크래핑함. 이런 건 합리적인 사용임. 반면, 분 단위로 콘텐츠를 긁어가거나 취약점을 찾는 건 완전히 다른 문제임
- AI의 등장이 윤리의식 자체를 약화시키는 게 가장 우울함. 예전엔 자유를 중시하던 사람들이 이제는 저작권 강화나 익명성 제거를 요구함. 기술이 사람을 더 나쁘게 만들고 있음
-
Apache 서버를 직접 관리한다면, RewriteEngine으로 PHP 요청을 바로 차단할 수 있음
RewriteEngine On RewriteCond %{REQUEST_URI} (\.php|%2ephp|%2e%70%68%70) [NC,OR] RewriteCond %{QUERY_STRING} \.php [NC,OR] RewriteCond %{THE_REQUEST} \.php [NC] RewriteRule .* - [F,L]내 서버엔 PHP가 없으니 이런 요청은 전부 악성임
- nginx에서도 비슷하게 설정함. PHP나 ASPX 요청엔 HTTP 418 “I’m a teapot” 코드를 반환함
이렇게 하면 로그 필터링이 쉬워짐. 예시: FreeSolitaire.win/wp-login.phplocation ~* \.(?:php|aspx?|jsp|dll|sql|bak)$ { return 418; } error_page 418 /418.html;
- nginx에서도 비슷하게 설정함. PHP나 ASPX 요청엔 HTTP 418 “I’m a teapot” 코드를 반환함
-
대부분의 공격성 스크래퍼는 WordPress 취약점을 노림. PHP 파일 자체보다 그 출력 결과를 원함. 이런 설정은 일종의 허니팟에 가깝지만, 봇이 스크립트대로 안 움직이면 그냥 떠남
- 아마 그들은 출력에서 정규식으로 관리자 로그인 패턴을 찾을 것임. 없으면 바로 건너뜀. 즉, 4KB짜리 가짜 PHP를 생성하는 것보다 정규식 한 줄이 훨씬 효율적임
-
예전에 zipbomb 전략을 HN에 올렸다가 트래픽이 하루 10만 건으로 폭증했음. $6짜리 VPS로는 감당 불가였음. 지금은 가장 공격적인 봇만 zipbomb으로 대응하고, 나머지는 403을 줌. 새 전략이 잘 먹히지만 다시 공개할지는 고민 중임. 참고: 이전 글
-
예전엔 fail2ban만 썼지만, 좀 더 재미있는 방어책을 만들고 싶었음
.htaccess에서 의심스러운 경로(/.git,/wp-login)를decoy.php로 리다이렉트하고, 10GB짜리 decoy.zip을 강제 다운로드하게 함.
decoy.php는 요청된 민감 파일처럼 보이지만, 실제로는 가짜 로그와 SQL 데이터를 무한 스트리밍하여 봇을 붙잡아둠 -
이 봇들은 PHP 파일을 긁는 게 아니라, 프레임워크 취약점을 찾는 것임. 예상치 못한 응답을 주면 바로 포기하고 다른 타깃으로 이동함
-
가끔 이런 생각을 함 — 봇들이 낭비하는 리소스로 암호화폐를 채굴하게 만들 수는 없을까?
- 시도하려면 JavaScript 실행을 유도해야 하지만, 대부분의 봇은 이미 그런 시도를 막는 대응책을 갖고 있을 것임