SQL Injection
개발자가 설계한 SQL 쿼리문에 해커가 악의적인 공격 구문을 삽입해 쿼리가 해커의 의도대로 실행되게 하는 공격
SQL Injection 심화 실습
임의의 값을 입력하고 Get Account Info 누르면 실행된 쿼리 정보 확인 가능
asdf';select*from user_system_data-
- asdf'
- ' (따옴표)는 SQL 쿼리의 문자열 종료를 의도적으로 발생시켜, 기존 쿼리의 문법을 깨트리는 데 사용된다.
- ; (세미콜론)
- SQL에서 쿼리 종료를 의미하며, **여러 쿼리 연결(chaining)**을 허용한다. 즉, 하나의 입력을 통해 두 개 이상의 쿼리를 실행하도록 시도할 수 있다.
- select * from user_system_data
- 데이터베이스 테이블인 user_system_data의 모든 데이터를 조회하는 쿼리이다.
- -- (주석 처리)
- SQL에서는 -- 이후의 모든 내용이 주석으로 처리된다.
이로 인해, 원래 쿼리의 나머지 부분이 무시되며, 공격자가 추가한 악의적인 쿼리가 정상적으로 실행될 수 있다.
- SQL에서는 -- 이후의 모든 내용이 주석으로 처리된다.
일반 SQL 인젝션 vs. 블라인드 SQL 인젝션
- 일반 SQL 인젝션:
- 데이터베이스에서 발생한 에러 메시지를 그대로 출력하거나, 쿼리의 실행 결과를 웹 페이지에 반영한다.
- 예를 들어, UNION을 사용하면 테이블의 데이터를 직접 출력할 수 있다.
- 블라인드 SQL 인젝션:
- 에러 메시지를 표시하지 않는 경우, 참/거짓 조건을 반복적으로 사용해 데이터베이스와 간접적으로 소통해야 한다.
- 웹 애플리케이션이 일반 에러 메시지를 숨겼지만 SQL 인젝션 취약점이 여전히 존재할 때 사용된다.
2. 블라인드 SQL 인젝션의 종류
- Content-based SQL Injection (내용 기반)
- 참/거짓 조건에 따라 페이지의 내용이나 출력이 달라지는지를 확인한다.
- Time-based SQL Injection (시간 기반)
- 페이지의 출력이 항상 동일할 때, 응답 시간을 지연시켜 참/거짓을 구분한다.
- Error based Blind SQL Injection (오류 기반)
오류를 참고해 참과 거짓을 구분한다.
중복이라 가입이 불가능하다고 뜸 -> 중복 체크 위하여 서버에서 select 구문 이용하고 있음을 추측할 수 있음
-> 가입 성공 유무를 통해 select쿼리가 참인지 거짓인지 구별할 수 있을 뿐이라 Blind SQL Injection
1=1이라는 참이 되는 조건 넣었는데 이미 존재한다고 가입이 안됨
1=2이라는 거짓이 되는 조건 넣으니 가입이 됨
-> 중복체크 쿼리가 참이면 가입 불가, 거짓이면 가입 성공
asdf는 이미 존재하는 계정이라 앞 조건은 참, 싱글쿼터로 인해 문자열 범위를 벗어남
password 컬럼에 존재하는 데이터 중 길이가 30자 미만인 경우 참이 되는 조건 확인
이미 존재하는 계정 -> asfd 패스워드는 30 미만임을 알 수 있음
숫자를 하나씩 줄여가면서 가입이 된 것을 확인할 수 있다.
이제 톰의 비밀번호를 구해보겠다.
톰의 비밀번호가 23자리인 것을 알았다.
인터루더를 이용한다.
페이로드는 이와 같이 설정했다.
116에서 길이가 확 달라졌다. 즉 다른 응답이 온 것이고 116의 아스키 코드를 가진 소문자 t가 password 첫 자리이다.
이걸 23자리 다 하면서 찾으면 된다.
그런데...첫 자리 찾고 그 이후부터 길이가 달라지지 않았다...