SQL Injection(Advanced)
SQL Injection에서 좀 더 어려운 난이도를 도전해보자!
실습
먼저
1' or '1'='1'--
와 같이 항상 참이 되는 SQL 문을 입력해보자. 이때 조회되는 열의 개수는 7개다. 이때 '--'는 주석처리다.
union을 이용해서 dave의 비밀번호를 알아내보자. 쿼리문
' union select userid, user_name, password, cookie, null, null, null from user_system_data --
을 살펴보면 홑따옴표(')을 통해 앞의 쿼리문을 종결하고, 실제 얻고 싶은 쿼리문을 union 뒤에 쓴다.
union을 쓸 때는 앞의 쿼리와 열의 수를 맞춰야한다!
이번에는 다중 쿼리를 이용해보자.
'; select * from user_system_data --
와 같이 앞의 쿼리문을 세미콜론(;)을 통해 종결하고 쓰고 싶은 쿼리는 쓰면 된다.
이번에는 TOM의 비밀번호를 알아내는 문제다. 문제에 살짝 옥의 티가 있는데 id는 tom과 같이 소문자로 써야 한다.
먼저 참인 쿼리문이 통하는지 확인해보자.
새 아이디를 만드는 탭이 있다. 계정을 생성 후 다른 방법이 있는지 확인해야 할 것 같다.
id : test
email : 1@abc.com
password : 123
로 계정을 생성 후 똑같이 만들어보자.
혹시 boolean 문이 아닐까? 시도해보자.
test' and 1=2 --
와 같이 항상 거짓인 SQL 문을 입력했더니 id가 생성됐다.
test' or 1=1 --
와 같이 입력하면 id가 생성되지 않는다.
즉, id를 확인할 때 select를 사용해서 참, 거짓의 결과를 통해 id를 생성 여부를 결정하는 것 같다.
이제 참, 거짓 정도는 우리가 판단할 수 있게 된 것이다!
tom' and length(userid)=3 --
와 같이 이력하면 참인 SQL이므로 id가 생성되지 않는다.
tom' and substr(password,1,1)='a' --
와 같이 입력해보자.
이런 방법으로 시도하면 언젠가 비밀번호를 알 수 있다! 시간이 많이 걸리므로 무작위 공격을 시도하자.
이제 bupr suit을 통해 무작위 공격을 시도해보려고 한다. intercept를 on으로 켜고 아래와 같이 설정해보자.
tom' and substr(password,1,1)='a' --
을 입력하고 Register Now를 클릭하면 아래와 같이 패킷을 잡을 수 있다.
Intruder 탭에서 아래와 같이 설정하자.
비밀번호가 몇 자리인지 알고 하면 더욱 간편하다.
이 경우에는 몇 자리인지 모르고 시작했기 때문에 10자리 단위마다 무작위 공격을 시행했다.
21~30자리 무작위 공격은 중간에 끄고, 21~24자리까지만 무작위 공격을 시행했다.
결과를 조합해보면
thisisasecretfortomonly
가 비밀번호임을 알 수 있다.
this is a secret for to monly
와 같이 뜻이 담겨있다. 짧은 실습이었지만 정말 재밌었다.
tom' and length(password)<30 --
와 같이 예측해보는 방법으로
무작위 공격을 시행하기 전 실제 23자리 임을 미리 확인할 수 있다.