본문 바로가기
CS/시큐어 코딩

[시큐어코딩] SQL 삽입(Injection)

by J-rain 2024. 5. 17.

 

SQL 삽입

웹 애플리케이션에서 입력받아 데이터베이스로 전달하는 정상적인 쿼리(CRUD)를 변조, 삽입하여 데이터베이스에 불법적인 데이터 열람, 시스템 명령 수행등 비정상적인 데이터베이스에 접근 하는 기법이다. 모든 종류의 DBMS에 적용 가능한 공격기법이며, 지속적으로 발전되고 있는 공격기법이다.

 

해당 취약점으로 인해

악성 스크립트 실행, 외부 프로그램 사용가능, DB 정보 열람,추가,수정,삭제 가능, 프로시저를 통한 운영체제 명령어 수행, 불법 로그인등의 침해 사고가 발생 할 수 있다.

 

발생원인

웹 애플리케이션의 SQL 쿼리문의 일부로 사용되는 사용자의 입력데이터에 대한 적절한 검증 작업이 수행되지 않아서 발생한다.

해결방안

  • 규범화 : 데이터 손실이 없는 동일한 내용으로 축소 , 공백 제거 등
  • 정규화 : 데이터 손실이 있지만 간단한 형태로 변환 , 문자열 정규화
  • 새니타이즈 : 입력 데이터를 시스템 요구사항에 맞게 가공 , 입력 출력에 포함되지 말아야 하는 문자 제거
  • 검증 : 입력된 데이터가 프로그램에서원하는 영역 안의 값인지 확인하는 과정

 

 

SQL 삽입 취약점을 가지는 동적 쿼리 구조

입력 값 검증 없이 쿼리 문 생성에 바로 사용할 때 발생

 

 

정적 쿼리를 이용한 SQL 삽입 공격 방어

 

1. Statement 방식 DB Query

PreparedStatement 의 setXXX () 메소드로 외부 입력 데이터를 쿼리문에 설정하여 쿼리 구조가 변조되는 것을 방지한다.

 

 

2. Hibernate Query Language 방식

Hibernate Query Language에 외부 입력값을 바인드 방식으로 처리하여 쿼리문이 변조 되지 않도록 한다.

 

 

3. Java Persistence API 방식

 

4. MyBatis 방식

외부에서 입력되는 값을 쿼리문에 사용하는 경우 입력값을 받는 변수를 $ 대신 # 을 사용함으로써 바인딩 처리할 수 있다.

 

 

 

 

SQL 삽입 공격의 유형

 

Form Based SQL 삽입

공격자가 웹 애플리케이션의 입력 필드(예: 로그인 폼, 검색 필드 등)에 SQL 구문을 삽입하여 데이터베이스에 대한 무단 액세스 또는 조작을 시도하는 공격 기법

 

실습 환경은 웹 애플리케이션 서버는 사용자의 입력을 받아 동적 쿼리에 사용하고 있으며 화이트리스트 기반의 필터링을 전혀 사용하지 않다고 가정한다.

 

1. 실습 환경에서 정상 상태 확인

 

 

 

2.비정상적인 입력 값으로 인증 우회 가능성 확인 진단자가 의도한 실행 쿼리문

select * from member where id = ' or'a'='a and password =' or'a'='a


 

a=a 와같은 코드가 실행되어 항상 '참' 값이 반환되어 모든 테이블의 정보를 확인하라는 명령어로 변경되어 데이터베이스에 전달되었다. 그러다보니 서버측에서 너무 많은 정보를 회신할 수 없어서 returned too many results 라는 오류가 생겼다.
즉, 공격은 성공했으나 회신오류

 

 

 

3.비정상적인 입력 값으로 인증 우회 확인 진단자가 의도한 실행 쿼리문

select * from member where id = admin'#  and password= 'aaa'


admin'# 으로 입력하였더니 [ 관리자 ] 모드로 연결되었다.
공격자가 입력한 #은 #이후 문자열을 주석처리하도록 쿼리문의 의미를 변경한다. 이로인해 패스워드의 입력내용 상관없이 admin값을 조회하여 로그인이 가능하다.

 

 

 

 

UNION SQL 삽입

공격자가 UNION SQL 연산자를 사용하여 원래의 쿼리와 결과를 병합하고 추가적인 쿼리 결과를 반환하는 기법이다. 이를 이용하여 단계적으로 보안 자산의 정보 추출이 가능하다.

 

 

1. 정상적인 요청 처리 


IDX, ID, PASSWORD, 이름이 출력되었다.

 

 

 

2. 공격가능성 확인


DB에서 사용하고 있는 컬럼의 개수를 확인하는 과정이다.

 


컬럼의 갯수가 6일때 정보가 나오는것을 확인할 수 있다. 즉, 해당 데이터베이스의 컬럼의 갯수가 6개이고 화면에 출력된 결과를 기반으로 1,2,3,4 번 컬럼을 통해 데이터를 불러올 수 있다. 
→ 컬럼은 6개로 맞춰주고, 1~4번 컬럼에 악성 쿼리문을 삽입하면 정보 유출 가능

 

 

3. DB 버전 확인


1번 컬럼에 version()을 삽입하여 5.1.41-community  DB 버전을 확인할 수 있다. 
union seclect와 버전 키워드를 사용하여 해당 DBMS의 버전 정보를 얻을 수 있었다.

 

 

4. 공격대상 DB 목록 확인


DB 목록 확인 가능

 

 


5. 특정 DB(information_shcema) 선정 후 , 테이블 목록 확인


information_schema DB에서 현재 사용하고 있는 DB table 목록 확인 가능

 

 


6. 테이블의 특정 컬럼(board_member)명 확인


board_member table의 컬럼명 확인 가능

 


7. 컬럼 데이터 추출 → 공격 목표 최종 달성


board_member의 컬럼 데이터 추출

 

 

 

 

 

 

 

 

참고: 해킹 방어를 위한 JAVA 시큐어코딩(실무에 바로 적용하는)(개정판 4판) 김영숙

 

 

 

 

댓글