los의 1번 문제 Grenlin의 내용은 다음과 같다.
먼저 query를 보면 id와 password의 값을 받는 것을 알 수 있다.
코드를 확인해보면 먼저 5 번째 줄과 6 번째 줄의 if문에서 특정 문자를 필터링하고 있음을 알 수 있다. pregmatch 함수는 첫 번째 인자로 들어가는 정규식으로 표현된 문자들이 두 번째 인자로 들어가는 문자열에 포함되어 있다면 true를 반환한다. 즉 ‘prob’, ‘’, ‘.’, ‘\’ 이 값들 중 하나라도 입력값에 존재한다면 필터링 되어 ‘No Hack’이라는 문구를 확인하게 된다.
9 번째 줄에서는 query의 값을 배열로 result라는 변수에 저장하게 된다.
그리고 10 번째 줄에서 if($result[‘id’]) 라는 if문이 있는데, 9 번째 줄에서 저장한 id에 해당하는 배열의 값이 존재하기만 하면 문제가 해결된다는 것을 알 수 있다.
id에 값을 넣어 반드시 참이 되도록 하고 뒤의 pw부분은 앞에 ‘#’을 넣어 주석처리가 되도록 하면 문제는 해결된다.
먼저 id안에 ‘hi’(아무값)을 넣어주고 뒤에 따옴표(‘)를 추가하고, ‘ or 1=1을 삽입하여 쿼리문이 참이 되도록 해준다. 그 후 뒤 쪽 pw는 주석처리를 해주었다. 정답은 다음과 같다. 따옴표(%27), 공백(%20), #(%23)은 모두 URL 인코딩을 따라 입력한다.
https://los.rubiya.kr/chall/gremlin_280c5552de8b681110e9287421b834fd.php?id=hi%27or%201=1%20%23
Gremlin의 상황은 입력값을 GET방식으로 받았기 때문에 발생한다. GET방식은 파라미터(URL)에 입력값이 그대로 노출된다는 보안적인 문제를 가지고 있기 때문이다. 이를 방지하기 위해서는 동적쿼리가 아닌 정적쿼리를 지향해야한다. (정적쿼리: 외부의 입력값에 의해서 쿼리문의 구조가 변하지 않는 쿼리)