SQL Injection이란?
- 입력 란이나 URL 파라미터 등을 통해 SQL 명령어를 주입하여 데이터베이스의 정보를 조회, 수정, 삭제하는 공격 방식
SQL Injection 공격 기법
Union-Based SQL Injection (유니온 기반 SQL 인젝션)
- UNION 연산자를 사용하여 여러 쿼리의 결과를 결합하는 기법.
- UNION이란?
- 두 개 이상의 SELECT 쿼리의 결과를 결합하여 하나의 결과 집합으로 만드는 연산자.
- UNION으로 결합하는 각 SELECT 쿼리는 동일한 수의 열을 가져야 하며, 각 열의 데이터 타입도 호환되어야 함.
- UNION이란?
- 장점
- 다양한 테이블에서 정보를 동시에 조회가 가능.
- 결과를 조합하여 다양한 정보를 얻을 수 있음.
- 단점
- 기존 SQL 구문과 조회하려고 하는 SQL 구문의 컬럼 수가 같아야함.
- 테이블 구조(DB명, Table명, Clomun명)을 알고있어야 함.
SELECT email, password FROM login UNION SELECT username, phone FROM uaers;
Error-Based SQL Injection (에러 기반 SQL 인젝션)
- 쿼리 실행 중 발생하는 오류 메시지를 통해 데이터베이스의 정보를 추출하는 기법
- 장점
- 오류 메시지를 통해 데이터베이스의 정보를 직접적으로 추출할 수 있음.
- 잘못된 쿼리에 대한 피드백을 통해 추가 정보를 얻을 수 있음.
- 단점
- 많은 웹 애플리케이션에서 오류 메시지를 숨기거나 필터링하므로 효과가 제한적일 수 있음.
SELECT * FROM users WHERE username = 'test' and extractvalue( '1', concat(0x3a, (select database()))) and '1' = '1';
Blind SQL Injection (블라인드 SQL 인젝션)
- 공격자가 쿼리의 결과를 직접적으로 알 수 없는 경우, 참/거짓 질문을 통해 정보를 추측하는 기법
- 데이터베이스의 구조 및 데이터에 대한 정보를 점진적으로 수집
- 장점
- 직접적인 결과가 보이지 않아 방어 시스템이 감지하기 어려울 수 있음.
- 데이터베이스 구조를 추측할 수 있는 유용한 정보 수집이 가능함.
- 단점
- 공격자가 정보를 얻는 데 시간이 많이 소요될 수 있음.
- 공격의 성공률이 낮을 수 있으며, 반복적인 쿼리로 인해 탐지될 위험이 있음.
SELECT * FROM users WHERE username = 'test' and (ascii(substr((select database()),1,1)) > 0) and '1'='1
Time-Based SQL Injection (타임 기반 SQL 인젝션)
- 쿼리 실행 시 지연을 발생시켜 응답 시간을 통해 정보를 유출하는 기법
- 네트워크에서 응답을 지연시키는 방법으로 보안 시스템을 우회할 수 있음
- 장점
- 응답 시간을 통해 참/거짓을 판단하여 정보를 추출할 수 있어, 결과가 보이지 않는 경우에도 공격이 가능함.
- 특정 조건을 통해 시스템의 반응을 관찰할 수 있음.
- 단점
- 쿼리 실행 지연으로 인해 서버의 성능에 영향을 줄 수 있음.
- 방어 시스템이 시간 지연을 감지할 경우 차단될 수 있음.
SELECT * FROM users WHERE username = 'test' AND IF((ascii(substr((select database()),1,1)) > 0), SLEEP(5), 0);
Out-of-Band SQL Injection (오프 밴드 SQL 인젝션)
- 데이터베이스의 응답을 웹 페이지가 아닌 다른 채널(예: DNS 요청, 외부 요청)을 통해 받는 기법
- 일반적인 SQL Injection 공격이 실패했을 때 사용됨
- 장점
- 다른 채널을 통해 정보를 수집하므로 탐지되기 어려울 수 있음.
- 특정 상황에서만 사용할 수 있지만, 효과적인 정보 수집이 가능함.
- 단점
- 설정이 복잡할 수 있으며, 성공적으로 작동하기 위해서는 특정 환경이 필요함.
- 네트워크 연결이 차단된 경우 효과가 없을 수 있음.
SELECT * FROM users WHERE username = 'test';
SELECT @@version INTO OUTFILE '/var/www/html/version.txt';
SQL Injecion 예방법
- Prepared Statements 사용: SQL 쿼리를 미리 컴파일하여 사용자 입력을 쿼리와 분리함으로써 SQL Injection을 방지.
cursor.execute("SELECT * FROM users WHERE username = ? AND password = ?", (username, password))
- ORM (Object-Relational Mapping) 사용: SQL 쿼리를 직접 작성하는 대신 ORM을 사용하여 데이터베이스와 상호작용하는 것이 좋음.
- 입력값 검증: 사용자 입력을 철저히 검증하고 필터링하여 악의적인 SQL 코드가 포함되지 않도록 해야함. 예를 들어, 숫자 필드는 숫자만 허용하고, 문자열 필드는 길이와 형식을 제한해야 함.
- 화이트리스트 기반 접근: 허용된 값만을 사용하도록 입력값을 제한. 예를 들어, 특정 선택된 값만 사용할 수 있도록 해야 함.
- 오류 메시지 숨기기: SQL 오류 메시지를 사용자에게 노출시키지 않도록 하여 공격자가 시스템의 구조를 추측하지 못하게 해야 함. 주석의 경우도 배포 전 확인 하고 배포해야 함.
- 최소 권한 원칙 적용: 데이터베이스 사용자에게 필요한 최소한의 권한만 부여하여 데이터에 접근할 수 있는 가능성을 줄임.
후기
- SQL Injection을 직접 해본 결과 생각보다 쉬운 방법으로 DB에 있는 데이터를 추출할 수 있어서 놀랐다.
- Blind SQLi에 경우 직접 하나 입력하는 것 보다 코드로 프로그램을 개발하여 실행하는 방법이 훨씬 효율적일 것 같다.
728x90
반응형