<aside> 💡 password = 12AB 라고 가정
</aside>
substr(lpad(bin(ascii(substr(pw,{},1))),7,0),{},1)=1
substr(pw,1,1)
ABCD → 1 추출
ascii(1)
1의 ascii값은 49
bin(49)
49의 이진값은 11 0001
lpad(110001, 7, 0)
ascii값의 범위는 0~127
즉, 000 0000 ~ 111 1111 의 숫자로 모두 나타날 수 있다
그래서 빈자리는 0으로 채우고 7자리 숫자로 만든다
substr(0110001, 1, 1) = 1
lpad로 생성한 7자리 숫자를 하나씩 비교해서 ascii값을 확인한다
비밀번호 12AB중 첫번째 글자를 알아내기 위해 7번의 실행만 하면 된다
왜 이 방법으로 blind SQL injection을 수행해야 하는가?
실행 속도의 향상
키보드로 입력 가능한 모든 문자는 33~126까지 94가지
만약, 리스트를 작성해서 비교하는 방식이라면
한 글자를 알아내기 위해 94번의 시행이 필요하다
한글이나 한자 같은 유니코드도 사용 가능 하면 그 경우의 수는 헤아릴 수 없다..
substr(pw, 1, 1) = 'a'
substr(pw, 1, 1) = 'Z'
...
substr(pw, 1, 1) = '0'
substr(pw, 1, 1) = '9'
substr(pw, 1, 1) = '!'
substr(pw, 1, 1) = '~'
하지만, lpad
를 이용한 bit연산이라면 어떠한 문자를 사용하더라도
단, 7번의 시행 만으로 알아낼 수 있다 (ascii문자의 경우 / 멀티바이트의 경우 24번 만으로도 알아낼 수 있다)
substr(lpad(...), 1, 1) = 1 # false
substr(lpad(...), 2, 1) = 1 # true
substr(lpad(...), 3, 1) = 1 # true
substr(lpad(...), 4, 1) = 1 # false
substr(lpad(...), 5, 1) = 1 # false
substr(lpad(...), 6, 1) = 1 # false
substr(lpad(...), 7, 1) = 1 # true
→ 011 0001 → 49 → “ 1 “
탐지 정확성 향상
substr(pw, 1, 1) = 'a'
substr(pw, 1, 1) = 'Z'
...
substr(pw, 1, 1) = '0'
substr(pw, 1, 1) = '9'
substr(pw, 1, 1) = '!'
substr(pw, 1, 1) = '~'
위 코드처럼, 지정한 문자와 비교하는 방식은 탐지 못하는 비밀번호가 발생할 수 있다
내가 영어와 숫자만 비교했다면 특수 문자를 사용한 비밀번호의 경우는 알아낼 수가 없다
하지만, lpad
는 가능한 모든 문자를 탐색할 수 있기 때문에 정확성과 속도 모두를 개선한 방법이다