본문 바로가기
보안/보안공부

DB SQL Injection

by 보안매크로 2023. 6. 18.
728x90

select

schema.tables

%

SQL 인젝션이 통하는지 확인 -> 3) order by 이용 칼럼 수 찾기 -> 4) data 출력 위치 파악 -> 5) 데이터베이스 이름 알기 -> 6) 테이블 이름 알아내기 -> 7) 칼럼 이름 알아내기 -> 8) data추출하기

저는 그중 일반적인 updatexml 을 활용하겠습니다

 

쓰는 방법은 1' and updatexml(null,concat(0x3a,'test'),null) and '1' = '1 입니다.

 

어렵게 생각하지 마세요! 그저 가운데 concat만 보시면 돼요!

 

concat은 문자열을 붙이는 거잖아요? 0x3a는 :을 뜻합니다 즉! 이 문은 :test을 확인하는 질의문이라 보시면 돼요!

해보겠습니다.

아스키코드 0x7e - ~

https://itkjspo56.tistory.com/94

FLOOR 함수는 소수점 첫째 자리에서 버림하는 함수로, 주어진 숫자와 가장 근접한 작은 정수를 출력한다. ROUND 함수와는 다르게, 매개 값을 받아 버림할 자릿수를 정할 수는 없다.


1. 종류

