본문 바로가기

컴퓨터/사이트 분석

네이버 로그인 분석

Python을 이용해 네이버 로그인을 구현하기 위한 분석 내용입니다. 일단 네이버 로그인을 할 때 https 통신을 이용해서 정보를 주고 받기 때문에 Wireshark와 같은 툴을 사용해 패킷을 가져오더라도 암호화가 되어 있어서 그 내용을 알기 어렵습니다. 물론 인증서에 대한 키 값을 알고 있다면 쉽게 복호화가 가능합니다. 또한 Paros나 Burp Suite와 같은 프록시 툴을 사용한다면 중간에 어떤 요청이 들어갔는지를 알아 낼 수 있습니다. 하지만 네이버는 프록시 툴을 이용하더라도 로그인 정보를 알 수 없게 만들었습니다. 여기에서는 어떠한 방식으로 구현을 했는지를 살펴보도록 하겠습니다.


여기에서는 특별한 프로그램을 사용하지 않고 Chrome에서 기본으로 제공하는 기능만을 사용해서 분석을 하겠습니다.


먼저 네이버의 로그인 화면입니다. 여기에서 일단 요청을 보냈을 때 ID와 PW 정보를 포함해서 보내는지를 간단하게 확인하기 위해서 ID와 PW에 각각 'test'를 입력하고 로그인을 누릅니다.




Chrome의 Network 기능을 이용하면 어떤 요청이 있었는지를 확인합니다.



보다시피 id와 pw에는 빈 값이 들어있고, encpw 필드에서 매우 긴 값이 있는 것을 볼 수 있습니다. encpw라고 필드 명이 되어 있는 것으로 보아 계정 정보를 암호화한 필드라고 예상을 할 수 있습니다. 이제 이 예상이 맞는지를 확인해보도록 하겠습니다.


로그인 화면의 소스코드를 살펴보도록 하겠습니다.

소스코드의 form 부분을 보시면 제출을 했을 때 confirmSubmit 함수를 호출하는 것을 확인할 수 있습니다. confirmSubmit 함수에 대한 내용은 아래 코드와 같습니다.


function confirmSubmit() {
	var id = $("id");
	var pw = $("pw");
	var encpw = $("encpw");
	
	//if(id.value == "" && encpw.value == "") {
	if(id.value == "") {
		show("err_empty_id");
		hide("err_empty_pw");
		hide("err_common");
		id.focus();
		return false;
	//} else if(pw.value == "" && encpw.value == "") {
	} else if(pw.value == "") {
		hide("err_empty_id");
		show("err_empty_pw");
		hide("err_common");
		pw.focus();
		return false;
	}
	try{
		$("ls").value = localStorage.getItem("nid_t");
	}catch(e){}

	return encryptIdPw();
}


이 코드를 살펴보면 id 필드나 pw 필드가 비어 있을 때 비어 있다는 에러 메시지를 출력하고, id와 pw 값이 있다면 encryptIdPw 함수를 호출합니다. encryptIdPw 함수의 소스코드는 아래와 같습니다.


function encryptIdPw() {
	var id = $("id");
	var pw = $("pw");
	var encpw = $("encpw");
	var rsa = new RSAKey;

	if (keySplit(session_keys)) {
		rsa.setPublic(evalue, nvalue);
		try{
			encpw.value = rsa.encrypt(
				getLenChar(sessionkey) + sessionkey +
				getLenChar(id.value) + id.value +
				getLenChar(pw.value) + pw.value);
		} catch(e) {
			return false;
		}
		$('enctp').value = 1;
		id.value = "";
		pw.value = "";
		return true;
	}
	else
	{
		getKeyByRuntimeInclude();
		return false;
	}

	return false;
}


이 코드를 살펴보면, 'rsa'라는 변수명이 등장하는 것을 보실 수 있습니다. 그리고 encpw 필드의 값을 rsa.encrypt 부분을 통해서 설정하고 있는 것을 볼 수 있습니다. 즉 네이버는 로그인을 할 때, evalue와 nvalue 값을 rsa의 공개키로 사용을 하고, sessionKey, id 필드 값과 pw 필드 값과 각각의 길이 정보를 이용해서 rsa로 암호화를 하는 것을 알 수 있습니다. 참고로 evalue, nvalue, sessionKey의 경우에는 keySplit 함수에서 값이 설정됩니다.


function keySplit(a) {
	keys = a.split(",");
	if (!a || !keys[0] || !keys[1] || !keys[2] || !keys[3]) {
		return false;
	}
	sessionkey = keys[0];
	keyname = keys[1];
	evalue = keys[2];
	nvalue = keys[3];
	$("encnm").value = keyname;
	return true
}


그리고 keySplit 함수의 인자로 들어가는 session_keys의 경우에는 xhr로 받아오는 것을 확인할 수 있습니다.


즉 정리하자면, 네이버의 경우에는 로그인을 할 때 세션키와 공개키를 xhr로 받아오고, 아이디, 비밀번호 그리고 세션키 정보를 이용해서 RSA로 암호화를 한 후에 그것을 요청으로 보낸다는 것을 알 수 있습니다.

'컴퓨터 > 사이트 분석' 카테고리의 다른 글

네이버 로그인 분석  (6) 2016.08.24
티스토리 방문자 통계 및 유입로그 분석  (0) 2015.12.22