LOS(Lord of SQL Injection) : https://los.rubiya.kr/gate.php
SQL Injection 공격에 대해 공부할 수 있다.
Level1 : gremlin
php 코드가 나온다.
빨간 박스를 보면 id와 pw를 GET 방식으로 받아오는 것을 알 수 있고, 초록 박스에서 query를 db에 질의하여 결과값이 있다면 문제를 해결할 수 있을 것으로 보인다.
먼저, GET방식으로 아무 값이나 넣어본다.
다음 사진과 같이 URL 주소 맨 뒤에 '?id=1&pw=1'를 입력한다.
* ?는 URL주소 뒤에 변수를 지정할 수 있도록 구분하고, &는 변수와 또 다른 변수의 값을 넣어줄때 변수를 구분해준다.
엔터를 누르면 쿼리문의 where에 GET 방식으로 값이 입력된 것을 알 수 있다.
쿼리문만 따로 보면 입력된 아이디와 패스워드가 일치하는 id를 검색하는 구문이다.
php코드에서 if문은 이 쿼리문에서 id값이 조회되기만 하면 된다.
id='1' and pw='1'
우리는 db에 저장된 id와 pw를 모르지만, 현재 보이는 이 조건을 or연산을 이용해서 True로 반환할 것이다.
id='1' or '1'='1' and pw='1' or '1'='1'
이 조건만 놓고 생각해본다면 결과는 id값이 1이던 말던, pw값이 1이던 말던 '1'='1'은 True를 반환하기 때문에 or 연산으로 인해서 True가 된다.
그러면 db안에 저장된 모든 id를 select하게되는 SQL 질의구문이 만들어 지게 되는 것이다.
다시 GET 방식으로 입력한 것을 보면 '?id=1&pw=1' 라고 입력했고, 쿼리문에서 확인해보면 싱글쿼터(')가 자동으로 달려서 id='1' and pw='1' 인 것을 확인할 수 있다.
결론적으로 우리는 쿼리문에 나타나는 where문을 id='1' or '1'='1' and pw='1' or '1'='1' 로 만들어야 하기 때문에
GET 방식으로 입력되는 값 양쪽에 싱글쿼터(')를 생각해서 값을 넣어주면 된다.
?id=1' or '1'='1 & pw=1' or '1'='1
GREMLIN Clear! 라고 뜨면서 문제를 풀었다.
+ 추가적으로
여기서 다시 URL의 GET 방식으로 값을 넘겨주는 부분을 다시 확인해보면, 내가 입력한 값이 아닌 %27, %20과 같은 처음 보는 값으로 바뀐다.
이것이 url인코딩이다.
싱글쿼터(') : %27
공백 : %20
# : %23
등등등...
url인코딩은 url 스트링에 있는 텍스트를 브라우저에 정확하게 전송하기 위해 존재한다.
?, &, /, 공백 등 특수문자 경우에 잘리거나 변형될 수 있기 때문에 특수문자는 인코딩이 되는 것이 좋다.
이외에도 한국어, 일본어 등 ASCII 코드를 사용하지 않는 문자들은 인코딩을 해줘야 한다.