블라인드SQL인젝션은 보통의 SQL 인젝션보다 더 어렵다. 당연히 SQL 인젝션이 유행하면서 많은 개발자들이 이에 경각심을 갖기 시작했고 시큐어코딩을 적용했다. 


하지만 해커들의 열정은 웹사이트 개발자보다 월등히 높다. 해커들은 손쉬운 SQL인젝션이 통하지 않지만 제목에서도 알 수 있듯.. 깜깜한 어둠 속에서 손을 더듬어 가며 손에 닿는 감촉으로 무엇인가를 인식할 수 있듯.. DB에 접근할 것으로 추측되는 화면만 있으면 조회 결과가 화면에 보이지 않더라도 화면 조작의 결과가 화면에 표현되는 방식에 따라 그 결과를 추측하여 DB에 접속하는 공격을 시도하기 시작했다.


그런 공격의 유형이 바로 Blind SQl Injection 이다.


DVAW에서는 SQL 인젝션 다음의 예제로 실습을 해볼 수 있다. 



Blind SQL 인젝션의 실습 화면이다. 

User ID를 입력하면 그 결과가 다음 라인에 적색 텍스트로 표현된다. 사용자 ID가 DB에 있다. 없다.로 그 결과면 표시된다. 해커는 당연히 이 페이지가 DB에 접속하여 사용자 정보가 담긴 테이블을 조회(SELECT) 한다고 추측할 수 있다. 어떻게 추측할 수 있는지 이해가 되지 않는다면...  뭐라 해줄 수 있는 말이 없다. 직접 로그인을 수행하는 웹페이지를 코딩해 보고 다시 이 포스트를 보기 바란다.

 

그런데 문제는 단순히 이 웹페이지에서저 작은 User ID 입력창에 DB의 종류를 알아내고 DB와 Table의 구조를 알아내고 테이블을 조회해 내용을 알아낼 수 있는 SQL을 입력하는 것도 힘든 작업이지만 문제는 앞에서 테스트한 SQL Injection 예제 처럼 그 결과를 이 화면에서는 표시해 볼 수 없다는 점이다.  


공격의 이름에 Blind 라는 단어가 들어가는 이유가 여기에 있다. 예를 들어 MySQL DB의 버전을 가져오려면 아래와 같은 SQL을 실행해야 한다.



문제는 SQL Injection 취약점이 있다 하더라도 select @@version; 의 결과를 화면에 표시할 수 없다면..?? 어떻게 해야 하나? 실습 화면에서 보듯 사용자 ID가 DB에 조회(SELECT)해 보니 있다, 없다만 표시하는 화면이므로 SQL을 조작해 "사용자ID가 DB에 있고 버전을 조회한 결과의 첫번째 문자가 5냐 아니냐"로 결과를 출력하도록 해야 한다.


사용자ID는 위 화면처럼 2로 고정하고 아래 SQL문을 추가해 조작하여 그 결과를 모니터링하는 것이다.



솔직하게 이야기 해 substr()의 결과가 5... 즉 5.7 버전의 앞글자 5라면 그 결과가 참(1)이 되는데... 이런 식으로 수백, 수천번의 SQL을 직접 실행해 그 결과를 확인하는 방법으로 해킹이 가능할까 싶다. SQL 인젝션을 통해 위의 SQL을 조작해 실행하고 사용자 ID가 DB에 있다...없다를 보면서 한글자...한글자... 아니면 SQL의 참/거짓 여부를 확인하는 노가다를 하면서 해킹을 하고 싶지는 않다. 무슨 부귀영화를 누리겠다고 그런 노가다를 한다는 말인가.. 


그래서 도구를 만들고 사용한다. 



이때 활용할 수 있는 도구가 바로 SQLMap 이라는 DB 취약점 점검 도구다.

SQLMap은 칼리리눅스에 기본으로 설치되어 있기 때문에 이번 블라인드 SQL 공격 실습은 칼리리눅스에서 해봤다.


먼저 칼리리눅스에 설치된 사파리 웹 브라우저를 통해 DVWA에 접속한다. 



왜냐하면 SQLMap을 통해 웹브라우저를 시뮬레이션하면서 취약점 점검을 수행하려면 웹브라우저에서 해당 사이트에 로그인한 뒤 부여받는 세션ID가 필요하다. 그래서 칼리리눅스에 설치된 사파리 브라우저로 DVWA에 로그인 한 뒤 세션ID를 복사해 SQLMap 명령행에 입력해줘야 한다.


접속했다면 브라우저의 ! 아이콘을 클릭한 뒤 > 표시를 클릭한다.



아래의 More Information 을 클릭한다.



Security를 클릭하면 나오는 View Cookies를 클릭한다.



번저 PHPSESSID를 선택하고 아래의 Content에 있는 길다란...문자열을 복사한다. 이 문자열이 웹서버가 로그인한 사파리 브라우저에게 부여한 세션ID다. 

 


두번째 쿠키는 security 레벨을 설정하는 쿠키다. 값은 low 다. 



그리고 칼리리눅스에 SSH로 접속해 root로 su 한 뒤 sqlmap을 실행한다.



위 화면처럼 SQL Injection (Blind) 메뉴를 선택했을 때 사파리 주소창에 표시되는 URL과 조금 전 복사해 둔 두개의 쿠키 즉 세션ID와 Security Level을 위 화면처럼 입력해준다.


그리고 엔터키를 누르면 sqlmap이 실행되고 취약점을 찾아준다.


id라는 GET 방식의 파라미터가 취약할 수 있고 id가 AND boolean-based blind 고역에 취약할 것 같고... DB는 MySQL인걸로 보인다는 둥 앞에서 설명한 방법을 통해 자동으로 취약한 정보들을 수집해준다.


주루룩~~계속 수집해준다.



점검이 끝나면 점검결과를 요약해준다.



백엔드에 숨어 있는 DB는 MySQL이고 운영체제는 Ubuntu, 웹서버는 아파치며 에러도 발견되었다는 이야기다.

그리고 그 앞에 가장 중요한 GET 방식의 id 파라미터가 AND boolean-based blind 공격에 취약하다는 것과 time-based blind 공격에도 취약할 수 있다는 결과를 알려준다.


Blind SQL Injection 취약점이 있는 것 같으므로 이제 DB 이름을 확인해 본다. 아래 화면처럼 --current-db 옵션을 추가해 실행한다.



db이름이 dvwa로 확인되었다. 그렇다면 dvwa DB에 어떤 테이블들이 있는지 확인하기 위해 -D 옵션과 --tables 옵션을 함께 써본다.



주루룩...스캔하더니 guestbook 과 users 테이블이 있다고 알려준다.


테이블이 확인되었으니 테이블의 내용을 조회해보자.  -D, -T, --dump 옵션을 함께 써본다. 테이블은 users 테이블을 지정해보자. 



뭔가 값들을 가져오기 시작한다. 계속 가져온다.. (이야~~신난다~~)



가져오는 내용에 Hash 값으로 추측되는 문자열도 보인다. 그런데 hash 문자열이 조금 짧다.



역시나 조금 짧은 Hash 문자열은 MD5다. 비밀번호를 크랙하겠냐고 물어본다. 사전파일도 자체적으로 갖고 있는 사전 파일을 쓰겠냐고도 물어본다.  그리고 Hash를 무작위 대입 공격으로 크랙해본다. 사전파일에 있는 비밀번호를 사용한다면 크랙이 될 것이다.


역시나 크랙이 된다. 그리고 최종적으로 users 테이블에서 조회된 사용자 정보를 일목요연하게 정래해 보여준다.