이전 기사 에서는 Tor 브라우저로 실행되고 VNC 클라이언트를 통해 데스크톱 환경에 연결된 Kali Linux 컨테이너를 시연할 수 있었습니다. 탐색 세션 중에 Tor 브라우저가 Tor 네트워크에 연결되고 있음을 확인했습니다. 이 설정을 통해 웹 사이트를 표적으로 삼는 공격자로부터 발생할 수 있는 트래픽 종류를 시뮬레이션할 수 있습니다.
이 실험에서는 Selenium을 사용하여 Tor 브라우저를 자동화하여 브라우저의 WebDriver 인터페이스를 통해 키 입력과 탐색 이벤트를 합성하겠습니다. 각 크롤러에는 탐지를 회피하기 위해 내장된 Tor 프록시가 제공하는 임의의 IP 주소가 있습니다. 결과를 로컬 파일 시스템에 JSON 개체로 저장한 후 Python을 사용하여 단일 CSV 파일로 처리하겠습니다. 마지막으로 봇 활동을 감지, 속도 제한 및 차단하기 위해 데이터 센터 및 클라이언트 측에 어떤 대응 조치를 적용할 수 있는지 논의하겠습니다.
모든 파일과 해당 라이센스는 다음 오픈 소스 저장소에서 사용할 수 있습니다: tor-driver-python
저는 테스트 자동화에 대한 배경 지식을 갖고 있으며 테스트를 설계하는 데 많은 시간을 보냈습니다. 나는 또한 Selenium을 사용하여 작업하는 데 많은 시간을 보냈으며 테스트 목적으로 웹 브라우저를 자동화하기 위해 다양한 프로그래밍 언어 및 설정에서 Selenium을 사용했습니다. 실제 브라우저에서만 웹 애플리케이션을 테스트할 수 있는 시나리오가 있으며 Selenium은 이를 위한 훌륭한 도구입니다.
DevOps 엔지니어로 일하면서 저는 제가 담당하고 있는 웹 애플리케이션을 공격하고 때로는 노골적으로 공격하는 웹 크롤러를 어떻게 해야 할지 고민하며 적지 않은 시간을 보냈습니다. 이 문제의 이면을 한 번쯤 살펴보는 것도 흥미로운 실험이 아닐까 생각했습니다.
저는 교육 목적으로 봇넷의 공격을 얼마나 시뮬레이션할 수 있는지 확인하고 현대 데이터 센터에서 의심스러운 Tor 네트워크 트래픽과 같은 것에 대응하는 방법에 대해 논의하고 싶습니다. 봇넷은 일반적으로 크리덴셜 스터핑 공격을 수행하는 데 사용됩니다. 나는 유사한 기술을 사용하여 검색어를 검색하고 웹에서 정보를 수집할 것입니다.
크리덴셜 스터핑은 사용자 계정에 부정하게 접근하기 위해 훔친 사용자 이름과 비밀번호 쌍(“자격 증명”)을 웹사이트 로그인 양식에 자동으로 삽입하는 것입니다. 1
윤리적인 문제를 피하는 동시에 업무에 충실하려고 노력합니다. 시나리오를 다음과 같이 변경합니다.
robots.txt
파일이 있는 사이트를 대상으로 하며, 작성 당시 크롤링을 배제하지 않는 이용 약관을 확인했습니다. 예를 들어 IMDB의 이용 약관은 서면 동의 없이 크롤링하는 것을 명시적으로 금지합니다.
로봇 제외 프로토콜은 웹마스터가 크롤러에게 자신의 위치와 정보 수집이 허용되지 않는 위치를 알려주는 방법입니다. 자세한 내용과 예시는 robotstxt.org 웹사이트에서 확인할 수 있습니다. 검색 결과 페이지에서 웹 스크래핑을 허용하는 검색 엔진을 찾는 동안 대체 검색 엔진 목록이라는 기사를 발견했습니다. 아래는 해당 연구를 요약한 것입니다.
검색 엔진 | robots.txt URL | 크롤링이 허용됩니까? |
---|---|---|
아니요, 하지만 API가 있습니다. | ||
아니요, 하지만 API가 있습니다. | ||
아니요 | ||
아니요, 하지만 API가 있습니다. | ||
예, 하지만 정확히 내가 찾던 내용은 아니었습니다. | ||
예 |
이 주제를 조사하는 동안 유용하다고 생각한 기타 리소스:
이 예에서는 셀레늄 이외의 라이브러리를 사용하지 않을 것입니다. 제가 보여드리고 싶은 몇 가지 기본적인 패턴이 있으며, 무슨 일이 일어나고 있는지 이해하기 어렵게 만들 수 있는 특정 도메인 특정 언어(DSL)로 인해 문제가 발생하고 싶지 않습니다.
하지만 테스트 실행 프레임워크를 사용하는 것이 이런 종류의 코드를 구성하는 좋은 방법이라고 생각합니다. 프레임워크를 추가하면 일반 코드 구조, 재시도 논리, 심지어 보고와 관련된 많은 문제를 해결할 수 있습니다.
WebDriver 세션에서 페이지를 조작하는 방법에 대한 기본 패턴이 있습니다. 또한 모든 작업이 수행된 후에 일시 중지를 추가합니다. 브라우저 자동화는 불안정할 수 있습니다. 시간 초과는 크롤링에 많은 안정성을 추가하고 속도 제한 및 차단 가능성을 크게 제한합니다. 필요할 때마다 다른 검색 엔진이나 정보 소스에 대한 API 호출을 통해 크롤링을 강화하기도 합니다.
나는 선택자에 대해 정말 간단한 접근 방식을 취했습니다. 브라우저에서 사용할 수 있는 xpath 및 CSS 선택기를 모두 사용하고 있습니다. 크롤링 중에 페이지 간을 탐색하기 위한 앵커 태그 및 URL 조각에 주로 중점을 둡니다.
요소를 클릭하기 전에 해당 요소가 나타날 때까지 기다리는 예상 조건을 사용하고 있습니다. Selenium 프로젝트에는 많은 문서가 있지만 Stack Overflow 의 예제 사용과 함께 대기 조건에 대한 토론도 귀중한 리소스라는 것을 알았습니다.
비슷한 기능을 가진 tbselenium 이라는 기존 PyPi 프로젝트가 있습니다. 이 실험에서는 Firefox 프로필 설정을 참조했지만 tbselenium에 포함된 다른 기능은 필요하지 않았습니다. 루트 액세스 권한이 없는 컨테이너의 추가적인 복잡성으로 인해 디버깅이 더욱 어려워졌습니다. 이는 종속성을 제한하고 기존의 간단한 솔루션을 시도하려는 동기를 추가했습니다. 예를 들어, 순수한 Python 솔루션을 직접 구현하는 대신 Linux 도구와 하위 셸을 사용하는 곳이 많습니다.
완성된 수업은 약 150줄의 Python입니다. 검토할 내용이 적어서 무슨 일이 일어나고 있는지 심층적으로 분석하는 것이 더 쉬울 것이라고 생각합니다. Tor 브라우저 실행기의 작동 방식과 Firefox 프로필 구성 방법에 대해 많은 것을 배웠습니다. 이 프로필은 온라인의 여러 소스에서 수집되었으며 이 문서뿐만 아니라 소스 코드에도 언급되어 있습니다.
저는 시작, 해체 및 매우 일반적인 탐색 논리 부분을 TorDriver
라는 클래스로 추상화했습니다. Tor 브라우저 실행기로 Firefox 프로필을 설정하는 매우 간단한 클래스입니다. 요소가 페이지에 표시되는지 확인하는 방법과 프록시 소켓이 실행 중인지 확인하는 방법이 있습니다. Firefox 프로필 설정 및 디버깅은 스택 오버플로 토론인 Open Tor Browser with Selenium을 통해 대부분 정보를 얻었습니다.
완성된 파일은 여기에서 찾을 수 있습니다: tor-driver-python/torDriver.py
설정 및 WebDriver 구성 요소에 대한 셀레늄, pprint, 하위 프로세스 및 소켓을 가져옵니다.
다음 메서드는 요소 검사를 추상화하고 시간 초과 내에 해당 요소가 표시되면 True
또는 False
반환합니다.
프록시 포트는 신호를 보내기 전에 활성화되어야 합니다. Python에서 소켓 연결 테스트 에 대한 스택 오버플로의 몇 가지 예를 따르면 다음과 같습니다.
모듈의 대부분은 Firefox 프로필을 제어하고, geckodriver를 다운로드하고, torbrowser-launcher를 시작하는 클래스입니다.
여기에 기본 구성과 항목을 재정의하는 몇 가지 방법이 있지만 대부분은 최대한 단순하게 유지합니다.
프록시 포트에 연결하려면 최소한 Firefox 프로필을 구성해야 하며, JavaScript도 비활성화했습니다.
TorDriver의 프로필과 바이너리를 사용하여 드라이버를 초기화합니다.
하위 프로세스에서 geckodriver를 다운로드하고 추출하는 방법을 추가합니다. 컨테이너에서 실행할 때 tar.gz
더 이상 압축되지 않으며 단순히 보관 취소가 필요하다는 점을 언급할 가치가 있습니다. 오류에 대한 자세한 내용은 stdin: not in gzip format error 에서 확인할 수 있습니다.
소켓이 응답할 때까지 프록시 포트에 대한 연결을 다시 시도합니다.
이 예에서는 다음과 같은 2단계 접근 방식을 사용했습니다. 첫 번째 단계는 정보 수집이고, 다음 단계는 정보 처리입니다. 이렇게 하면 전체 프로세스가 네트워크 연결에 얽매이지 않고 소스 자료로 돌아가지 않고도 필요한 만큼 여러 번 결과 구문 분석을 다시 시도할 수 있습니다.
전체 파일은 여기에서 찾을 수 있습니다: tor-driver-python/crawler.py
크롤러는 텍스트 파일을 읽고 해당 정보를 사용하여 WebDriver 세션의 쿼리를 채웁니다. 크롤링 상태는 쿼리당 하나씩 json 파일 폴더에 보관됩니다. 정보를 한 번 내보내는 데 절대적으로 필요한 최소한의 처리를 시도하며 이후의 처리는 사이트로 돌아가는 대신 기존 데이터에서 발생할 수 있습니다.
검색 내용을 저장하기 위해 텍스트 파일을 사용하고 있습니다. 재구성이 매우 쉽기 때문에 텍스트 파일을 선택했습니다. 텍스트 편집은 새로운 정보로 크롤링을 시작하거나 중간에 실패한 정보를 다시 시작하는 데 장벽이 낮습니다. 이 크롤러에 더 복잡한 데이터 요구 사항이 있는 경우 대신 데이터베이스 사용을 고려할 것입니다. 이를 통해 보고를 위해 사용자 정의 사용자 인터페이스로 스캔을 제어하기 위한 API를 구현할 수 있습니다.
예제 파일은 이미 저장소의 결과 폴더에 있습니다: tor-driver-python/results
보다 강력한 크롤러에서는 실제 데이터베이스 기술을 사용하는 것이 좋습니다. 이는 데이터 수집이 중지된 위치를 쉽게 파악하고 다시 시작하는 데 충분합니다.
크롤러는 다음 명령을 사용하여 컨테이너에서 실행할 수 있습니다. 보고서 생성기에는 JSON 파일이 있어야 합니다. 내보내기 CSV 파일의 예는 여기에서 찾을 수 있습니다.
컨테이너를 시작합니다.
docker run -it --rm -p 5901:5901 -v "${HOME}/src":/src excitingtheory/kalilinux-xvfb:torbrowser
컨테이너에서 VNC 서버를 시작하면 세션 비밀번호를 묻는 메시지가 표시됩니다.
/opt/start-vnc-server-once.sh
VNC 세션 내부에서 크롤링을 시작합니다.
python3 crawler.py
크롤러는 Tor 브라우저의 초기화를 기다립니다. 안타깝게도 이는 수동 단계입니다. 확인란을 클릭하고 연결을 클릭하기만 하면 됩니다. 예를 보려면 비디오 데모를 참조하세요.
보고서 스크립트는 다음에서 CSV(쉼표로 구분된 값) 파일을 생성합니다.
크롤러가 크롤링 전체에 걸쳐 저장하는 JSON(JavaScript Object Notation) 결과 파일입니다. 동료들과 공유하는 데 더 일반적인 형식이면서도 추가 분석을 위해 다른 도구로 가져오기가 쉽기 때문에 CSV 형식을 선택했습니다.
전체 파일은 여기에서 찾을 수 있습니다: tor-driver-python/report.py
이는 내장된 Python 라이브러리를 사용하여 JSON을 읽고, CSV를 작성하고, 형식 지정 및 데이터 표시를 위해 URL을 구문 분석합니다. 그런 다음 결과를 반복하고 로드하여 데이터 처리를 시작합니다.
이것이 보고서 생성기의 핵심 기능입니다. 이는 결과 개체에 캡처된 데이터의 최종 프리젠테이션 및 순서를 지정합니다. 일반적으로 URL은 사이트를 통한 크롤러 기능 이동에만 유용하며 최종 데이터 캡처로는 유용하지 않지만 추가 데이터 추출을 사용자 정의하기 위한 좋은 시작입니다.
크롤링 결과는 ./results
디렉터리에 JSON 파일로 저장됩니다. 다음 스크립트를 사용하여 데이터에서 보고서를 생성하겠습니다.
python3 report.py
출력 CSV 파일의 예는 다음에서 찾을 수 있습니다: tor-driver-python/output.csv
봇 활동을 감지하고 완화하는 방법에는 몇 가지가 있습니다. 저는 주로 데이터 센터 측면에 초점을 맞추겠지만 몇 가지 클라이언트 측 탐지 방법에 대해서도 논의하겠습니다. 클라이언트 측 신호는 언제든지 변경될 수 있고 스푸핑될 수 있으므로 클라이언트를 실제로 신뢰할 수는 없습니다. 탐지 시스템을 설계할 때 이 점을 염두에 두는 것이 중요하다고 생각합니다. 데이터 센터에는 속도 제한과 평판 차단이라는 두 가지 보호 형태가 있습니다.
javascript만으로 클라이언트 측에서 활성 WebDriver 세션을 감지하는 몇 가지 방법이 있습니다. Github의 관련 문제가 더 자세히 설명되어 있습니다 . 기본적으로 WebDriver 프로토콜은 문서 및 창 개체를 변경하기 때문에 클라이언트 측 코드에서 감지될 수 있습니다.
저는 제가 가장 경험이 많은 솔루션인 Fastly, AWS WAF, Nginx에 중점을 두려고 합니다. CloudFlare는 정말 놀랐습니다. 그래서 CloudFlare의 제품에 대해서도 이야기하겠습니다.
AWS 웹 애플리케이션 방화벽(WAF) 속도 기반 규칙은 서비스 거부 수준의 활동을 차단하는 데에도 사용할 수 있으며 Tor 네트워크 트래픽을 감지하는 데에도 사용할 수 있는 기본 규칙이 있습니다. 자세한 내용은 IP 평판 규칙 문서를 참조하세요. 또 다른 일반적인 접근 방식은 다른 데이터 센터의 모든 트래픽을 차단하는 것입니다. 이는 대상 고객이 소비자인 경우 안전합니다. 그러나 기업에서는 이를 합법적인 트래픽에 해로울 수 있는 클라우드 VPN 및 기타 기술을 사용할 수 있습니다.
매우 인기 있는 솔루션인 Fastly의 Signal Science를 사용하여 Tor 트래픽을 구체적으로 탐지할 수 있습니다. 첫째, DDOS 공격으로부터 보호할 수 있습니다. 자세한 내용은 DDOS 완화 페이지를 참조하세요. 둘째, Tor 트래픽을 감지하고 차단할 수 있습니다. 이를 다루는 시스템 신호 사용 문서는 다음과 같습니다.
Nginx 의 경우 이 작업에 대한 몇 가지 기사도 있습니다: Nginx 또는 웹 애플리케이션 내부에서 익명 트래픽을 차단하는 방법 . 기본적으로 Tor 출구 노드에 대한 정보를 얻기 위해 API를 호출함으로써 IP 차단 규칙을 생성하고 일정에 따라 Nginx에 적용할 수 있습니다.
위의 클라우드 제공업체와는 대조적으로 CloudFlare는 Tor 클라이언트에 대한 지원을 제공합니다. Tor 지원 문서를 발견했습니다!? 여기서는 네트워크에서 Tor 사용자에게 콘텐츠를 제공하는 기능에 대해 논의합니다. 저는 이것이 정말 흥미로운 접근 방식이라고 생각하며 앞으로도 이를 더 탐구하고 싶습니다.
WebDriver는 테스트를 위한 강력한 도구이며 API에 액세스할 수 없는 곳에서 정보를 수집하는 데에도 사용할 수 있습니다. 예를 들어 액세스가 제한되거나, 검열되거나, 너무 비싸거나, 일반적으로 반경쟁적 관행으로 인해 잠겨 있습니다. 더 나은 방법은 웹 크롤링에서 수집한 데이터와 API에서 수집한 정보를 결합하는 것입니다.
봇의 악성 트래픽을 방지하는 것이 점점 더 어려워지고 있으며 공격이 발생할 때까지 기다렸다가 완화 방법을 고려하는 것은 좋은 보안 관행이 아니기 때문에 이는 중요한 연습입니다. 나는 정보를 온라인에 게시하는 책임을 맡은 모든 사람이 유출된 정보가 자신이 담당하는 시스템에 어떻게 사용될 것인지를 알아야 한다고 믿습니다. 윤리적 제약이 있는 단순화된 시나리오에서는 다음을 수행하여 이를 시연했습니다.