본문 바로가기
WEB HACKING/웹 해킹[이론]

SQL Injection : 로그인 Case 별 인증 우회

by madevth 2021. 10. 22.
반응형

이전 글 : [모의해킹_이론] - SQL Injection

 

앞선 포스팅에서는 SQL Injection의 개념에 대해 간략하게 알아보았다.

이번 포스팅에서는 로그인 과정에 따른 SQL Injection 인증 우회에 대해 살펴보자.

 

 

① 식별 VS 인증

로그인 처리 방식은 약 5가지 경우의 수로 나눌 수 있는데, 이를 이해하기 위해서는 식별과 인증의 개념을 짚고 넘어갈 필요가 있다.

> 식별 : 많은 데이터 중 특정 데이터를 구분하는 작업으로, 시스템이 식별할 수 있도록 ID와 같은 고유값이 필요하다.

> 인증 : 사용자의 신분을 확인하는 절차

 

로그인을 할 때 시스템은 고유 값(ID)으로 사용자를 식별한 후 PW의 일치 여부를 바탕으로 인증 과정을 거치는데,

이 식별과 인증 과정을 어떻게 진행하는지에 따라 크게 5가지의 Case가 존재한다.

 

 

② 로그인 Case

  1.  식별 - 인증 동시
    식별 - 인증 동시란 SQL 실행 한 번에 식별과 인증을 동시에 처리하는 것을 의미한다.
    select * from tbname where id = 'INPUT1' and pw = 'INPUT2';
    로그인 인증과정을 위와 같이 진행한다면, 이는 식별과 인증 과정을 동시에 하고 있는 것이다.
    id와 pw 값이 모두 일치하는 행이 존재한다면 로그인에 성공하고, 존재하지 않는다면 로그인에 실패한다.

  2. 식별 - 인증 분리
    식별 - 인증 분리란 ID 값으로 식별 과정을 거친 후, DB의 PW와 사용자가 입력한 PW 값이 일치하는지로 인증 과정을 거친다.
    select pw from tbname where id = 'INPUT1';
    우선 위와 같은 식별 과정을 거쳐서 pw를 받아온 후, 결과값과 사용자의 pw 입력 값을 비교하여 일치하면 로그인 성공, 일치하지 않는다면 로그인에 실패한다.

  3. 식별 - 인증 동시 with Hash
    이 경우는 1번과 같지만, 비밀번호를 Hash 처리하여 저장하는 방식이다.
    Hash란 input 값을 고정된 길이의 output으로 매핑하는 함수인데, 유명한 Hash 함수인 SHA256을 살펴보자.
    SHA256으로 "안녕하세요."와 "안녕하세요"를 변환한 결과인데, 온점 하나 차이임에도 결과값이 크게 다르다.
    "안녕하세요"를 넣으면 항상 "2c68318e352971113645cbc72861e1ec23f48d5baa5f9b405fed9dddca893eb4" 를 얻을 수 있지만 "2c68318e352971113645cbc72861e1ec23f48d5baa5f9b405fed9dddca893eb4"를 가지고 "안녕하세요"를 얻을 수는 없기 때문에, 비밀번호를 Hash 처리하여 저장하면 DB를 탈취당해도 비밀번호 유출은 막을 수 있다.
    select * from tbname where id = 'INPUT1' and pw = sha256('INPUT2');​
    어떤 Hash 함수를 사용할지는 모르지만, SHA256를 사용한다고 가정하면 3번째 case의 SQL 구문은 위와 같다.

  4. 식별 - 인증 분리 with hash
    이 경우는 2번과 같지만, 비밀번호를 Hash 처리하여 저장하는 방식이다.
    식별 부분은 2번과 SQL 구문이 같지만, 결과값이 Hash 처리된 pw이므로 사용자의 입력값을 Hash 처리하여 비교해준다.

  5. 식별 - 인증 동시 with 개행(Enter)
    select * from tbname where id = 'INPUT1'
    and pw = 'INPUT2';​
     마지막 Case는 말 그대로 식별 - 인증을 동시에 하지만 Enter가 들어간 경우이다.
    SQL Injection 중에는 주석 코드를 넣어서 뒷부분을 전부 무효화시키는 방식이 있는데 Enter로 인해 구문이 다음 줄로 넘어간다면 주석이 힘을 잃게 된다.

 

③ 로그인 Case 별 SQL Injection 인증 우회

