일반 SQL Injection은 원하는 정보를 한 번에 알아낼 수 있다. 하지만 원하는 정보를 한 번에 얻지 못할 때, 서버에서 주는 참과 거짓의 응답만으로 데이터를 유출해내는 기법을 Blind SQL Injection 이라고 한다.
[ 얻고자 하는 정보의 길이 ]
얻고자 하는 정보의 길이를 알게 되면 효율적인 공격이 가능해지기 때문에 length() 함수를 사용해 데이터의 길이를 알아낼 수 있다.
아래는 pw 컬럼에 들어 있는 데이터의 길이를 확인하기 위한 payload이다.
a' or length(pw)<10--
-- 뒤 공백은 필수이다. pw가 10자 보다 짧은 계정이 있다면 로그인이 성공하고, 만약 거짓이라면 로그인 실패가 뜨게 된다. 이런식으로 참과 거짓을 알려주는 서버의 응답을 통해 데이터를 유추해낼 수 있다.
pw가 10보다 짧은 계정이 존재한다. 계속해서 숫자를 줄여나가며 공격을 시도해보면 length(pw)<8 에서 로그인 실패가 뜬다.
이를 통해 guest 계정의 비밀번호는 8자리인 것을 알 수 있게 된다. 그렇다면 admin 계정의 비밀번호 길이를 알고 싶다면 어떻게 해야할까?
이때는 AND 구문을 이용해주면 된다. 아래와 같은 payload를 작성하면 id가 admin일 때의 경우에만 조건을 걸 수 있다.
a' or length(pw)<10 and id='admin'--
[ 실제 데이터의 값 대입 ]
위 payload를 통해 admin 계정의 pw 길이 또한 8인 것을 알아냈다고 가정한다. 길이를 알아낸 후에는 실제 데이터 값을 알아내야 한다.
이때 사용할 수 있는 함수가 substring() 이다. 문자열을 조각내는 함수로 첫 번째 인자는 자르고자 하는 대상, 두 번째 인자는 몇 번째부터 자를지, 세 번째 인자는 몇 글자를 자를지 지정할 수 있다.
우선은 실습을 위한 것이기 때문에 admin 계정의 비밀번호가 admin123이라는 것을 알고 시작하도록 한다. MySQL은 대문자와 소문자를 구별하지 못하기 때문에 문자의 대입은 아스키코드를 사용하는 것이 정확한 결과를 얻을 수 있다.
아래 payload는 pw 칼럼에 존재하는 데이터의 첫 번째 글자부터 한 글자를 자르고 그 값이 소문자 a와 일치하는지 확인하는 구문이다.
a' or ascii(substring(pw,1,1))=97 and id='admin'--(공백)
로그인에 성공한 모습을 보아, admin 계정의 pw 첫 글자는 'a' 라는 것을 알 수 있다. 위 방법을 이용하면 데이터 값을 알아낼 수 있게 된다.
다음 포스팅은 Time Based, Union Based SQL Injection에 대해 설명한다.
'Security > Web Hacking' 카테고리의 다른 글
SuNiNaTaS(써니나타스) Challenges 2번 문제 풀이 (0) | 2023.03.21 |
---|---|
SuNiNaTaS(써니나타스) Challenges 1번 문제 풀이 (0) | 2023.03.21 |
PHP SQL Injection 방어 기법 (0) | 2022.09.01 |
Time-Based/Union-Based SQL Injection (0) | 2022.08.31 |
SQL Injection (0) | 2022.08.30 |