1.1 Error based SQL Injection

  • GET, POST 요청 필드, HTTP 헤더값, 쿠키값 등에 특수문자(싱글 쿼드(') 혹은 세미콜론(;)) 삽입 시, SQL 관련 에러를 통해 데이터베이스 정보 예상

✅ 예시 - 우편번호 검색

  • 검색창에 '(작은 따옴표) 입력 후 검색 시도
  • Error base SQL Injection에 취약함 확인
  • zipcode_id라는 컬럼 값 확인
  • ' and db_namd() > 1-- 입력하여 DB명(web) 확인
  • 문자열인 DB 명을 숫자형(int)으로 비교하려고 함에 따라 에러 메시지 출력
  • ' having 1=1-- 입력하여 테이블명.컬럼명(zipcode.zipcode_id) 확인
  • 구문 오류에 따라 메시지 출력
  • (having 구문은 반드시 앞에 group by가 같이 쓰여야 함)

1.2 Union based SQL Injection

  • 공격자가 Union을 이용하여 원래의 요청에 추가 쿼리를 삽입하여 정보를 얻어내는 방식

💡 Union

2개 이상의 쿼리를 요청하여 결과를 얻은 SQL 연산자

  • Union 쿼리는 2개의 테이블이 동일한 필드 갯수와 데이터타입을 가져야 함
  • → 사전 공격을 통해 해당 정보를 얻어야 함

✅ 예시

  • unionselect 절을 이용해 컬럼 갯수를 알아냄
  • select는 검색을 하려던 테이블의 컬럼 명 대신 컬럼 순서를 대신 입력 가능
  • → 컬럼 수 확인 가능

1.3 Blind based SQL Injection

  • 에러가 발생되지 않는 사이트에서 SQL 쿼리의 참/거짓 동작만으로 DB 구조를 파악하는 공격 기법
  • 조건이 참이면 페이지가 정상적으로 출력, 거짓이면 페이지가 출력되지 않음으로 구분 가능
  • 요즘에는 에러 메시지를 출력하지 않게 웹서버를 구축하고 있기 때문에 주로 사용하는 방식임

✅ 예시

  • SQL문을 통한 결과가 참인 경우
  • SQL문을 통한 결과가 거짓인 경우

1.4 Stored Procedure based SQL Injection

  • 웹에서 Stored Procedure에 대한 접근 권한을 가짐으로써 실행 가능

💡 저장 프로시저(Stored Procedure)

사용하고자 하는 Query에 미리 형식을 지정하는 것

일련의 쿼리를 하나의 함수처럼 실행하기 위한 쿼리의 집합

운영상 편의를 위해 만들어둔 SQL 집합 형태

  • 시스템 권한을 획득해야 하므로 공격 난이도가 높으나, 성공한다면 서버에 직접적인 피해 입힐 수 있음

✅ 예시

  • User라는 테이블이 있다고 가정

CREATE TABLE User( username VARCHAR(50), password VARCHAR(50) )ENGINE=InnoDB;

  • 데이터베이스에서 usernamepassword 선택

String Query = "SELECT * FROM username = ' " + username + " ' AND password = ' " + password + " ' "; execute_query(Query);

  • 사용자 입력을 받은 후 유효성 검사 없이 쿼리 생성

//문제 없이 수행 SELECT * FROM `User` WHERE UserName = 'Hady' AND Password = 'root'; //SQL Injection 공격 - 테이블 삭제 SELECT * FROM `User` WHERE UserName = '' AND Password = '';drop table User;--'

1.5 Time based SQL Injection

  • 쿼리 결과를 특정 시간만큼 지연시키는 것을 이용하는 기법
  • Blind 기법과 마찬가지로 에러가 발생되지 않는 조건에서 사용 가능

✅ 예시

  • 현재 사용하고 있는 데이터베이스의 길이를 알아냄
  • 악의적인 사용자가 abc123’ OR (LENGTH(DATABASE())=1 AND SLEEP(2)) – 이라는 구문을 주입
  • LENGTH() : 문자열의 길이 반환
  • DATABASE() : 데이터베이스의 이름 반환
  • LENGTH(DATABASE()) = 1
  • 참 → SLEEP(2) 동작
  • 거짓 → SLEEP(2) 동작 x
  • 숫자 1 부분을 조작하여 데이터베이스의 길이 알아낼 수 있음

2. 대응 방안

2.1 입력값 검증

  • 사용자의 입력이 DB Query에 동적으로 영향을 주는 경우, 입력된 값이 개발자가 의도한 값 인지 검증

/*, –, ‘, “, ?, #, (, ), ;, @, =, *, +, union, select, drop, update, from, where, join, substr, user_tables, user_table_columns, information_schema, sysobject, table_schema, declare, dual,…

✅ 예시

import java.util.regex.Matcher; import java.util.regex.Pattern; /* 특수문자 공백 처리 */ final Pattern SpecialChars = Pattern.compile(“[‘\”\\-#()@;=*/+]”); UserInput = SpecialChars.matcher(UserInput).replaceAll(“”); final String regex = “(union|select|from|where)”; final Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE); final Matcher matcher = pattern.matcher(UserInput); if(matcher.find()){ out.println(“<script>alert(‘No SQL-Injection’);</script>”); }

2.2 저장 프로시저 사용

  • 저장 프로시저를 사용하여 지정된 형식의 데이터가 아니면 Query가 실행되지 않도록 함

✅ 예시

📝 취약 코드

try{ String uId = props.getProperty(“jdbc.uId”); String query = “SELECT * FROM tb_user WHERE uId=” + uId; stmt = conn.prepareStatement(query); ResultSet rs = stmt.executeQuery(); while(rs.next()){ .. … } }catch(SQLException se){ .. … }finally{ .. … }

📝 안전한 코드

try{ String uId = props.getProperty(“jdbc.uId”); String query = “SELECT * FROM tb_user WHERE uId= ?” stmt = conn.prepareStatement(query); stmt.setString(1, uId); ResultSet rs = stmt.executeQuery(); while(rs.next()){ .. … } }catch(SQLException se){ .. … }finally{ .. … }

2.3 서버 보안

  • 최소 권한 유저로 DB 운영
  • 사용하지 않는 저장 프로시저와 내장함수 제거/권한 제어
  • 목적에 따라 Query 권한 수정
  • 공용 시스템 객체의 접근 제어
  • 신뢰할 수 있는 네트워크, 서버에 대해서만 접근 허용
  • 에러 메시지 노출 차단
728x90