-
로그인에 관해서 알아보려고 한다. 로그인이란 그 사람이 맞는지 확인하는 작업을 일컫는다. 여기서 따라오는 개념이 두가지가 있다.
먼저 식별이다. 식별이란 수 많은 데이터 중에서 특정 데이터를 찾아내는 작업을 뜻한다. 이때 식별하기 위해서는 식별정보가 필요한데, 그래서 이 식별정보는 절대로 중복되어서는 안된다. 만약 식별 정보가 중복되어서 여러개라면 원하는 특정 데이터를 찾아낼 수 없기 때문이다. 따라서 식별정보는 Unique 해야한다. 이런 필요에 의해 데이터베이스에서 table에서 column을 설정할때 id와 같은 정보들은 primary key로 등록하기도 한다.
또한 '고유식별정보'라는 개념도 있는데, 이것은 예를들어 이 정보만 가지고 한 국가에서 정확히 누구인지 딱 집어낼 수 있는 정보를 뜻한다. 주민등록번호가 이에 속한다. 그래서 일반적인 아이디와 같은 식별정보는 노출이 되어도 그렇게 문제가 되지 않지만, 고유식별정보는 무게감이 다르다. 따라서 모의해킹을 하면서 웹패킷을 분석할 때, 일반 식별정보가 평문으로 돌아다니는 것은 큰 취약점이 아니지만, 고유식별정보가 평문으로 움직이면 취약점이라고 판단할 수 있다.
다음은 인증이다. 인증이란 그 사람 본인이 맞는지 확인하는 작업이다. 로그인시에 인증이 일어난다고 할 수 있으며, 보통 비밀번호와 같은 인증정보를 이용해서 인증을 한다. 아이디는 식별정보이고 비밀번호는 인증정보라고 할 수 있다. 그래서 로그인을 할 때 식별과 인증이 동시에 일어난다. 그 때문에 사용자는 로그인 시 아이디와 비밀번호를 동시에 제공한다. 그렇다면 로그인시 식별은 어떤 과정으로 이뤄질까? 바로 select 문을 통해서 특정 이용자를 찾는 것이 식별이다. 그리고 얻은 비밀번호로 인증하는 것이 인증이다. 그렇기에 인증을 위한 인증번호인 비밀번호가 form에 입력할 때 '*' 처리가 되어 노출을 최소화하는 것이다. 또한 인증정보를 db에 저장하는 것도 '잘' 저장해야한다. 이에 대해서는 잠시 후에 서술할 것이다. 결론은 인증정보는 유출되면 위험하다는 것이다.
식별과 인증이 로그인 시에 일어난다고 했는데, 그렇기에 이 두가지가 조합되는 방식마다 로그인 로직 케이스가 나뉜다.
로그인 로직을 잘 알아야 추후에 모의해킹을 할 때 로그인 우회 방법을 고민하는 데에 도움이 된다.
로그인 로직 케이스를 알아보겠다.
(1) 식별/인증 동시
이것은 DB 질의를 한번에 수행해서 로그인 구현을 하는 것을 의미한다.
//아래는 sudo 코드이다. $sql = "select * from member where id='$user_id' and pass='$user_pass'"; // 식별과 인증을 동시에 진행한다. 아이디와 비밀번호 두개를 확인하고 둘 다 있으면 반환할것. $ret = $sql.execute(); // 성공하면 참을 반환. 실패하면 거짓을 반환 if($ret){ 로그인 성공 } else { 로그인 실패 }
(2) 식별/인증 분리
//마찬가지로 sudo 코드이다. $sql = select * from member where id=‘$user_id’; // id만 가져옴 $db_pass = sql.ret[’pass’]; sql결과값에서 따로 db에서 비밀번호만 가져옴 if($db_pass == $user_pass){ //user가 입력한 $user_pass와 db에서 가져온것과 비교 로그인 성공 } else { 로그인 실패 }
(3),(4)를 위한 추가적인 설명
인증 로직에 HASH를 추가하면 좋다. HASH란 단방향(1way)알고리즘을 뜻한다. 다시 원문으로 돌아올 수 있는 암호화와 인코딩과는 다르게 Hash는 다시 되돌리지 못한다. 그렇기 때문에 해쉬처리된 비밀번호가 db에 저장되어 있다면, 만약 db가 노출되어도 1차적인 방어막은 존재. 아예 괜찮지는 않음. 만약 쉬운 비밀번호를 써서 해쉬처리했다면 찾기 쉽기 때문이다. 하지만 어려운 비밀번호를 사용했었다면 원문을 찾는 것은 매우 어려움.
그렇다면 인증은 어떻게 하는가? 해쉬처리된 비밀번호를 다시 원문으로 돌리지는 못하지만, 항상 같은 문자열을 해쉬처리하면 같은 문자열이 나오며, 1대1 대응이다. 따라서 회원가입 시 입력한 비밀번호를 해쉬처리해서 db에 저장하고, 로그인 할 때 입력하는 비밀번호를 해쉬처리해서 db에 있는 해쉬처리된 데이터와 비교하면 인증이 가능하다.
해쉬에는 SHA256과 MD5와 같은 것들이 있다.
이렇게 비밀번호를 해쉬처리하면 앞선 1,2 번에 적용해서 총 4개의 로그인 로직 케이스가 생긴다.
이제 로그인을 성공했다. 그렇다면 이 로그인을 어떻게 계속 유지할 수 있을까? 웹 서버는 결국 파일을 제공해줄 뿐이다. 웹 서버 입장에서는 사용자가 로그인을 했던 안했던 누구인지 모른다. 하지만 우리는 평소에 웹사이트에 로그인을 하고 그 상태를 유지하면서 활동을 하고 있다. 이게 어떻게 가능할까. 웹 서버는 우리가 누구인줄 어떻게 알까?
개인을 식별하는 것에 ip주소를 사용하면 어떻게 될까? 그냥 생각하면 가능할 것 같지만, public ip 주소는 여러 사람이 공유하기 때문에 식별정보로 활용하기 어렵다. 카페의 Wi-Fi를 이용해서 로그인 한다고 생각하면, 내 옆에 앉은 사람과 나의 ip 주소는 같기 때문에 그 둘을 구별할 수 없기 때문이다.
그래서 로그인 유지를 위해 쿠키가 이용될 수 있다. 클라이언트가 웹서버로 요청을 보낼 때 '내가 ~~이다'라는 메시지를 전달하는 것이다. 그러면 웹 서버는 그 메시지를 보고 사용자를 알아채고 특정 페이지를 반환하도록 한다. 그래서 웹 초창기에는 쿠키로 로그인 상태를 인증하는 사이트가 많았다고 한다. 하지만 이 방법은 큰 취약점이 있다. 그건 바로 쿠키의 저장소가 클라이언트쪽이라는 것이다. 로그인을 처음에 하고 나면 웹서버는 respond에 Set-Cookie: loginUser=shadow 와 같이 쿠키를 세팅하도록 메시지를 보낸다. 그럼 그 respond를 받은 클라이언트는 다음부터 request를 보낼 때 Cookie:loginUser=shadow 를 넣어서 보낸다. 이때, 클라이언트가 쿠키를 변조할 수 있다. 이게 바로 쿠키변조 취약점이다. 2000년대 초반까지 대학 사이트에서 쿠키로 인증하는 경우가 꽤 있었을 정도로 사용되었지만 문제점이 있었다. 따라서 이 방법은 굉장히 문제가 많기에 다른 방법이 필요했다. 아까 말했듯, respest로 전송하기위한 쿠키가 저장되는 장소가 클라이언트 쪽이었기 때문에 그 문제가 생겼기 때문에, 이제 웹 서버에 저장하는 방법을 택한다.
그게 바로 세션이다. 세션을 설정하면 웹 서버의 어딘가에 저장되어 마음대로 사용자가 바꿔서 전송할 수 없다. 이제 세션들이 웹서버에 저장이 될 것인데 이것을 누구의 정보인지 알 수가 없다. 그래서 id값이 필요하다. 그래서 세션마다 식별값인 id값을 가지며, 그것을 세션id라고 한다. 이제 클라이언트에서 사용자가 로그인을 하면 웹서버에서 클라이언트에게 respond에 세션id를 쿠키로 세팅해주고, 그 다음부터 클라이언트는 request마다 쿠키에 세션id를 담아서 보낸다.
여기서도 마찬가지로 결국 클라이언트에서 세션id를 쿠키로 보내기 때문에, 쿠키를 변조해서 타인인척 할수 있지 않냐는 의문이 들 수 있다. 그렇다. 하지만 세션id는 랜덤문자열이기 때문에 추측하기가 어려우며 로그인 할때마다 바뀌고 로그아웃하면 사라진다. 따라서 쿠키로 로그인을 유지하는 것보다는 보안이 튼튼하다. 그러나 세션을 이용할때도, 사용자가 로그인 한 상태여서 웹서버에 해당 세션이 저장되어 있는데, 만약 해커가 사용자 컴퓨터의 쿠키에 저장된 세션id를 털어서 본인의 컴퓨터에서 쿠키에 그 값을 넣고 request를 보내도 로그인이 된 것처럼 페이지가 나온다. 그렇기 때문에 세션도 완벽하게 안전한 방식이 아니므로, 해커들은 세션 id를 탈취하기 위해 xss, 웹쉘을 이용하기도 한다. 따라서 모의해킹을 하기 위해서는 세션id를 탈취하는 방법을 잘 알고 있어야 한다.
과제는 다음과 같다.
로그인 페이지 로직 4개로 만들어 오기.
1. 식별/인증 동시
2. 식별/인증 분리
3. 식별/인증 동시 with HASH
4. 식별/인증 분리 with HASH
추가과제
1. JWT 스스로 찾아서 공부하기(요새는 많은 곳에서 JWT로 로그인 구현을 한다고 함. cookie에 loginToken이라는 문자열 세개가 붙여진 굉장히 긴 문자열이 있다.)
2. JWT로 로그인 구현하기
'웹 해킹' 카테고리의 다른 글
Login Logic Case 분석 (0) 2024.06.16 2주차 과제 (0) 2024.04.28 2주차 수업 정리 (0) 2024.04.28 1주차 수업 정리 (1) 2024.04.19