로그인이 위와 같은 5가지의 경우로 이루어지므로, SQL Injection 또한 각 경우에 맞는 삽입 구문이 존재한다.
앞선 SQL Injection 포스팅에서 설명한 두 가지 방식이 첫 번째와 두 번째 케이스에서 사용된다. 

  1.  식별 - 인증 동시
    select * from tbname where id = 'INPUT1' and pw = 'INPUT2';
    로그인 시 위와 같은 SQL 구문이 실행된다고 가정해보자. 첫 번째 로그인 인증 케이스는 위 쿼리의 결과값이 존재하기만 하면 로그인에 성공한다.

    > ID: admin' # / PW: 1234
    select * from tbname where id = 'admin' #' and pw = '1234';
    SQL 문법에서 #는 주석을 의미한다. --도 주석을 의미하기는 하지만, -- 뒤에 '가 오는 경우 주석이 잘 먹히지 않는 경우도 있어서 #로 사용하였다.
    #에 의해 뒤의 password 구문은 주석처리가 되고, DB에 admin이라는 ID가 존재하면 로그인에 성공한다.

    > ID: admin' or 1 = 1; # (' or 1 = 1; #) / PW: 1234
    select * from tbname where id = 'admin' or 1 = 1; #' and pw = '1234';
    ID가 admin인 사람이 없는 경우(로그인 가능한 ID를 하나도 모르는 경우)에는 or 1 = 1을 삽입하여 쿼리가 무조건 참이 되게 하는 방식으로 인증을 우회할 수 있다.

  2. 식별 - 인증 분리
    두 번째 case에서의 SQL Injection은 앞선 포스팅에서의 Union을 사용한 방식과 같다.
    select pw from tbname where id = 'INPUT1';​
    위와 같은 경우에서 ID값에 ' union select 'test', '1234를 넣고 pw에 1234를 입력하면 로그인을 우회할 수 있다.
    이해를 돕기 위해 id와 pw를 선택한다고 가정하고 왜 우회가 가능한지 살펴보자.
    select id, pw from users where id = '' union select 'test', '1234';​
     우선 mysql에서 select 'test', '1234';를 실행해보면 입력한 값으로 column과 data가 생기는 것을 볼 수 있다.
    SQL에서 Union을 사용하면 두 개의 쿼리문에 대한 결과를 한 번에 볼 수 있게 된다.
    때, id와 pw를 선택하는 구문과 함께 union을 사용하여 select 'test', '1234';를 실행하면, id와 pw의 콜럼으로 'test'와 '1234'의 데이터가 들어가게 된다. (Column과 Table 이름이 달라서 그 부분만 가렸다.)
    따라서 pw로 1234를 입력해주면 DB에서 가져온 1234라는 값과 일치하게 되므로 로그인에 성공한다.

  3. 식별 - 인증 동시 with Hash
    식별 - 인증 동시는 주석으로 인해 패스워드 부분이 가려지므로 Hash 처리와 관계가 없게 되어 3번과 1번의 Injection 방식이 같다.

  4. 식별 - 인증 분리 with Hash
    4번은 2번 case의 SQL 구문에서 select 'pw' 부분에 Hash를 거친 비밀번호를 입력해주면 된다.

  5. 식별 - 인증 동시 with 개행(Enter)
    select * from tbname where id = 'INPUT1'
    and pw = 'INPUT2';​
     마지막 케이스의 핵심은 "Enter가 있다 = 주석 처리를 통한 SQL Injection이 먹히지 않는다."이다.
    이 경우는 논리 기호를 활용하되 '를 사용하여 구문을 맞춰주는 방식을 사용할 수 있다.

    > ID: admin' or '1' = '1 / PW: 1234
    select * from tbname where id = 'admin' or '1' = '1' and pw = '1234';
    1번 방식에서 1 = 1 대신 '1' = '1을 넣어 구문을 맞춰준 것이지만, 위 쿼리문이 왜 통과되는지 의문이 생길 수 있다.
    그 이유는 and 연산자가 or 연산자보다 먼저 처리되기 때문이다. (사칙연산에서 x가 +보다 먼저 되는 것처럼)
    따라서 select * from tbname where id = 'admin' or ('1' = '1' and pw = '1234')가 되기 때문에 id가 admin인 사용자가 있으면 로그인에 성공한다.

 

이렇게 5가지 로그인 방식과 그에 따른 SQL Injection에 대해 알아보았다.

위에서 정리한 방식 말고도 많은 방식이 있겠지만, 중요한 것은 식별과 인증이 어떤 방식으로 이루어지고 있는지를 이해하고 방식에 따라 SQL 구문을 어떻게 넣어줘야 하는지 핵심을 인지하는 것이다.

 

이를 위해 실습 Part에서 직접 5가지 로그인 케이스를 구현해보고 SQL Injection의 결과를 확인해 볼 것이다.

반응형

'WEB HACKING > 웹 해킹[이론]' 카테고리의 다른 글

SQL Injection : Blind SQL Injection  (0) 2021.11.05
SQL Injection : Error Based SQL Injection  (0) 2021.11.04
SQL Injection : Union SQL Injection  (0) 2021.10.28
SQL Injection  (0) 2021.10.21
웹 서버 구조와 동작  (0) 2021.10.18

댓글