<aside> 💡 password = 12AB 라고 가정

</aside>

payload

substr(lpad(bin(ascii(substr(pw,{},1))),7,0),{},1)=1

실행 과정

  1. substr(pw,1,1)

    ABCD → 1 추출

  2. ascii(1)

    1의 ascii값은 49

  3. bin(49)

    49의 이진값은 11 0001

  4. lpad(110001, 7, 0)

    ascii값의 범위는 0~127

    즉, 000 0000 ~ 111 1111 의 숫자로 모두 나타날 수 있다

    그래서 빈자리는 0으로 채우고 7자리 숫자로 만든다

  5. substr(0110001, 1, 1) = 1

    lpad로 생성한 7자리 숫자를 하나씩 비교해서 ascii값을 확인한다

    비밀번호 12AB중 첫번째 글자를 알아내기 위해 7번의 실행만 하면 된다

Why?

왜 이 방법으로 blind SQL injection을 수행해야 하는가?

  1. 실행 속도의 향상

    Untitled

    키보드로 입력 가능한 모든 문자는 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 “

  2. 탐지 정확성 향상

    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는 가능한 모든 문자를 탐색할 수 있기 때문에 정확성과 속도 모두를 개선한 방법이다