[취업반 스터디 2달 4주차]

Minseok Jo·2024년 2월 13일
post-thumbnail

[2달 4주차 주제 : SQL Injection: Advanced]


1. SQL Injection 유형

1) Union Based & Error Based & Blind SQLi

  • 3가지 경우 모두 우리가 원하는 select문을 실행하는 것이 핵심이다.
    우리가 실행할 SQL문이 명확해야 한다.

2) Union Based SQLi 특징

  • SQL 질의문의 결과가 화면에 출력되는 경우 사용

3) Error Based SQli 특징

  • SQL 에러 메시지가 응답에 포함되는 경우 사용

4) Blind SQLi 특징

  • SQL Injection 포인트가 존재하는 모든 경우에서 사용 가능

2. SQL Injection 포인트 찾기

[SQLi 발생 위치]
: DB에게 SQL 질의문을 사용하는 곳

화면에 보이는 데이터가 고정된 것인지 혹은 DB로부터 데이터를 가져와 출력하는 곳인지 확인 후 어떤 파라미터가 영향을 미치는지 캐치한다.


[SQLi 포인트 단계별 정리]

(1) 아이디를 입력하면, SQL 질의문을 통해 데이터를 가져와 출력하는 것을 확인

(2) SQL 질의문 추측
select (컬럼) from (테이블) where user_id like '%___%'

(3) SQL 질의문 삽입 가능 여부 확인
○ nor 검색 결과와 nor%' and '1%'='1 의 검색 결과가 동일. 즉, SQLi를 수행할 수 있다고 판단

(4) 참 / 거짓 조건 실행 결과 확인

그러나 사용자의 입력을 통해서만 SQL Injection 이 가능한 것은 아니다.


3. SQL Injection Case

[1. 쿠키값을 통한 SQLi]

(1) 마이페이지
○ 쿠키값을 통해 개인정보를 출력해주고 있다.
● 즉, 쿠키값을 통해 DB에 질의하고 그 결과를 출력하고 있다.

(2) SQL 질의문 추측
select (컬럼) from (테이블) where user_id = '쿠키 값'

(3) SQL 질의문 삽입 가능 여부 확인
○ 생성되는 쿼리 : ~ where user_id='ttest' and '1'='1'
● ttest 값을 전달한 결과와 동일

(4) 참/거짓 조건 실행 결과 확인
○ 참/거짓 조건에 따라 유저의 정보 출력 여부가 차이난다.



[2. HTTP 요청헤더(User-Agent)를 통한 SQL Injection]

(1) 이용자의 IP와 User-Agent String 기록

(2) SQL 질의문 추측
('User-Agent String', 'IP')

(3) SQL 질의문 삽입 가능 여부 확인
○ User-Agent: test', '1'='1')#

(4) 참/거짓 조건 실행 결과 확인
○ 참 조건일때 IP에 1, 거짓 조건일때 IP에 0으로 출력된다.



[3. 컬럼 이름을 통한 SQL Injection]

(1) 게시판에서 작성자 이름으로 게시글 검색

(2) SQL 질의문 추측
select (컬럼) from (테이블) where option_val like '%board_result%'

(3) SQL 질의문 삽입 가능여부 확인
○ option_val : '1'='1' and username

(4) 참/거짓 조건 실행 결과 확인
○ 참/거짓 조건에 따라 게시글 출력 여부가 차이난다.



[4. 정렬을 통한 SQL Injection]

(1) 게시판에서 게시글 제목으로 게시글 검색

(2) SQL 질의문 추측
select (컬럼) from (테이블) where option_val like '%board_result%' order by sort
○ order by 부분에 참/거짓 조건을 삽입하기 위하여 case when 문법이 사용된다.
● case when (조건) then (참일때 실행) else (거짓일때 실행) end

(3) SQL 질의문 삽입 가능여부 확인
○ sort : case when (1=1) then 1 else (select 1 union select 2) end
● 조건이 참일때 order by 1, 조건이 거짓일때 행렬이 되어 오류 발생
(3-1) 오류 발생 추가적인 구문
○ sort : (select 1 union select 2 where (1=1))
● 조건이 참일때 행렬이 되어 오류 발생, 조건이 거짓일때 order by 1

(4) 참/거짓 조건 실행 결과 확인
○ 참/거짓 조건에 따라 게시글 출력 여부가 차이난다.



[5. 참/거짓 조건의 결과가 동일할때 SQL Injection]

(1) 마이 페이지
○ 쿠키값을 통해 개인정보 출력

(2) SQL 질의문 추측
select (컬럼) from (테이블) where user_id = '쿠키 값'

(3) SQL 질의문 삽입 가능여부 확인
○ Cookie : ttest' and '1'='1 / ttest' and '1'='2
● 참/거짓 조건의 실행결과가 동일

(4) 에러를 유발하여 결과값이 달라지도록 유도
○ Cookie : ttest' and (select 1 union select 2 where (1=1)) and '1'='1

(5) 참/거짓 조건 실행 결과 확인
○ 조건이 참일때 DB에러 발생, 조건이 거짓일때 개인정보 정상 출력

4. SQL Injection 대응 방안

1) Prepared Statement

Prepared Statement 란?
쿼리 실행계획 분석과 컴파일을 미리 수행하여 사용하는 방식이다.
바인딩 변수(?)를 사용하여 SQL의 반복되는 내용을 쉽게 구현 가능하다.

String prepareStatement = "select * from users where name=? and password=?";
PreparedStatement preparedStatement = connection.prepareStatement(prepareStatement);
preparedStatement.setString(1, loginName);
preparedStatement.setString(2, loginPassword);

Prepared Statement 장점

  • Statement 객체의 SQL 쿼리문은 실행될 때마다 분석해야 하는 반면 Prepared Statement 객체는 한번 분석되면 이후에 재사용이 용이하다.

  • 각 인수에 대해 placeholder (?)를 사용하여 SQL문을 정의할 수 있으며, 이를 통해 SQL Injection 공격에 방어할 수 있다.



2) White List 기반의 필터링

  • Prepared Statement 방식을 사용하면 근본적으로 SQL Injection 방어가 가능하다.

  • 그러나 order by, table 이름, 컬럼 이름 등에는 Prepared Statement 적용이 불가능하다.

  • 이러한 경우 화이트리스트 기반의 필터링을 적용한다.

if (sort == 'title')
	제목 기준 정렬
elif (sort == 'user_name')
	작성자 이름 기준 정렬
else
	조회수 기준 정렬

0개의 댓글