webhacking/sql, sql injection

information_schema

qkqhxla1 2014. 9. 28. 15:05

information_schema 데이터베이스에는 모든 테이블의 정보가 들어있음.


데이터베이스.테이블이름 이런 형식으로 접근 가능함.


많이 쓰이는건


information_schema.tables, information_schema.columns, information_schema.processlist


테이블명을 알아낼때. information_schema.table 테이블의 table_name컬럼이 있음.


이 컬럼은 영어 그대로 테이블 이름을 저장해둠.


select table_name from information_schema.tables; 로 해보면 시스템 테이블이라던지


모든 테이블이 보여져서 찾기가 불편함. 





현재 내가 들어온 db의 테이블만 보려면


select table_name from information_schema.tables where table_schema=database();


로 하면 현재 내가 들어와있는 db의 테이블명이 전부 보이게됨. database()함수는


현재 내 db정보를 보여주는 함수. information_schema.tables 테이블의 table_schema컬럼은


모든 db 정보가 저장되어있는 컬럼. 그러므로 위 쿼리


select table_name from information_schema.tables where table_schema=database();


는 모든 테이블이 저장된곳(information_schema.tables)에서 테이블 이름을 가져와라


(select table_name). 그런데 그 중에 데이터베이스는 현재 내 데이터베이스와 같은 것만


(table_schema=database()), 즉 현재 내 데이터베이스 내부의 테이블이름만 가져와라. 라는


쿼리가 된다. 내 db에 들어가서 show tables; 한 결과랑 같다고 보면 된다.(mysql)


그런데 여기서 또 단점이 있다. 웹해킹 시에 우연히 원하는 결과를 출력하게 했다고 해도


제일 위 하나의 출력되는게 대부분이다. 그러면 하나씩 확인하려면 limit 0,1, limit 1,1;


이런식으로 하나씩 출력해서 목록을 만들어야 하는데 상당히 귀찮고 시간이 오래 걸린다.


하나의 컬럼에 한번에 출력하려면 group_concat()함수를 쓰면 된다. 




이렇게 한 컬럼에 모든 결과를 모아서 출력이 가능하다. 구분은 ,로 구분하니 이게 더 보기 좋다.


그리고 위의 쿼리였던


select table_name from information_schema.tables where table_schema=database(); 를


select group_concat(table_name) from information_schema.tables where table_schema=database();


로 하면 테이블 이름을 보기가 더 편하다. 테이블 이름을 뽑아내려면 여기서 블라인드 인젝션


하듯이 하나씩 뽑아내면 된다.


select ascii(substr(group_concat(table_name),1,1))=숫자 from information_schema.tables where table_schema=database();


여기서 눈으로 보고, 또는 여러가지 정보를 파악하여 내가 원하는 테이블을 파악한 다음. (내가 원하는


테이블이 정확히 뭔지 모르고 여러개 있다고 하면 여러개 테이블의 값을 전부다 뽑아보면 된다.)


테이블이름을 뽑아냈으면 컬럼을 뽑아내야 되는데 위에 말한대로 information_schema.columns


테이블에는 모든 컬럼정보가 들어있다.(데이터형식은 무엇인지, 컬럼 이름은 뭔지 등등등)


우리가 원하는건 컬럼 이름이다. information_schema.columns에는 column_name이라는 컬럼이 


있는데, 여기에 컬럼 이름이 들어있다. 그리고 information_schema.tables 테이블에 table_name


이라는 컬럼이 있고 여기에 테이블 이름이 들어가있다고 했었는데 information_schema.columns


테이블에도 table_name이라는 컬럼이 있다. 이것도 테이블 이름이며, 동일한 정보가 들어가있지만


컬럼 갯수에 따라 동일한 테이블 이름이 반복된다.(설명하기 복잡하니 실험 해보시길 추천.)


그러므로 위의 테이블네임 뽑아오는 과정에서 뽑아온 테이블 이름이 prob


라고 가정하면 select column_name from information_schema.columns where table_name='prob';


같은 형식으로 쿼리를 입력하면 prob라는 테이블에 어떤 컬럼이름을 가진 것들이 있는지 알 수 있다.




제대로 뜨는걸 확인할수 있다. 컬럼명을 한 컬럼에 보려면 위에서 말했듯이 group_concat(column_name)


으로 확인 가능하다. 위 prob테이블을 예로들면 컬럼명이 id,pw라는걸 확인했으니 이제 값을 또 뽑아오면


된다. pw을 뽑는다고 가정하면 이제 정상적으로 select ascii(substr(pw,1,1))=숫자 from prob;


등의 형식으로 뽑아오면 된다. 여기서 필터링이 걸리면 관련 문서를 보고 필터링을 우회하면 된다.


그리고 마지막으로 information_schema.processlist 테이블이 있는데 이건 현재 실행중인 쿼리를


보여준다.



sqli는 가능한데 db나 다른 환경을 모를 경우 이용하면 정보 얻기가 쉬울 것 같다.




요런식으로 인젝션해서 어떻게 값을 잘 뽑아오면 될듯 싶다.. 아니면 다른 방법이나.


information_schema.tables나 information_schema.columns테이블에는 여러 가지 다른 컬럼도


많으니 찾아보시길.



추가.

select * from information_schema.schemata; 

여기에는 db 이름이 있다.

mysql> select group_concat(schema_name) from information_schema.schemata;

+-------------------------------------------------------------+

| group_concat(schema_name)                                   |

+-------------------------------------------------------------+

| information_schema,challenge_30_table,mydb,mysql,phpmyadmin |

+-------------------------------------------------------------+

'webhacking > sql, sql injection' 카테고리의 다른 글

webhacking.kr 18번.  (0) 2014.10.03
wargame.kr DB is really GOOD  (0) 2014.10.01
wargame.kr lonely_guys  (0) 2014.09.28
rubiya.kr 19번 다른방법.(원래방법?)  (3) 2014.09.11
rubiya.kr 19번.  (0) 2014.09.10