공격 백터는 pw 파라미터이며, pw 파라미터에 대한 검증은 prob, _, ., ()을 필터링하고 있다.
하지만 이 문제의 가장 큰 문제점은 select id from prob_dragon where id='guest'# and pw='{$_GET[pw]}'로 입력된 pw가 id 뒤로 넣어지게 되는데, id 뒤부터는 #로부터 주석처리가 된다는 것이다.
이 문제를 클리어하기 위해선 #를 무력화 시켜야하는 문제로 보인다.
위와 같이 URL 인코딩의 줄바꿈인 %0A 로 입력하여, 주석을 우회하려고 했지만 실패하였다.
혹시 내가 사용한 방법이 틀렸는지 확인하기 위해서 인터넷에 sqli %0a로 검색해보니, 내가 틀린 방법으로 하고 있었다.
원리는 밑과 같다. SELECT id FROM prob_dragon WHERE id=‘guest’# and pw=‘’인 쿼리에서 줄바꿈을 하면, 그 쿼리문랑 이어지게 작성을 해야한다.
나는 새로운 쿼리를 만든다는 생각으로 작성하니, 실패한 것이였다. (SELECT ‘admin’ as id)
SELECT id FROM prob_dragon WHERE id=‘guest’# and pw=‘’
or pw='admin'#'
위와 같이 이어지게 생각한다면 첫번째 줄에서만 주석처리가 되고, 두번째 줄은 주석처리가 안되는 것을 알 수 있다. 하지만 위 쿼리문으로 문제를 해결할 수 없다.
그 이유는 DB 안에 guest가 있기 때문에 SELECT id FROM prob_dragon WHERE id=‘guest’으로만 True가 되기 때문에 SELECT id FROM prob_dragon WHERE id=‘guest’ or pw='admin'이면 guest가 로그인된다. 그러므로 id=guest를 False로 만들어줘야한다.
나는 False를 만들기 위한 방법은 and pw=''를 줌으로써 False를 만들어줬다. 아주 간단하게 해결하였다.